source: MondoRescue/branches/3.0/mondo/src/mondorestore/mondo-rstr-tools.c@ 3185

Last change on this file since 3185 was 3185, checked in by Bruno Cornec, 11 years ago

Simplify the interface of mr_getline and mr_asprintf. With 3.1 compatibility now will allow backports from this branch into 3.0

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