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

Last change on this file since 2382 was 2382, checked in by Bruno Cornec, 15 years ago
  • Change NFS support into a NetFS support to allow for multiple protocol in addition to NFS (NEEDS TESTING)

(Backport from 2.2.9)

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