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

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

r3336@localhost: bruno | 2009-08-11 16:32:36 +0200

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