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

Last change on this file since 1541 was 1541, checked in by Bruno Cornec, 17 years ago

Fix small typos

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