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

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