source: MondoRescue/branches/stable/mondo/src/mondorestore/mondo-rstr-tools.c@ 1581

Last change on this file since 1581 was 1581, checked in by Bruno Cornec, 17 years ago

Continue to remove floppy support

  • Property svn:keywords set to Id
File size: 70.8 KB
RevLine 
[1]1/***************************************************************************
[1080]2 * $Id: mondo-rstr-tools.c 1581 2007-07-27 00:11:55Z bruno $
[1]3*/
4
5
6#include <pthread.h>
[1216]7#include <unistd.h>
[1067]8#include "my-stuff.h"
[1168]9#include "mr_mem.h"
10#include "mr_msg.h"
11#include "mr_str.h"
[1556]12#include "mr_gettext.h"
[1168]13
14#include "mondostructures.h"
15#include "libmondo.h"
[1]16#include "mr-externs.h"
17#include "mondo-rstr-tools.h"
18
[1268]19extern char *bkptype_to_string(t_bkptype bt);
20
[1]21extern bool g_sigpipe_caught;
[128]22extern bool g_ISO_restore_mode; /* are we in Iso Mode? */
[1]23extern bool g_I_have_just_nuked;
24extern char *g_tmpfs_mountpt;
25extern char *g_isodir_device;
26extern char *g_isodir_format;
27extern long g_current_progress, g_maximum_progress;
[128]28extern char *g_biggielist_txt; // where 'biggielist.txt' is stored, on ramdisk / tempdir;
29 // biggielist.txt is the list of big files stored on the
30 // backup media set in question
31extern char *g_filelist_full; // filelist.full.gz is the list of all regular files
32 // (excluding big files) stored on the backup media set
33extern char *g_biggielist_pot; // list of big files which _could_ be restored, if the
34 // user chooses them
35extern char *g_filelist_imagedevs; // list of devices (e.g. /dev/hda1, /dev/sda5) which
36 // were archived as images, not just /dev entries
37 // ... e.g. NTFS, BeOS partitions
38extern char *g_imagedevs_restthese; // of the imagedevs listed in FILELIST_IMAGEDEVS,
39 // restore only these
40extern char *g_mondo_cfg_file; // where m*ndo-restore.cfg (the config file) is stored
41extern char *g_mountlist_fname; // where mountlist.txt (the mountlist file) is stored
[1]42
43extern t_bkptype g_backup_media_type;
[1216]44extern char *g_backup_media_string;
[1]45
46extern int g_partition_table_locked_up;
[1326]47extern char *MONDO_LOGFILE;
[1]48
[949]49/* Should we use or not extended attributes and acl when restoring */
50char *g_getfattr = NULL;
51char *g_getfacl = NULL;
52
[1]53/**
54 * @addtogroup restoreUtilityGroup
55 * @{
56 */
57/**
58 * Free the malloc()s for the filename variables.
59 */
[1103]60void free_MR_global_filenames(void)
[1]61{
[1080]62 mr_free(g_biggielist_txt);
63 mr_free(g_filelist_full);
64 mr_free(g_filelist_imagedevs);
65 mr_free(g_imagedevs_restthese);
66 mr_free(g_mondo_cfg_file);
67 mr_free(g_mountlist_fname);
68 mr_free(g_tmpfs_mountpt);
69 mr_free(g_isodir_device);
70 mr_free(g_isodir_format);
[1]71}
72
73
74/**
75 * Ask the user which imagedevs from the list contained in @p infname should
76 * actually be restored.
77 * @param infname The file containing a list of all imagedevs.
78 * @param outfname The location of the output file containing the imagedevs the user wanted to restore.
79 * @ingroup restoreUtilityGroup
80 */
[128]81void ask_about_these_imagedevs(char *infname, char *outfname)
[1]82{
[1216]83 FILE *fin = NULL;
84 FILE *fout = NULL;
[1]85 /************************************************************************
86 * allocate memory regions. test and set -sab 16 feb 2003 *
87 ************************************************************************/
[1216]88 char *incoming = NULL;
89 char *question = NULL;
[1]90
[1216]91 size_t n = 0;
[1]92
[128]93 assert_string_is_neither_NULL_nor_zerolength(infname);
94 assert_string_is_neither_NULL_nor_zerolength(outfname);
[1]95
[128]96 if (!(fin = fopen(infname, "r"))) {
97 fatal_error("Cannot openin infname");
[1]98 }
[128]99 if (!(fout = fopen(outfname, "w"))) {
100 fatal_error("Cannot openin outfname");
101 }
[1216]102 for (mr_getline(&incoming, &n, fin);
103 !feof(fin); mr_getline(&incoming, &n, fin)) {
104 mr_strip_spaces(incoming);
[1]105
[128]106 if (incoming[0] == '\0') {
107 continue;
108 }
[1]109
[1216]110 mr_asprintf(&question,
111 _("Should I restore the image of %s ?"), incoming);
[128]112
[1216]113 if (ask_me_yes_or_no(question)) {
114 fprintf(fout, "%s\n", incoming);
[128]115 }
[1216]116 mr_free(question);
[128]117 }
118
[1]119 /*** free memory ***********/
[1216]120 mr_free(incoming);
[1]121
[128]122 paranoid_fclose(fout);
123 paranoid_fclose(fin);
[1]124}
125
126/**************************************************************************
127 *ASK_ABOUT_THESE_IMAGEDEVS *
128 **************************************************************************/
129
130
131/**
132 * Extract @c mondo-restore.cfg and @c mountlist.txt from @p ramdisk_fname.
133 * @param bkpinfo The backup information structure. @c tmpdir is the only field used.
134 * @param ramdisk_fname The filename of the @b compressed ramdisk to look in.
135 * @param output_cfg_file Where to put the configuration file extracted.
136 * @param output_mountlist_file Where to put the mountlist file extracted.
137 * @return 0 for success, nonzero for failure.
138 * @ingroup restoreUtilityGroup
139 */
[128]140int
141extract_config_file_from_ramdisk(struct s_bkpinfo *bkpinfo,
142 char *ramdisk_fname,
143 char *output_cfg_file,
144 char *output_mountlist_file)
[1]145{
[1216]146 char *mountpt = NULL;
147 char *command = NULL;
148 char *orig_fname = NULL;
[128]149 int retval = 0;
[1]150
[128]151 assert(bkpinfo != NULL);
152 assert_string_is_neither_NULL_nor_zerolength(ramdisk_fname);
153 assert_string_is_neither_NULL_nor_zerolength(output_cfg_file);
154 assert_string_is_neither_NULL_nor_zerolength(output_mountlist_file);
[1216]155 mr_asprintf(&mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
156 mr_asprintf(&command, "mkdir -p %s", mountpt);
[128]157 run_program_and_log_output(command, FALSE);
[1216]158 mr_free(command);
159
160 mr_asprintf(&command, "gzip -dc %s > %s/mindi.rd 2> /dev/null",
[128]161 ramdisk_fname, bkpinfo->tmpdir);
162 run_program_and_log_output(command, FALSE);
[1216]163 mr_free(command);
[1]164
[1216]165 mr_asprintf(&command, "umount %s", mountpt);
[128]166 run_program_and_log_output(command, FALSE);
[1216]167 mr_free(command);
[1]168
[1216]169 mr_asprintf(&command, "mount -o loop %s/mindi.rd -t ext2 %s",
[128]170 bkpinfo->tmpdir, mountpt);
171 run_program_and_log_output(command, FALSE);
[1216]172 mr_free(command);
[1]173
[1216]174 mr_asprintf(&command, "mkdir -p %s/tmp", bkpinfo->tmpdir);
[128]175 run_program_and_log_output(command, FALSE);
[1216]176 mr_free(command);
[1]177
[1216]178 mr_asprintf(&command, "cp -f %s/%s %s", // %s/%s becomes {mountpt}/tmp/m*ndo-restore.cfg
[128]179 mountpt, g_mondo_cfg_file, output_cfg_file);
180 run_program_and_log_output(command, FALSE);
[1216]181 mr_free(command);
[1]182
[1216]183 mr_asprintf(&orig_fname, "%s/%s", mountpt, g_mountlist_fname);
[128]184 if (does_file_exist(orig_fname)) {
[1216]185 mr_asprintf(&command, "cp -f %s %s", orig_fname, output_mountlist_file);
[128]186 run_program_and_log_output(command, FALSE);
[1216]187 mr_free(command);
[128]188 }
[1216]189 mr_asprintf(&command, "umount %s", mountpt);
190 mr_free(mountpt);
191
[128]192 run_program_and_log_output(command, FALSE);
[1216]193 mr_free(command);
194
[128]195 if (!does_file_exist(output_cfg_file)
196 || (!does_file_exist(output_mountlist_file)
197 && does_file_exist(orig_fname))) {
[1108]198 mr_msg(2, "Failed to extract %s and/or %s from ramdisk",
[128]199 output_cfg_file, output_mountlist_file);
200 retval = 1;
201 } else {
202 retval = 0;
203 }
[1080]204 mr_free(orig_fname);
[128]205 return (retval);
[1]206}
207
208
209/**
210 * Keep trying to get mondo-restore.cfg from the archive, until the user gives up.
211 * @param bkpinfo The backup information structure.
212 */
213void get_cfg_file_from_archive_or_bust(struct s_bkpinfo *bkpinfo)
214{
[128]215 while (get_cfg_file_from_archive(bkpinfo)) {
216 if (!ask_me_yes_or_no
[1216]217 (_
218 ("Failed to find config file/archives. Choose another source?")))
[128]219 {
220 fatal_error("Could not find config file/archives. Aborting.");
221 }
222 interactively_obtain_media_parameters_from_user(bkpinfo, FALSE);
223 }
[1]224}
225
226
227/**
228 * Determine whether @p list_fname contains a line containing @p f.
229 * @param f The line to search for.
230 * @param list_fname The file to search in.
231 * @param preamble Ignore this beginning part of @p f ("" to disable).
232 * @return TRUE if it's in the list, FALSE if it's not.
233 */
[128]234bool is_file_in_list(char *f, char *list_fname, char *preamble)
[1]235{
236
237 /** needs malloc **/
[1216]238 char *command = NULL;
239 char *file = NULL;
240 char *tmp = NULL;
241 int res = 0;
[1]242
[128]243 assert_string_is_neither_NULL_nor_zerolength(f);
244 assert_string_is_neither_NULL_nor_zerolength(list_fname);
245 assert(preamble != NULL);
[1]246
[128]247 if (strncmp(preamble, f, strlen(preamble)) == 0) {
[1216]248 mr_asprintf(&file, f + strlen(preamble));
[128]249 } else {
[1216]250 mr_asprintf(&file, f);
[128]251 }
252 if (file[0] == '/' && file[1] == '/') {
[1216]253 mr_asprintf(&tmp, file);
254 mr_free(file);
255 mr_asprintf(&file, tmp + 1);
256 mr_free(tmp);
[128]257 }
[1216]258 mr_msg(2, "Checking to see if f=%s, file=%s, is in the list of biggiefiles",
[128]259 f, file);
[1216]260 mr_asprintf(&command, "grep -E '^%s$' %s", file, list_fname);
261 mr_free(file);
262
[128]263 res = run_program_and_log_output(command, FALSE);
[1080]264 mr_free(command);
[128]265 if (res) {
266 return (FALSE);
267 } else {
268 return (TRUE);
269 }
[1]270}
271/**************************************************************************
272 *END_IS_FILE_IN_LIST *
273 **************************************************************************/
274
275
276/**
277 * Set up an ISO backup.
278 * @param bkpinfo The backup information structure. Fields used:
279 * - @c bkpinfo->backup_media_type
280 * - @c bkpinfo->disaster_recovery
281 * - @c bkpinfo->isodir
282 * @param nuke_me_please If TRUE, we're in nuke mode; if FALSE we're in interactive mode.
283 * @return 0 for success, nonzero for failure.
284 */
285int iso_fiddly_bits(struct s_bkpinfo *bkpinfo, bool nuke_me_please)
286{
[1216]287 char *mount_isodir_command = NULL;
288 char *command = NULL;
289 int retval = 0, i = 0;
[128]290 bool already_mounted = FALSE;
[1]291
[128]292 assert(bkpinfo != NULL);
[1216]293
[128]294 g_ISO_restore_mode = TRUE;
295 read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
296 if (bkpinfo->disaster_recovery) {
[1216]297 /* Patch Conor Daly 26-june-2004
298 * Don't let this clobber an existing bkpinfo->isodir */
299 if (!bkpinfo->isodir) {
300 mr_allocstr(bkpinfo->isodir, "/tmp/isodir");
[128]301 }
[1]302/* End patch */
[1216]303 mr_asprintf(&command, "mkdir -p %s", bkpinfo->isodir);
[128]304 run_program_and_log_output(command, 5);
[1216]305 mr_free(command);
[1108]306 mr_msg(2, "Setting isodir to %s", bkpinfo->isodir);
[128]307 }
[1]308
[128]309 if (!get_isodir_info
310 (g_isodir_device, g_isodir_format, bkpinfo->isodir,
311 nuke_me_please)) {
312 return (1);
313 }
314 paranoid_system("umount " MNT_CDROM " 2> /dev/null"); /* just in case */
[1]315
[128]316 if (is_this_device_mounted(g_isodir_device)) {
[1216]317 log_to_screen(_("WARNING - isodir is already mounted"));
[128]318 already_mounted = TRUE;
319 } else {
320 if (strlen(g_isodir_format) > 1) {
[1216]321 mr_asprintf(&mount_isodir_command, "mount %s -t %s -o ro %s", g_isodir_device, g_isodir_format, bkpinfo->isodir);
322 } else {
323 mr_asprintf(&mount_isodir_command, "mount %s -o ro %s", g_isodir_device, bkpinfo->isodir);
[128]324 }
[691]325 run_program_and_log_output("df -m", FALSE);
[1216]326 mr_msg(1, "The 'mount' command is '%s'. PLEASE report this command to be if you have problems, ok?",
[128]327 mount_isodir_command);
328 if (run_program_and_log_output(mount_isodir_command, FALSE)) {
329 popup_and_OK
[1216]330 (_
331 ("Cannot mount the device where the ISO files are stored."));
332 mr_free(mount_isodir_command);
[128]333 return (1);
334 }
[1216]335 mr_free(mount_isodir_command);
[128]336 log_to_screen
[1216]337 (_
338 ("I have mounted the device where the ISO files are stored."));
[128]339 }
340 if (!IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
341 mount_cdrom(bkpinfo);
342 }
343 i = what_number_cd_is_this(bkpinfo); /* has the side-effect of calling mount_cdrom() */
[1216]344 mr_msg(1, "%s #%d has been mounted via loopback mount",
345 bkpinfo->backup_media_string, i);
[128]346 if (i < 0) {
347 popup_and_OK
[1216]348 (_("Cannot find ISO images in the directory you specified."));
[128]349 retval = 1;
350 }
[1108]351 mr_msg(2, "%ld: bkpinfo->isodir is now %s", __LINE__,
[128]352 bkpinfo->isodir);
353 return (retval);
[1]354}
355
356
357/**
358 * Kill all Petris processes.
359 */
[128]360void kill_petris(void)
[1]361{
[1216]362 char *command = NULL;
363 mr_asprintf(&command,
[792]364 "kill `ps 2> /dev/null | grep petris 2> /dev/null | grep -v grep | cut -d' ' -f2` 2> /dev/null");
[128]365 paranoid_system(command);
[1080]366 mr_free(command);
[1]367}
[128]368
[1]369/**************************************************************************
370 *END_KILL_PETRIS *
371 **************************************************************************/
372
373/**
[1216]374 * Mount @p device at @p mpt as @p format.
375 * @param device The device (/dev entry) to mount.
376 * @param mpt The directory to mount it on.
377 * @param format The filesystem type of @p device.
378 * @param writeable If TRUE, mount read-write; if FALSE, mount read-only.
[1]379 * @return 0 for success, nonzero for failure.
380 */
[1216]381int mount_device(char *device, char *mpt, char *format, bool writeable)
[1]382{
[1216]383 int res = 0;
[1]384
[1216]385 char *command = NULL;
386 char *mountdir = NULL;
387 char *mountpoint = NULL;
388 char *additional_parameters = NULL;
[1219]389
[1216]390 assert_string_is_neither_NULL_nor_zerolength(device);
391 assert_string_is_neither_NULL_nor_zerolength(mpt);
392 assert(format != NULL);
[1]393
[1216]394 if (!strcmp(mpt, "/1")) {
395 mr_asprintf(&mountpoint, "/");
396 mr_msg(3, "Mommm! SME is being a dildo!");
397 } else {
398 mr_asprintf(&mountpoint, mpt);
399 }
[1]400
[1216]401 if (!strcmp(mountpoint, "lvm")) {
402 mr_free(mountpoint);
403 return (0);
404 }
405 if (!strcmp(mountpoint, "image")) {
406 mr_free(mountpoint);
407 return (0);
408 }
[1219]409 mr_msg(1, "Mounting device %s ", device);
[1216]410 if (writeable) {
[1219]411 mr_asprintf(&additional_parameters, "-o rw");
[1216]412 } else {
[1219]413 mr_asprintf(&additional_parameters, "-o ro");
[1216]414 }
415 if (find_home_of_exe("setfattr")) {
[1219]416 mr_strcat(additional_parameters, ",user_xattr");
[1216]417 }
418 if (find_home_of_exe("setfacl")) {
[1219]419 mr_strcat(additional_parameters, ",acl");
[1216]420 }
[1]421
[1216]422 if (!strcmp(mountpoint, "swap")) {
[1219]423 mr_asprintf(&command, "swapon %s", device);
[1216]424 } else {
425 if (!strcmp(mountpoint, "/")) {
[1219]426 mr_asprintf(&mountdir, MNT_RESTORING);
[1216]427 } else {
[1219]428 mr_asprintf(&mountdir, "%s%s", MNT_RESTORING, mountpoint);
[1216]429 }
[1219]430 mr_asprintf(&command, "mkdir -p %s", mountdir);
[1216]431 run_program_and_log_output(command, FALSE);
[1219]432 mr_free(command);
433
434 mr_asprintf(&command, "mount -t %s %s %s %s 2>> %s", format, device,
[1216]435 additional_parameters, mountdir, MONDO_LOGFILE);
436 mr_msg(2, "command='%s'", command);
[128]437 }
[1219]438 mr_free(additional_parameters);
439
[1216]440 res = run_program_and_log_output(command, TRUE);
441 if (res && (strstr(command, "xattr") || strstr(command, "acl"))) {
442 mr_msg(1, "Re-trying without the fancy extra parameters");
[1219]443 mr_free(command);
444
445 mr_asprintf(&command, "mount -t %s %s %s 2>> %s", format, device,
[1216]446 mountdir, MONDO_LOGFILE);
447 res = run_program_and_log_output(command, TRUE);
[128]448 }
[1216]449 if (res) {
450 mr_msg(1, "Unable to mount device %s (type %s) at %s", device,
451 format, mountdir);
452 mr_msg(1, "command was '%s'", command);
453 if (!strcmp(mountpoint, "swap")) {
[1219]454 log_to_screen("Unable to mount device %s (type %s) at %s", device,
455 format, mountdir);
[1216]456 } else {
457 mr_msg(2, "Retrying w/o the '-t' switch");
[1219]458 mr_free(command);
459
460 mr_asprintf(&command, "mount %s %s 2>> %s", device, mountdir,
[1216]461 MONDO_LOGFILE);
462 mr_msg(2, "2nd command = '%s'", command);
463 res = run_program_and_log_output(command, TRUE);
464 if (res == 0) {
465 mr_msg(1,
466 "That's OK. I called mount w/o a filesystem type and it worked fine in the end.");
467 }
468 }
469 }
[1219]470 mr_free(command);
471 mr_free(mountdir);
472
[1216]473 if (res && !strcmp(mountpoint, "swap")) {
474 mr_msg(2, "That's ok. It's just a swap partition.");
475 mr_msg(2, "Non-fatal error. Returning 0.");
476 res = 0;
477 }
478 mr_free(mountpoint);
479
480 return (res);
[1]481}
482/**************************************************************************
[1216]483 *END_MOUNT_DEVICE *
[1]484 **************************************************************************/
485
486
487/**
488 * Mount all devices in @p p_external_copy_of_mountlist on @p MNT_RESTORING.
489 * @param p_external_copy_of_mountlist The mountlist containing devices to be mounted.
490 * @param writeable If TRUE, then mount read-write; if FALSE mount read-only.
491 * @return The number of errors encountered (0 for success).
492 */
[128]493int mount_all_devices(struct mountlist_itself
494 *p_external_copy_of_mountlist, bool writeable)
[1]495{
[1219]496 int retval = 0;
497 int lino = 0;
498 int res = 0;
499 char *tmp = NULL;
500 char *these_failed = NULL;
501 char *format = NULL;
502 struct mountlist_itself *mountlist = NULL;
[1]503
[128]504 assert(p_external_copy_of_mountlist != NULL);
[1102]505 mountlist = (struct mountlist_itself *)mr_malloc(sizeof(struct mountlist_itself));
[128]506 memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
507 sizeof(struct mountlist_itself));
508 sort_mountlist_by_mountpoint(mountlist, 0);
[1]509
[1219]510 mvaddstr_and_log_it(g_currentY, 0, _("Mounting devices "));
511 open_progress_form(_("Mounting devices"),
512 _("I am now mounting all the drives."),
513 _("This should not take long."),
[128]514 "", mountlist->entries);
515
516 for (lino = 0; lino < mountlist->entries; lino++) {
517 if (!strcmp(mountlist->el[lino].device, "/proc")) {
[1108]518 mr_msg(1,
[128]519 "Again with the /proc - why is this in your mountlist?");
520 } else if (is_this_device_mounted(mountlist->el[lino].device)) {
[1219]521 log_to_screen(_("%s is already mounted"),
[128]522 mountlist->el[lino].device);
523 } else if (strcmp(mountlist->el[lino].mountpoint, "none")
524 && strcmp(mountlist->el[lino].mountpoint, "lvm")
525 && strcmp(mountlist->el[lino].mountpoint, "raid")
526 && strcmp(mountlist->el[lino].mountpoint, "image")) {
[1219]527 mr_asprintf(&tmp, "Mounting %s", mountlist->el[lino].device);
[128]528 update_progress_form(tmp);
[1219]529 mr_free(tmp);
530
531 mr_asprintf(&format, mountlist->el[lino].format);
[128]532 if (!strcmp(format, "ext3")) {
[1219]533 mr_free(format);
534 mr_asprintf(&format, "ext2");
[128]535 }
536 res = mount_device(mountlist->el[lino].device,
537 mountlist->el[lino].mountpoint,
538 format, writeable);
539 retval += res;
540 if (res) {
[1219]541 if (these_failed != NULL) { /* not the first time */
542 mr_strcat(these_failed, " %s", mountlist->el[lino].device);
543 } else { /* The first time */
544 mr_asprintf(&these_failed, "%s", mountlist->el[lino].device);
545 }
[128]546 }
[1219]547 mr_free(format);
[128]548 }
549 g_current_progress++;
[1]550 }
[128]551 close_progress_form();
[691]552 run_program_and_log_output("df -m", TRUE);
[128]553 if (retval) {
554 if (g_partition_table_locked_up > 0) {
555 log_to_screen
[1219]556 (_
557 ("fdisk's ioctl() call to refresh its copy of the partition table causes the kernel to"));
558 log_to_screen(_
559 ("lock up the partition table. You might have to reboot and use Interactive Mode to"));
560 log_to_screen(_
561 ("format and restore *without* partitioning first. Sorry for the inconvenience."));
[128]562 }
[1219]563 mr_asprintf(&tmp, _("Could not mount devices %s- shall I abort?"),
[128]564 these_failed);
[1219]565 mr_free(these_failed);
566
[128]567 if (!ask_me_yes_or_no(tmp)) {
568 retval = 0;
569 log_to_screen
[1219]570 (_
571 ("Continuing, although some devices failed to be mounted"));
572 mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
[128]573 } else {
[1219]574 mvaddstr_and_log_it(g_currentY++, 74, _("Failed."));
[128]575 log_to_screen
[1219]576 (_("Unable to mount some or all of your partitions."));
[128]577 }
[1219]578 mr_free(tmp);
[128]579 } else {
[1219]580 log_to_screen(_("All partitions were mounted OK."));
581 mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
[1]582 }
[691]583 run_program_and_log_output("df -m", 3);
[1124]584 mr_free(mountlist);
[128]585 return (retval);
[1]586}
587 /**************************************************************************
588 *END_MOUNT_ALL_DEVICES *
589 **************************************************************************/
590
591
592/**
593 * Mount the CD-ROM device at /mnt/cdrom.
594 * @param bkpinfo The backup information structure. Fields used:
595 * - @c bkpinfo->backup_media_type
596 * - @c bkpinfo->disaster_recovery
597 * - @c bkpinfo->isodir
598 * - @c bkpinfo->media_device
599 * @return 0 for success, nonzero for failure.
600 */
601int mount_cdrom(struct s_bkpinfo *bkpinfo)
602{
[1219]603 char *mount_cmd = NULL;
604 int i = 0, res = 0;
[1]605#ifdef __FreeBSD__
[1219]606 char *mddev = NULL;
[1]607#endif
608
[128]609 assert(bkpinfo != NULL);
[1]610
[128]611 if (bkpinfo->backup_media_type == tape
612 || bkpinfo->backup_media_type == udev) {
[1108]613 mr_msg(8, "Tape/udev. Therefore, no need to mount CDROM.");
[128]614 return 0;
615 }
[1]616
[681]617 if (!run_program_and_log_output("mount | grep -F " MNT_CDROM, FALSE)) {
[1108]618 mr_msg(2, "mount_cdrom() - CD already mounted. Fair enough.");
[128]619 return (0);
[1]620 }
621
[128]622 if (bkpinfo->backup_media_type == nfs) {
[1108]623 mr_msg(2, "Mounting for NFS thingy");
624 mr_msg(2, "isodir = %s", bkpinfo->isodir);
[128]625 if ((!bkpinfo->isodir[0] || !strcmp(bkpinfo->isodir, "/"))
626 && am_I_in_disaster_recovery_mode()) {
627 strcpy(bkpinfo->isodir, "/tmp/isodir");
[1108]628 mr_msg(1, "isodir is being set to %s", bkpinfo->isodir);
[128]629 }
[1]630#ifdef __FreeBSD__
[1219]631 mr_asprintf(&mount_cmd, "/mnt/isodir/%s/%s/%s-%d.iso", bkpinfo->isodir,
632 bkpinfo->nfs_remote_dir, bkpinfo->prefix,
633 g_current_media_number);
[128]634 mddev = make_vn(mount_cmd);
[1219]635 mr_free(mount_cmd);
636
637 mr_asprintf(&mount_cmd, "mount_cd9660 -r %s " MNT_CDROM, mddev);
638 mr_free(mddev);
[1]639#else
[1219]640 mr_asprintf(&mount_cmd,
641 "mount %s/%s/%s-%d.iso -t iso9660 -o loop,ro %s",
642 bkpinfo->isodir, bkpinfo->nfs_remote_dir, bkpinfo->prefix,
643 g_current_media_number, MNT_CDROM);
[1]644#endif
645
[1219]646 } else if (bkpinfo->backup_media_type == iso) {
[1]647#ifdef __FreeBSD__
[1219]648 mr_asprintf(&mount_cmd, "%s/%s-%d.iso", bkpinfo->isodir,
[148]649 bkpinfo->prefix, g_current_media_number);
[128]650 mddev = make_vn(mount_cmd);
[1219]651 mr_free(mount_cmd);
652
653 mr_asprintf(&mount_cmd, "mount_cd9660 -r %s %s", mddev, MNT_CDROM);
654 mr_free(mddev);
[1]655#else
[1219]656 mr_asprintf(&mount_cmd, "mount %s/%s-%d.iso -t iso9660 -o loop,ro %s",
657 bkpinfo->isodir, bkpinfo->prefix, g_current_media_number,
658 MNT_CDROM);
[1]659#endif
[128]660 } else if (strstr(bkpinfo->media_device, "/dev/"))
[1]661#ifdef __FreeBSD__
[128]662 {
[1219]663 mr_asprintf(&mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device,
[128]664 MNT_CDROM);
665 }
[1]666#else
[128]667 {
[1219]668 mr_asprintf(&mount_cmd, "mount %s -t iso9660 -o ro %s",
[128]669 bkpinfo->media_device, MNT_CDROM);
670 }
[1]671#endif
672
[128]673 else {
674 if (bkpinfo->disaster_recovery
675 && does_file_exist("/tmp/CDROM-LIVES-HERE")) {
676 strcpy(bkpinfo->media_device,
677 last_line_of_file("/tmp/CDROM-LIVES-HERE"));
678 } else {
679 find_cdrom_device(bkpinfo->media_device, TRUE);
680 }
[1]681
682#ifdef __FreeBSD__
[1219]683 mr_asprintf(&mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device,
[128]684 MNT_CDROM);
[1]685#else
[1219]686 mr_asprintf(&mount_cmd, "mount %s -t iso9660 -o ro %s",
[128]687 bkpinfo->media_device, MNT_CDROM);
[1]688#endif
689
690 }
[1108]691 mr_msg(2, "(mount_cdrom) --- command = %s", mount_cmd);
[128]692 for (i = 0; i < 2; i++) {
693 res = run_program_and_log_output(mount_cmd, FALSE);
694 if (!res) {
695 break;
696 } else {
[1108]697 mr_msg(2, "Failed to mount CD-ROM drive.");
[128]698 sleep(5);
699 run_program_and_log_output("sync", FALSE);
700 }
[1]701 }
[1219]702 mr_free(mount_cmd);
703
[128]704 if (res) {
[1108]705 mr_msg(2, "Failed, despite %d attempts", i);
[128]706 } else {
[1108]707 mr_msg(2, "Mounted CD-ROM drive OK");
[128]708 }
709 return (res);
[1]710}
711/**************************************************************************
712 *END_MOUNT_CDROM *
713 **************************************************************************/
714
715
716/**
717 * Fix some miscellaneous things in the filesystem so the system will come
718 * up correctly on the first boot.
719 */
[128]720void protect_against_braindead_sysadmins()
[1]721{
[128]722 run_program_and_log_output("touch " MNT_RESTORING "/var/log/pacct",
723 FALSE);
724 run_program_and_log_output("touch " MNT_RESTORING "/var/account/pacct",
725 FALSE);
726 if (run_program_and_log_output("ls " MNT_RESTORING " /tmp", FALSE)) {
727 run_program_and_log_output("chmod 1777 " MNT_RESTORING "/tmp",
728 FALSE);
729 }
730 run_program_and_log_output("mkdir -p " MNT_RESTORING
731 "/var/run/console", FALSE);
732 run_program_and_log_output("chmod 777 " MNT_RESTORING "/dev/null",
733 FALSE);
734 run_program_and_log_output("cd " MNT_RESTORING
[691]735 "; for i in `ls home/`; do echo \"Moving $i's spurious files to $i/.disabled\"; mkdir \"$i\"/.disabled ; mv -f \"$i\"/.DCOP* \"$i\"/.MCOP* \"$i\"/.*authority \"$i\"/.kde/tmp* \"$i\"/.kde/socket* \"$i\"/.disabled/ ; done",
[128]736 TRUE);
737 run_program_and_log_output("rm -f " MNT_RESTORING "/var/run/*.pid",
738 TRUE);
739 run_program_and_log_output("rm -f " MNT_RESTORING "/var/lock/subsys/*",
740 TRUE);
[1]741}
742/**************************************************************************
743 *END_PROTECT_AGAINST_BRAINDEAD_SYSADMINS *
744 **************************************************************************/
745
746
747/**
748 * Fill out @p bkpinfo based on @p cfg_file.
749 * @param cfg_file The mondo-restore.cfg file to read into @p bkpinfo.
750 * @param bkpinfo The backup information structure to fill out with information
751 * from @p cfg_file.
752 * @return 0 for success, nonzero for failure.
753 */
[128]754int read_cfg_file_into_bkpinfo(char *cfgf, struct s_bkpinfo *bkpinfo)
[1]755{
[870]756 char *value = NULL;
757 char *tmp = NULL;
[873]758 char *envtmp1 = NULL;
759 char *envtmp2 = NULL;
[870]760 char *command = NULL;
761 char *iso_mnt = NULL;
762 char *iso_path = NULL;
763 char *old_isodir = NULL;
[1219]764 char *cfg_file = NULL;
[128]765 t_bkptype media_specified_by_user;
[1]766
[128]767 malloc_string(value);
768 assert(bkpinfo != NULL);
[1]769
[128]770 if (!cfgf) {
[1219]771 cfg_file = g_mondo_cfg_file;
[128]772 } else {
[1219]773 cfg_file = cfgf;
[128]774 }
[1]775
[128]776 media_specified_by_user = bkpinfo->backup_media_type; // or 'none', if not specified
[1]777
[128]778 if (0 == read_cfg_var(cfg_file, "backup-media-type", value)) {
779 if (!strcmp(value, "cdstream")) {
780 bkpinfo->backup_media_type = cdstream;
781 } else if (!strcmp(value, "cdr")) {
782 bkpinfo->backup_media_type = cdr;
783 } else if (!strcmp(value, "cdrw")) {
784 bkpinfo->backup_media_type = cdrw;
785 } else if (!strcmp(value, "dvd")) {
786 bkpinfo->backup_media_type = dvd;
787 } else if (!strcmp(value, "iso")) {
[1219]788 // Patch by Conor Daly - 2004/07/12
[128]789 bkpinfo->backup_media_type = iso;
790 if (am_I_in_disaster_recovery_mode()) {
791 /* Check to see if CD is already mounted before mounting it... */
792 if (!is_this_device_mounted("/dev/cdrom")) {
[1108]793 mr_msg(2,
[128]794 "NB: CDROM device not mounted, mounting...");
795 run_program_and_log_output("mount /dev/cdrom "
796 MNT_CDROM, 1);
797 }
[253]798 if (does_file_exist(MNT_CDROM "/archives/filelist.0")) {
[128]799 bkpinfo->backup_media_type = cdr;
800 run_program_and_log_output("umount " MNT_CDROM, 1);
801 log_it
802 ("Re-jigging configuration AGAIN. CD-R, not ISO.");
803 }
[253]804 }
[251]805 if (read_cfg_var(cfg_file, "iso-prefix", value) == 0) {
806 strcpy(bkpinfo->prefix,value);
807 } else {
808 strcpy(bkpinfo->prefix,STD_PREFIX);
[128]809 }
810 } else if (!strcmp(value, "nfs")) {
811 bkpinfo->backup_media_type = nfs;
[148]812 if (read_cfg_var(cfg_file, "iso-prefix", value) == 0) {
813 strcpy(bkpinfo->prefix,value);
814 } else {
815 strcpy(bkpinfo->prefix,STD_PREFIX);
816 }
[801]817 if (strstr(call_program_and_get_last_line_of_output
818 ("cat /proc/cmdline"), "pxe")) {
[913]819 /* We need to override prefix value in PXE mode as it's
820 * already done in start-nfs */
821 envtmp1 = getenv("imgname");
822 if (envtmp1 == NULL) {
823 fatal_error("no imgname variable in environment");
824 }
825 strcpy(bkpinfo->prefix,envtmp1);
[801]826 }
827
[128]828 } else if (!strcmp(value, "tape")) {
829 bkpinfo->backup_media_type = tape;
830 } else if (!strcmp(value, "udev")) {
831 bkpinfo->backup_media_type = udev;
832 } else {
833 fatal_error("UNKNOWN bkp-media-type");
834 }
835 } else {
836 fatal_error("backup-media-type not specified!");
[1]837 }
[128]838 if (bkpinfo->disaster_recovery) {
839 if (bkpinfo->backup_media_type == cdstream) {
[1219]840 strcpy(bkpinfo->media_device, "/dev/cdrom");
[1384]841 bkpinfo->media_size = (long)1999*1024;
[1376]842 bkpinfo->media_size = (long)650; /* good guess */
[128]843 } else if (bkpinfo->backup_media_type == tape
844 || bkpinfo->backup_media_type == udev) {
845 if (read_cfg_var(cfg_file, "media-dev", value)) {
846 fatal_error("Cannot get tape device name from cfg file");
847 }
848 strcpy(bkpinfo->media_device, value);
849 read_cfg_var(cfg_file, "media-size", value);
[1376]850 bkpinfo->media_size = atol(value);
[1219]851 mr_msg(2, "Backup medium is TAPE --- dev=%s",
[128]852 bkpinfo->media_device);
853 } else {
854 strcpy(bkpinfo->media_device, "/dev/cdrom"); /* we don't really need this var */
[1384]855 bkpinfo->media_size = (long)1999*1024; /* 650, probably, but we don't need this var anyway */
856 bkpinfo->media_size = (long)1999*1024; /* 650, probably, but we don't need this var anyway */
[1108]857 mr_msg(2, "Backup medium is CD-R[W]");
[128]858 }
859 } else {
[1108]860 mr_msg(2,
[128]861 "Not in Disaster Recovery Mode. No need to derive device name from config file.");
[1]862 }
[128]863
864 read_cfg_var(cfg_file, "use-star", value);
865 if (strstr(value, "yes")) {
866 bkpinfo->use_star = TRUE;
[1108]867 mr_msg(1, "Goody! ... bkpinfo->use_star is now true.");
[1]868 }
[128]869
[949]870 read_cfg_var(cfg_file, "acl", value);
[1087]871 if (strstr(value, "yes")) {
[1080]872 mr_asprintf(&g_getfacl,"setfacl");
[1108]873 mr_msg(1, "We will restore ACLs");
[951]874 if (! find_home_of_exe("setfacl")) {
[1108]875 mr_msg(1, "Unable to restore ACLs as no setfacl found");
[949]876 }
877 }
878 read_cfg_var(cfg_file, "xattr", value);
[1087]879 if (strstr(value, "yes")) {
[1080]880 mr_asprintf(&g_getfattr,"setfattr");
[1108]881 mr_msg(1, "We will restore XATTRs");
[951]882 if (! find_home_of_exe("setfattr")) {
[1108]883 mr_msg(1, "Unable to restore XATTRs as no setfattr found");
[949]884 }
885 }
886
[128]887 if (0 == read_cfg_var(cfg_file, "internal-tape-block-size", value)) {
888 bkpinfo->internal_tape_block_size = atol(value);
[1108]889 mr_msg(1, "Internal tape block size has been custom-set to %ld",
[128]890 bkpinfo->internal_tape_block_size);
891 } else {
892 bkpinfo->internal_tape_block_size =
893 DEFAULT_INTERNAL_TAPE_BLOCK_SIZE;
[1108]894 mr_msg(1, "Internal tape block size = default (%ld)",
[128]895 DEFAULT_INTERNAL_TAPE_BLOCK_SIZE);
[1]896 }
[128]897
898 read_cfg_var(cfg_file, "use-lzo", value);
899 if (strstr(value, "yes")) {
900 bkpinfo->use_lzo = TRUE;
[998]901 bkpinfo->use_gzip = FALSE;
[128]902 strcpy(bkpinfo->zip_exe, "lzop");
903 strcpy(bkpinfo->zip_suffix, "lzo");
904 } else {
[998]905 read_cfg_var(cfg_file, "use-gzip", value);
[128]906 if (strstr(value, "yes")) {
907 bkpinfo->use_lzo = FALSE;
[998]908 bkpinfo->use_gzip = TRUE;
909 strcpy(bkpinfo->zip_exe, "gzip");
910 strcpy(bkpinfo->zip_suffix, "gz");
[128]911 } else {
[998]912 read_cfg_var(cfg_file, "use-comp", value);
913 if (strstr(value, "yes")) {
914 bkpinfo->use_lzo = FALSE;
915 bkpinfo->use_gzip = FALSE;
916 strcpy(bkpinfo->zip_exe, "bzip2");
917 strcpy(bkpinfo->zip_suffix, "bz2");
918 } else {
919 bkpinfo->zip_exe[0] = bkpinfo->zip_suffix[0] = '\0';
920 }
[128]921 }
[1]922 }
923
[128]924 value[0] = '\0';
925 read_cfg_var(cfg_file, "differential", value);
926 if (!strcmp(value, "yes") || !strcmp(value, "1")) {
927 bkpinfo->differential = TRUE;
[1]928 }
[1108]929 mr_msg(2, "differential var = '%s'", value);
[128]930 if (bkpinfo->differential) {
[1108]931 mr_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
[128]932 } else {
[1108]933 mr_msg(2, "This is a regular (full) backup");
[1]934 }
935
[128]936 read_cfg_var(g_mondo_cfg_file, "please-dont-eject", tmp);
937 if (tmp[0]
938 ||
939 strstr(call_program_and_get_last_line_of_output
940 ("cat /proc/cmdline"), "donteject")) {
941 bkpinfo->please_dont_eject = TRUE;
[1108]942 mr_msg(2, "Ok, I shan't eject when restoring! Groovy.");
[128]943 }
[1]944
[128]945 if (bkpinfo->backup_media_type == nfs) {
946 if (!cfgf) {
[1108]947 mr_msg(2, "nfs_mount remains %s", bkpinfo->nfs_mount);
948 mr_msg(2, "nfs_remote_dir remains %s",
[128]949 bkpinfo->nfs_remote_dir);
[1108]950 mr_msg(2,
[128]951 "...cos it wouldn't make sense to abandon the values that GOT ME to this config file in the first place");
952 } else {
953 read_cfg_var(g_mondo_cfg_file, "nfs-server-mount",
954 bkpinfo->nfs_mount);
955 read_cfg_var(g_mondo_cfg_file, "nfs-server-path",
956 bkpinfo->nfs_remote_dir);
[1108]957 mr_msg(2, "nfs_mount is %s", bkpinfo->nfs_mount);
958 mr_msg(2, "nfs_remote_dir is %s", bkpinfo->nfs_remote_dir);
[128]959 }
[801]960 if (strstr(call_program_and_get_last_line_of_output
961 ("cat /proc/cmdline"), "pxe")) {
[913]962 /* We need to override values in PXE mode as it's
963 * already done in start-nfs */
964 envtmp1 = getenv("nfsmount");
965 if (envtmp1 == NULL) {
966 fatal_error("no nfsmount variable in environment");
[801]967 }
[913]968 envtmp2 = getenv("dirimg");
969 if (envtmp2 == NULL) {
970 fatal_error("no dirimg variable in environment");
971 }
972 strcpy(bkpinfo->nfs_mount,envtmp1);
973 strcpy(bkpinfo->nfs_remote_dir,envtmp2);
974 }
[128]975 } else if (bkpinfo->backup_media_type == iso) {
976 /* Patch by Conor Daly 23-june-2004
977 * to correctly mount iso-dev and set a sensible
978 * isodir in disaster recovery mode
979 */
[1219]980 mr_asprintf(&old_isodir, bkpinfo->isodir);
[128]981 read_cfg_var(g_mondo_cfg_file, "iso-mnt", iso_mnt);
982 read_cfg_var(g_mondo_cfg_file, "isodir", iso_path);
983 sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
984 if (!bkpinfo->isodir[0]) {
985 strcpy(bkpinfo->isodir, old_isodir);
986 }
987 if (!bkpinfo->disaster_recovery) {
988 if (strcmp(old_isodir, bkpinfo->isodir)) {
989 log_it
990 ("user nominated isodir differs from archive, keeping user's choice: %s %s\n",
991 old_isodir, bkpinfo->isodir);
992 strcpy(bkpinfo->isodir, old_isodir);
993 }
994 }
[1219]995 mr_free(old_isodir);
996
[128]997 read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
[1219]998 mr_msg(2, "isodir=%s; iso-dev=%s", bkpinfo->isodir, g_isodir_device);
[128]999 if (bkpinfo->disaster_recovery) {
1000 if (is_this_device_mounted(g_isodir_device)) {
[1108]1001 mr_msg(2, "NB: isodir is already mounted");
[128]1002 /* Find out where it's mounted */
[1219]1003 mr_asprintf(&command,
[909]1004 "mount | grep -E '^%s' | tail -n1 | cut -d' ' -f3",
[128]1005 g_isodir_device);
1006 log_it("command = %s", command);
[1219]1007 mr_asprintf(&iso_mnt, "%s",
[128]1008 call_program_and_get_last_line_of_output(command));
[1219]1009 log_it("res of it = %s", iso_mnt);
[128]1010 } else {
[1219]1011 mr_asprintf(&iso_mnt, "/tmp/isodir");
1012 mr_asprintf(&tmp, "mkdir -p %s", iso_mnt);
[128]1013 run_program_and_log_output(tmp, 5);
[1219]1014 mr_free(tmp);
1015
1016 mr_asprintf(&tmp, "mount %s %s", g_isodir_device, iso_mnt);
[128]1017 if (run_program_and_log_output(tmp, 3)) {
[1108]1018 mr_msg(1,
[128]1019 "Unable to mount isodir. Perhaps this is really a CD backup?");
1020 bkpinfo->backup_media_type = cdr;
1021 strcpy(bkpinfo->media_device, "/dev/cdrom"); /* superfluous */
[1219]1022 bkpinfo->isodir[0] = '\0';
1023 mr_free(iso_mnt);
1024 mr_free(iso_path);
1025 mr_asprintf(&iso_mnt, "");
1026 mr_asprintf(&iso_path, "");
[128]1027 if (mount_cdrom(bkpinfo)) {
1028 fatal_error
1029 ("Unable to mount isodir. Failed to mount CD-ROM as well.");
1030 } else {
[1108]1031 mr_msg(1,
[801]1032 "You backed up to disk, then burned some CDs.");
[128]1033 }
1034 }
[1219]1035 mr_free(tmp);
[128]1036 }
[148]1037 /* bkpinfo->isodir should now be the true path to prefix-1.iso etc... */
[128]1038 if (bkpinfo->backup_media_type == iso) {
1039 sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1040 }
[1219]1041 mr_free(iso_mnt);
1042 mr_free(iso_path);
[128]1043 }
[1]1044 }
1045
[128]1046 if (media_specified_by_user != none) {
1047 if (g_restoring_live_from_cd) {
1048 if (bkpinfo->backup_media_type != media_specified_by_user) {
[1108]1049 mr_msg(2,
[128]1050 "bkpinfo->backup_media_type != media_specified_by_user, so I'd better ask :)");
[1219]1051 interactively_obtain_media_parameters_from_user(bkpinfo, FALSE);
[128]1052 media_specified_by_user = bkpinfo->backup_media_type;
1053 get_cfg_file_from_archive(bkpinfo);
1054 }
1055 }
1056 bkpinfo->backup_media_type = media_specified_by_user;
1057 }
1058 g_backup_media_type = bkpinfo->backup_media_type;
[1219]1059 strcpy(bkpinfo->backup_media_string, bkptype_to_string(bkpinfo->backup_media_type));
1060 strcpy(g_backup_media_string, bkpinfo->backup_media_string);
[1080]1061 mr_free(value);
[128]1062 return (0);
[1]1063}
1064/**************************************************************************
1065 *END_READ_CFG_FILE_INTO_BKPINFO *
1066 **************************************************************************/
1067
1068
1069/**
1070 * Allow the user to edit the filelist and biggielist.
1071 * The filelist is unlinked after it is read.
1072 * @param bkpinfo The backup information structure. Fields used:
1073 * - @c bkpinfo->backup_media_type
1074 * - @c bkpinfo->isodir
1075 * - @c bkpinfo->media_device
1076 * - @c bkpinfo->tmpdir
1077 * @return The filelist structure containing the information read from disk.
1078 */
1079struct
[128]1080s_node *process_filelist_and_biggielist(struct s_bkpinfo *bkpinfo)
[1]1081{
[1219]1082 struct s_node *filelist = NULL;
[1]1083
[1219]1084 char *command = NULL;
1085 char *tmp = NULL;
[128]1086 int res = 0;
[1219]1087 size_t n = 0;
[128]1088 pid_t pid;
[1]1089
[128]1090 assert(bkpinfo != NULL);
1091 malloc_string(tmp);
[1]1092
[128]1093 if (does_file_exist(g_filelist_full)
1094 && does_file_exist(g_biggielist_txt)) {
[1108]1095 mr_msg(1, "%s exists", g_filelist_full);
1096 mr_msg(1, "%s exists", g_biggielist_txt);
1097 mr_msg(2,
[128]1098 "Filelist and biggielist already recovered from media. Yay!");
1099 } else {
1100 getcwd(tmp, MAX_STR_LEN);
1101 chdir(bkpinfo->tmpdir);
[1108]1102 mr_msg(1, "chdir(%s)", bkpinfo->tmpdir);
[128]1103 log_to_screen("Extracting filelist and biggielist from media...");
1104 unlink("/tmp/filelist.full");
1105 unlink("/" FILELIST_FULL_STUB);
1106 unlink("/tmp/i-want-my-lvm");
1107 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
[1219]1108 mr_asprintf(&command,
[1241]1109 "tar -b %ld -zxf %s %s %s %s %s %s",
1110 bkpinfo->internal_tape_block_size,
[128]1111 bkpinfo->media_device,
1112 MOUNTLIST_FNAME_STUB,
1113 BIGGIELIST_TXT_STUB,
1114 FILELIST_FULL_STUB,
1115 "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
[1108]1116 mr_msg(1, "tarcommand = %s", command);
[128]1117 run_program_and_log_output(command, 1);
[1219]1118 mr_free(command);
[128]1119 } else {
[1108]1120 mr_msg(2,
[128]1121 "Calling insist_on_this_cd_number; bkpinfo->isodir=%s",
1122 bkpinfo->isodir);
1123 insist_on_this_cd_number(bkpinfo, 1);
[1108]1124 mr_msg(2, "Back from iotcn");
[128]1125 run_program_and_log_output("mount", 1);
[1219]1126 mr_asprintf(&command,
[128]1127 "tar -zxf %s/images/all.tar.gz %s %s %s %s %s",
1128 MNT_CDROM,
1129 MOUNTLIST_FNAME_STUB,
1130 BIGGIELIST_TXT_STUB,
1131 FILELIST_FULL_STUB,
1132 "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
[1]1133
[1108]1134 mr_msg(1, "tarcommand = %s", command);
[128]1135 run_program_and_log_output(command, 1);
[1219]1136 mr_free(command);
1137
[128]1138 if (!does_file_exist(BIGGIELIST_TXT_STUB)) {
1139 fatal_error
1140 ("all.tar.gz did not include tmp/biggielist.txt");
1141 }
1142 if (!does_file_exist(FILELIST_FULL_STUB)) {
1143 fatal_error
1144 ("all.tar.gz did not include tmp/filelist.full.gz");
1145 }
1146 }
[1219]1147 mr_asprintf(&command, "cp -f %s %s", MONDO_CFG_FILE_STUB,
[128]1148 g_mondo_cfg_file);
1149 run_program_and_log_output(command, FALSE);
[1219]1150 mr_free(command);
[1]1151
[1219]1152 mr_asprintf(&command, "cp -f %s/%s %s", bkpinfo->tmpdir,
[128]1153 BIGGIELIST_TXT_STUB, g_biggielist_txt);
[1108]1154 mr_msg(1, "command = %s", command);
[128]1155 paranoid_system(command);
[1219]1156 mr_free(command);
1157
1158 mr_asprintf(&command, "ln -sf %s/%s %s", bkpinfo->tmpdir,
[128]1159 FILELIST_FULL_STUB, g_filelist_full);
[1108]1160 mr_msg(1, "command = %s", command);
[128]1161 paranoid_system(command);
[1219]1162 mr_free(command);
[128]1163 }
[1]1164
[128]1165 if (am_I_in_disaster_recovery_mode()
1166 &&
[1219]1167 ask_me_yes_or_no(_
1168 ("Do you want to retrieve the mountlist as well?")))
[128]1169 {
[1219]1170 mr_asprintf(&command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB,
[128]1171 bkpinfo->tmpdir);
1172 paranoid_system(command);
[1219]1173 mr_free(command);
[128]1174 }
[1]1175
[128]1176 chdir(tmp);
[1219]1177 mr_free(tmp);
[1]1178
[128]1179 if (!does_file_exist(g_biggielist_txt)) {
[1108]1180 mr_msg(1, "Warning - %s not found", g_biggielist_txt);
[128]1181 }
1182 if (!does_file_exist(g_filelist_full)) {
[1108]1183 mr_msg(1, "Warning - %s does not exist", g_filelist_full);
[128]1184 }
[1]1185
[1108]1186 mr_msg(2, "Forking");
[128]1187 pid = fork();
1188 switch (pid) {
1189 case -1:
1190 fatal_error("Forking error");
1191 break;
[1]1192
[128]1193 case 0:
[1219]1194 log_to_screen(_("Pre-processing filelist"));
[128]1195 if (!does_file_exist(g_biggielist_txt)) {
[1241]1196 mr_asprintf(&command, "echo -n > %s", g_biggielist_txt);
[128]1197 paranoid_system(command);
[1219]1198 mr_free(command);
[128]1199 }
[1219]1200 mr_asprintf(&command, "grep -E '^/dev/.*' %s > %s",
[128]1201 g_biggielist_txt, g_filelist_imagedevs);
1202 paranoid_system(command);
[1219]1203 mr_free(command);
[128]1204 exit(0);
1205 break;
1206
1207 default:
[1219]1208 open_evalcall_form(_("Pre-processing filelist"));
[128]1209 while (!waitpid(pid, (int *) 0, WNOHANG)) {
1210 usleep(100000);
1211 update_evalcall_form(0);
1212 }
[1]1213 }
[128]1214 close_evalcall_form();
[1]1215
[1108]1216 mr_msg(3, "loading filelist");
[128]1217 filelist = load_filelist(g_filelist_full);
[1108]1218 mr_msg(3, "deleting original filelist");
[128]1219 unlink(g_filelist_full);
1220 if (g_text_mode) {
[1219]1221 printf(_("Restore which directory? --> "));
1222 mr_getline(&tmp, &n, stdin);
[128]1223 toggle_path_selection(filelist, tmp, TRUE);
1224 if (strlen(tmp) == 0) {
1225 res = 1;
1226 } else {
1227 res = 0;
1228 }
[1219]1229 mr_free(tmp);
[128]1230 } else {
1231 res = edit_filelist(filelist);
[1]1232 }
[128]1233 if (res) {
[1108]1234 mr_msg(2, "User hit 'cancel'. Freeing filelist and aborting.");
[128]1235 free_filelist(filelist);
1236 return (NULL);
1237 }
1238 ask_about_these_imagedevs(g_filelist_imagedevs, g_imagedevs_restthese);
1239 close_evalcall_form();
[1]1240
[128]1241 // NB: It's not necessary to add g_biggielist_txt to the filelist.full
1242 // file. The filelist.full file already contains the filename of EVERY
1243 // file backed up - regular and biggie files.
[1]1244
[128]1245 // However, we do want to make sure the imagedevs selected by the user
1246 // are flagged for restoring.
1247 if (length_of_file(g_imagedevs_restthese) > 2) {
1248 add_list_of_files_to_filelist(filelist, g_imagedevs_restthese,
1249 TRUE);
1250 }
1251 return (filelist);
1252}
[1]1253/**************************************************************************
1254 *END_ PROCESS_FILELIST_AND_BIGGIELIST *
1255 **************************************************************************/
1256
1257
1258/**
1259 * Make a backup copy of <tt>path_root</tt>/<tt>filename</tt>.
1260 * The backup filename is the filename of the original with ".pristine" added.
1261 * @param path_root The place where the filesystem is mounted (e.g. MNT_RESTORING).
1262 * @param filename The filename (absolute path) within @p path_root.
1263 * @return 0 for success, nonzero for failure.
1264 */
[128]1265int backup_crucial_file(char *path_root, char *filename)
[1]1266{
[1219]1267 char *command = NULL;
1268 int res = 0;
[1]1269
[128]1270 assert(path_root != NULL);
1271 assert_string_is_neither_NULL_nor_zerolength(filename);
1272
[1219]1273 mr_asprintf(&command, "cp -f %s/%s %s/%s.pristine", path_root, filename,path_root, filename);
[128]1274 res = run_program_and_log_output(command, 5);
[1080]1275 mr_free(command);
[128]1276 return (res);
[1]1277}
1278
1279
1280/**
1281 * Install the user's boot loader in the MBR.
1282 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported.
1283 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1284 * @return 0 for success, nonzero for failure.
1285 */
[128]1286int run_boot_loader(bool offer_to_hack_scripts)
[1]1287{
[1219]1288 int res = 0;
[128]1289 int retval = 0;
[1]1290
[1219]1291 char *device = NULL;
[1265]1292#ifdef __FreeBSD__
[1219]1293 char *tmp = NULL;
[1265]1294#endif
[1219]1295 char *name = NULL;
[1]1296
[128]1297 malloc_string(device);
1298 malloc_string(name);
1299 backup_crucial_file(MNT_RESTORING, "/etc/fstab");
1300 backup_crucial_file(MNT_RESTORING, "/etc/grub.conf");
1301 backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf");
1302 backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf");
1303 read_cfg_var(g_mondo_cfg_file, "bootloader.device", device);
1304 read_cfg_var(g_mondo_cfg_file, "bootloader.name", name);
[1219]1305 mr_msg(2, "run_boot_loader: device='%s', name='%s'", device, name);
1306 sync();
[128]1307 if (!strcmp(name, "LILO")) {
1308 res = run_lilo(offer_to_hack_scripts);
1309 } else if (!strcmp(name, "ELILO")) {
1310 res = run_elilo(offer_to_hack_scripts);
1311 } else if (!strcmp(name, "GRUB")) {
1312 res = run_grub(offer_to_hack_scripts, device);
1313 } else if (!strcmp(name, "RAW")) {
1314 res = run_raw_mbr(offer_to_hack_scripts, device);
1315 }
[1]1316#ifdef __FreeBSD__
[128]1317 else if (!strcmp(name, "BOOT0")) {
[1219]1318 mr_asprintf(&tmp, "boot0cfg -B %s", device);
[128]1319 res = run_program_and_log_output(tmp, FALSE);
[1219]1320 mr_free(tmp);
[128]1321 } else {
[1219]1322 mr_asprintf(&tmp, "ls /dev | grep -Eq '^%ss[1-4].*$'", device);
[128]1323 if (!system(tmp)) {
[1219]1324 mr_free(tmp);
1325 mr_asprintf(&tmp, MNT_RESTORING "/sbin/fdisk -B %s", device);
[128]1326 res = run_program_and_log_output(tmp, 3);
1327 } else {
[1108]1328 mr_msg(1,
[128]1329 "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");
1330 }
[1219]1331 mr_free(tmp);
[128]1332 }
[1]1333#else
[128]1334 else {
1335 log_to_screen
[1219]1336 (_
1337 ("Unable to determine type of boot loader. Defaulting to LILO."));
[128]1338 res = run_lilo(offer_to_hack_scripts);
1339 }
[1]1340#endif
[1219]1341 mr_free(device);
1342 mr_free(name);
1343
[128]1344 retval += res;
1345 if (res) {
[1219]1346 log_to_screen(_("Your boot loader returned an error"));
[128]1347 } else {
[1219]1348 log_to_screen(_("Your boot loader ran OK"));
[128]1349 }
1350 return (retval);
[1]1351}
1352/**************************************************************************
1353 *END_ RUN_BOOT_LOADER *
1354 **************************************************************************/
1355
1356
1357/**
1358 * Attempt to find the user's editor.
1359 * @return The editor found ("vi" if none could be found).
1360 * @note The returned string points to static storage that will be overwritten with each call.
1361 */
1362char *find_my_editor(void)
1363{
[128]1364 static char output[MAX_STR_LEN];
[1275]1365 char *p;
[1219]1366
[1275]1367 if ((p = getenv("EDITOR")) != NULL) {
1368 strcpy(output, p);
1369 }
[128]1370 if (find_home_of_exe("pico")) {
1371 strcpy(output, "pico");
1372 } else if (find_home_of_exe("nano")) {
1373 strcpy(output, "nano");
[1275]1374 } else if (find_home_of_exe("vim")) {
1375 strcpy(output, "vim");
[128]1376 } else {
1377 strcpy(output, "vi");
1378 }
1379 if (!find_home_of_exe(output)) {
[1108]1380 mr_msg(2, " (find_my_editor) --- warning - %s not found", output);
[128]1381 }
1382 return (output);
[1]1383}
1384
1385
1386/**
1387 * Install GRUB on @p bd.
1388 * @param offer_to_run_stabgrub If TRUE, then offer to hack the user's fstab for them.
1389 * @param bd The boot device where GRUB is installed.
1390 * @return 0 for success, nonzero for failure.
1391 */
[128]1392int run_grub(bool offer_to_run_stabgrub, char *bd)
[1]1393{
[1219]1394 char *command = NULL;
1395 char *boot_device = NULL;
1396 char *tmp = NULL;
1397 char *editor = NULL;
[1]1398
[1219]1399 int res = 0;
1400 int done = 0;
[1]1401
[128]1402 malloc_string(boot_device);
[1219]1403 strcpy(boot_device, bd);
[128]1404 assert_string_is_neither_NULL_nor_zerolength(bd);
[1219]1405 mr_asprintf(&editor, find_my_editor());
[128]1406
1407 if (offer_to_run_stabgrub
[1219]1408 && ask_me_yes_or_no(_("Did you change the mountlist?")))
[128]1409 /* interactive mode */
[1]1410 {
[128]1411 mvaddstr_and_log_it(g_currentY,
1412 0,
[1548]1413 ("Modifying fstab, mtab, device.map and grub.conf, and running GRUB... "));
[128]1414 for (done = FALSE; !done;) {
[1219]1415 popup_and_get_string(_("Boot device"),
1416 _("Please confirm/enter the boot device. If in doubt, try /dev/hda"), boot_device, MAX_STR_LEN / 4);
1417 mr_asprintf(&command, "stabgrub-me %s", boot_device);
[128]1418 res = run_program_and_log_output(command, 1);
[1219]1419 mr_free(command);
1420
[128]1421 if (res) {
1422 popup_and_OK
[1219]1423 (_
1424 ("GRUB installation failed. Please install manually using 'grub-install' or similar command. You are now chroot()'ed to your restored system. Please type 'exit' when you are done."));
[128]1425 newtSuspend();
1426 system("chroot " MNT_RESTORING);
1427 newtResume();
[1219]1428 popup_and_OK(_("Thank you."));
[128]1429 } else {
1430 done = TRUE;
1431 }
[1548]1432 popup_and_OK(_("You will now edit fstab, mtab, device.map and grub.conf"));
[128]1433 if (!g_text_mode) {
1434 newtSuspend();
1435 }
[1500]1436 mr_asprintf(&tmp, "chroot %s %s /etc/fstab", MNT_RESTORING, editor);
[128]1437 paranoid_system(tmp);
[1219]1438 mr_free(tmp);
1439
[1548]1440 mr_asprintf(&tmp, "chroot %s %s /etc/mtab", MNT_RESTORING, editor);
1441 paranoid_system(tmp);
1442 mr_free(tmp);
1443
[1500]1444 mr_asprintf(&tmp, "chroot %s %s /etc/grub.conf", MNT_RESTORING, editor);
[128]1445 paranoid_system(tmp);
[1219]1446 mr_free(tmp);
1447
[1548]1448 mr_asprintf(&tmp, "chroot %s %s /boot/grub/device.map", MNT_RESTORING, editor);
1449 paranoid_system(tmp);
1450 mr_free(tmp);
1451
[128]1452 if (!g_text_mode) {
1453 newtResume();
1454 }
1455 }
[1219]1456 } else {
[128]1457 /* nuke mode */
[1219]1458 if (!run_program_and_log_output("which grub-MR", FALSE)) {
1459 mr_msg(1, "Yay! grub-MR found...");
1460 mr_asprintf(&command, "grub-MR %s /tmp/mountlist.txt", bd);
1461 mr_msg(1, "command = %s", command);
1462 } else {
1463 mr_asprintf(&command, "chroot " MNT_RESTORING " grub-install %s", bd);
1464 mr_msg(1, "WARNING - grub-MR not found; using grub-install");
1465 }
[128]1466 mvaddstr_and_log_it(g_currentY,
1467 0,
[1219]1468 _
1469 ("Running GRUB... "));
[128]1470 iamhere(command);
1471 res = run_program_and_log_output(command, 1);
[1219]1472 mr_free(command);
1473
[128]1474 if (res) {
1475 popup_and_OK
[1219]1476 (_
1477 ("Because of bugs in GRUB's own installer, GRUB was not installed properly. Please install the boot loader manually now, using this chroot()'ed shell prompt. Type 'exit' when you have finished."));
[128]1478 newtSuspend();
1479 system("chroot " MNT_RESTORING);
1480 newtResume();
[1219]1481 popup_and_OK(_("Thank you."));
[128]1482 }
[1]1483 }
[128]1484 if (res) {
[1219]1485 mvaddstr_and_log_it(g_currentY++, 74, _("Failed."));
[1384]1486 log_to_screen(_("GRUB ran w/error(s). See %s for more info."), MONDO_LOGFILE);
[1108]1487 mr_msg(1, "Type:-");
1488 mr_msg(1, " mount-me");
1489 mr_msg(1, " chroot " MNT_RESTORING);
1490 mr_msg(1, " mount /boot");
1491 mr_msg(1, " grub-install '(hd0)'");
1492 mr_msg(1, " exit");
1493 mr_msg(1, " unmount-me");
1494 mr_msg(1,
[128]1495 "If you're really stuck, please e-mail the mailing list.");
1496 } else {
[1219]1497 mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
[128]1498 }
[1080]1499 mr_free(boot_device);
1500 mr_free(editor);
[128]1501 return (res);
[1]1502}
1503/**************************************************************************
1504 *END_RUN_GRUB *
1505 **************************************************************************/
1506
1507
1508/**
1509 * Install ELILO on the user's boot drive (determined by elilo.conf).
1510 * @param offer_to_run_stabelilo If TRUE, then offer to hack the user's fstab for them.
1511 * @return 0 for success, nonzero for failure.
1512 */
[128]1513int run_elilo(bool offer_to_run_stabelilo)
[1]1514{
[1219]1515 char *command = NULL;
1516 char *tmp = NULL;
1517 char *editor = NULL;
[1]1518
[1219]1519 int res = 0;
1520 int done = 0;
[1]1521
[1219]1522 mr_asprintf(&editor, find_my_editor());
[128]1523 if (offer_to_run_stabelilo
[1219]1524 && ask_me_yes_or_no(_("Did you change the mountlist?")))
[1]1525
[128]1526 /* interactive mode */
1527 {
1528 mvaddstr_and_log_it(g_currentY,
1529 0,
[1219]1530 _
1531 ("Modifying fstab and elilo.conf... "));
1532 mr_asprintf(&command, "stabelilo-me");
[128]1533 res = run_program_and_log_output(command, 3);
[1219]1534 mr_free(command);
1535
[128]1536 if (res) {
1537 popup_and_OK
[1219]1538 (_
1539 ("You will now edit fstab and elilo.conf, to make sure they match your new mountlist."));
[128]1540 for (done = FALSE; !done;) {
1541 if (!g_text_mode) {
1542 newtSuspend();
1543 }
[1219]1544 mr_asprintf(&tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
[128]1545 paranoid_system(tmp);
[1219]1546 mr_free(tmp);
1547
1548 mr_asprintf(&tmp, "%s " MNT_RESTORING "/etc/elilo.conf", editor);
[128]1549 paranoid_system(tmp);
[1219]1550 mr_free(tmp);
1551
[128]1552 if (!g_text_mode) {
1553 newtResume();
1554 }
[1]1555// newtCls();
[1219]1556 if (ask_me_yes_or_no(_("Edit them again?"))) {
[128]1557 continue;
1558 }
1559 done = TRUE;
1560 }
1561 } else {
[1219]1562 log_to_screen(_("elilo.conf and fstab were modified OK"));
[1]1563 }
[128]1564 } else
1565 /* nuke mode */
[1]1566 {
[128]1567 res = TRUE;
[1]1568 }
[1080]1569 mr_free(editor);
[128]1570 return (res);
1571}
[1]1572/**************************************************************************
1573 *END_RUN_ELILO *
1574 **************************************************************************/
1575
1576
1577/**
1578 * Install LILO on the user's boot drive (determined by /etc/lilo.conf).
1579 * @param offer_to_run_stablilo If TRUE, then offer to hack the user's fstab for them.
1580 * @return 0 for success, nonzero for failure.
1581 */
[128]1582int run_lilo(bool offer_to_run_stablilo)
[1]1583{
1584 /** malloc **/
[1219]1585 char *command = NULL;
1586 char *tmp = NULL;
1587 char *editor = NULL;
[1]1588
[1219]1589 int res = 0;
1590 int done = 0;
[128]1591 bool run_lilo_M = FALSE;
[1]1592
[128]1593 if (!run_program_and_log_output
1594 ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) {
1595 run_lilo_M = TRUE;
1596 }
[1]1597
[1219]1598 mr_asprintf(&editor, find_my_editor());
[128]1599 if (offer_to_run_stablilo
[1219]1600 && ask_me_yes_or_no(_("Did you change the mountlist?"))) {
[128]1601 /* interactive mode */
1602 mvaddstr_and_log_it(g_currentY,
1603 0,
[1219]1604 _
1605 ("Modifying fstab and lilo.conf, and running LILO... "));
1606 mr_asprintf(&command, "stablilo-me");
[128]1607 res = run_program_and_log_output(command, 3);
[1219]1608 mr_free(command);
1609
[128]1610 if (res) {
1611 popup_and_OK
[1219]1612 (_
1613 ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist."));
[128]1614 for (done = FALSE; !done;) {
1615 if (!g_text_mode) {
1616 newtSuspend();
1617 }
[1219]1618 mr_asprintf(&tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
[128]1619 paranoid_system(tmp);
[1219]1620 mr_free(tmp);
1621
1622 mr_asprintf(&tmp, "%s " MNT_RESTORING "/etc/lilo.conf", editor);
[128]1623 paranoid_system(tmp);
[1219]1624 mr_free(tmp);
1625
[128]1626 if (!g_text_mode) {
1627 newtResume();
1628 }
[1219]1629 if (ask_me_yes_or_no(_("Edit them again?"))) {
[128]1630 continue;
1631 }
1632 res =
1633 run_program_and_log_output("chroot " MNT_RESTORING
1634 " lilo -L", 3);
1635 if (res) {
1636 res =
1637 run_program_and_log_output("chroot " MNT_RESTORING
1638 " lilo", 3);
1639 }
1640 if (res) {
1641 done =
1642 ask_me_yes_or_no
[1219]1643 (_("LILO failed. Re-edit system files?"));
[128]1644 } else {
1645 done = TRUE;
1646 }
1647 }
1648 } else {
[1219]1649 log_to_screen(_("lilo.conf and fstab were modified OK"));
[1]1650 }
[1219]1651 } else {
[128]1652 /* nuke mode */
1653 mvaddstr_and_log_it(g_currentY,
1654 0,
[1219]1655 _
1656 ("Running LILO... "));
[128]1657 res =
1658 run_program_and_log_output("chroot " MNT_RESTORING " lilo -L",
1659 3);
1660 if (res) {
1661 res =
1662 run_program_and_log_output("chroot " MNT_RESTORING " lilo",
1663 3);
[1]1664 }
[128]1665 if (res) {
[1219]1666 mvaddstr_and_log_it(g_currentY++, 74, _("Failed."));
[128]1667 log_to_screen
[1219]1668 (_
1669 ("Failed to re-jig fstab and/or lilo. Edit/run manually, please."));
[128]1670 } else {
[1219]1671 mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
[128]1672 }
[1]1673 }
[128]1674 if (run_lilo_M) {
1675 run_program_and_log_output("chroot " MNT_RESTORING
1676 " lilo -M /dev/hda", 3);
1677 run_program_and_log_output("chroot " MNT_RESTORING
1678 " lilo -M /dev/sda", 3);
[1]1679 }
[1080]1680 mr_free(editor);
[128]1681 return (res);
1682}
[1]1683
1684/**************************************************************************
1685 *END_RUN_LILO *
1686 **************************************************************************/
1687
1688
1689/**
1690 * Install a raw MBR onto @p bd.
1691 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1692 * @param bd The device to copy the stored MBR to.
1693 * @return 0 for success, nonzero for failure.
1694 */
[128]1695int run_raw_mbr(bool offer_to_hack_scripts, char *bd)
[1]1696{
[1219]1697 char *command = NULL;
1698 char *boot_device = NULL;
1699 char *tmp = NULL;
1700 char *editor = NULL;
1701 int res = 0;
1702 int done = 0;
[1]1703
[128]1704 assert_string_is_neither_NULL_nor_zerolength(bd);
[1]1705
[1219]1706 malloc_string(boot_device);
1707 mr_asprintf(&editor, find_my_editor());
[128]1708 strcpy(boot_device, bd);
1709 if (offer_to_hack_scripts
[1219]1710 && ask_me_yes_or_no(_("Did you change the mountlist?"))) {
[128]1711 /* interactive mode */
1712 mvaddstr_and_log_it(g_currentY, 0,
[1219]1713 _
1714 ("Modifying fstab and restoring MBR... "));
[128]1715 for (done = FALSE; !done;) {
1716 if (!run_program_and_log_output("which vi", FALSE)) {
[1219]1717 popup_and_OK(_("You will now edit fstab"));
[128]1718 if (!g_text_mode) {
1719 newtSuspend();
1720 }
[1219]1721 mr_asprintf(&tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
[128]1722 paranoid_system(tmp);
[1219]1723 mr_free(tmp);
1724
[128]1725 if (!g_text_mode) {
1726 newtResume();
1727 }
1728 }
[1219]1729 popup_and_get_string(_("Boot device"),
1730 _("Please confirm/enter the boot device. If in doubt, try /dev/hda"), boot_device, MAX_STR_LEN / 4);
1731 mr_asprintf(&command, "stabraw-me %s", boot_device);
[128]1732 res = run_program_and_log_output(command, 3);
[1219]1733 mr_free(command);
1734
[128]1735 if (res) {
[1219]1736 done =
1737 ask_me_yes_or_no(_("Modifications failed. Re-try?"));
[128]1738 } else {
1739 done = TRUE;
1740 }
1741 }
[1219]1742 } else {
[128]1743 /* nuke mode */
1744 mvaddstr_and_log_it(g_currentY, 0,
[1219]1745 _("Restoring MBR... "));
1746 mr_asprintf(&command, "raw-MR %s /tmp/mountlist.txt", boot_device);
1747 mr_msg(2, "run_raw_mbr() --- command='%s'", command);
[128]1748 res = run_program_and_log_output(command, 3);
[1219]1749 mr_free(command);
[1]1750 }
[128]1751 if (res) {
[1219]1752 mvaddstr_and_log_it(g_currentY++, 74, _("Failed."));
[1384]1753 log_to_screen(_("MBR+fstab processed w/error(s). See %s for more info."), MONDO_LOGFILE);
[128]1754 } else {
[1219]1755 mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
[128]1756 }
[1080]1757 mr_free(boot_device);
1758 mr_free(editor);
[128]1759 return (res);
[1]1760}
1761/**************************************************************************
1762 *END_RUN_RAW_MBR *
1763 **************************************************************************/
1764
1765
1766/**
1767 * Turn signal trapping on or off.
1768 * @param on If TRUE, then do full cleanup when we receive a signal; if FALSE, then
1769 * print a message and exit immediately.
1770 */
[128]1771void set_signals(int on)
[1]1772{
[128]1773 int signals[] =
1774 { SIGKILL, SIGPIPE, SIGTERM, SIGHUP, SIGTRAP, SIGABRT, SIGINT,
[1219]1775 SIGSTOP, 0
1776 };
[128]1777 int i;
1778 for (i = 0; signals[i]; i++) {
1779 if (on) {
1780 signal(signals[i], terminate_daemon);
1781 } else {
1782 signal(signals[i], termination_in_progress);
1783 }
[1]1784 }
1785}
1786
1787/**************************************************************************
1788 *END_SET_SIGNALS *
1789 **************************************************************************/
1790
1791
1792/**
1793 * malloc() and set sensible defaults for the mondorestore filename variables.
1794 * @param bkpinfo The backup information structure. Fields used:
1795 * - @c bkpinfo->tmpdir
1796 * - @c bkpinfo->disaster_recovery
1797 */
[128]1798void setup_MR_global_filenames(struct s_bkpinfo *bkpinfo)
[1]1799{
[128]1800 char *temppath;
[1]1801
[128]1802 assert(bkpinfo != NULL);
[1]1803
[128]1804 malloc_string(g_biggielist_txt);
1805 malloc_string(g_filelist_full);
1806 malloc_string(g_filelist_imagedevs);
1807 malloc_string(g_imagedevs_restthese);
1808 malloc_string(g_mondo_cfg_file);
1809 malloc_string(g_mountlist_fname);
1810 malloc_string(g_tmpfs_mountpt);
1811 malloc_string(g_isodir_device);
1812 malloc_string(g_isodir_format);
[1]1813
[128]1814 temppath = bkpinfo->tmpdir;
[1]1815
[128]1816 sprintf(g_biggielist_txt, "%s/%s", temppath, BIGGIELIST_TXT_STUB);
1817 sprintf(g_filelist_full, "%s/%s", temppath, FILELIST_FULL_STUB);
1818 sprintf(g_filelist_imagedevs, "%s/tmp/filelist.imagedevs", temppath);
1819 sprintf(g_imagedevs_restthese, "%s/tmp/imagedevs.restore-these",
1820 temppath);
1821 if (bkpinfo->disaster_recovery) {
1822 sprintf(g_mondo_cfg_file, "/%s", MONDO_CFG_FILE_STUB);
1823 sprintf(g_mountlist_fname, "/%s", MOUNTLIST_FNAME_STUB);
1824 } else {
1825 sprintf(g_mondo_cfg_file, "%s/%s", temppath, MONDO_CFG_FILE_STUB);
1826 sprintf(g_mountlist_fname, "%s/%s", temppath,
1827 MOUNTLIST_FNAME_STUB);
1828 }
[1]1829}
[128]1830
[1]1831/**************************************************************************
1832 *END_SET_GLOBAL_FILENAME *
1833 **************************************************************************/
1834
1835
1836/**
1837 * Copy @p input_file (containing the result of a compare) to @p output_file,
1838 * deleting spurious "changes" along the way.
1839 * @param output_file The output file to write with spurious changes removed.
1840 * @param input_file The input file, a list of changed files created by a compare.
1841 */
[128]1842void streamline_changes_file(char *output_file, char *input_file)
[1]1843{
[128]1844 FILE *fin;
1845 FILE *fout;
[1219]1846 char *incoming = NULL;
1847 size_t n = 0;
[1]1848
[128]1849 assert_string_is_neither_NULL_nor_zerolength(output_file);
1850 assert_string_is_neither_NULL_nor_zerolength(input_file);
1851
1852 if (!(fin = fopen(input_file, "r"))) {
1853 log_OS_error(input_file);
1854 return;
1855 }
1856 if (!(fout = fopen(output_file, "w"))) {
1857 fatal_error("cannot open output_file");
1858 }
[1219]1859 for (mr_getline(&incoming, &n, fin); !feof(fin);
1860 mr_getline(&incoming, &n, fin)) {
[128]1861 if (strncmp(incoming, "etc/adjtime", 11)
1862 && strncmp(incoming, "etc/mtab", 8)
1863 && strncmp(incoming, "tmp/", 4)
1864 && strncmp(incoming, "boot/map", 8)
1865 && !strstr(incoming, "incheckentry")
1866 && strncmp(incoming, "etc/mail/statistics", 19)
1867 && strncmp(incoming, "var/", 4))
1868 fprintf(fout, "%s", incoming); /* don't need \n here, for some reason.. */
1869 }
[1219]1870 mr_free(incoming);
[128]1871 paranoid_fclose(fout);
1872 paranoid_fclose(fin);
[1]1873}
1874/**************************************************************************
1875 *END_STREAMLINE_CHANGES_FILE *
1876 **************************************************************************/
1877
1878
1879/**
1880 * Exit due to a signal (normal cleanup).
1881 * @param sig The signal we're exiting due to.
1882 */
[128]1883void terminate_daemon(int sig)
[1]1884{
[128]1885 log_to_screen
[1219]1886 (_("Mondorestore is terminating in response to a signal from the OS"));
[1166]1887 free_MR_global_filenames();
1888 finish(254);
[1]1889}
1890/**************************************************************************
1891 *END_TERMINATE_DAEMON *
1892 **************************************************************************/
1893
1894
1895/**
1896 * Give the user twenty seconds to press Ctrl-Alt-Del before we nuke their drives.
1897 */
[128]1898void twenty_seconds_til_yikes()
[1]1899{
[128]1900 int i;
[1219]1901 char *tmp = NULL;
[1]1902
[128]1903 if (does_file_exist("/tmp/NOPAUSE")) {
1904 return;
1905 }
[1219]1906 open_progress_form(_("CAUTION"),
1907 _
1908 ("Be advised: I am about to ERASE your hard disk(s)!"),
1909 _("You may press Ctrl+Alt+Del to abort safely."),
[128]1910 "", 20);
1911 for (i = 0; i < 20; i++) {
1912 g_current_progress = i;
[1219]1913 mr_asprintf(&tmp, _("You have %d seconds left to abort."), 20 - i);
[128]1914 update_progress_form(tmp);
[1219]1915 mr_free(tmp);
[128]1916 sleep(1);
1917 }
1918 close_progress_form();
[1]1919}
1920/**************************************************************************
1921 *END_TWENTY_SECONDS_TIL_YIKES *
1922 **************************************************************************/
1923
1924
1925/**
1926 * Exit due to a signal (no cleanup).
1927 * @param sig The signal we're exiting due to.
1928 */
[128]1929void termination_in_progress(int sig)
[1]1930{
[1108]1931 mr_msg(1, "Termination in progress");
[128]1932 usleep(1000);
1933 pthread_exit(0);
[1]1934}
1935/**************************************************************************
1936 *END_TERMINATION_IN_PROGRESS *
1937 **************************************************************************/
1938
1939
1940/**
1941 * Unmount all devices in @p p_external_copy_of_mountlist.
1942 * @param p_external_copy_of_mountlist The mountlist to guide the devices to unmount.
1943 * @return 0 for success, nonzero for failure.
1944 */
[128]1945int unmount_all_devices(struct mountlist_itself
1946 *p_external_copy_of_mountlist)
[1]1947{
[128]1948 struct mountlist_itself *mountlist;
[1219]1949 int retval = 0;
1950 int lino = 0;
1951 int res = 0;
1952 int i = 0;
1953 char *command = NULL;
1954 char *tmp = NULL;
[1]1955
[128]1956 assert(p_external_copy_of_mountlist != NULL);
[1]1957
[1102]1958 mountlist = (struct mountlist_itself *)mr_malloc(sizeof(struct mountlist_itself));
[128]1959 memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
1960 sizeof(struct mountlist_itself));
1961 sort_mountlist_by_mountpoint(mountlist, 0);
[1]1962
[691]1963 run_program_and_log_output("df -m", 3);
[1219]1964 mvaddstr_and_log_it(g_currentY, 0, _("Unmounting devices "));
1965 open_progress_form(_("Unmounting devices"),
1966 _("Unmounting all devices that were mounted,"),
1967 _
1968 ("in preparation for the post-restoration reboot."),
[128]1969 "", mountlist->entries);
1970 chdir("/");
1971 for (i = 0;
1972 i < 10
1973 &&
1974 run_program_and_log_output
[792]1975 ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
[128]1976 i++) {
1977 sleep(1);
[1108]1978 mr_msg(2, "Waiting for buffer() to finish");
[128]1979 }
[1]1980
[1219]1981 sync();
[1]1982
[1326]1983 sprintf(tmp, "cp -f %s " MNT_RESTORING "/var/log", MONDO_LOGFILE);
1984 if (run_program_and_log_output(tmp, FALSE)) {
[1108]1985 mr_msg(1,
[1326]1986 "Error. Failed to copy log to PC's /var/log dir. (Mounted read-only?)");
[1]1987 }
[128]1988 if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
1989 run_program_and_log_output("mkdir -p " MNT_RESTORING
1990 "/mnt/.boot.d", 5);
[1]1991 }
[128]1992 for (lino = mountlist->entries - 1; lino >= 0; lino--) {
1993 if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
1994 continue;
1995 }
[1219]1996 mr_asprintf(&tmp, _("Unmounting device %s "),
1997 mountlist->el[lino].device);
[128]1998
1999 update_progress_form(tmp);
[1219]2000
[128]2001 if (is_this_device_mounted(mountlist->el[lino].device)) {
2002 if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
[1219]2003 mr_asprintf(&command, "swapoff %s", mountlist->el[lino].device);
[128]2004 } else {
2005 if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
[1219]2006 mr_asprintf(&command, "umount %s/", MNT_RESTORING);
[1108]2007 mr_msg(3,
[128]2008 "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2009 } else {
[1219]2010 mr_asprintf(&command, "umount " MNT_RESTORING "%s",
[128]2011 mountlist->el[lino].mountpoint);
2012 }
2013 }
[1108]2014 mr_msg(10, "The 'umount' command is '%s'", command);
[128]2015 res = run_program_and_log_output(command, 3);
[1219]2016 mr_free(command);
[128]2017 } else {
[1219]2018 mr_strcat(tmp, _("...not mounted anyway :-) OK"));
[128]2019 res = 0;
2020 }
2021 g_current_progress++;
2022 if (res) {
[1219]2023 mr_strcat(tmp, _("...Failed"));
[128]2024 retval++;
2025 log_to_screen(tmp);
2026 } else {
[1108]2027 mr_msg(2, tmp);
[128]2028 }
[1219]2029 mr_free(tmp);
[128]2030 }
2031 close_progress_form();
2032 if (retval) {
[1219]2033 mvaddstr_and_log_it(g_currentY++, 74, _("Failed."));
[128]2034 } else {
[1219]2035 mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
[128]2036 }
2037 if (retval) {
[1219]2038 log_to_screen(_("Unable to unmount some of your partitions."));
[128]2039 } else {
[1219]2040 log_to_screen(_("All partitions were unmounted OK."));
[128]2041 }
[1124]2042 mr_free(mountlist);
[128]2043 return (retval);
[1]2044}
2045/**************************************************************************
2046 *END_UNMOUNT_ALL_DEVICES *
2047 **************************************************************************/
2048
2049
2050/**
2051 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2052 * to the ./tmp/ directory.
2053 * @param dev The tape device to read from.
2054 * @return 0 for success, nonzero for failure.
2055 */
[128]2056int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
[1]2057{
[1219]2058 char *command = NULL;
[128]2059 int res = 0;
[1219]2060 // BERLIOS: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
[128]2061 long tape_block_size = 32768;
[1]2062
[128]2063 // tar -zxvf-
[1219]2064 mr_asprintf(&command,
[128]2065 "dd if=%s bs=%ld count=%ld 2> /dev/null | tar -zx %s %s %s %s %s",
2066 dev,
2067 tape_block_size,
2068 1024L * 1024 * 32 / tape_block_size,
2069 MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB,
2070 BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, "tmp/i-want-my-lvm");
[1108]2071 mr_msg(2, "command = '%s'", command);
[128]2072 res = run_program_and_log_output(command, -1);
[1219]2073 mr_free(command);
2074
[128]2075 if (res != 0 && does_file_exist(MONDO_CFG_FILE_STUB)) {
2076 res = 0;
2077 }
2078 return (res);
[1]2079}
2080
[128]2081
[1]2082/**
[1581]2083 * Get the configuration file from the tape, or CD.
[1]2084 * @param bkpinfo The backup information structure. Fields used:
2085 * - @c bkpinfo->backup_media_type
2086 * - @c bkpinfo->media_device
2087 * - @c bkpinfo->tmpdir
2088 * @return 0 for success, nonzero for failure.
2089 */
[128]2090int get_cfg_file_from_archive(struct s_bkpinfo *bkpinfo)
[1]2091{
[128]2092 int retval = 0;
[1219]2093 char *command = NULL;
2094 char *cfg_file = NULL;
2095 char *mounted_cfgf_path = NULL;
2096 char *tmp = NULL;
2097 char *mountpt = NULL;
2098 char *ramdisk_fname = NULL;
2099 char *mountlist_file = NULL;
2100 int res = 0;
[128]2101
[1219]2102 bool try_plan_B = FALSE;
[1]2103
[128]2104 assert(bkpinfo != NULL);
[1108]2105 mr_msg(2, "gcffa --- starting");
[1219]2106 log_to_screen(_("I'm thinking..."));
2107 mr_asprintf(&mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
[128]2108 chdir(bkpinfo->tmpdir);
[1219]2109 // MONDO_CFG_FILE_STUB is missing the '/' at the start, FYI, by intent
2110 unlink(MONDO_CFG_FILE_STUB);
2111
[128]2112 unlink(FILELIST_FULL_STUB);
2113 unlink(BIGGIELIST_TXT_STUB);
2114 unlink("tmp/i-want-my-lvm");
[1219]2115 mr_asprintf(&command, "mkdir -p %s", mountpt);
[128]2116 run_program_and_log_output(command, FALSE);
[1219]2117 mr_free(command);
[128]2118
[1219]2119 mr_asprintf(&cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2120 mr_asprintf(&mountlist_file, "%s/%s", bkpinfo->tmpdir,
[128]2121 MOUNTLIST_FNAME_STUB);
[1108]2122 mr_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
[128]2123
[1219]2124 mr_asprintf(&tmp, "mkdir -p %s/tmp", bkpinfo->tmpdir);
[128]2125 run_program_and_log_output(tmp, FALSE);
[1219]2126 mr_free(tmp);
[128]2127
2128 if (!does_file_exist(cfg_file)) {
[1108]2129 mr_msg(2, "gcffa --- we don't have cfg file yet.");
[128]2130 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2131 try_plan_B = TRUE;
2132 } else {
[1108]2133 mr_msg(2, "gcffa --- calling mount_cdrom now :)");
[128]2134 if (!mount_cdrom(bkpinfo)) {
[1108]2135 mr_msg(2,
[128]2136 "gcffa --- managed to mount CD; so, no need for Plan B");
2137 try_plan_B = FALSE;
2138 } else {
2139 try_plan_B = TRUE;
2140 }
2141 if (what_number_cd_is_this(bkpinfo) > 1) {
2142 insist_on_this_cd_number(bkpinfo,
2143 (g_current_media_number = 1));
2144 }
2145 }
2146 if (try_plan_B) {
[1108]2147 mr_msg(2, "gcffa --- OK, switching to Plan B");
[128]2148 chdir(bkpinfo->tmpdir);
2149 run_program_and_log_output("mkdir -p tmp", FALSE);
[1]2150
[128]2151 if (strlen(bkpinfo->media_device) == 0) {
2152 strcpy(bkpinfo->media_device, "/dev/st0");
[1219]2153 mr_msg(2, "media_device is blank; assuming %s",
2154 bkpinfo->media_device);
[128]2155 }
[1219]2156 mr_asprintf(&tmp, bkpinfo->media_device);
[128]2157 if (extract_cfg_file_and_mountlist_from_tape_dev
2158 (bkpinfo->media_device)) {
2159 strcpy(bkpinfo->media_device, "/dev/st0");
2160 if (extract_cfg_file_and_mountlist_from_tape_dev
2161 (bkpinfo->media_device)) {
2162 strcpy(bkpinfo->media_device, "/dev/osst0");
2163 if (extract_cfg_file_and_mountlist_from_tape_dev
2164 (bkpinfo->media_device)) {
2165 strcpy(bkpinfo->media_device, "/dev/ht0");
2166 if (extract_cfg_file_and_mountlist_from_tape_dev
2167 (bkpinfo->media_device)) {
[1108]2168 mr_msg(3,
[128]2169 "I tried lots of devices but none worked.");
2170 strcpy(bkpinfo->media_device, tmp);
2171 }
2172 }
2173 }
2174 }
[1219]2175 mr_free(tmp);
[1]2176
[128]2177 if (!does_file_exist("tmp/mondo-restore.cfg")) {
[1219]2178 log_to_screen(_
[1581]2179 ("Cannot find config info on tape/CD"));
[128]2180 return (1);
2181 }
2182 } else {
[1219]2183 mr_asprintf(&mounted_cfgf_path, "%s/%s", mountpt, cfg_file);
[128]2184 if (!does_file_exist(mounted_cfgf_path)) {
[1419]2185 mr_msg(2,
[1408]2186 "gcffa --- Plan B, a.k.a. untarring some file from all.tar.gz");
[1219]2187 mr_asprintf(&command, "tar -zxvf " MNT_CDROM "/images/all.tar.gz %s %s %s %s %s", MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB, BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, "tmp/i-want-my-lvm"); // add -b TAPE_BLOCK_SIZE if you _really_ think it's necessary
[128]2188 run_program_and_log_output(command, TRUE);
[1219]2189 mr_free(command);
2190
[128]2191 if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2192 fatal_error
2193 ("Please reinsert the disk/CD and try again.");
2194 }
2195 }
[1219]2196 mr_free(mounted_cfgf_path);
[1]2197 }
[128]2198 }
[1219]2199 mr_free(mountpt);
2200
[128]2201 if (does_file_exist(MONDO_CFG_FILE_STUB)) {
[1108]2202 mr_msg(1, "gcffa --- great! We've got the config file");
[1219]2203 mr_asprintf(&tmp, "%s/%s",
[128]2204 call_program_and_get_last_line_of_output("pwd"),
2205 MONDO_CFG_FILE_STUB);
[1219]2206 mr_asprintf(&command, "cp -f %s %s", tmp, cfg_file);
[128]2207 iamhere(command);
[1219]2208
[128]2209 if (strcmp(tmp, cfg_file)
2210 && run_program_and_log_output(command, 1)) {
[1108]2211 mr_msg(1,
[128]2212 "... but an error occurred when I tried to move it to %s",
2213 cfg_file);
2214 } else {
[1108]2215 mr_msg(1, "... and I moved it successfully to %s", cfg_file);
[128]2216 }
[1219]2217 mr_free(command);
2218
2219 mr_asprintf(&command, "cp -f %s/%s %s",
[128]2220 call_program_and_get_last_line_of_output("pwd"),
2221 MOUNTLIST_FNAME_STUB, mountlist_file);
2222 iamhere(command);
2223 if (strcmp(tmp, cfg_file)
2224 && run_program_and_log_output(command, 1)) {
[1108]2225 mr_msg(1, "Failed to get mountlist");
[128]2226 } else {
[1108]2227 mr_msg(1, "Got mountlist too");
[1219]2228 mr_free(command);
2229 mr_asprintf(&command, "cp -f %s %s", mountlist_file,
[128]2230 g_mountlist_fname);
2231 if (run_program_and_log_output(command, 1)) {
[1108]2232 mr_msg(1, "Failed to copy mountlist to /tmp");
[128]2233 } else {
[1108]2234 mr_msg(1, "Copied mountlist to /tmp as well OK");
[1219]2235 mr_free(command);
2236 mr_asprintf(&command, "cp -f tmp/i-want-my-lvm /tmp/");
[128]2237 run_program_and_log_output(command, 1);
2238 }
2239 }
[1219]2240 mr_free(command);
2241 mr_free(tmp);
[128]2242 }
2243 run_program_and_log_output("umount " MNT_CDROM, FALSE);
2244 if (!does_file_exist(cfg_file)) {
2245 iamhere(cfg_file);
[1108]2246 mr_msg(1, "%s not found", cfg_file);
[128]2247 log_to_screen
[1219]2248 (_
2249 ("Oh dear. Unable to recover configuration file from boot disk"));
[128]2250 return (1);
2251 }
[1]2252
[1219]2253 log_to_screen(_("Recovered mondo-restore.cfg"));
[128]2254 if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
[1219]2255 log_to_screen(_("...but not mountlist.txt - a pity, really..."));
[128]2256 }
[1]2257/* start SAH */
[128]2258 else {
[1219]2259 mr_asprintf(&command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB,
[128]2260 bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2261 run_program_and_log_output(command, FALSE);
[1219]2262 mr_free(command);
[128]2263 }
[1]2264/* end SAH */
2265
[1219]2266 mr_asprintf(&command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2267 mr_free(cfg_file);
[128]2268 run_program_and_log_output(command, FALSE);
[1219]2269 mr_free(command);
2270
2271 mr_asprintf(&command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2272 mr_free(mountlist_file);
[128]2273 run_program_and_log_output(command, FALSE);
[1219]2274 mr_free(command);
2275
2276 mr_asprintf(&command, "cp -f etc/raidtab /etc/");
[128]2277 run_program_and_log_output(command, FALSE);
[1219]2278 mr_free(command);
2279
2280 mr_asprintf(&command, "cp -f tmp/i-want-my-lvm /tmp/");
[128]2281 run_program_and_log_output(command, FALSE);
[1219]2282 mr_free(command);
2283
[128]2284 g_backup_media_type = bkpinfo->backup_media_type;
[1267]2285 strncpy(bkpinfo->backup_media_string,bkptype_to_string(bkpinfo->backup_media_type), (size_t)63);
[1219]2286 g_backup_media_string = bkpinfo->backup_media_string;
[128]2287 return (retval);
[1]2288}
2289/**************************************************************************
2290 *END_GET_CFG_FILE_FROM_ARCHIVE *
2291 **************************************************************************/
2292/* @} - end restoreUtilityGroup */
2293
2294
[1251]2295void wait_until_software_raids_are_prepped(int wait_for_percentage)
[1]2296{
[1219]2297 struct raidlist_itself *raidlist = NULL;
2298 int unfinished_mdstat_devices = 9999, i = 0;
2299 char *screen_message = NULL;
[1]2300
[1102]2301 raidlist = (struct raidlist_itself *)mr_malloc(sizeof(struct raidlist_itself));
[128]2302
2303 assert(wait_for_percentage <= 100);
[799]2304 iamhere("wait_until_software_raids_are_prepped");
[128]2305 while (unfinished_mdstat_devices > 0) {
[558]2306 // FIXME: Prefix '/dev/' should really be dynamic!
2307 if (parse_mdstat(raidlist, "/dev/")) {
2308 log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
[1219]2309 mr_msg(1, "Sorry, cannot read %s", MDSTAT_FILE);
[128]2310 return;
[1]2311 }
[558]2312 for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2313 if (raidlist->el[i].progress < wait_for_percentage) {
[128]2314 unfinished_mdstat_devices++;
[704]2315 if (raidlist->el[i].progress == -1) // delayed while another partition inits
2316 {
2317 continue;
2318 }
[1108]2319 mr_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
[1219]2320 mr_asprintf(&screen_message, "Sync'ing %s",
[558]2321 raidlist->el[i].raid_device);
[128]2322 open_evalcall_form(screen_message);
[1219]2323 mr_free(screen_message);
2324
[558]2325 while (raidlist->el[i].progress < wait_for_percentage) {
[1108]2326 mr_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
[558]2327 update_evalcall_form(raidlist->el[i].progress);
[128]2328 sleep(2);
[558]2329 // FIXME: Prefix '/dev/' should really be dynamic!
2330 if (parse_mdstat(raidlist, "/dev/")) {
[128]2331 break;
2332 }
2333 }
2334 close_evalcall_form();
2335 }
[1]2336 }
[128]2337 }
[1124]2338 mr_free(raidlist);
[1]2339}
Note: See TracBrowser for help on using the repository browser.