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

Last change on this file since 2404 was 2404, checked in by Bruno Cornec, 15 years ago
  • At restore time read the netfs protocol in the conf file
  • Use dir for shell related commands and dir1 for C related actions in open_and_list_dir to avoid missing some files with { in names e.g.

(Backports from 2.2.9)

  • Property svn:keywords set to Id
File size: 75.3 KB
Line 
1/***************************************************************************
2$Id: mondo-rstr-tools.c 2404 2009-09-17 00:23:18Z bruno $
3***************************************************************************/
4
5#include <pthread.h>
6#include <linux/fd.h>
7#include "my-stuff.h"
8#include "mr_mem.h"
9#include "mr_str.h"
10#include "../common/mondostructures.h"
11#include "../common/libmondo.h"
12#include "mr-externs.h"
13#include "mondo-rstr-tools.h"
14
15/**
16 * The biggielist stub (appended to the directory where all.tar.gz was unpacked).
17 */
18#define BIGGIELIST_TXT_STUB "tmp/biggielist.txt"
19
20/**
21 * The filelist stub (appended to the directory where all.tar.gz was unpacked).
22 */
23#define FILELIST_FULL_STUB "tmp/filelist.full.gz"
24
25/**
26 * The mountlist stub (appended to the directory where all.tar.gz was unpacked).
27 */
28#define MOUNTLIST_FNAME_STUB "tmp/mountlist.txt"
29
30/**
31 * The mondo-restore.cfg stub (appended to the directory where all.tar.gz was unpacked).
32 */
33#define MONDO_CFG_FILE_STUB "tmp/mondo-restore.cfg"
34/**
35 * The i-want-my-lvm stub
36 */
37#define IWANTMYLVM_STUB "tmp/i-want-my-lvm"
38
39extern bool g_ISO_restore_mode; /* are we in Iso Mode? */
40extern bool g_I_have_just_nuked;
41/*
42extern char *g_tmpfs_mountpt;
43*/
44extern char *g_isodir_device;
45extern long g_current_progress, g_maximum_progress;
46extern char *g_biggielist_txt; // where 'biggielist.txt' is stored, on ramdisk / tempdir;
47 // biggielist.txt is the list of big files stored on the
48 // backup media set in question
49extern char *g_filelist_full; // filelist.full.gz is the list of all regular files
50 // (excluding big files) stored on the backup media set
51extern char *g_biggielist_pot; // list of big files which _could_ be restored, if the
52 // user chooses them
53extern char *g_filelist_imagedevs; // list of devices (e.g. /dev/hda1, /dev/sda5) which
54 // were archived as images, not just /dev entries
55 // ... e.g. NTFS, BeOS partitions
56extern char *g_imagedevs_restthese; // of the imagedevs listed in FILELIST_IMAGEDEVS,
57 // restore only these
58extern char *g_mondo_cfg_file; // where m*ndo-restore.cfg (the config file) is stored
59extern char *g_mountlist_fname; // where mountlist.txt (the mountlist file) is stored
60extern char *g_mondo_home; // homedir of Mondo; usually /usr/local/share/mondo
61
62extern t_bkptype g_backup_media_type;
63
64extern int g_partition_table_locked_up;
65extern char *MONDO_LOGFILE;
66
67/* Reference to global bkpinfo */
68extern struct s_bkpinfo *bkpinfo;
69
70/* Should we use or not extended attributes and acl when restoring */
71char *g_getfattr = NULL;
72char *g_getfacl = NULL;
73
74extern void kill_anything_like_this(char *str);
75extern int skip_obdr(void);
76extern int set_tape_block_size_with_mt(long internal_tape_block_size);
77
78/**
79* @addtogroup restoreUtilityGroup
80* @{
81*/
82/**
83* Free the malloc()s for the filename variables.
84*/
85void free_MR_global_filenames(void)
86{
87paranoid_free(g_biggielist_txt);
88paranoid_free(g_filelist_full);
89paranoid_free(g_filelist_imagedevs);
90paranoid_free(g_imagedevs_restthese);
91paranoid_free(g_mondo_cfg_file);
92paranoid_free(g_mountlist_fname);
93paranoid_free(g_mondo_home);
94/*
95paranoid_free(g_tmpfs_mountpt);
96*/
97mr_free(g_isodir_device);
98
99}
100
101
102
103/**
104* Ask the user which imagedevs from the list contained in @p infname should
105* actually be restored.
106* @param infname The file containing a list of all imagedevs.
107* @param outfname The location of the output file containing the imagedevs the user wanted to restore.
108* @ingroup restoreUtilityGroup
109*/
110void ask_about_these_imagedevs(char *infname, char *outfname) {
111
112FILE *fin;
113FILE *fout;
114char *incoming = NULL;
115char *question = NULL;
116
117assert_string_is_neither_NULL_nor_zerolength(infname);
118assert_string_is_neither_NULL_nor_zerolength(outfname);
119
120if (!(fin = fopen(infname, "r"))) {
121 fatal_error("Cannot openin infname");
122}
123if (!(fout = fopen(outfname, "w"))) {
124 fatal_error("Cannot openin outfname");
125}
126for (mr_getline(incoming, fin); !feof(fin); mr_getline(incoming, fin)) {
127 mr_strip_spaces(incoming);
128
129 if (incoming[0] == '\0') {
130 mr_free(incoming);
131 continue;
132 }
133
134 mr_asprintf(question, "Should I restore the image of %s ?", incoming);
135
136 if (ask_me_yes_or_no(question)) {
137 fprintf(fout, "%s\n", incoming);
138 }
139 mr_free(incoming);
140}
141mr_free(incoming);
142mr_free(question);
143paranoid_fclose(fout);
144paranoid_fclose(fin);
145}
146
147/**************************************************************************
148*ASK_ABOUT_THESE_IMAGEDEVS *
149**************************************************************************/
150
151
152
153
154
155
156
157
158/**
159* Extract @c mondo-restore.cfg and @c mountlist.txt from @p ramdisk_fname.
160* @param bkpinfo The backup information structure. @c tmpdir is the only field used.
161* @param ramdisk_fname The filename of the @b compressed ramdisk to look in.
162* @param output_cfg_file Where to put the configuration file extracted.
163* @param output_mountlist_file Where to put the mountlist file extracted.
164* @return 0 for success, nonzero for failure.
165* @ingroup restoreUtilityGroup
166*/
167
168/**
169* Keep trying to get mondo-restore.cfg from the archive, until the user gives up.
170*/
171void get_cfg_file_from_archive_or_bust()
172{
173while (get_cfg_file_from_archive()) {
174if (!ask_me_yes_or_no
175 ("Failed to find config file/archives. Choose another source?"))
176{
177 fatal_error("Could not find config file/archives. Aborting.");
178}
179interactively_obtain_media_parameters_from_user(FALSE);
180}
181}
182
183
184/**
185* Determine whether @p list_fname contains a line containing @p f.
186* @param f The line to search for.
187* @param list_fname The file to search in.
188* @param preamble Ignore this beginning part of @p f ("" to disable).
189* @return TRUE if it's in the list, FALSE if it's not.
190*/
191bool is_file_in_list(char *f, char *list_fname, char *preamble)
192{
193
194char *command = NULL;
195char *file = NULL;
196char *tmp = NULL;
197int res;
198
199assert_string_is_neither_NULL_nor_zerolength(f);
200assert_string_is_neither_NULL_nor_zerolength(list_fname);
201assert(preamble != NULL);
202
203if (strncmp(preamble, f, strlen(preamble)) == 0) {
204 mr_asprintf(file, "%s", f + strlen(preamble));
205} else {
206 mr_asprintf(file, "%s", f);
207}
208if (file[0] == '/' && file[1] == '/') {
209 mr_asprintf(tmp, "%s", file);
210 mr_free(file);
211
212 mr_asprintf(file, "%s", tmp + 1);
213 mr_free(tmp);
214}
215log_msg(2, "Checking to see if f=%s, file=%s, is in the list of biggiefiles", f, file);
216mr_asprintf(command, "grep -E '^%s$' %s", file, list_fname);
217mr_free(file);
218
219res = run_program_and_log_output(command, FALSE);
220mr_free(command);
221if (res) {
222 return (FALSE);
223} else {
224 return (TRUE);
225}
226}
227
228/**************************************************************************
229*END_IS_FILE_IN_LIST *
230**************************************************************************/
231
232
233
234/**
235* Set up an ISO backup.
236* @param bkpinfo The backup information structure. Fields used:
237* - @c bkpinfo->backup_media_type
238* - @c bkpinfo->disaster_recovery
239* - @c bkpinfo->isodir
240* @param nuke_me_please If TRUE, we're in nuke mode; if FALSE we're in interactive mode.
241* @return 0 for success, nonzero for failure.
242*/
243int iso_fiddly_bits(bool nuke_me_please)
244{
245 char *mount_isodir_command = NULL;
246 char *command = NULL;
247 char *mds = NULL;
248 int retval = 0, i;
249 bool already_mounted = FALSE;
250 char *isodir_format = NULL;
251
252g_ISO_restore_mode = TRUE;
253mr_free(g_isodir_device);
254g_isodir_device = read_cfg_var(g_mondo_cfg_file, "iso-dev");
255if (bkpinfo->disaster_recovery) {
256 /* Patch Conor Daly 26-june-2004
257 * Don't let this clobber an existing bkpinfo->isodir */
258 if (!bkpinfo->isodir[0]) {
259 mr_free(bkpinfo->isodir);
260 mr_asprintf(bkpinfo->isodir, "/tmp/isodir");
261 }
262 /* End patch */
263 mr_asprintf(command, "mkdir -p %s", bkpinfo->isodir);
264 run_program_and_log_output(command, 5);
265 mr_free(command);
266 log_msg(2, "Setting isodir to %s", bkpinfo->isodir);
267}
268
269/* g_isodir_device is passed and modified in this function - memory is managed correctly in it */
270if (!get_isodir_info(g_isodir_device, isodir_format, bkpinfo->isodir, nuke_me_please)) {
271 mr_free(isodir_format);
272 return (1);
273}
274paranoid_system("umount " MNT_CDROM " 2> /dev/null"); /* just in case */
275
276if (is_this_device_mounted(g_isodir_device)) {
277 log_to_screen("WARNING - isodir is already mounted");
278 already_mounted = TRUE;
279} else {
280 mr_asprintf(mount_isodir_command, "mount %s", g_isodir_device);
281 if (isodir_format) {
282 mr_strcat(mount_isodir_command, " -t %s", isodir_format);
283 }
284
285 mr_strcat(mount_isodir_command, " -o ro %s", bkpinfo->isodir);
286 run_program_and_log_output("df -m -P", FALSE);
287 log_msg(1, "The 'mount' command is '%s'. PLEASE report this command to be if you have problems, ok?", mount_isodir_command);
288 if (run_program_and_log_output(mount_isodir_command, FALSE)) {
289 popup_and_OK
290 ("Cannot mount the device where the ISO files are stored.");
291 return (1);
292 }
293 paranoid_free(mount_isodir_command);
294 log_to_screen
295 ("I have mounted the device where the ISO files are stored.");
296}
297mr_free(isodir_format);
298
299if (!IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
300 mount_media();
301}
302i = what_number_cd_is_this(); /* has the side-effect of calling mount_media() */
303mds = media_descriptor_string(bkpinfo->backup_media_type);
304mr_free(mds);
305
306log_msg(1, "%s #%d has been mounted via loopback mount", mds, i);
307if (i < 0) {
308 popup_and_OK("Cannot find ISO images in the directory you specified.");
309 retval = 1;
310}
311log_msg(2, "bkpinfo->isodir is now %s", bkpinfo->isodir);
312return (retval);
313}
314
315
316
317
318/**
319* Kill all Petris processes.
320*/
321void kill_petris(void) {
322 kill_anything_like_this("petris");
323}
324
325/**************************************************************************
326*END_KILL_PETRIS *
327**************************************************************************/
328
329
330/**
331 * Mount @p device at @p mpt as @p format.
332 * @param device The device (/dev entry) to mount.
333 * @param mpt The directory to mount it on.
334 * @param format The filesystem type of @p device.
335 * @param writeable If TRUE, mount read-write; if FALSE, mount read-only.
336 * @return 0 for success, nonzero for failure.
337 */
338int mount_device(char *device, char *mpt, char *format, bool writeable)
339{
340int res = 0;
341
342/** malloc **/
343char *tmp = NULL;
344char *command = NULL;
345char *mountdir = NULL;
346char *mountpoint = NULL;
347char *additional_parameters = NULL;
348
349assert_string_is_neither_NULL_nor_zerolength(device);
350assert_string_is_neither_NULL_nor_zerolength(mpt);
351assert(format != NULL);
352
353 if (!strcmp(mpt, "/1")) {
354 mr_asprintf(mountpoint, "/");
355 log_msg(3, "Mommm! SME is being a dildo!");
356 } else {
357 mr_asprintf(mountpoint, "%s", mpt);
358 }
359
360 if (!strcmp(mountpoint, "lvm")) {
361 return (0);
362 }
363 if (!strcmp(mountpoint, "image")) {
364 return (0);
365 }
366 mr_asprintf(tmp, "Mounting device %s ", device);
367 log_msg(1, tmp);
368 /* Deal with additional params only if not /proc or /sys */
369 mr_asprintf(additional_parameters, "");
370 if (strcmp(format, "proc") && strcmp(format, "sys")) {
371 if (writeable) {
372 mr_strcat(additional_parameters, "-o rw");
373 } else {
374 mr_strcat(additional_parameters, "-o ro");
375 }
376 tmp = find_home_of_exe("setfattr");
377 if (tmp) {
378 mr_strcat(additional_parameters, ",user_xattr");
379 }
380 mr_free(tmp);
381
382 tmp = find_home_of_exe("setfacl");
383 if (tmp) {
384 mr_strcat(additional_parameters, ",acl");
385 }
386 mr_free(tmp);
387 }
388
389 if (!strcmp(mountpoint, "swap")) {
390 mr_asprintf(command, "swapon %s", device);
391 mr_asprintf(mountdir, "swap");
392 } else {
393 if (!strcmp(mountpoint, "/")) {
394 mr_asprintf(mountdir, "%s", MNT_RESTORING);
395 } else {
396 mr_asprintf(mountdir, "%s%s", MNT_RESTORING, mountpoint);
397 }
398 mr_asprintf(command, "mkdir -p %s", mountdir);
399 run_program_and_log_output(command, FALSE);
400 mr_free(command);
401
402 mr_asprintf(command, "mount -t %s %s %s %s 2>> %s", format, device, additional_parameters, mountdir, MONDO_LOGFILE);
403 log_msg(2, "command='%s'", command);
404 }
405 mr_free(additional_parameters);
406
407 res = run_program_and_log_output(command, TRUE);
408 if (res && (strstr(command, "xattr") || strstr(command, "acl"))) {
409 log_msg(1, "Re-trying without the fancy extra parameters");
410 mr_free(command);
411 mr_asprintf(command, "mount -t %s %s %s 2>> %s", format, device, mountdir, MONDO_LOGFILE);
412 res = run_program_and_log_output(command, TRUE);
413 }
414 if (res) {
415 log_msg(1, "Unable to mount device %s (type %s) at %s", device, format, mountdir);
416 log_msg(1, "command was '%s'", command);
417 if (!strcmp(mountpoint, "swap")) {
418 log_to_screen(tmp);
419 } else {
420 log_msg(2, "Retrying w/o the '-t' switch");
421 mr_free(command);
422 mr_asprintf(command, "mount %s %s 2>> %s", device, mountdir, MONDO_LOGFILE);
423 log_msg(2, "2nd command = '%s'", command);
424 res = run_program_and_log_output(command, TRUE);
425 if (res == 0) {
426 log_msg(1,
427 "That's OK. I called mount w/o a filesystem type and it worked fine in the end.");
428 } else {
429 log_to_screen(tmp);
430 }
431 }
432 }
433
434 if (res && !strcmp(mountpoint, "swap")) {
435 log_msg(2, "That's ok. It's just a swap partition.");
436 log_msg(2, "Non-fatal error. Returning 0.");
437 res = 0;
438 }
439
440mr_free(tmp);
441mr_free(command);
442mr_free(mountdir);
443mr_free(mountpoint);
444
445 return (res);
446}
447/**************************************************************************
448 *END_MOUNT_DEVICE *
449**************************************************************************/
450
451
452/**
453 * Mount all devices in @p p_external_copy_of_mountlist on @p MNT_RESTORING.
454 * @param p_external_copy_of_mountlist The mountlist containing devices to be mounted.
455 * @param writeable If TRUE, then mount read-write; if FALSE mount read-only.
456 * @return The number of errors encountered (0 for success).
457 */
458int mount_all_devices(struct mountlist_itself *p_external_copy_of_mountlist, bool writeable)
459{
460int retval = 0, lino, res;
461char *tmp = NULL;
462char *these_failed = NULL;
463struct mountlist_itself *mountlist = NULL;
464
465assert(p_external_copy_of_mountlist != NULL);
466mountlist = malloc(sizeof(struct mountlist_itself));
467memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
468 sizeof(struct mountlist_itself));
469 sort_mountlist_by_mountpoint(mountlist, 0);
470
471
472 mvaddstr_and_log_it(g_currentY, 0, "Mounting devices ");
473 open_progress_form("Mounting devices", "I am now mounting all the drives.", "This should not take long.", "", mountlist->entries);
474
475 mr_asprintf(these_failed, "");
476 for (lino = 0; lino < mountlist->entries; lino++) {
477 if (!strcmp(mountlist->el[lino].device, "/proc")) {
478 log_msg(1, "Again with the /proc - why is this in your mountlist?");
479 } else if (is_this_device_mounted(mountlist->el[lino].device)) {
480 log_to_screen("%s is already mounted", mountlist->el[lino].device);
481 } else if (strcmp(mountlist->el[lino].mountpoint, "none")
482 && strcmp(mountlist->el[lino].mountpoint, "lvm")
483 && strcmp(mountlist->el[lino].mountpoint, "raid")
484 && strcmp(mountlist->el[lino].mountpoint, "image")) {
485 mr_asprintf(tmp, "Mounting %s", mountlist->el[lino].device);
486 update_progress_form(tmp);
487 mr_free(tmp);
488 res = mount_device(mountlist->el[lino].device, mountlist->el[lino].mountpoint, mountlist->el[lino].format, writeable);
489
490 retval += res;
491 if (res) {
492 mr_strcat(these_failed, "%s ",mountlist->el[lino].device);
493 }
494 }
495 g_current_progress++;
496 }
497 close_progress_form();
498 if (retval) {
499 if (g_partition_table_locked_up > 0) {
500 log_to_screen("fdisk's ictol() call to refresh its copy of the partition table causes the kernel to");
501 log_to_screen("lock up the partition table. You might have to reboot and use Interactive Mode to");
502 log_to_screen("format and restore *without* partitioning first. Sorry for the inconvenience.");
503 }
504 mr_asprintf(tmp, "Could not mount device(s) %s- shall I abort?", these_failed);
505
506 if (!ask_me_yes_or_no(tmp)) {
507 retval = 0;
508 log_to_screen("Continuing, although some device(s) failed to be mounted");
509 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
510 } else {
511 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
512 log_to_screen("Unable to mount some or all of your partitions.");
513 }
514 mr_free(tmp);
515 } else {
516 log_to_screen("All partitions were mounted OK.");
517 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
518 }
519 paranoid_free(these_failed);
520
521 /* Also mounting under MNT_RESTORING special FS */
522 (void)mount_device("/proc","/proc","proc",TRUE);
523 (void)mount_device("/sys","/sys","sysfs",TRUE);
524 run_program_and_log_output("df -m -P", 3);
525 paranoid_free(mountlist);
526 return (retval);
527}
528/**************************************************************************
529*END_MOUNT_ALL_DEVICES *
530**************************************************************************/
531
532
533/**
534* Mount the CD-ROM or USB device at /mnt/cdrom.
535* @param bkpinfo The backup information structure. Fields used:
536* - @c bkpinfo->backup_media_type
537* - @c bkpinfo->disaster_recovery
538* - @c bkpinfo->isodir
539* - @c bkpinfo->media_device
540* @return 0 for success, nonzero for failure.
541*/
542int mount_media() {
543
544 char *mount_cmd = NULL;
545 int i, res;
546#ifdef __FreeBSD__
547 char mdd[32];
548 char *mddev = mdd;
549#endif
550
551 if (bkpinfo->backup_media_type == tape || bkpinfo->backup_media_type == udev) {
552 log_msg(8, "Tape/udev. Therefore, no need to mount a media.");
553 return 0;
554 }
555
556 if (!run_program_and_log_output("mount | grep -F " MNT_CDROM, FALSE)) {
557 log_msg(2, "mount_media() - media already mounted. Fair enough.");
558 return (0);
559 }
560
561 if (bkpinfo->media_device == NULL) {
562 fatal_error("No media device at that point");
563 }
564
565 if (bkpinfo->backup_media_type == netfs) {
566 log_msg(2, "Mounting for Network thingy");
567 log_msg(2, "isodir = %s", bkpinfo->isodir);
568 if (!strcmp(bkpinfo->isodir, "/") && am_I_in_disaster_recovery_mode()) {
569 mr_free(bkpinfo->isodir);
570 mr_asprintf(bkpinfo->isodir, "/tmp/isodir");
571 log_msg(1, "isodir is being set to %s", bkpinfo->isodir);
572 }
573 if ((bkpinfo->isodir == NULL) || (bkpinfo->netfs_remote_dir == NULL) || (bkpinfo->prefix == NULL)) {
574 fatal_error("Unable to prepare the iso filename");
575 }
576#ifdef __FreeBSD__
577 mr_asprintf(mount_cmd, "/mnt/isodir/%s/%s/%s-%d.iso", bkpinfo->isodir, bkpinfo->netfs_remote_dir, bkpinfo->prefix, g_current_media_number);
578 mddev = make_vn(mount_cmd);
579 mr_free(mount_cmd);
580
581 mr_asprintf(mount_cmd, "mount_cd9660 -r %s " MNT_CDROM, mddev);
582#else
583 mr_asprintf(mount_cmd, "mount %s/%s/%s-%d.iso -t iso9660 -o loop,ro %s", bkpinfo->isodir, bkpinfo->netfs_remote_dir, bkpinfo->prefix, g_current_media_number, MNT_CDROM);
584#endif
585
586 } else if (bkpinfo->backup_media_type == iso) {
587#ifdef __FreeBSD__
588 mr_asprintf(mount_cmd, "%s/%s-%d.iso", bkpinfo->isodir, bkpinfo->prefix, g_current_media_number);
589 mddev = make_vn(mount_cmd);
590 mr_free(mount_cmd);
591
592 mr_asprintf(mount_cmd, "mount_cd9660 -r %s %s", mddev, MNT_CDROM);
593#else
594 mr_asprintf(mount_cmd, "mount %s/%s-%d.iso -t iso9660 -o loop,ro %s", bkpinfo->isodir, bkpinfo->prefix, g_current_media_number, MNT_CDROM);
595#endif
596 } else if (bkpinfo->backup_media_type == usb) {
597 mr_asprintf(mount_cmd, "mount -t vfat %s %s", bkpinfo->media_device, MNT_CDROM);
598 } else if (strstr(bkpinfo->media_device, "/dev/")) {
599#ifdef __FreeBSD__
600 mr_asprintf(mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device, MNT_CDROM);
601#else
602 mr_asprintf(mount_cmd, "mount %s -t iso9660 -o ro %s", bkpinfo->media_device, MNT_CDROM);
603#endif
604 } else {
605 mr_free(bkpinfo->media_device);
606 if (bkpinfo->disaster_recovery && does_file_exist("/tmp/CDROM-LIVES-HERE")) {
607 bkpinfo->media_device = last_line_of_file("/tmp/CDROM-LIVES-HERE");
608 } else {
609 bkpinfo->media_device = find_cdrom_device(TRUE);
610 }
611
612#ifdef __FreeBSD__
613 mr_asprintf(mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device, MNT_CDROM);
614#else
615 mr_asprintf(mount_cmd, "mount %s -t iso9660 -o ro %s", bkpinfo->media_device, MNT_CDROM);
616#endif
617 }
618
619 log_msg(2, "(mount_media) --- command = %s", mount_cmd);
620 for (i = 0; i < 2; i++) {
621 res = run_program_and_log_output(mount_cmd, FALSE);
622 if (!res) {
623 break;
624 } else {
625 log_msg(2, "Failed to mount device.");
626 sleep(5);
627 sync();
628 }
629 }
630 mr_free(mount_cmd);
631
632 if (res) {
633 log_msg(2, "Failed, despite %d attempts", i);
634 } else {
635 log_msg(2, "Mounted media drive OK");
636 }
637 return (res);
638}
639/**************************************************************************
640*END_MOUNT_CDROM *
641**************************************************************************/
642
643
644/**
645* Fix some miscellaneous things in the filesystem so the system will come
646* up correctly on the first boot.
647*/
648void protect_against_braindead_sysadmins()
649{
650run_program_and_log_output("touch " MNT_RESTORING "/var/log/pacct",
651 FALSE);
652run_program_and_log_output("touch " MNT_RESTORING "/var/account/pacct",
653 FALSE);
654if (run_program_and_log_output("ls " MNT_RESTORING " /tmp", FALSE)) {
655run_program_and_log_output("chmod 1777 " MNT_RESTORING "/tmp",
656 FALSE);
657}
658run_program_and_log_output("mkdir -p " MNT_RESTORING
659 "/var/run/console", FALSE);
660run_program_and_log_output("chmod 777 " MNT_RESTORING "/dev/null",
661 FALSE);
662run_program_and_log_output("cd " MNT_RESTORING
663 "; for i in `ls home/`; do echo \"Moving $i's spurious files to $i/.disabled\"; mkdir \"$i\"/.disabled ; mv -f \"$i\"/.DCOP* \"$i\"/.MCOP* \"$i\"/.*authority \"$i\"/.kde/tmp* \"$i\"/.kde/socket* \"$i\"/.disabled/ ; done",
664 TRUE);
665run_program_and_log_output("rm -f " MNT_RESTORING "/var/run/*.pid",
666 TRUE);
667run_program_and_log_output("rm -f " MNT_RESTORING "/var/lock/subsys/*",
668 TRUE);
669}
670
671/**************************************************************************
672*END_PROTECT_AGAINST_BRAINDEAD_SYSADMINS *
673**************************************************************************/
674
675
676
677
678/**
679* Fill out @p bkpinfo based on @p cfg_file.
680* @param cfg_file The mondo-restore.cfg file to read into @p bkpinfo.
681* @param bkpinfo The backup information structure to fill out with information
682* from @p cfg_file.
683* @return 0 for success, nonzero for failure.
684*/
685int read_cfg_file_into_bkpinfo(char *cfgf)
686{
687/** add mallocs **/
688char *value = NULL;
689char *tmp = NULL;
690char *tmp1 = NULL;
691char *envtmp1 = NULL;
692char *envtmp2 = NULL;
693char *command = NULL;
694char *iso_mnt = NULL;
695char *iso_path = NULL;
696char *old_isodir = NULL;
697char *cfg_file = NULL;
698t_bkptype media_specified_by_user;
699
700malloc_string(tmp);
701// assert_string_is_neither_NULL_nor_zerolength(cfg_file);
702assert(bkpinfo != NULL);
703
704if (!cfgf) {
705 cfg_file = g_mondo_cfg_file;
706} else {
707 cfg_file = cfgf;
708}
709
710media_specified_by_user = bkpinfo->backup_media_type; // or 'none', if not specified
711
712if ((value = read_cfg_var(cfg_file, "backup-media-type")) == 0) {
713 if (!strcmp(value, "cdstream")) {
714 bkpinfo->backup_media_type = cdstream;
715 } else if (!strcmp(value, "cdr")) {
716 bkpinfo->backup_media_type = cdr;
717 } else if (!strcmp(value, "cdrw")) {
718 bkpinfo->backup_media_type = cdrw;
719 } else if (!strcmp(value, "dvd")) {
720 bkpinfo->backup_media_type = dvd;
721 } else if (!strcmp(value, "usb")) {
722 bkpinfo->backup_media_type = usb;
723 bkpinfo->please_dont_eject = TRUE;
724 } else if (!strcmp(value, "iso")) {
725 // Patch by Conor Daly - 2004/07/12
726 bkpinfo->backup_media_type = iso;
727 if (am_I_in_disaster_recovery_mode()) {
728 /* Check to see if CD is already mounted before mounting it... */
729 if (!is_this_device_mounted("/dev/cdrom")) {
730 log_msg(2, "NB: CDROM device not mounted, mounting...");
731 run_program_and_log_output("mount /dev/cdrom " MNT_CDROM, 1);
732 }
733 if (does_file_exist(MNT_CDROM "/archives/filelist.0")) {
734 bkpinfo->backup_media_type = cdr;
735 run_program_and_log_output("umount " MNT_CDROM, 1);
736 log_it
737 ("Re-jigging configuration AGAIN. CD-R, not ISO.");
738 }
739 }
740 mr_free(bkpinfo->prefix);
741 mr_free(value);
742 if ((value = read_cfg_var(cfg_file, "iso-prefix")) == 0) {
743 mr_asprintf(bkpinfo->prefix, "%s", value);
744 } else {
745 mr_asprintf(bkpinfo->prefix, "%s", STD_PREFIX);
746 }
747 } else if ((!strcmp(value, "netfs")) || (!strcmp(value, "nfs"))) {
748 /* Stay compatible with previous versions by allowing nfs as an entry here */
749 bkpinfo->backup_media_type = netfs;
750 bkpinfo->please_dont_eject = TRUE;
751 mr_free(value);
752
753 mr_free(bkpinfo->netfs_proto);
754 if ((value = read_cfg_var(cfg_file, "netfs-proto")) == 0) {
755 mr_asprintf(bkpinfo->netfs_proto, "%s", value);
756 } else {
757 /* For compatibility, force protocol in old nfs case to be transparent */
758 mr_asprintf(bkpinfo->netfs_proto, "nfs");
759 }
760 mr_free(value);
761
762 mr_free(bkpinfo->prefix);
763 if ((value = read_cfg_var(cfg_file, "iso-prefix")) == 0) {
764 mr_asprintf(bkpinfo->prefix, "%s", value);
765 } else {
766 mr_asprintf(bkpinfo->prefix, "%s", STD_PREFIX);
767 }
768 mr_free(value);
769
770 tmp = call_program_and_get_last_line_of_output("cat " CMDLINE);
771 if (strstr(tmp, "pxe")) {
772 /* We need to override prefix value in PXE mode as it's
773 * already done in start-netfs */
774 envtmp1 = getenv("imgname");
775 if (envtmp1 == NULL) {
776 fatal_error("no imgname variable in environment");
777 }
778 mr_free(bkpinfo->prefix);
779 mr_asprintf(bkpinfo->prefix, "%s", envtmp1);
780 }
781 mr_free(tmp);
782
783 } else if (!strcmp(value, "tape")) {
784 bkpinfo->backup_media_type = tape;
785 } else if (!strcmp(value, "udev")) {
786 bkpinfo->backup_media_type = udev;
787 } else {
788 fatal_error("UNKNOWN bkp-media-type");
789 }
790} else {
791 fatal_error("backup-media-type not specified!");
792}
793mr_free(value);
794
795if (bkpinfo->disaster_recovery) {
796 if (bkpinfo->backup_media_type == cdstream) {
797 mr_free(bkpinfo->media_device);
798 mr_asprintf(bkpinfo->media_device, "/dev/cdrom");
799 bkpinfo->media_size[0] = 1999 * 1024;
800 bkpinfo->media_size[1] = 650; /* good guess */
801 } else if (bkpinfo->backup_media_type == usb) {
802 envtmp1 = getenv("MRUSBDEV");
803 if (envtmp1 == NULL) {
804 if ((value = read_cfg_var(cfg_file, "usb-dev")) == NULL) {
805 fatal_error("Cannot get USB device name from cfg file");
806 }
807 } else {
808 mr_asprintf(value,"%s", envtmp1);
809 }
810 mr_free(bkpinfo->media_device);
811 mr_asprintf(bkpinfo->media_device, "%s1", value);
812 mr_free(value);
813 log_msg(2, "Backup medium is USB --- dev=%s", bkpinfo->media_device);
814 } else if (bkpinfo->backup_media_type == tape || bkpinfo->backup_media_type == udev) {
815 if ((value = read_cfg_var(cfg_file, "media-dev")) == NULL) {
816 fatal_error("Cannot get tape device name from cfg file");
817 }
818 mr_free(bkpinfo->media_device);
819 bkpinfo->media_device = value;
820
821 value = read_cfg_var(cfg_file, "media-size");
822 if (value != NULL) {
823 bkpinfo->media_size[1] = atol(value);
824 mr_free(value);
825 } else {
826 bkpinfo->media_size[1] = 0L;
827 }
828 log_msg(2, "Backup medium is TAPE --- dev=%s", bkpinfo->media_device);
829 } else {
830 mr_free(bkpinfo->media_device);
831 mr_asprintf(bkpinfo->media_device, "/dev/cdrom"); /* we don't really need this var */
832 bkpinfo->media_size[0] = 1999 * 1024; /* 650, probably, but we don't need this var anyway */
833 bkpinfo->media_size[1] = 1999 * 1024; /* 650, probably, but we don't need this var anyway */
834 log_msg(2, "Backup medium is CD-R[W]");
835 }
836} else {
837 log_msg(2, "Not in Disaster Recovery Mode. No need to derive device name from config file.");
838}
839
840value = read_cfg_var(cfg_file, "use-star");
841if (value && strstr(value, "yes")) {
842 bkpinfo->use_star = TRUE;
843 log_msg(1, "Goody! ... bkpinfo->use_star is now true.");
844}
845mr_free(value);
846
847value = read_cfg_var(cfg_file, "obdr");
848if (value && strstr(value, "TRUE")) {
849 bkpinfo->use_obdr = TRUE;
850 log_msg(1, "OBDR mode activated");
851}
852mr_free(value);
853
854value = read_cfg_var(cfg_file, "acl");
855if (value && strstr(value, "TRUE")) {
856 mr_asprintf(g_getfacl,"setfacl");
857 log_msg(1, "We will restore ACLs");
858 tmp = find_home_of_exe("setfacl");
859 if (!tmp) {
860 log_msg(1, "Unable to restore ACLs as no setfacl found");
861 }
862 mr_free(tmp);
863}
864mr_free(value);
865
866value = read_cfg_var(cfg_file, "xattr");
867if (value && strstr(value, "TRUE")) {
868 mr_asprintf(g_getfattr,"setfattr");
869 log_msg(1, "We will restore XATTRs");
870 tmp = find_home_of_exe("setfattr");
871 if (!tmp) {
872 log_msg(1, "Unable to restore XATTRs as no setfattr found");
873 }
874 mr_free(tmp);
875}
876mr_free(value);
877
878value = read_cfg_var(cfg_file, "internal-tape-block-size");
879if (value != NULL) {
880 bkpinfo->internal_tape_block_size = atol(value);
881} else {
882 bkpinfo->internal_tape_block_size = DEFAULT_INTERNAL_TAPE_BLOCK_SIZE;
883}
884log_msg(1, "Internal tape block size set to %ld", bkpinfo->internal_tape_block_size);
885mr_free(value);
886
887value = read_cfg_var(cfg_file, "use-lzma");
888if (value && strstr(value, "yes")) {
889 bkpinfo->use_lzma = TRUE;
890 bkpinfo->use_lzo = FALSE;
891 bkpinfo->use_gzip = FALSE;
892 mr_free(bkpinfo->zip_exe);
893 mr_asprintf(bkpinfo->zip_exe, "lzma");
894 mr_free(bkpinfo->zip_suffix);
895 mr_asprintf(bkpinfo->zip_suffix, "lzma");
896}
897mr_free(value);
898
899value = read_cfg_var(cfg_file, "use-lzo");
900if (value && strstr(value, "yes")) {
901 bkpinfo->use_lzma = FALSE;
902 bkpinfo->use_lzo = TRUE;
903 bkpinfo->use_gzip = FALSE;
904 mr_free(bkpinfo->zip_exe);
905 mr_asprintf(bkpinfo->zip_exe, "lzop");
906 mr_free(bkpinfo->zip_suffix);
907 mr_asprintf(bkpinfo->zip_suffix, "lzo");
908}
909mr_free(value);
910
911value = read_cfg_var(cfg_file, "use-gzip");
912if (value && strstr(value, "yes")) {
913 bkpinfo->use_lzma = FALSE;
914 bkpinfo->use_lzo = FALSE;
915 bkpinfo->use_gzip = TRUE;
916 mr_free(bkpinfo->zip_exe);
917 mr_asprintf(bkpinfo->zip_exe, "gzip");
918 mr_free(bkpinfo->zip_suffix);
919 mr_asprintf(bkpinfo->zip_suffix, "gz");
920}
921mr_free(value);
922
923value = read_cfg_var(cfg_file, "use-comp");
924if (value && strstr(value, "yes")) {
925 bkpinfo->use_lzma = FALSE;
926 bkpinfo->use_lzo = FALSE;
927 bkpinfo->use_gzip = FALSE;
928 mr_free(bkpinfo->zip_exe);
929 mr_asprintf(bkpinfo->zip_exe, "bzip2");
930 mr_free(bkpinfo->zip_suffix);
931 mr_asprintf(bkpinfo->zip_suffix, "bz2");
932}
933mr_free(value);
934
935if (bkpinfo->zip_exe == NULL) {
936 mr_asprintf(bkpinfo->zip_exe, "none");
937}
938if (bkpinfo->zip_suffix == NULL) {
939 mr_asprintf(bkpinfo->zip_suffix, "");
940}
941
942value = read_cfg_var(cfg_file, "differential");
943if (value && (!strcmp(value, "yes") || !strcmp(value, "1"))) {
944 bkpinfo->differential = TRUE;
945}
946log_msg(2, "differential var = '%s'", value);
947mr_free(value);
948if (bkpinfo->differential) {
949 log_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
950} else {
951 log_msg(2, "This is a regular (full) backup");
952}
953
954tmp = read_cfg_var(g_mondo_cfg_file, "please-dont-eject");
955tmp1 = call_program_and_get_last_line_of_output("cat " CMDLINE);
956if (tmp || strstr(tmp1, "donteject")) {
957 bkpinfo->please_dont_eject = TRUE;
958 log_msg(2, "Ok, I shan't eject when restoring! Groovy.");
959}
960mr_free(tmp);
961mr_free(tmp1);
962
963if (bkpinfo->backup_media_type == netfs) {
964 if (!cfgf) {
965 if (bkpinfo->netfs_mount) {
966 log_msg(2, "netfs_mount remains %s", bkpinfo->netfs_mount);
967 }
968 if (bkpinfo->netfs_remote_dir) {
969 log_msg(2, "netfs_remote_dir remains %s", bkpinfo->netfs_remote_dir);
970 }
971 log_msg(2, "...cos it wouldn't make sense to abandon the values that GOT ME to this config file in the first place");
972 } else {
973 mr_free(bkpinfo->netfs_mount);
974 bkpinfo->netfs_mount = read_cfg_var(g_mondo_cfg_file, "netfs-server-mount");
975
976 mr_free(bkpinfo->netfs_remote_dir);
977 bkpinfo->netfs_remote_dir = read_cfg_var(g_mondo_cfg_file, "netfs-server-path");
978
979 if (bkpinfo->netfs_mount != NULL) {
980 log_msg(2, "netfs_mount is %s", bkpinfo->netfs_mount);
981 }
982 if (bkpinfo->netfs_remote_dir != NULL) {
983 log_msg(2, "netfs_remote_dir is %s", bkpinfo->netfs_remote_dir);
984 }
985 if (bkpinfo->netfs_proto != NULL) {
986 log_msg(2, "netfs_proto is %s", bkpinfo->netfs_proto);
987 }
988 }
989 tmp1 = call_program_and_get_last_line_of_output("cat " CMDLINE);
990 if (strstr(tmp1, "pxe")) {
991 mr_free(tmp1);
992 /* We need to override values in PXE mode as it's
993 * already done in start-netfs */
994 envtmp1 = getenv("netfsmount");
995 if (envtmp1 == NULL) {
996 fatal_error("no netfsmount variable in environment");
997 }
998 envtmp2 = getenv("dirimg");
999 if (envtmp2 == NULL) {
1000 fatal_error("no dirimg variable in environment");
1001 }
1002 mr_free(bkpinfo->netfs_mount);
1003 mr_asprintf(bkpinfo->netfs_mount, "%s", envtmp1);
1004
1005 mr_free(bkpinfo->netfs_remote_dir);
1006 mr_asprintf(bkpinfo->netfs_remote_dir, "%s", envtmp2);
1007 } else {
1008 mr_free(tmp1);
1009 }
1010
1011} else if (bkpinfo->backup_media_type == iso) {
1012 /* Patch by Conor Daly 23-june-2004
1013 * to correctly mount iso-dev and set a sensible
1014 * isodir in disaster recovery mode
1015 */
1016 mr_asprintf(old_isodir, "%s", bkpinfo->isodir);
1017 iso_mnt = read_cfg_var(g_mondo_cfg_file, "iso-mnt");
1018 iso_path = read_cfg_var(g_mondo_cfg_file, "isodir");
1019 mr_free(bkpinfo->isodir);
1020 mr_asprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1021 mr_free(iso_mnt);
1022
1023 if (!bkpinfo->isodir[0]) {
1024 mr_free(bkpinfo->isodir);
1025 bkpinfo->isodir = old_isodir;
1026 } else {
1027 mr_free(old_isodir);
1028 }
1029 if (!bkpinfo->disaster_recovery) {
1030 if (strcmp(old_isodir, bkpinfo->isodir)) {
1031 log_it("user nominated isodir %s differs from archive, keeping user's choice: %s\n", bkpinfo->isodir, old_isodir );
1032 mr_free(bkpinfo->isodir);
1033 bkpinfo->isodir = old_isodir;
1034 } else {
1035 mr_free(old_isodir);
1036 }
1037 }
1038 mr_free(g_isodir_device);
1039 g_isodir_device = read_cfg_var(g_mondo_cfg_file, "iso-dev");
1040 log_msg(2, "isodir=%s; iso-dev=%s", bkpinfo->isodir, g_isodir_device);
1041
1042 if (bkpinfo->disaster_recovery) {
1043 if (is_this_device_mounted(g_isodir_device)) {
1044 log_msg(2, "NB: isodir is already mounted");
1045 /* Find out where it's mounted */
1046 mr_asprintf(command, "mount | grep -E '^%s' | tail -n1 | cut -d' ' -f3", g_isodir_device);
1047 log_it("command = %s", command);
1048 iso_mnt = call_program_and_get_last_line_of_output(command);
1049 log_it("res of it = %s", iso_mnt);
1050 mr_free(command);
1051 } else {
1052 mr_asprintf(iso_mnt, "/tmp/isodir");
1053 mr_asprintf(tmp1, "mkdir -p %s", iso_mnt);
1054 run_program_and_log_output(tmp1, 5);
1055 mr_free(tmp1);
1056
1057 mr_asprintf(tmp1, "mount %s %s", g_isodir_device, iso_mnt);
1058 if (run_program_and_log_output(tmp1, 3)) {
1059 log_msg(1, "Unable to mount isodir. Perhaps this is really a CD backup?");
1060 bkpinfo->backup_media_type = cdr;
1061 mr_free(bkpinfo->media_device);
1062 mr_asprintf(bkpinfo->media_device, "/dev/cdrom"); /* superfluous */
1063 if (mount_media()) {
1064 mr_free(tmp1);
1065 fatal_error("Unable to mount isodir. Failed to mount CD-ROM as well.");
1066 } else {
1067 log_msg(1, "You backed up to disk, then burned some CDs.");
1068 }
1069 }
1070 mr_free(tmp1);
1071 }
1072 /* bkpinfo->isodir should now be the true path to prefix-1.iso etc... */
1073 if (bkpinfo->backup_media_type == iso) {
1074 mr_free(bkpinfo->isodir);
1075 mr_asprintf(tmp1, "%s%s", iso_mnt, iso_path);
1076 bkpinfo->isodir = tmp1;
1077 }
1078 mr_free(iso_mnt);
1079 }
1080 mr_free(iso_path);
1081}
1082
1083if (media_specified_by_user != none) {
1084 if (g_restoring_live_from_cd) {
1085 if (bkpinfo->backup_media_type != media_specified_by_user) {
1086 log_msg(2,
1087 "bkpinfo->backup_media_type != media_specified_by_user, so I'd better ask :)");
1088 interactively_obtain_media_parameters_from_user(FALSE);
1089 media_specified_by_user = bkpinfo->backup_media_type;
1090 get_cfg_file_from_archive();
1091 /*
1092 if (media_specified_by_user != cdr && media_specified_by_user == cdrw)
1093 { g_restoring_live_from_cd = FALSE; }
1094 */
1095 }
1096 }
1097 bkpinfo->backup_media_type = media_specified_by_user;
1098}
1099g_backup_media_type = bkpinfo->backup_media_type;
1100paranoid_free(value);
1101paranoid_free(tmp);
1102return (0);
1103
1104}
1105
1106/**************************************************************************
1107*END_READ_CFG_FILE_INTO_BKPINFO *
1108**************************************************************************/
1109
1110
1111
1112
1113/**
1114 * Allow the user to edit the filelist and biggielist.
1115 * The filelist is unlinked after it is read.
1116 * @param bkpinfo The backup information structure. Fields used:
1117 * - @c bkpinfo->backup_media_type
1118 * - @c bkpinfo->isodir
1119 * - @c bkpinfo->media_device
1120 * - @c bkpinfo->tmpdir
1121 * @return The filelist structure containing the information read from disk.
1122 */
1123struct
1124s_node *process_filelist_and_biggielist()
1125{
1126struct s_node *filelist;
1127
1128/** add mallocs**/
1129char *command = NULL;
1130char *tmp;
1131char *tmp1 = NULL;
1132int res = 0;
1133pid_t pid;
1134bool extract_mountlist_stub = FALSE;
1135
1136assert(bkpinfo != NULL);
1137malloc_string(tmp);
1138
1139/* If those files already exist, do not overwrite them later on */
1140if (does_file_exist("/"MOUNTLIST_FNAME_STUB)) {
1141 extract_mountlist_stub = FALSE;
1142} else {
1143 extract_mountlist_stub = TRUE;
1144}
1145
1146if (does_file_exist(g_filelist_full)
1147&& does_file_exist(g_biggielist_txt)) {
1148 log_msg(1, "%s exists", g_filelist_full);
1149 log_msg(1, "%s exists", g_biggielist_txt);
1150 log_msg(2,
1151 "Filelist and biggielist already recovered from media. Yay!");
1152} else {
1153 getcwd(tmp, MAX_STR_LEN);
1154 chdir(bkpinfo->tmpdir);
1155 log_msg(1, "chdir(%s)", bkpinfo->tmpdir);
1156 log_to_screen("Extracting filelist and biggielist from media...");
1157 unlink("/tmp/filelist.full");
1158 unlink(FILELIST_FULL_STUB);
1159 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
1160 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);
1161 log_msg(1, "tarcommand = %s", command);
1162 run_program_and_log_output(command, 1);
1163 mr_free(command);
1164
1165 if (!does_file_exist(FILELIST_FULL_STUB)) {
1166 /* Doing that allow us to remain compatible with pre-2.2.5 versions */
1167 log_msg(2, "pre-2.2.4 compatible mode on");
1168 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);
1169 log_msg(1, "tarcommand = %s", command);
1170 run_program_and_log_output(command, 1);
1171 mr_free(command);
1172 }
1173 } else {
1174 log_msg(2, "Calling insist_on_this_cd_number; bkpinfo->isodir=%s", bkpinfo->isodir);
1175 insist_on_this_cd_number(1);
1176 log_msg(2, "Back from iotcn");
1177 run_program_and_log_output("mount", 1);
1178 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);
1179
1180 log_msg(1, "tarcommand = %s", command);
1181 run_program_and_log_output(command, 1);
1182 mr_free(command);
1183
1184 if (!does_file_exist(FILELIST_FULL_STUB)) {
1185 /* Doing that allow us to remain compatible with pre-2.2.5 versions */
1186 log_msg(2, "pre-2.2.4 compatible mode on");
1187 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);
1188
1189 log_msg(1, "tarcommand = %s", command);
1190 run_program_and_log_output(command, 1);
1191 mr_free(command);
1192 }
1193 if (!does_file_exist(BIGGIELIST_TXT_STUB)) {
1194 fatal_error
1195 ("all.tar.gz did not include " BIGGIELIST_TXT_STUB);
1196 }
1197 if (!does_file_exist(FILELIST_FULL_STUB)) {
1198 fatal_error
1199 ("all.tar.gz did not include " FILELIST_FULL_STUB);
1200 }
1201 }
1202 mr_asprintf(command, "cp -f %s %s", MONDO_CFG_FILE_STUB, g_mondo_cfg_file);
1203 run_program_and_log_output(command, FALSE);
1204 mr_free(command);
1205
1206 mr_asprintf(command, "cp -f %s/%s %s", bkpinfo->tmpdir, BIGGIELIST_TXT_STUB, g_biggielist_txt);
1207 log_msg(1, "command = %s", command);
1208 paranoid_system(command);
1209 mr_free(command);
1210
1211 mr_asprintf(command, "ln -sf %s/%s %s", bkpinfo->tmpdir, FILELIST_FULL_STUB, g_filelist_full);
1212 log_msg(1, "command = %s", command);
1213 paranoid_system(command);
1214 mr_free(command);
1215}
1216
1217if (am_I_in_disaster_recovery_mode()
1218 &&
1219 /* If it was there, do not overwrite it */
1220 (extract_mountlist_stub)
1221 &&
1222 ask_me_yes_or_no("Do you want to retrieve the mountlist as well?")) {
1223 mr_asprintf(command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB, bkpinfo->tmpdir);
1224 paranoid_system(command);
1225 mr_free(command);
1226 }
1227
1228 chdir(tmp);
1229
1230 if (!does_file_exist(g_biggielist_txt)) {
1231 log_msg(1, "Warning - %s not found", g_biggielist_txt);
1232 }
1233 if (!does_file_exist(g_filelist_full)) {
1234 log_msg(1, "Warning - %s does not exist", g_filelist_full);
1235 }
1236// popup_and_OK("Wonderful.");
1237
1238 log_msg(2, "Forking");
1239 pid = fork();
1240 switch (pid) {
1241 case -1:
1242 fatal_error("Forking error");
1243 break;
1244
1245 case 0:
1246 log_to_screen("Pre-processing filelist");
1247 if (!does_file_exist(g_biggielist_txt)) {
1248 mr_asprintf(command, "echo -n > %s", g_biggielist_txt);
1249 paranoid_system(command);
1250 mr_free(command);
1251 }
1252 mr_asprintf(command, "grep -E '^/dev/.*' %s > %s", g_biggielist_txt, g_filelist_imagedevs);
1253 paranoid_system(command);
1254 mr_free(command);
1255 exit(0);
1256 break;
1257
1258 default:
1259 open_evalcall_form("Pre-processing filelist");
1260 while (!waitpid(pid, (int *) 0, WNOHANG)) {
1261 usleep(100000);
1262 update_evalcall_form(0);
1263 }
1264 }
1265 close_evalcall_form();
1266
1267 log_msg(3, "loading filelist");
1268 filelist = load_filelist(g_filelist_full);
1269 log_msg(3, "deleting original filelist");
1270 unlink(g_filelist_full);
1271 if (g_text_mode) {
1272 printf("Restore which directory? --> ");
1273 mr_getline(tmp1, stdin);
1274 toggle_path_selection(filelist, tmp1, TRUE);
1275 if (strlen(tmp1) == 0) {
1276 res = 1;
1277 } else {
1278 res = 0;
1279 }
1280 mr_free(tmp1);
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 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 char *incoming = NULL;
1953
1954 assert_string_is_neither_NULL_nor_zerolength(output_file);
1955 assert_string_is_neither_NULL_nor_zerolength(input_file);
1956
1957 if (!(fin = fopen(input_file, "r"))) {
1958 log_OS_error(input_file);
1959 return;
1960 }
1961 if (!(fout = fopen(output_file, "w"))) {
1962 fatal_error("cannot open output_file");
1963 }
1964 for (mr_getline(incoming, fin); !feof(fin); mr_getline(incoming, fin)) {
1965 if (strncmp(incoming, "etc/adjtime", 11)
1966 && strncmp(incoming, "etc/mtab", 8)
1967 && strncmp(incoming, "tmp/", 4)
1968 && strncmp(incoming, "boot/map", 8)
1969 && !strstr(incoming, "incheckentry")
1970 && strncmp(incoming, "etc/mail/statistics", 19)
1971 && strncmp(incoming, "var/", 4))
1972 fprintf(fout, "%s", incoming); /* don't need \n here, for some reason.. */
1973 mr_free(incoming);
1974 }
1975 mr_free(incoming);
1976 paranoid_fclose(fout);
1977 paranoid_fclose(fin);
1978}
1979
1980/**************************************************************************
1981 *END_STREAMLINE_CHANGES_FILE *
1982 **************************************************************************/
1983
1984
1985/**
1986 * Give the user twenty seconds to press Ctrl-Alt-Del before we nuke their drives.
1987 */
1988void twenty_seconds_til_yikes()
1989{
1990 int i;
1991 /* MALLOC * */
1992 char *tmp = NULL;
1993
1994 if (does_file_exist("/tmp/NOPAUSE")) {
1995 return;
1996 }
1997 open_progress_form("CAUTION",
1998 "Be advised: I am about to ERASE your hard disk(s)!",
1999 "You may press Ctrl+Alt+Del to abort safely.",
2000 "", 20);
2001 for (i = 0; i < 20; i++) {
2002 g_current_progress = i;
2003 mr_asprintf(tmp, "You have %d seconds left to abort.", 20 - i);
2004 update_progress_form(tmp);
2005 mr_free(tmp);
2006 sleep(1);
2007 }
2008 close_progress_form();
2009}
2010
2011/**************************************************************************
2012 *END_TWENTY_SECONDS_TIL_YIKES *
2013 **************************************************************************/
2014
2015
2016/**
2017 * Unmount all devices in @p p_external_copy_of_mountlist.
2018 * @param p_external_copy_of_mountlist The mountlist to guide the devices to unmount.
2019 * @return 0 for success, nonzero for failure.
2020 */
2021int unmount_all_devices(struct mountlist_itself
2022 *p_external_copy_of_mountlist)
2023{
2024 struct mountlist_itself *mountlist;
2025 int retval = 0, lino, res = 0, i;
2026 char *command = NULL;
2027 char *tmp = NULL;
2028
2029 assert(p_external_copy_of_mountlist != NULL);
2030
2031 mountlist = malloc(sizeof(struct mountlist_itself));
2032 memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
2033 sizeof(struct mountlist_itself));
2034 sort_mountlist_by_mountpoint(mountlist, 0);
2035
2036 run_program_and_log_output("df -m -P", 3);
2037 mvaddstr_and_log_it(g_currentY, 0, "Unmounting devices ");
2038 open_progress_form("Unmounting devices",
2039 "Unmounting all devices that were mounted,",
2040 "in preparation for the post-restoration reboot.",
2041 "", mountlist->entries);
2042 chdir("/");
2043 for (i = 0;
2044 i < 10
2045 &&
2046 run_program_and_log_output
2047 ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
2048 i++) {
2049 sleep(1);
2050 log_msg(2, "Waiting for buffer() to finish");
2051 }
2052
2053 sync();
2054
2055 mr_asprintf(tmp, "cp -f %s " MNT_RESTORING "/var/log", MONDO_LOGFILE);
2056 if (run_program_and_log_output(tmp, FALSE)) {
2057 log_msg(1,
2058 "Error. Failed to copy log to PC's /var/log dir. (Mounted read-only?)");
2059 }
2060 paranoid_free(tmp);
2061 if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2062 run_program_and_log_output("mkdir -p " MNT_RESTORING
2063 "/mnt/.boot.d", 5);
2064 }
2065
2066 /* Unmounting the local /proc and /sys first */
2067 run_program_and_log_output("umount " MNT_RESTORING "/proc",3);
2068 run_program_and_log_output("umount " MNT_RESTORING "/sys",3);
2069
2070 for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2071 if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2072 continue;
2073 }
2074 mr_asprintf(tmp, "Unmounting device %s ", mountlist->el[lino].device);
2075 update_progress_form(tmp);
2076
2077 if (is_this_device_mounted(mountlist->el[lino].device)) {
2078 if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
2079 mr_asprintf(command, "swapoff %s", mountlist->el[lino].device);
2080 } else {
2081 if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
2082 mr_asprintf(command, "umount %s/", MNT_RESTORING);
2083 log_msg(3,
2084 "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2085 } else {
2086 mr_asprintf(command, "umount " MNT_RESTORING "%s", mountlist->el[lino].mountpoint);
2087
2088 /* To support latest Ubuntu where /var is a separate FS
2089 * Cf: http://linux.derkeiler.com/Mailing-Lists/Ubuntu/2007-04/msg01319.html
2090 * we need to create some dirs under the real / before unmounting it */
2091 if (!strcmp(mountlist->el[lino].mountpoint, "/")) {
2092 run_program_and_log_output("mkdir -p " MNT_RESTORING "/var/lock", FALSE);
2093 run_program_and_log_output("mkdir -p " MNT_RESTORING "/var/run", FALSE);
2094 }
2095 }
2096 }
2097 log_msg(10, "The 'umount' command is '%s'", command);
2098 res = run_program_and_log_output(command, 3);
2099 mr_free(command);
2100 } else {
2101 mr_strcat(tmp, "...not mounted anyway :-) OK");
2102 res = 0;
2103 }
2104 g_current_progress++;
2105 if (res) {
2106 mr_strcat(tmp, "...Failed");
2107 retval++;
2108 log_to_screen(tmp);
2109 } else {
2110 log_msg(2, tmp);
2111 }
2112 paranoid_free(tmp);
2113 }
2114 close_progress_form();
2115 if (retval) {
2116 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2117 } else {
2118 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2119 }
2120 if (retval) {
2121 log_to_screen("Unable to unmount some of your partitions.");
2122 } else {
2123 log_to_screen("All partitions were unmounted OK.");
2124 }
2125 free(mountlist);
2126 return (retval);
2127}
2128
2129/**************************************************************************
2130 *END_UNMOUNT_ALL_DEVICES *
2131 **************************************************************************/
2132
2133
2134
2135/**
2136 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2137 * to the ./tmp/ directory.
2138 * @param dev The tape device to read from.
2139 * @return 0 for success, nonzero for failure.
2140 */
2141int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2142{
2143 char *command = NULL;
2144 int res = 0;
2145
2146 if (bkpinfo->use_obdr) {
2147 skip_obdr();
2148 } else {
2149 // BCO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
2150 set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size);
2151 }
2152
2153 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);
2154 log_msg(2, "command = '%s'", command);
2155 res = run_program_and_log_output(command, -1);
2156 mr_free(command);
2157
2158 if (res != 0) {
2159 if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2160 res = 0;
2161 } else {
2162 /* Doing that allow us to remain compatible with pre-2.2.5 versions */
2163 log_msg(2, "pre-2.2.4 compatible mode on");
2164 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);
2165 log_msg(2, "command = '%s'", command);
2166 res = run_program_and_log_output(command, -1);
2167 mr_free(command);
2168
2169 if ((res != 0) && (does_file_exist(MONDO_CFG_FILE_STUB))) {
2170 res = 0;
2171 }
2172 }
2173 }
2174 return (res);
2175}
2176
2177
2178
2179/**
2180 * Get the configuration file from the floppy, tape, or CD.
2181 * @param bkpinfo The backup information structure. Fields used:
2182 * - @c bkpinfo->backup_media_type
2183 * - @c bkpinfo->media_device
2184 * - @c bkpinfo->tmpdir
2185 * @return 0 for success, nonzero for failure.
2186 */
2187int get_cfg_file_from_archive()
2188{
2189 int retval = 0;
2190
2191 /** malloc *****/
2192 char *device;
2193 char *command = NULL;
2194 char *cfg_file = NULL;
2195 char *mounted_cfgf_path;
2196 char *tmp = NULL;
2197 char *tmp1 = NULL;
2198 char *mountpt = NULL;
2199 char *ramdisk_fname;
2200 char *mountlist_file = NULL;
2201 bool extract_mountlist_stub = FALSE;
2202 bool extract_i_want_my_lvm = FALSE;
2203
2204 bool try_plan_B;
2205
2206 assert(bkpinfo != NULL);
2207 malloc_string(mounted_cfgf_path);
2208 malloc_string(ramdisk_fname);
2209 malloc_string(device);
2210 log_msg(2, "gcffa --- starting");
2211 log_to_screen("I'm thinking...");
2212 mr_asprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
2213 device[0] = '\0';
2214 chdir(bkpinfo->tmpdir);
2215 mr_asprintf(cfg_file, "%s", MONDO_CFG_FILE_STUB);
2216 unlink(cfg_file); // cfg_file[] is missing the '/' at the start, FYI, by intent
2217 mr_free(cfg_file);
2218
2219 unlink(FILELIST_FULL_STUB);
2220 unlink(BIGGIELIST_TXT_STUB);
2221 mr_asprintf(command, "mkdir -p %s", mountpt);
2222 run_program_and_log_output(command, FALSE);
2223 mr_free(command);
2224
2225 mr_asprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2226 mr_asprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2227 log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
2228 mr_free(mountpt);
2229
2230 if (!does_file_exist(cfg_file)) {
2231 log_msg(2, "gcffa --- we don't have cfg file yet.");
2232 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2233 try_plan_B = TRUE;
2234 } else {
2235 log_msg(2, "gcffa --- calling mount_media now :)");
2236 if (!mount_media()) {
2237 log_msg(2,
2238 "gcffa --- managed to mount CD; so, no need for Plan B");
2239 try_plan_B = FALSE;
2240 } else {
2241 try_plan_B = TRUE;
2242 }
2243 if (what_number_cd_is_this() > 1) {
2244 insist_on_this_cd_number((g_current_media_number = 1));
2245 }
2246 }
2247 if (try_plan_B) {
2248 log_msg(2, "gcffa --- OK, switching to Plan B");
2249 chdir(bkpinfo->tmpdir);
2250 run_program_and_log_output("mkdir -p tmp", FALSE);
2251
2252 if (! bkpinfo->media_device) {
2253 mr_asprintf(bkpinfo->media_device, "/dev/st0");
2254 log_msg(2, "media_device is blank; assuming %s", bkpinfo->media_device);
2255 }
2256 mr_asprintf(tmp, "%s", bkpinfo->media_device);
2257 if (extract_cfg_file_and_mountlist_from_tape_dev (bkpinfo->media_device)) {
2258 mr_free(bkpinfo->media_device);
2259 mr_asprintf(bkpinfo->media_device, "/dev/st0");
2260 if (extract_cfg_file_and_mountlist_from_tape_dev (bkpinfo->media_device)) {
2261 mr_free(bkpinfo->media_device);
2262 mr_asprintf(bkpinfo->media_device, "/dev/osst0");
2263 if (extract_cfg_file_and_mountlist_from_tape_dev (bkpinfo->media_device)) {
2264 mr_free(bkpinfo->media_device);
2265 mr_asprintf(bkpinfo->media_device, "/dev/ht0");
2266 if (extract_cfg_file_and_mountlist_from_tape_dev (bkpinfo->media_device)) {
2267 log_msg(3, "I tried lots of devices but none worked.");
2268 mr_free(bkpinfo->media_device);
2269 mr_asprintf(bkpinfo->media_device, "%s", tmp);
2270 }
2271 }
2272 }
2273 }
2274 mr_free(tmp);
2275
2276 if (!does_file_exist("tmp/mondo-restore.cfg")) {
2277 log_to_screen("Cannot find config info on media");
2278 return (1);
2279 }
2280 } else {
2281 if (does_file_exist("/"MOUNTLIST_FNAME_STUB)) {
2282 extract_mountlist_stub = FALSE;
2283 } else {
2284 extract_mountlist_stub = TRUE;
2285 }
2286 if (does_file_exist("/"IWANTMYLVM_STUB)) {
2287 extract_i_want_my_lvm = FALSE;
2288 } else {
2289 extract_i_want_my_lvm = TRUE;
2290 }
2291
2292 log_msg(2,
2293 "gcffa --- Plan B, a.k.a. untarring some file from all.tar.gz");
2294 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
2295 run_program_and_log_output(command, TRUE);
2296 mr_free(command);
2297
2298 if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2299 /* Doing that allow us to remain compatible with pre-2.2.5 versions */
2300 log_msg(2, "pre-2.2.4 compatible mode on");
2301 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
2302 run_program_and_log_output(command, TRUE);
2303 mr_free(command);
2304
2305 if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2306 fatal_error
2307 ("Please reinsert the disk/CD and try again.");
2308 }
2309 }
2310 }
2311 }
2312 if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2313 log_msg(1, "gcffa --- great! We've got the config file");
2314 tmp = call_program_and_get_last_line_of_output("pwd");
2315 mr_strcat(tmp, "/%s", 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 tmp1 = call_program_and_get_last_line_of_output("pwd");
2326 mr_asprintf(command, "cp -f %s/%s %s", tmp1, MOUNTLIST_FNAME_STUB, mountlist_file);
2327 mr_free(tmp1);
2328
2329 log_it("%s",command);
2330 if (extract_mountlist_stub) {
2331 if (strcmp(tmp, cfg_file) && run_program_and_log_output(command, 1)) {
2332 log_msg(1, "Failed to get mountlist");
2333 } else {
2334 log_msg(1, "Got mountlist too");
2335
2336 mr_free(command);
2337 mr_asprintf(command, "cp -f %s %s", mountlist_file, g_mountlist_fname);
2338 if (run_program_and_log_output(command, 1)) {
2339 log_msg(1, "Failed to copy mountlist to /tmp");
2340 } else {
2341 log_msg(1, "Copied mountlist to /tmp as well OK");
2342 mr_free(command);
2343 mr_asprintf(command, "cp -f %s /tmp/",IWANTMYLVM_STUB);
2344 run_program_and_log_output(command, 1);
2345 }
2346 }
2347 }
2348 mr_free(tmp);
2349 mr_free(command);
2350 }
2351 run_program_and_log_output("umount " MNT_CDROM, FALSE);
2352 if (!does_file_exist(cfg_file)) {
2353 log_it("%s",cfg_file);
2354 log_msg(1, "%s not found", cfg_file);
2355 log_to_screen
2356 ("Oh dear. Unable to recover configuration file from boot disk");
2357 return (1);
2358 }
2359
2360 log_to_screen("Recovered mondo-restore.cfg");
2361 if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2362 log_to_screen("...but not mountlist.txt - a pity, really...");
2363 }
2364 else {
2365 /* Is this code really useful ??? */
2366 if (extract_mountlist_stub) {
2367 mr_asprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2368 run_program_and_log_output(command, FALSE);
2369 mr_free(command);
2370 }
2371 }
2372
2373 mr_asprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2374 mr_free(cfg_file);
2375
2376 run_program_and_log_output(command, FALSE);
2377 mr_free(command);
2378
2379 if (extract_mountlist_stub) {
2380 mr_asprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2381 run_program_and_log_output(command, FALSE);
2382 mr_free(command);
2383 }
2384 mr_free(mountlist_file);
2385
2386 mr_asprintf(command, "cp -f etc/raidtab /etc/");
2387 run_program_and_log_output(command, FALSE);
2388 mr_free(command);
2389
2390 if (extract_i_want_my_lvm) {
2391 mr_asprintf(command, "cp -f %s /tmp/",IWANTMYLVM_STUB);
2392 run_program_and_log_output(command, FALSE);
2393 mr_free(command);
2394 }
2395 g_backup_media_type = bkpinfo->backup_media_type;
2396 paranoid_free(device);
2397 paranoid_free(mounted_cfgf_path);
2398 paranoid_free(ramdisk_fname);
2399 return (retval);
2400}
2401
2402/**************************************************************************
2403 *END_GET_CFG_FILE_FROM_ARCHIVE *
2404 **************************************************************************/
2405
2406/* @} - end restoreUtilityGroup */
2407
2408void wait_until_software_raids_are_prepped(char *mdstat_file,
2409 int wait_for_percentage)
2410{
2411 struct raidlist_itself *raidlist;
2412 int unfinished_mdstat_devices = 9999, i;
2413 char *screen_message = NULL;
2414
2415 raidlist = malloc(sizeof(struct raidlist_itself));
2416
2417 assert(wait_for_percentage <= 100);
2418 log_it("wait_until_software_raids_are_prepped");
2419 while (unfinished_mdstat_devices > 0) {
2420 // FIXME: Prefix '/dev/' should really be dynamic!
2421 if (parse_mdstat(raidlist, "/dev/")) {
2422 log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2423 log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2424 return;
2425 }
2426 for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2427 if (raidlist->el[i].progress < wait_for_percentage) {
2428 unfinished_mdstat_devices++;
2429 if (raidlist->el[i].progress == -1) // delayed while another partition inits
2430 {
2431 continue;
2432 }
2433 log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2434 mr_asprintf(screen_message, "Sync'ing %s", raidlist->el[i].raid_device);
2435 open_evalcall_form(screen_message);
2436 mr_free(screen_message);
2437
2438 while (raidlist->el[i].progress < wait_for_percentage) {
2439 log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2440 update_evalcall_form(raidlist->el[i].progress);
2441 sleep(2);
2442 // FIXME: Prefix '/dev/' should really be dynamic!
2443 if (parse_mdstat(raidlist, "/dev/")) {
2444 break;
2445 }
2446 }
2447 close_evalcall_form();
2448 }
2449 }
2450 }
2451 paranoid_free(raidlist);
2452}
2453
2454
Note: See TracBrowser for help on using the repository browser.