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

Last change on this file since 1216 was 1216, checked in by Bruno Cornec, 17 years ago

First merge for mondo-rstr-tools.c

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