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

Last change on this file since 1948 was 1948, checked in by Bruno Cornec, 16 years ago
  • Adds OBDR support (use_obdr field in bkpinfo added, -o option changed to mean OBDR - LILO not usable anyway as a bootloader for ISO images)
  • Property svn:keywords set to Id
File size: 76.9 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")) {
1043 bkpinfo->use_star = TRUE;
1044 log_msg(1, "Goody! ... bkpinfo->use_star is now true.");
1045}
1046
1047read_cfg_var(cfg_file, "obdr", value);
1048if (strstr(value, "TRUE")) {
1049 bkpinfo->use_obdr = TRUE;
1050 log_msg(1, "OBDR mode activated");
1051}
1052
1053read_cfg_var(cfg_file, "acl", value);
1054if (strstr(value, "TRUE")) {
1055 asprintf(&g_getfacl,"setfacl");
1056 log_msg(1, "We will restore ACLs");
1057 if (! find_home_of_exe("setfacl")) {
1058 log_msg(1, "Unable to restore ACLs as no setfacl found");
1059 }
1060}
1061read_cfg_var(cfg_file, "xattr", value);
1062if (strstr(value, "TRUE")) {
1063 asprintf(&g_getfattr,"setfattr");
1064 log_msg(1, "We will restore XATTRs");
1065 if (! find_home_of_exe("setfattr")) {
1066 log_msg(1, "Unable to restore XATTRs as no setfattr found");
1067 }
1068}
1069
1070if (0 == read_cfg_var(cfg_file, "internal-tape-block-size", value)) {
1071bkpinfo->internal_tape_block_size = atol(value);
1072log_msg(1, "Internal tape block size has been custom-set to %ld",
1073 bkpinfo->internal_tape_block_size);
1074} else {
1075bkpinfo->internal_tape_block_size =
1076 DEFAULT_INTERNAL_TAPE_BLOCK_SIZE;
1077log_msg(1, "Internal tape block size = default (%ld)",
1078 DEFAULT_INTERNAL_TAPE_BLOCK_SIZE);
1079}
1080
1081read_cfg_var(cfg_file, "use-lzo", value);
1082if (strstr(value, "yes")) {
1083bkpinfo->use_lzo = TRUE;
1084bkpinfo->use_gzip = FALSE;
1085strcpy(bkpinfo->zip_exe, "lzop");
1086strcpy(bkpinfo->zip_suffix, "lzo");
1087} else {
1088read_cfg_var(cfg_file, "use-gzip", value);
1089if (strstr(value, "yes")) {
1090 bkpinfo->use_lzo = FALSE;
1091 bkpinfo->use_gzip = TRUE;
1092 strcpy(bkpinfo->zip_exe, "gzip");
1093 strcpy(bkpinfo->zip_suffix, "gz");
1094} else {
1095 read_cfg_var(cfg_file, "use-comp", value);
1096 if (strstr(value, "yes")) {
1097 bkpinfo->use_lzo = FALSE;
1098 bkpinfo->use_gzip = FALSE;
1099 strcpy(bkpinfo->zip_exe, "bzip2");
1100 strcpy(bkpinfo->zip_suffix, "bz2");
1101 } else {
1102 bkpinfo->zip_exe[0] = bkpinfo->zip_suffix[0] = '\0';
1103 }
1104}
1105}
1106
1107value[0] = '\0';
1108read_cfg_var(cfg_file, "differential", value);
1109if (!strcmp(value, "yes") || !strcmp(value, "1")) {
1110bkpinfo->differential = TRUE;
1111}
1112log_msg(2, "differential var = '%s'", value);
1113if (bkpinfo->differential) {
1114log_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
1115} else {
1116log_msg(2, "This is a regular (full) backup");
1117}
1118
1119read_cfg_var(g_mondo_cfg_file, "please-dont-eject", tmp);
1120if (tmp[0]
1121||
1122strstr(call_program_and_get_last_line_of_output
1123 ("cat /proc/cmdline"), "donteject")) {
1124bkpinfo->please_dont_eject = TRUE;
1125log_msg(2, "Ok, I shan't eject when restoring! Groovy.");
1126}
1127
1128if (bkpinfo->backup_media_type == nfs) {
1129 if (!cfgf) {
1130 log_msg(2, "nfs_mount remains %s", bkpinfo->nfs_mount);
1131 log_msg(2, "nfs_remote_dir remains %s",
1132 bkpinfo->nfs_remote_dir);
1133 log_msg(2,
1134 "...cos it wouldn't make sense to abandon the values that GOT ME to this config file in the first place");
1135 } else {
1136 read_cfg_var(g_mondo_cfg_file, "nfs-server-mount",
1137 bkpinfo->nfs_mount);
1138 read_cfg_var(g_mondo_cfg_file, "nfs-server-path",
1139 bkpinfo->nfs_remote_dir);
1140 log_msg(2, "nfs_mount is %s", bkpinfo->nfs_mount);
1141 log_msg(2, "nfs_remote_dir is %s", bkpinfo->nfs_remote_dir);
1142 }
1143 if (strstr(call_program_and_get_last_line_of_output
1144 ("cat /proc/cmdline"), "pxe")) {
1145 /* We need to override values in PXE mode as it's
1146 * already done in start-nfs */
1147 envtmp1 = getenv("nfsmount");
1148 if (envtmp1 == NULL) {
1149 fatal_error("no nfsmount variable in environment");
1150 }
1151 envtmp2 = getenv("dirimg");
1152 if (envtmp2 == NULL) {
1153 fatal_error("no dirimg variable in environment");
1154 }
1155 strcpy(bkpinfo->nfs_mount,envtmp1);
1156 strcpy(bkpinfo->nfs_remote_dir,envtmp2);
1157 }
1158} else if (bkpinfo->backup_media_type == iso) {
1159 /* Patch by Conor Daly 23-june-2004
1160 * to correctly mount iso-dev and set a sensible
1161 * isodir in disaster recovery mode
1162 */
1163 strcpy(old_isodir, bkpinfo->isodir);
1164 read_cfg_var(g_mondo_cfg_file, "iso-mnt", iso_mnt);
1165 read_cfg_var(g_mondo_cfg_file, "isodir", iso_path);
1166 sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1167 if (!bkpinfo->isodir[0]) {
1168 strcpy(bkpinfo->isodir, old_isodir);
1169 }
1170 if (!bkpinfo->disaster_recovery) {
1171 if (strcmp(old_isodir, bkpinfo->isodir)) {
1172 log_it
1173 ("user nominated isodir differs from archive, keeping user's choice: %s %s\n",
1174 old_isodir, bkpinfo->isodir);
1175 strcpy(bkpinfo->isodir, old_isodir);
1176 }
1177 }
1178 read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
1179 log_msg(2, "isodir=%s; iso-dev=%s", bkpinfo->isodir,
1180 g_isodir_device);
1181 if (bkpinfo->disaster_recovery) {
1182 if (is_this_device_mounted(g_isodir_device)) {
1183 log_msg(2, "NB: isodir is already mounted");
1184 /* Find out where it's mounted */
1185 sprintf(command,
1186 "mount | grep -E '^%s' | tail -n1 | cut -d' ' -f3",
1187 g_isodir_device);
1188 log_it("command = %s", command);
1189 log_it("res of it = %s",
1190 call_program_and_get_last_line_of_output(command));
1191 sprintf(iso_mnt, "%s",
1192 call_program_and_get_last_line_of_output(command));
1193 } else {
1194 sprintf(iso_mnt, "/tmp/isodir");
1195 sprintf(tmp, "mkdir -p %s", iso_mnt);
1196 run_program_and_log_output(tmp, 5);
1197 sprintf(tmp, "mount %s %s", g_isodir_device, iso_mnt);
1198 if (run_program_and_log_output(tmp, 3)) {
1199 log_msg(1,
1200 "Unable to mount isodir. Perhaps this is really a CD backup?");
1201 bkpinfo->backup_media_type = cdr;
1202 strcpy(bkpinfo->media_device, "/dev/cdrom"); /* superfluous */
1203 bkpinfo->isodir[0] = iso_mnt[0] = iso_path[0] = '\0';
1204 if (mount_media()) {
1205 fatal_error
1206 ("Unable to mount isodir. Failed to mount CD-ROM as well.");
1207 } else {
1208 log_msg(1,
1209 "You backed up to disk, then burned some CDs.");
1210 }
1211 }
1212 }
1213 /* bkpinfo->isodir should now be the true path to prefix-1.iso etc... */
1214 if (bkpinfo->backup_media_type == iso) {
1215 sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1216 }
1217 }
1218}
1219
1220if (media_specified_by_user != none) {
1221 if (g_restoring_live_from_cd) {
1222 if (bkpinfo->backup_media_type != media_specified_by_user) {
1223 log_msg(2,
1224 "bkpinfo->backup_media_type != media_specified_by_user, so I'd better ask :)");
1225 interactively_obtain_media_parameters_from_user(FALSE);
1226 media_specified_by_user = bkpinfo->backup_media_type;
1227 get_cfg_file_from_archive();
1228 /*
1229 if (media_specified_by_user != cdr && media_specified_by_user == cdrw)
1230 { g_restoring_live_from_cd = FALSE; }
1231 */
1232 }
1233 }
1234 bkpinfo->backup_media_type = media_specified_by_user;
1235}
1236g_backup_media_type = bkpinfo->backup_media_type;
1237paranoid_free(value);
1238paranoid_free(tmp);
1239paranoid_free(command);
1240paranoid_free(iso_mnt);
1241paranoid_free(iso_path);
1242paranoid_free(old_isodir);
1243return (0);
1244
1245}
1246
1247/**************************************************************************
1248*END_READ_CFG_FILE_INTO_BKPINFO *
1249**************************************************************************/
1250
1251
1252
1253
1254/**
1255 * Allow the user to edit the filelist and biggielist.
1256 * The filelist is unlinked after it is read.
1257 * @param bkpinfo The backup information structure. Fields used:
1258 * - @c bkpinfo->backup_media_type
1259 * - @c bkpinfo->isodir
1260 * - @c bkpinfo->media_device
1261 * - @c bkpinfo->tmpdir
1262 * @return The filelist structure containing the information read from disk.
1263 */
1264struct
1265s_node *process_filelist_and_biggielist()
1266{
1267struct s_node *filelist;
1268
1269/** add mallocs**/
1270char *command;
1271char *tmp;
1272int res = 0;
1273pid_t pid;
1274
1275assert(bkpinfo != NULL);
1276malloc_string(command);
1277malloc_string(tmp);
1278
1279if (does_file_exist(g_filelist_full)
1280&& does_file_exist(g_biggielist_txt)) {
1281log_msg(1, "%s exists", g_filelist_full);
1282log_msg(1, "%s exists", g_biggielist_txt);
1283log_msg(2,
1284 "Filelist and biggielist already recovered from media. Yay!");
1285} else {
1286getcwd(tmp, MAX_STR_LEN);
1287chdir(bkpinfo->tmpdir);
1288log_msg(1, "chdir(%s)", bkpinfo->tmpdir);
1289log_to_screen("Extracting filelist and biggielist from media...");
1290unlink("/tmp/filelist.full");
1291unlink("/" FILELIST_FULL_STUB);
1292unlink("/tmp/i-want-my-lvm");
1293if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
1294 sprintf(command,
1295 "tar -b %ld -zxf %s %s %s %s %s %s",
1296 bkpinfo->internal_tape_block_size,
1297 bkpinfo->media_device,
1298 MOUNTLIST_FNAME_STUB,
1299 BIGGIELIST_TXT_STUB,
1300 FILELIST_FULL_STUB,
1301 "./tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1302 log_msg(1, "tarcommand = %s", command);
1303 run_program_and_log_output(command, 1);
1304} else {
1305 log_msg(2,
1306 "Calling insist_on_this_cd_number; bkpinfo->isodir=%s",
1307 bkpinfo->isodir);
1308 insist_on_this_cd_number(1);
1309 log_msg(2, "Back from iotcn");
1310 run_program_and_log_output("mount", 1);
1311 sprintf(command,
1312 "tar -zxf %s/images/all.tar.gz %s %s %s %s %s",
1313 MNT_CDROM,
1314 MOUNTLIST_FNAME_STUB,
1315 BIGGIELIST_TXT_STUB,
1316 FILELIST_FULL_STUB,
1317 "./tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1318
1319 log_msg(1, "tarcommand = %s", command);
1320 run_program_and_log_output(command, 1);
1321// popup_and_OK("Press ENTER to continue");
1322 if (!does_file_exist(BIGGIELIST_TXT_STUB)) {
1323 fatal_error
1324 ("all.tar.gz did not include ./tmp/biggielist.txt");
1325 }
1326 if (!does_file_exist(FILELIST_FULL_STUB)) {
1327 fatal_error
1328 ("all.tar.gz did not include ./tmp/filelist.full.gz");
1329 }
1330}
1331sprintf(command, "cp -f %s %s", MONDO_CFG_FILE_STUB,
1332 g_mondo_cfg_file);
1333run_program_and_log_output(command, FALSE);
1334
1335sprintf(command, "cp -f %s/%s %s", bkpinfo->tmpdir,
1336 BIGGIELIST_TXT_STUB, g_biggielist_txt);
1337log_msg(1, "command = %s", command);
1338paranoid_system(command);
1339sprintf(command, "ln -sf %s/%s %s", bkpinfo->tmpdir,
1340 FILELIST_FULL_STUB, g_filelist_full);
1341log_msg(1, "command = %s", command);
1342paranoid_system(command);
1343}
1344
1345if (am_I_in_disaster_recovery_mode()
1346&&
1347ask_me_yes_or_no("Do you want to retrieve the mountlist as well?"))
1348{
1349// sprintf(command, "cp -f tmp/mountlist.txt /tmp");
1350sprintf(command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB,
1351 bkpinfo->tmpdir);
1352paranoid_system(command);
1353}
1354
1355chdir(tmp);
1356
1357if (!does_file_exist(g_biggielist_txt)) {
1358log_msg(1, "Warning - %s not found", g_biggielist_txt);
1359}
1360if (!does_file_exist(g_filelist_full)) {
1361log_msg(1, "Warning - %s does not exist", g_filelist_full);
1362}
1363// popup_and_OK("Wonderful.");
1364
1365log_msg(2, "Forking");
1366pid = fork();
1367switch (pid) {
1368case -1:
1369fatal_error("Forking error");
1370break;
1371
1372case 0:
1373log_to_screen("Pre-processing filelist");
1374if (!does_file_exist(g_biggielist_txt)) {
1375 sprintf(command, "echo -n > %s", g_biggielist_txt);
1376 paranoid_system(command);
1377 }
1378 sprintf(command, "grep -E '^/dev/.*' %s > %s",
1379 g_biggielist_txt, g_filelist_imagedevs);
1380 paranoid_system(command);
1381 exit(0);
1382 break;
1383
1384 default:
1385 open_evalcall_form("Pre-processing filelist");
1386 while (!waitpid(pid, (int *) 0, WNOHANG)) {
1387 usleep(100000);
1388 update_evalcall_form(0);
1389 }
1390 }
1391 close_evalcall_form();
1392
1393 log_msg(3, "loading filelist");
1394 filelist = load_filelist(g_filelist_full);
1395 log_msg(3, "deleting original filelist");
1396 unlink(g_filelist_full);
1397 if (g_text_mode) {
1398 printf("Restore which directory? --> ");
1399 fgets(tmp, sizeof(tmp), stdin);
1400 toggle_path_selection(filelist, tmp, TRUE);
1401 if (strlen(tmp) == 0) {
1402 res = 1;
1403 } else {
1404 res = 0;
1405 }
1406 } else {
1407 res = edit_filelist(filelist);
1408 }
1409 if (res) {
1410 log_msg(2, "User hit 'cancel'. Freeing filelist and aborting.");
1411 free_filelist(filelist);
1412 return (NULL);
1413 }
1414 ask_about_these_imagedevs(g_filelist_imagedevs, g_imagedevs_restthese);
1415 close_evalcall_form();
1416
1417 // NB: It's not necessary to add g_biggielist_txt to the filelist.full
1418 // file. The filelist.full file already contains the filename of EVERY
1419 // file backed up - regular and biggie files.
1420
1421 // However, we do want to make sure the imagedevs selected by the user
1422 // are flagged for restoring.
1423 if (length_of_file(g_imagedevs_restthese) > 2) {
1424 add_list_of_files_to_filelist(filelist, g_imagedevs_restthese,
1425 TRUE);
1426 }
1427
1428 paranoid_free(command);
1429 paranoid_free(tmp);
1430 return (filelist);
1431}
1432
1433/**************************************************************************
1434 *END_ PROCESS_FILELIST_AND_BIGGIELIST *
1435 **************************************************************************/
1436
1437
1438
1439
1440/**
1441 * Make a backup copy of <tt>path_root</tt>/<tt>filename</tt>.
1442 * The backup filename is the filename of the original with ".pristine" added.
1443 * @param path_root The place where the filesystem is mounted (e.g. MNT_RESTORING).
1444 * @param filename The filename (absolute path) within @p path_root.
1445 * @return 0 for success, nonzero for failure.
1446 */
1447int backup_crucial_file(char *path_root, char *filename)
1448{
1449 char *tmp;
1450 char *command;
1451 int res;
1452
1453 malloc_string(tmp);
1454 malloc_string(command);
1455 assert(path_root != NULL);
1456 assert_string_is_neither_NULL_nor_zerolength(filename);
1457
1458 sprintf(tmp, "%s/%s", path_root, filename);
1459 sprintf(command, "cp -f %s %s.pristine", tmp, tmp);
1460
1461 res = run_program_and_log_output(command, 5);
1462 paranoid_free(tmp);
1463 paranoid_free(command);
1464 return (res);
1465}
1466
1467
1468/**
1469 * Install the user's boot loader in the MBR.
1470 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported.
1471 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1472 * @return 0 for success, nonzero for failure.
1473 */
1474int run_boot_loader(bool offer_to_hack_scripts)
1475{
1476 int res;
1477 int retval = 0;
1478
1479 /** malloc *******/
1480 char *device;
1481 char *tmp = NULL;
1482 char *name;
1483 char *cmd = NULL;
1484
1485 malloc_string(device);
1486 malloc_string(name);
1487
1488 /* In order to have a working bootloader, we need to have all devices
1489 * ready in the chroot. If they are not there (udev) then copy them from
1490 * the current /dev location
1491 */
1492 asprintf(&cmd,"tar cf - /dev | ( cd %s ; tar xf - )",MNT_RESTORING);
1493 run_program_and_log_output(cmd, 3);
1494 paranoid_free(cmd);
1495
1496 backup_crucial_file(MNT_RESTORING, "/etc/fstab");
1497 backup_crucial_file(MNT_RESTORING, "/etc/grub.conf");
1498 backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf");
1499 backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf");
1500 backup_crucial_file(MNT_RESTORING, "/boot/grub/device.map");
1501 backup_crucial_file(MNT_RESTORING, "/etc/mtab");
1502 read_cfg_var(g_mondo_cfg_file, "bootloader.device", device);
1503 read_cfg_var(g_mondo_cfg_file, "bootloader.name", name);
1504 asprintf(&tmp, "run_boot_loader: device='%s', name='%s'", device, name);
1505 log_msg(2, tmp);
1506 paranoid_free(tmp);
1507 system("sync");
1508 if (!strcmp(name, "LILO")) {
1509 res = run_lilo(offer_to_hack_scripts);
1510 } else if (!strcmp(name, "ELILO")) {
1511 res = run_elilo(offer_to_hack_scripts);
1512 } else if (!strcmp(name, "GRUB")) {
1513 res = run_grub(offer_to_hack_scripts, device);
1514 } else if (!strcmp(name, "RAW")) {
1515 res = run_raw_mbr(offer_to_hack_scripts, device);
1516 }
1517#ifdef __FreeBSD__
1518 else if (!strcmp(name, "BOOT0")) {
1519 asprintf(&tmp, "boot0cfg -B %s", device);
1520 res = run_program_and_log_output(tmp, FALSE);
1521 paranoid_free(tmp);
1522 } else {
1523 asprintf(&tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device);
1524 if (!system(tmp)) {
1525 paranoid_free(tmp);
1526 asprintf(&tmp, MNT_RESTORING "/sbin/fdisk -B %s", device);
1527 res = run_program_and_log_output(tmp, 3);
1528 } else {
1529 log_msg(1,
1530 "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");
1531 }
1532 paranoid_free(tmp);
1533 }
1534#else
1535 else {
1536 log_to_screen
1537 ("Unable to determine type of boot loader. Defaulting to LILO.");
1538 res = run_lilo(offer_to_hack_scripts);
1539 }
1540#endif
1541 retval += res;
1542 if (res) {
1543 log_to_screen("Your boot loader returned an error");
1544 } else {
1545 log_to_screen("Your boot loader ran OK");
1546 }
1547 paranoid_free(device);
1548 paranoid_free(name);
1549 return (retval);
1550}
1551
1552/**************************************************************************
1553 *END_ RUN_BOOT_LOADER *
1554 **************************************************************************/
1555
1556
1557
1558/**
1559 * Attempt to find the user's editor.
1560 * @return The editor found ("vi" if none could be found).
1561 * @note The returned string points to static storage that will be overwritten with each call.
1562 */
1563char *find_my_editor(void)
1564{
1565 static char output[MAX_STR_LEN];
1566 if (find_home_of_exe("pico")) {
1567 strcpy(output, "pico");
1568 } else if (find_home_of_exe("nano")) {
1569 strcpy(output, "nano");
1570 } else if (find_home_of_exe("e3em")) {
1571 strcpy(output, "e3em");
1572 } else if (find_home_of_exe("e3vi")) {
1573 strcpy(output, "e3vi");
1574 } else {
1575 strcpy(output, "vi");
1576 }
1577 if (!find_home_of_exe(output)) {
1578 log_msg(2, " (find_my_editor) --- warning - %s not found", output);
1579 }
1580 return (output);
1581}
1582
1583
1584/**
1585 * Install GRUB on @p bd.
1586 * @param offer_to_run_stabgrub If TRUE, then offer to hack the user's fstab for them.
1587 * @param bd The boot device where GRUB is installed.
1588 * @return 0 for success, nonzero for failure.
1589 */
1590int run_grub(bool offer_to_run_stabgrub, char *bd)
1591{
1592 /** malloc **/
1593 char *command;
1594 char *boot_device;
1595 char *rootdev;
1596 char *rootdrive;
1597 char *conffile;
1598 char *tmp;
1599 char *editor;
1600
1601 int res;
1602 int done;
1603
1604 malloc_string(command);
1605 malloc_string(boot_device);
1606 malloc_string(tmp);
1607 malloc_string(editor);
1608 malloc_string(rootdev);
1609 malloc_string(rootdrive);
1610 malloc_string(conffile);
1611 assert_string_is_neither_NULL_nor_zerolength(bd);
1612 strcpy(editor, find_my_editor());
1613 strcpy(boot_device, bd);
1614
1615 if (!run_program_and_log_output("which grub-MR", FALSE)) {
1616 log_msg(1, "Yay! grub-MR found...");
1617 sprintf(command, "grub-MR %s /tmp/mountlist.txt", boot_device);
1618 log_msg(1, "command = %s", command);
1619 } else {
1620 sprintf(command, "chroot " MNT_RESTORING " grub-install %s",
1621 boot_device);
1622 log_msg(1, "WARNING - grub-MR not found; using grub-install");
1623 }
1624 if (offer_to_run_stabgrub
1625 && ask_me_yes_or_no("Did you change the mountlist?"))
1626 /* interactive mode */
1627 {
1628 mvaddstr_and_log_it(g_currentY,
1629 0,
1630 "Modifying fstab, mtab, device.map and grub.conf, and running GRUB... ");
1631 for (done = FALSE; !done;) {
1632 popup_and_get_string("Boot device",
1633 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1634 boot_device, MAX_STR_LEN / 4);
1635 sprintf(command, "stabgrub-me %s", boot_device);
1636 res = run_program_and_log_output(command, 1);
1637 if (res) {
1638 popup_and_OK
1639 ("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.");
1640 newtSuspend();
1641 system("chroot " MNT_RESTORING);
1642 newtResume();
1643 popup_and_OK("Thank you.");
1644 } else {
1645 done = TRUE;
1646 }
1647 popup_and_OK("You will now edit fstab, mtab, device.map and grub.conf");
1648 if (!g_text_mode) {
1649 newtSuspend();
1650 }
1651 sprintf(tmp, "chroot %s %s /etc/fstab", MNT_RESTORING, editor);
1652 paranoid_system(tmp);
1653 sprintf(tmp, "chroot %s %s /etc/mtab", MNT_RESTORING, editor);
1654 paranoid_system(tmp);
1655 sprintf(tmp, "chroot %s %s /etc/grub.conf", MNT_RESTORING, editor);
1656 paranoid_system(tmp);
1657 sprintf(tmp, "chroot %s %s /boot/grub/device.map", MNT_RESTORING, editor);
1658 paranoid_system(tmp);
1659 if (!g_text_mode) {
1660 newtResume();
1661 }
1662 }
1663 } else
1664 /* nuke mode */
1665 {
1666 mvaddstr_and_log_it(g_currentY,
1667 0,
1668 "Running GRUB... ");
1669 iamhere(command);
1670 res = run_program_and_log_output(command, 1);
1671 if (res) {
1672 popup_and_OK
1673 ("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.");
1674 newtSuspend();
1675 system("chroot " MNT_RESTORING);
1676 newtResume();
1677 popup_and_OK("Thank you.");
1678 }
1679 }
1680 if (res) {
1681 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1682 log_to_screen
1683 ("GRUB ran w/error(s). See %s for more info.", MONDO_LOGFILE);
1684 log_msg(1, "Type:-");
1685 log_msg(1, " mount-me");
1686 log_msg(1, " chroot " MNT_RESTORING);
1687 log_msg(1, " mount /boot");
1688 log_msg(1, " grub-install '(hd0)'");
1689 log_msg(1, " exit");
1690 log_msg(1, " unmount-me");
1691 log_msg(1,
1692 "If you're really stuck, please e-mail the mailing list.");
1693 } else {
1694 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1695 }
1696 paranoid_free(rootdev);
1697 paranoid_free(rootdrive);
1698 paranoid_free(conffile);
1699 paranoid_free(command);
1700 paranoid_free(boot_device);
1701 paranoid_free(tmp);
1702 paranoid_free(editor);
1703
1704 return (res);
1705}
1706
1707/**************************************************************************
1708 *END_RUN_GRUB *
1709 **************************************************************************/
1710
1711
1712/**
1713 * Install ELILO on the user's boot drive (determined by elilo.conf).
1714 * @param offer_to_run_stabelilo If TRUE, then offer to hack the user's fstab for them.
1715 * @return 0 for success, nonzero for failure.
1716 */
1717int run_elilo(bool offer_to_run_stabelilo)
1718{
1719 /** malloc **/
1720 char *command;
1721 char *tmp;
1722 char *editor;
1723
1724 int res;
1725 int done;
1726
1727 malloc_string(command);
1728 malloc_string(tmp);
1729 malloc_string(editor);
1730 strcpy(editor, find_my_editor());
1731 if (offer_to_run_stabelilo
1732 && ask_me_yes_or_no("Did you change the mountlist?"))
1733
1734 /* interactive mode */
1735 {
1736 mvaddstr_and_log_it(g_currentY,
1737 0,
1738 "Modifying fstab and elilo.conf... ");
1739 sprintf(command, "stabelilo-me");
1740 res = run_program_and_log_output(command, 3);
1741 if (res) {
1742 popup_and_OK
1743 ("You will now edit fstab and elilo.conf, to make sure they match your new mountlist.");
1744 for (done = FALSE; !done;) {
1745 if (!g_text_mode) {
1746 newtSuspend();
1747 }
1748 sprintf(tmp, "chroot %s %s /etc/fstab", MNT_RESTORING, editor);
1749 paranoid_system(tmp);
1750 sprintf(tmp, "chroot %s %s /etc/elilo.conf", MNT_RESTORING, editor);
1751 paranoid_system(tmp);
1752 if (!g_text_mode) {
1753 newtResume();
1754 }
1755// newtCls();
1756 if (ask_me_yes_or_no("Edit them again?")) {
1757 continue;
1758 }
1759 done = TRUE;
1760 }
1761 } else {
1762 log_to_screen("elilo.conf and fstab were modified OK");
1763 }
1764 } else
1765 /* nuke mode */
1766 {
1767 res = TRUE;
1768 }
1769 paranoid_free(command);
1770 paranoid_free(tmp);
1771 paranoid_free(editor);
1772 return (res);
1773}
1774
1775/**************************************************************************
1776 *END_RUN_ELILO *
1777 **************************************************************************/
1778
1779
1780/**
1781 * Install LILO on the user's boot drive (determined by /etc/lilo.conf).
1782 * @param offer_to_run_stablilo If TRUE, then offer to hack the user's fstab for them.
1783 * @return 0 for success, nonzero for failure.
1784 */
1785int run_lilo(bool offer_to_run_stablilo)
1786{
1787 /** malloc **/
1788 char *command;
1789 char *tmp;
1790 char *editor;
1791
1792 int res;
1793 int done;
1794 bool run_lilo_M = FALSE;
1795 malloc_string(command);
1796 malloc_string(tmp);
1797 malloc_string(editor);
1798
1799 if (!run_program_and_log_output
1800 ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) {
1801 run_lilo_M = TRUE;
1802 }
1803
1804 strcpy(editor, find_my_editor());
1805 if (offer_to_run_stablilo
1806 && ask_me_yes_or_no("Did you change the mountlist?"))
1807
1808 /* interactive mode */
1809 {
1810 mvaddstr_and_log_it(g_currentY,
1811 0,
1812 "Modifying fstab and lilo.conf, and running LILO... ");
1813 sprintf(command, "stablilo-me");
1814 res = run_program_and_log_output(command, 3);
1815 if (res) {
1816 popup_and_OK
1817 ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist.");
1818 for (done = FALSE; !done;) {
1819 if (!g_text_mode) {
1820 newtSuspend();
1821 }
1822 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1823 paranoid_system(tmp);
1824 sprintf(tmp, "%s " MNT_RESTORING "/etc/lilo.conf", editor);
1825 paranoid_system(tmp);
1826 if (!g_text_mode) {
1827 newtResume();
1828 }
1829// newtCls();
1830 if (ask_me_yes_or_no("Edit them again?")) {
1831 continue;
1832 }
1833 res =
1834 run_program_and_log_output("chroot " MNT_RESTORING
1835 " lilo -L", 3);
1836 if (res) {
1837 res =
1838 run_program_and_log_output("chroot " MNT_RESTORING
1839 " lilo", 3);
1840 }
1841 if (res) {
1842 done =
1843 ask_me_yes_or_no
1844 ("LILO failed. Re-edit system files?");
1845 } else {
1846 done = TRUE;
1847 }
1848 }
1849 } else {
1850 log_to_screen("lilo.conf and fstab were modified OK");
1851 }
1852 } else
1853 /* nuke mode */
1854 {
1855 mvaddstr_and_log_it(g_currentY,
1856 0,
1857 "Running LILO... ");
1858 res =
1859 run_program_and_log_output("chroot " MNT_RESTORING " lilo -L",
1860 3);
1861 if (res) {
1862 res =
1863 run_program_and_log_output("chroot " MNT_RESTORING " lilo",
1864 3);
1865 }
1866 if (res) {
1867 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1868 log_to_screen
1869 ("Failed to re-jig fstab and/or lilo. Edit/run manually, please.");
1870 } else {
1871 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1872 }
1873 }
1874 if (run_lilo_M) {
1875 run_program_and_log_output("chroot " MNT_RESTORING
1876 " lilo -M /dev/hda", 3);
1877 run_program_and_log_output("chroot " MNT_RESTORING
1878 " lilo -M /dev/sda", 3);
1879 }
1880 paranoid_free(command);
1881 paranoid_free(tmp);
1882 paranoid_free(editor);
1883 return (res);
1884}
1885
1886/**************************************************************************
1887 *END_RUN_LILO *
1888 **************************************************************************/
1889
1890
1891/**
1892 * Install a raw MBR onto @p bd.
1893 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1894 * @param bd The device to copy the stored MBR to.
1895 * @return 0 for success, nonzero for failure.
1896 */
1897int run_raw_mbr(bool offer_to_hack_scripts, char *bd)
1898{
1899 /** malloc **/
1900 char *command;
1901 char *boot_device;
1902 char *tmp;
1903 char *editor;
1904 int res;
1905 int done;
1906
1907 malloc_string(command);
1908 malloc_string(boot_device);
1909 malloc_string(tmp);
1910 malloc_string(editor);
1911 assert_string_is_neither_NULL_nor_zerolength(bd);
1912
1913 strcpy(editor, find_my_editor());
1914 strcpy(boot_device, bd);
1915 sprintf(command, "raw-MR %s /tmp/mountlist.txt", boot_device);
1916 log_msg(2, "run_raw_mbr() --- command='%s'", command);
1917
1918 if (offer_to_hack_scripts
1919 && ask_me_yes_or_no("Did you change the mountlist?"))
1920 /* interactive mode */
1921 {
1922 mvaddstr_and_log_it(g_currentY, 0,
1923 "Modifying fstab and restoring MBR... ");
1924 for (done = FALSE; !done;) {
1925 if (!run_program_and_log_output("which vi", FALSE)) {
1926 popup_and_OK("You will now edit fstab");
1927 if (!g_text_mode) {
1928 newtSuspend();
1929 }
1930 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1931 paranoid_system(tmp);
1932 if (!g_text_mode) {
1933 newtResume();
1934 }
1935// newtCls();
1936 }
1937 popup_and_get_string("Boot device",
1938 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1939 boot_device, MAX_STR_LEN / 4);
1940 sprintf(command, "stabraw-me %s", boot_device);
1941 res = run_program_and_log_output(command, 3);
1942 if (res) {
1943 done = ask_me_yes_or_no("Modifications failed. Re-try?");
1944 } else {
1945 done = TRUE;
1946 }
1947 }
1948 } else
1949 /* nuke mode */
1950 {
1951 mvaddstr_and_log_it(g_currentY, 0,
1952 "Restoring MBR... ");
1953 res = run_program_and_log_output(command, 3);
1954 }
1955 if (res) {
1956 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1957 log_to_screen
1958 ("MBR+fstab processed w/error(s). See %s for more info.", MONDO_LOGFILE);
1959 } else {
1960 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1961 }
1962 paranoid_free(command);
1963 paranoid_free(boot_device);
1964 paranoid_free(tmp);
1965 paranoid_free(editor);
1966 return (res);
1967}
1968
1969/**************************************************************************
1970 *END_RUN_RAW_MBR *
1971 **************************************************************************/
1972
1973
1974
1975
1976
1977/**
1978 * Turn signal trapping on or off.
1979 * @param on If TRUE, then do full cleanup when we receive a signal; if FALSE, then
1980 * print a message and exit immediately.
1981 */
1982void set_signals(int on)
1983{
1984 int signals[] =
1985 { SIGKILL, SIGPIPE, SIGTERM, SIGHUP, SIGTRAP, SIGABRT, SIGINT,
1986SIGSTOP, 0 };
1987 int i;
1988 for (i = 0; signals[i]; i++) {
1989 if (on) {
1990 signal(signals[i], terminate_daemon);
1991 } else {
1992 signal(signals[i], termination_in_progress);
1993 }
1994 }
1995}
1996
1997/**************************************************************************
1998 *END_SET_SIGNALS *
1999 **************************************************************************/
2000
2001
2002/**
2003 * malloc() and set sensible defaults for the mondorestore filename variables.
2004 * @param bkpinfo The backup information structure. Fields used:
2005 * - @c bkpinfo->tmpdir
2006 * - @c bkpinfo->disaster_recovery
2007 */
2008void setup_MR_global_filenames()
2009{
2010 char *temppath;
2011
2012 assert(bkpinfo != NULL);
2013
2014 malloc_string(g_biggielist_txt);
2015 malloc_string(g_filelist_full);
2016 malloc_string(g_filelist_imagedevs);
2017 malloc_string(g_imagedevs_restthese);
2018 malloc_string(g_mondo_cfg_file);
2019 malloc_string(g_mountlist_fname);
2020 malloc_string(g_mondo_home);
2021 malloc_string(g_tmpfs_mountpt);
2022 malloc_string(g_isodir_device);
2023 malloc_string(g_isodir_format);
2024
2025 temppath = bkpinfo->tmpdir;
2026
2027 sprintf(g_biggielist_txt, "%s/%s", temppath, BIGGIELIST_TXT_STUB);
2028 sprintf(g_filelist_full, "%s/%s", temppath, FILELIST_FULL_STUB);
2029 sprintf(g_filelist_imagedevs, "%s/tmp/filelist.imagedevs", temppath);
2030// sprintf(g_imagedevs_pot, "%s/tmp/imagedevs.pot", temppath);
2031 sprintf(g_imagedevs_restthese, "%s/tmp/imagedevs.restore-these",
2032 temppath);
2033 if (bkpinfo->disaster_recovery) {
2034 sprintf(g_mondo_cfg_file, "/%s", MONDO_CFG_FILE_STUB);
2035 sprintf(g_mountlist_fname, "/%s", MOUNTLIST_FNAME_STUB);
2036 } else {
2037 sprintf(g_mondo_cfg_file, "%s/%s", temppath, MONDO_CFG_FILE_STUB);
2038 sprintf(g_mountlist_fname, "%s/%s", temppath,
2039 MOUNTLIST_FNAME_STUB);
2040 }
2041}
2042
2043/**************************************************************************
2044 *END_SET_GLOBAL_FILENAME *
2045 **************************************************************************/
2046
2047
2048/**
2049 * Copy @p input_file (containing the result of a compare) to @p output_file,
2050 * deleting spurious "changes" along the way.
2051 * @param output_file The output file to write with spurious changes removed.
2052 * @param input_file The input file, a list of changed files created by a compare.
2053 */
2054void streamline_changes_file(char *output_file, char *input_file)
2055{
2056 FILE *fin;
2057 FILE *fout;
2058 /** malloc **/
2059 char *incoming;
2060
2061 assert_string_is_neither_NULL_nor_zerolength(output_file);
2062 assert_string_is_neither_NULL_nor_zerolength(input_file);
2063 malloc_string(incoming);
2064
2065 if (!(fin = fopen(input_file, "r"))) {
2066 log_OS_error(input_file);
2067 return;
2068 }
2069 if (!(fout = fopen(output_file, "w"))) {
2070 fatal_error("cannot open output_file");
2071 }
2072 for (fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin);
2073 fgets(incoming, MAX_STR_LEN - 1, fin)) {
2074 if (strncmp(incoming, "etc/adjtime", 11)
2075 && strncmp(incoming, "etc/mtab", 8)
2076 && strncmp(incoming, "tmp/", 4)
2077 && strncmp(incoming, "boot/map", 8)
2078 && !strstr(incoming, "incheckentry")
2079 && strncmp(incoming, "etc/mail/statistics", 19)
2080 && strncmp(incoming, "var/", 4))
2081 fprintf(fout, "%s", incoming); /* don't need \n here, for some reason.. */
2082 }
2083 paranoid_fclose(fout);
2084 paranoid_fclose(fin);
2085 paranoid_free(incoming);
2086}
2087
2088/**************************************************************************
2089 *END_STREAMLINE_CHANGES_FILE *
2090 **************************************************************************/
2091
2092
2093/**
2094 * Exit due to a signal (normal cleanup).
2095 * @param sig The signal we're exiting due to.
2096 */
2097void terminate_daemon(int sig)
2098{
2099 log_to_screen
2100 ("Mondorestore is terminating in response to a signal from the OS");
2101 paranoid_MR_finish(254);
2102}
2103
2104/**************************************************************************
2105 *END_TERMINATE_DAEMON *
2106 **************************************************************************/
2107
2108
2109/**
2110 * Give the user twenty seconds to press Ctrl-Alt-Del before we nuke their drives.
2111 */
2112void twenty_seconds_til_yikes()
2113{
2114 int i;
2115 /* MALLOC * */
2116 char *tmp;
2117
2118 malloc_string(tmp);
2119 if (does_file_exist("/tmp/NOPAUSE")) {
2120 return;
2121 }
2122 open_progress_form("CAUTION",
2123 "Be advised: I am about to ERASE your hard disk(s)!",
2124 "You may press Ctrl+Alt+Del to abort safely.",
2125 "", 20);
2126 for (i = 0; i < 20; i++) {
2127 g_current_progress = i;
2128 sprintf(tmp, "You have %d seconds left to abort.", 20 - i);
2129 update_progress_form(tmp);
2130 sleep(1);
2131 }
2132 close_progress_form();
2133 paranoid_free(tmp);
2134}
2135
2136/**************************************************************************
2137 *END_TWENTY_SECONDS_TIL_YIKES *
2138 **************************************************************************/
2139
2140
2141
2142
2143
2144/**
2145 * Exit due to a signal (no cleanup).
2146 * @param sig The signal we're exiting due to.
2147 */
2148void termination_in_progress(int sig)
2149{
2150 log_msg(1, "Termination in progress");
2151 usleep(1000);
2152 pthread_exit(0);
2153}
2154
2155/**************************************************************************
2156 *END_TERMINATION_IN_PROGRESS *
2157 **************************************************************************/
2158
2159
2160
2161/**
2162 * Unmount all devices in @p p_external_copy_of_mountlist.
2163 * @param p_external_copy_of_mountlist The mountlist to guide the devices to unmount.
2164 * @return 0 for success, nonzero for failure.
2165 */
2166int unmount_all_devices(struct mountlist_itself
2167 *p_external_copy_of_mountlist)
2168{
2169 struct mountlist_itself *mountlist;
2170 int retval = 0, lino, res = 0, i;
2171 char *command;
2172 char *tmp;
2173
2174 malloc_string(command);
2175 malloc_string(tmp);
2176 assert(p_external_copy_of_mountlist != NULL);
2177
2178 mountlist = malloc(sizeof(struct mountlist_itself));
2179 memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
2180 sizeof(struct mountlist_itself));
2181 sort_mountlist_by_mountpoint(mountlist, 0);
2182
2183 run_program_and_log_output("df -m", 3);
2184 mvaddstr_and_log_it(g_currentY, 0, "Unmounting devices ");
2185 open_progress_form("Unmounting devices",
2186 "Unmounting all devices that were mounted,",
2187 "in preparation for the post-restoration reboot.",
2188 "", mountlist->entries);
2189 chdir("/");
2190 for (i = 0;
2191 i < 10
2192 &&
2193 run_program_and_log_output
2194 ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
2195 i++) {
2196 sleep(1);
2197 log_msg(2, "Waiting for buffer() to finish");
2198 }
2199
2200 paranoid_system("sync");
2201
2202 sprintf(tmp, "cp -f %s " MNT_RESTORING "/var/log", MONDO_LOGFILE);
2203 if (run_program_and_log_output(tmp, FALSE)) {
2204 log_msg(1,
2205 "Error. Failed to copy log to PC's /var/log dir. (Mounted read-only?)");
2206 }
2207 if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2208 run_program_and_log_output("mkdir -p " MNT_RESTORING
2209 "/mnt/.boot.d", 5);
2210 }
2211 for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2212 if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2213 continue;
2214 }
2215 sprintf(tmp, "Unmounting device %s ", mountlist->el[lino].device);
2216
2217 update_progress_form(tmp);
2218 if (is_this_device_mounted(mountlist->el[lino].device)) {
2219 if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
2220 sprintf(command, "swapoff %s", mountlist->el[lino].device);
2221 } else {
2222 if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
2223 sprintf(command, "umount %s/", MNT_RESTORING);
2224 log_msg(3,
2225 "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2226 } else {
2227 sprintf(command, "umount " MNT_RESTORING "%s",
2228 mountlist->el[lino].mountpoint);
2229 }
2230 }
2231 log_msg(10, "The 'umount' command is '%s'", command);
2232 res = run_program_and_log_output(command, 3);
2233 } else {
2234 strcat(tmp, "...not mounted anyway :-) OK");
2235 res = 0;
2236 }
2237 g_current_progress++;
2238 if (res) {
2239 strcat(tmp, "...Failed");
2240 retval++;
2241 log_to_screen(tmp);
2242 } else {
2243 log_msg(2, tmp);
2244 }
2245 }
2246 close_progress_form();
2247 if (retval) {
2248 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2249 } else {
2250 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2251 }
2252 if (retval) {
2253 log_to_screen("Unable to unmount some of your partitions.");
2254 } else {
2255 log_to_screen("All partitions were unmounted OK.");
2256 }
2257 free(mountlist);
2258 paranoid_free(command);
2259 paranoid_free(tmp);
2260 return (retval);
2261}
2262
2263/**************************************************************************
2264 *END_UNMOUNT_ALL_DEVICES *
2265 **************************************************************************/
2266
2267
2268
2269/**
2270 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2271 * to the ./tmp/ directory.
2272 * @param dev The tape device to read from.
2273 * @return 0 for success, nonzero for failure.
2274 */
2275int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2276{
2277 char *command;
2278 int res = 0;
2279 // BCO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
2280 long tape_block_size = 32768;
2281
2282 malloc_string(command);
2283
2284 // tar -zxvf-
2285 sprintf(command,
2286 "dd if=%s bs=%ld count=%ld 2> /dev/null | tar -zx %s %s %s %s %s",
2287 dev,
2288 tape_block_size,
2289 1024L * 1024 * 32 / tape_block_size,
2290 MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB,
2291 BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, "./tmp/i-want-my-lvm");
2292 log_msg(2, "command = '%s'", command);
2293 res = run_program_and_log_output(command, -1);
2294 if (res != 0 && does_file_exist(MONDO_CFG_FILE_STUB)) {
2295 res = 0;
2296 }
2297 paranoid_free(command);
2298 return (res);
2299}
2300
2301
2302
2303/**
2304 * Get the configuration file from the floppy, tape, or CD.
2305 * @param bkpinfo The backup information structure. Fields used:
2306 * - @c bkpinfo->backup_media_type
2307 * - @c bkpinfo->media_device
2308 * - @c bkpinfo->tmpdir
2309 * @return 0 for success, nonzero for failure.
2310 */
2311int get_cfg_file_from_archive()
2312{
2313 int retval = 0;
2314
2315 /** malloc *****/
2316 char *device;
2317 char *command;
2318 char *cfg_file;
2319 char *mounted_cfgf_path;
2320 char *tmp;
2321 char *mountpt;
2322 char *ramdisk_fname;
2323 char *mountlist_file;
2324
2325 bool try_plan_B;
2326
2327 assert(bkpinfo != NULL);
2328 malloc_string(cfg_file);
2329 malloc_string(mounted_cfgf_path);
2330 malloc_string(mountpt);
2331 malloc_string(ramdisk_fname);
2332 malloc_string(mountlist_file);
2333 malloc_string(device);
2334 malloc_string(command);
2335 malloc_string(tmp);
2336 log_msg(2, "gcffa --- starting");
2337 log_to_screen("I'm thinking...");
2338 sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
2339 device[0] = '\0';
2340 chdir(bkpinfo->tmpdir);
2341 strcpy(cfg_file, MONDO_CFG_FILE_STUB);
2342 unlink(cfg_file); // cfg_file[] is missing the '/' at the start, FYI, by intent
2343 unlink(FILELIST_FULL_STUB);
2344 unlink(BIGGIELIST_TXT_STUB);
2345 unlink("tmp/i-want-my-lvm");
2346 sprintf(command, "mkdir -p %s", mountpt);
2347 run_program_and_log_output(command, FALSE);
2348
2349// unlink( "tmp/mondo-restore.cfg" ); // superfluous, surely?
2350
2351 sprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2352 sprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir,
2353 MOUNTLIST_FNAME_STUB);
2354 // make_hole_for_file( cfg_file );
2355 // make_hole_for_file( mountlist_file);
2356 log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
2357
2358 if (!does_file_exist(cfg_file)) {
2359 log_msg(2, "gcffa --- we don't have cfg file yet.");
2360 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2361 try_plan_B = TRUE;
2362 } else {
2363 log_msg(2, "gcffa --- calling mount_media now :)");
2364 if (!mount_media()) {
2365 log_msg(2,
2366 "gcffa --- managed to mount CD; so, no need for Plan B");
2367 try_plan_B = FALSE;
2368 } else {
2369 try_plan_B = TRUE;
2370 }
2371 if (what_number_cd_is_this() > 1) {
2372 insist_on_this_cd_number((g_current_media_number = 1));
2373 }
2374 }
2375 if (try_plan_B) {
2376 log_msg(2, "gcffa --- OK, switching to Plan B");
2377 chdir(bkpinfo->tmpdir);
2378 run_program_and_log_output("mkdir -p tmp", FALSE);
2379
2380 if (strlen(bkpinfo->media_device) == 0) {
2381 strcpy(bkpinfo->media_device, "/dev/st0");
2382 log_msg(2, "media_device is blank; assuming %s");
2383 }
2384 strcpy(tmp, bkpinfo->media_device);
2385 if (extract_cfg_file_and_mountlist_from_tape_dev
2386 (bkpinfo->media_device)) {
2387 strcpy(bkpinfo->media_device, "/dev/st0");
2388 if (extract_cfg_file_and_mountlist_from_tape_dev
2389 (bkpinfo->media_device)) {
2390 strcpy(bkpinfo->media_device, "/dev/osst0");
2391 if (extract_cfg_file_and_mountlist_from_tape_dev
2392 (bkpinfo->media_device)) {
2393 strcpy(bkpinfo->media_device, "/dev/ht0");
2394 if (extract_cfg_file_and_mountlist_from_tape_dev
2395 (bkpinfo->media_device)) {
2396 log_msg(3,
2397 "I tried lots of devices but none worked.");
2398 strcpy(bkpinfo->media_device, tmp);
2399 }
2400 }
2401 }
2402 }
2403
2404 if (!does_file_exist("tmp/mondo-restore.cfg")) {
2405 log_to_screen("Cannot find config info on media");
2406 return (1);
2407 }
2408 } else {
2409 log_msg(2,
2410 "gcffa --- Plan B, a.k.a. untarring some file from all.tar.gz");
2411 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
2412 run_program_and_log_output(command, TRUE);
2413 if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2414 fatal_error
2415 ("Please reinsert the disk/CD and try again.");
2416 }
2417 }
2418 }
2419 if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2420 log_msg(1, "gcffa --- great! We've got the config file");
2421 sprintf(tmp, "%s/%s",
2422 call_program_and_get_last_line_of_output("pwd"),
2423 MONDO_CFG_FILE_STUB);
2424 sprintf(command, "cp -f %s %s", tmp, cfg_file);
2425 iamhere(command);
2426 if (strcmp(tmp, cfg_file)
2427 && run_program_and_log_output(command, 1)) {
2428 log_msg(1,
2429 "... but an error occurred when I tried to move it to %s",
2430 cfg_file);
2431 } else {
2432 log_msg(1, "... and I moved it successfully to %s", cfg_file);
2433 }
2434 sprintf(command, "cp -f %s/%s %s",
2435 call_program_and_get_last_line_of_output("pwd"),
2436 MOUNTLIST_FNAME_STUB, mountlist_file);
2437 iamhere(command);
2438 if (strcmp(tmp, cfg_file)
2439 && run_program_and_log_output(command, 1)) {
2440 log_msg(1, "Failed to get mountlist");
2441 } else {
2442 log_msg(1, "Got mountlist too");
2443 sprintf(command, "cp -f %s %s", mountlist_file,
2444 g_mountlist_fname);
2445 if (run_program_and_log_output(command, 1)) {
2446 log_msg(1, "Failed to copy mountlist to /tmp");
2447 } else {
2448 log_msg(1, "Copied mountlist to /tmp as well OK");
2449 sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2450 run_program_and_log_output(command, 1);
2451/* sprintf(command, "grep \" lvm \" %s", g_mountlist_fname);
2452 if (!run_program_and_log_output(command, 5) && !does_file_exist("/tmp/i-want-my-lvm"))
2453 {
2454 log_msg(1, "Warning. You want LVM but I don't have i-want-my-lvm. FIXME.");
2455 }
2456 else if (run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2457 {
2458 log_msg(1, "Warning. You don't want LVM but i-want-my-lvm exists. I'll delete it. Cool.");
2459 do_my_funky_lvm_stuff(TRUE, FALSE); // ...after I stop any LVMs :)
2460 stop_raid_device("/dev/md0");
2461 stop_raid_device("/dev/md1");
2462 stop_raid_device("/dev/md2");
2463 unlink("/tmp/i-want-my-lvm");
2464 }
2465 else if (!run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2466 {
2467 log_msg(1, "You had better pray that i-want-my-lvm patches your mountlist. FIXME.");
2468 }
2469*/
2470 }
2471 }
2472 }
2473 run_program_and_log_output("umount " MNT_CDROM, FALSE);
2474 if (!does_file_exist(cfg_file)) {
2475 iamhere(cfg_file);
2476 log_msg(1, "%s not found", cfg_file);
2477 log_to_screen
2478 ("Oh dear. Unable to recover configuration file from boot disk");
2479 return (1);
2480 }
2481
2482 log_to_screen("Recovered mondo-restore.cfg");
2483 if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2484 log_to_screen("...but not mountlist.txt - a pity, really...");
2485 }
2486/* start SAH */
2487 else {
2488 sprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB,
2489 bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2490 run_program_and_log_output(command, FALSE);
2491 }
2492/*--commented out by SAH
2493 sprintf( command, "cp -f %s %s/%s", cfg_file, bkpinfo->tmpdir, MONDO_CFG_FILE_STUB );
2494 run_program_and_log_output( command, FALSE );
2495 sprintf( command, "cp -f %s %s/%s", mountlist_file, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB );
2496 run_program_and_log_output( command, FALSE );
2497*/
2498/* end SAH */
2499
2500 sprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2501 run_program_and_log_output(command, FALSE);
2502 sprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2503 run_program_and_log_output(command, FALSE);
2504 sprintf(command, "cp -f etc/raidtab /etc/");
2505 run_program_and_log_output(command, FALSE);
2506 sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2507 run_program_and_log_output(command, FALSE);
2508 g_backup_media_type = bkpinfo->backup_media_type;
2509 paranoid_free(device);
2510 paranoid_free(command);
2511 paranoid_free(tmp);
2512 paranoid_free(cfg_file);
2513 paranoid_free(mounted_cfgf_path);
2514 paranoid_free(mountpt);
2515 paranoid_free(ramdisk_fname);
2516 paranoid_free(mountlist_file);
2517 return (retval);
2518}
2519
2520/**************************************************************************
2521 *END_GET_CFG_FILE_FROM_ARCHIVE *
2522 **************************************************************************/
2523
2524/* @} - end restoreUtilityGroup */
2525
2526
2527/***************************************************************************
2528 * F@ *
2529 * () -- Hugo Rabson *
2530 * *
2531 * Purpose: *
2532 * *
2533 * Called by: *
2534 * Params: - - *
2535 * Returns: 0=success; nonzero=failure *
2536 ***************************************************************************/
2537
2538
2539
2540void wait_until_software_raids_are_prepped(char *mdstat_file,
2541 int wait_for_percentage)
2542{
2543 struct raidlist_itself *raidlist;
2544 int unfinished_mdstat_devices = 9999, i;
2545 char *screen_message;
2546
2547 malloc_string(screen_message);
2548 raidlist = malloc(sizeof(struct raidlist_itself));
2549
2550 assert(wait_for_percentage <= 100);
2551 iamhere("wait_until_software_raids_are_prepped");
2552 while (unfinished_mdstat_devices > 0) {
2553 // FIXME: Prefix '/dev/' should really be dynamic!
2554 if (parse_mdstat(raidlist, "/dev/")) {
2555 log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2556 log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2557 return;
2558 }
2559 for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2560 if (raidlist->el[i].progress < wait_for_percentage) {
2561 unfinished_mdstat_devices++;
2562 if (raidlist->el[i].progress == -1) // delayed while another partition inits
2563 {
2564 continue;
2565 }
2566 log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2567 sprintf(screen_message, "Sync'ing %s",
2568 raidlist->el[i].raid_device);
2569 open_evalcall_form(screen_message);
2570 while (raidlist->el[i].progress < wait_for_percentage) {
2571 log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2572 update_evalcall_form(raidlist->el[i].progress);
2573 sleep(2);
2574 // FIXME: Prefix '/dev/' should really be dynamic!
2575 if (parse_mdstat(raidlist, "/dev/")) {
2576 break;
2577 }
2578 }
2579 close_evalcall_form();
2580 }
2581 }
2582 }
2583 paranoid_free(screen_message);
2584 paranoid_free(raidlist);
2585}
Note: See TracBrowser for help on using the repository browser.