source: MondoRescue/branches/2.2.10/mondo/src/mondorestore/mondo-rstr-tools.c@ 2326

Last change on this file since 2326 was 2326, checked in by Bruno Cornec, 15 years ago

r3337@localhost: bruno | 2009-08-11 20:02:18 +0200
bkpinfo->boot_device and bkpinfo->zip_exe are now dynamically allocated

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