source: MondoRescue/branches/2.2.9/mondo/src/mondorestore/mondo-rstr-tools.c@ 2230

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