source: MondoRescue/branches/2.2.5/mondo/src/mondorestore/mondo-rstr-tools.c@ 1740

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

typo again

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