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

Last change on this file since 2287 was 2287, checked in by Bruno Cornec, 15 years ago

r3289@localhost: bruno | 2009-07-21 15:12:29 +0200

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