source: MondoRescue/branches/2.2.6/mondo/src/mondorestore/mondo-rstr-tools.c@ 1937

Last change on this file since 1937 was 1937, checked in by Bruno Cornec, 16 years ago

Attempt to fix problem with SuSE 10.2 boot loader not reinstalled - may also fix other SLES issues reported with the same problem - by mounting /proc and /sys in the chroot during mount_all_devices

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