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

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

call_program_and_get_last_line_of_output is now allocating memory and returning that string

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