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

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