source: MondoRescue/branches/2.2.10/mondo/src/mondorestore/mondo-rstr-tools.c@ 2850

Last change on this file since 2850 was 2850, checked in by Bruno Cornec, 13 years ago

svn merge -r 2773:2849 2.2.9 in 2.2.10

  • Adds 3 binaries called potentially by udev o support USB key mount at restore time (Victor Gattegno)
  • Really support both mkisofs and genisoimage everywhere
  • Try to handle netfs_user better in all cases (NFS and SSHFS)
    • Improve logging in init script
    • Format improvement
    • Removes a warning when trying to launch udevadm and it doesn't exist (RHEL 5 e.g.)
    • Fix syntax description in mondoarchive man page for -E & -I with |
  • Adds download entries for new distro supported (Mageia, Fedora 15, Ubuntu 11.04)

-Fix mindi-get-perl-modules when perl dirs in @INC are symlinks (case on Ubuntu 11.04)

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