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

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

r3338@localhost: bruno | 2009-08-11 23:03:30 +0200
bkpinfo->zip_suffix, bkpinfo->image_devs and bkpinfo->restore_path are now allocated dynmically

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