source: MondoRescue/branches/stable/mondo/src/mondorestore/mondo-rstr-tools.c@ 1770

Last change on this file since 1770 was 1770, checked in by Bruno Cornec, 16 years ago
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

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