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

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

Fix a problem in netfs analysis in mondoarchive
(Backport from 2.2.9)

  • Property svn:keywords set to Id
File size: 75.1 KB
Line 
1/***************************************************************************
2$Id: mondo-rstr-tools.c 2389 2009-09-10 18:31:57Z 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(bkpinfo->prefix);
752 mr_free(value);
753 if ((value = read_cfg_var(cfg_file, "iso-prefix")) == 0) {
754 mr_asprintf(bkpinfo->prefix, "%s", value);
755 } else {
756 mr_asprintf(bkpinfo->prefix, "%s", STD_PREFIX);
757 }
758
759 tmp = call_program_and_get_last_line_of_output("cat " CMDLINE);
760 if (strstr(tmp, "pxe")) {
761 /* We need to override prefix value in PXE mode as it's
762 * already done in start-netfs */
763 envtmp1 = getenv("imgname");
764 if (envtmp1 == NULL) {
765 fatal_error("no imgname variable in environment");
766 }
767 mr_free(bkpinfo->prefix);
768 mr_asprintf(bkpinfo->prefix, "%s", envtmp1);
769 }
770 mr_free(tmp);
771 /* For compatibility, force protocol in old nfs case to be transparent */
772 if (!strcmp(value, "nfs")) {
773 mr_free(bkpinfo->netfs_proto);
774 mr_asprintf(bkpinfo->netfs_proto, "nfs");
775 }
776
777 } else if (!strcmp(value, "tape")) {
778 bkpinfo->backup_media_type = tape;
779 } else if (!strcmp(value, "udev")) {
780 bkpinfo->backup_media_type = udev;
781 } else {
782 fatal_error("UNKNOWN bkp-media-type");
783 }
784} else {
785 fatal_error("backup-media-type not specified!");
786}
787mr_free(value);
788
789if (bkpinfo->disaster_recovery) {
790 if (bkpinfo->backup_media_type == cdstream) {
791 mr_free(bkpinfo->media_device);
792 mr_asprintf(bkpinfo->media_device, "/dev/cdrom");
793 bkpinfo->media_size[0] = 1999 * 1024;
794 bkpinfo->media_size[1] = 650; /* good guess */
795 } else if (bkpinfo->backup_media_type == usb) {
796 envtmp1 = getenv("MRUSBDEV");
797 if (envtmp1 == NULL) {
798 if ((value = read_cfg_var(cfg_file, "usb-dev")) == NULL) {
799 fatal_error("Cannot get USB device name from cfg file");
800 }
801 } else {
802 mr_asprintf(value,"%s", envtmp1);
803 }
804 mr_free(bkpinfo->media_device);
805 mr_asprintf(bkpinfo->media_device, "%s1", value);
806 mr_free(value);
807 log_msg(2, "Backup medium is USB --- dev=%s", bkpinfo->media_device);
808 } else if (bkpinfo->backup_media_type == tape || bkpinfo->backup_media_type == udev) {
809 if ((value = read_cfg_var(cfg_file, "media-dev")) == NULL) {
810 fatal_error("Cannot get tape device name from cfg file");
811 }
812 mr_free(bkpinfo->media_device);
813 bkpinfo->media_device = value;
814
815 value = read_cfg_var(cfg_file, "media-size");
816 if (value != NULL) {
817 bkpinfo->media_size[1] = atol(value);
818 mr_free(value);
819 } else {
820 bkpinfo->media_size[1] = 0L;
821 }
822 log_msg(2, "Backup medium is TAPE --- dev=%s", bkpinfo->media_device);
823 } else {
824 mr_free(bkpinfo->media_device);
825 mr_asprintf(bkpinfo->media_device, "/dev/cdrom"); /* we don't really need this var */
826 bkpinfo->media_size[0] = 1999 * 1024; /* 650, probably, but we don't need this var anyway */
827 bkpinfo->media_size[1] = 1999 * 1024; /* 650, probably, but we don't need this var anyway */
828 log_msg(2, "Backup medium is CD-R[W]");
829 }
830} else {
831 log_msg(2, "Not in Disaster Recovery Mode. No need to derive device name from config file.");
832}
833
834value = read_cfg_var(cfg_file, "use-star");
835if (value && strstr(value, "yes")) {
836 bkpinfo->use_star = TRUE;
837 log_msg(1, "Goody! ... bkpinfo->use_star is now true.");
838}
839mr_free(value);
840
841value = read_cfg_var(cfg_file, "obdr");
842if (value && strstr(value, "TRUE")) {
843 bkpinfo->use_obdr = TRUE;
844 log_msg(1, "OBDR mode activated");
845}
846mr_free(value);
847
848value = read_cfg_var(cfg_file, "acl");
849if (value && strstr(value, "TRUE")) {
850 mr_asprintf(g_getfacl,"setfacl");
851 log_msg(1, "We will restore ACLs");
852 tmp = find_home_of_exe("setfacl");
853 if (!tmp) {
854 log_msg(1, "Unable to restore ACLs as no setfacl found");
855 }
856 mr_free(tmp);
857}
858mr_free(value);
859
860value = read_cfg_var(cfg_file, "xattr");
861if (value && strstr(value, "TRUE")) {
862 mr_asprintf(g_getfattr,"setfattr");
863 log_msg(1, "We will restore XATTRs");
864 tmp = find_home_of_exe("setfattr");
865 if (!tmp) {
866 log_msg(1, "Unable to restore XATTRs as no setfattr found");
867 }
868 mr_free(tmp);
869}
870mr_free(value);
871
872value = read_cfg_var(cfg_file, "internal-tape-block-size");
873if (value != NULL) {
874 bkpinfo->internal_tape_block_size = atol(value);
875} else {
876 bkpinfo->internal_tape_block_size = DEFAULT_INTERNAL_TAPE_BLOCK_SIZE;
877}
878log_msg(1, "Internal tape block size set to %ld", bkpinfo->internal_tape_block_size);
879mr_free(value);
880
881value = read_cfg_var(cfg_file, "use-lzma");
882if (value && strstr(value, "yes")) {
883 bkpinfo->use_lzma = TRUE;
884 bkpinfo->use_lzo = FALSE;
885 bkpinfo->use_gzip = FALSE;
886 mr_free(bkpinfo->zip_exe);
887 mr_asprintf(bkpinfo->zip_exe, "lzma");
888 mr_free(bkpinfo->zip_suffix);
889 mr_asprintf(bkpinfo->zip_suffix, "lzma");
890}
891mr_free(value);
892
893value = read_cfg_var(cfg_file, "use-lzo");
894if (value && strstr(value, "yes")) {
895 bkpinfo->use_lzma = FALSE;
896 bkpinfo->use_lzo = TRUE;
897 bkpinfo->use_gzip = FALSE;
898 mr_free(bkpinfo->zip_exe);
899 mr_asprintf(bkpinfo->zip_exe, "lzop");
900 mr_free(bkpinfo->zip_suffix);
901 mr_asprintf(bkpinfo->zip_suffix, "lzo");
902}
903mr_free(value);
904
905value = read_cfg_var(cfg_file, "use-gzip");
906if (value && strstr(value, "yes")) {
907 bkpinfo->use_lzma = FALSE;
908 bkpinfo->use_lzo = FALSE;
909 bkpinfo->use_gzip = TRUE;
910 mr_free(bkpinfo->zip_exe);
911 mr_asprintf(bkpinfo->zip_exe, "gzip");
912 mr_free(bkpinfo->zip_suffix);
913 mr_asprintf(bkpinfo->zip_suffix, "gz");
914}
915mr_free(value);
916
917value = read_cfg_var(cfg_file, "use-comp");
918if (value && strstr(value, "yes")) {
919 bkpinfo->use_lzma = FALSE;
920 bkpinfo->use_lzo = FALSE;
921 bkpinfo->use_gzip = FALSE;
922 mr_free(bkpinfo->zip_exe);
923 mr_asprintf(bkpinfo->zip_exe, "bzip2");
924 mr_free(bkpinfo->zip_suffix);
925 mr_asprintf(bkpinfo->zip_suffix, "bz2");
926}
927mr_free(value);
928
929if (bkpinfo->zip_exe == NULL) {
930 mr_asprintf(bkpinfo->zip_exe, "none");
931}
932if (bkpinfo->zip_suffix == NULL) {
933 mr_asprintf(bkpinfo->zip_suffix, "");
934}
935
936value = read_cfg_var(cfg_file, "differential");
937if (value && (!strcmp(value, "yes") || !strcmp(value, "1"))) {
938 bkpinfo->differential = TRUE;
939}
940log_msg(2, "differential var = '%s'", value);
941mr_free(value);
942if (bkpinfo->differential) {
943 log_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
944} else {
945 log_msg(2, "This is a regular (full) backup");
946}
947
948tmp = read_cfg_var(g_mondo_cfg_file, "please-dont-eject");
949tmp1 = call_program_and_get_last_line_of_output("cat " CMDLINE);
950if (tmp || strstr(tmp1, "donteject")) {
951 bkpinfo->please_dont_eject = TRUE;
952 log_msg(2, "Ok, I shan't eject when restoring! Groovy.");
953}
954mr_free(tmp);
955mr_free(tmp1);
956
957if (bkpinfo->backup_media_type == netfs) {
958 if (!cfgf) {
959 if (bkpinfo->netfs_mount) {
960 log_msg(2, "netfs_mount remains %s", bkpinfo->netfs_mount);
961 }
962 if (bkpinfo->netfs_remote_dir) {
963 log_msg(2, "netfs_remote_dir remains %s", bkpinfo->netfs_remote_dir);
964 }
965 log_msg(2, "...cos it wouldn't make sense to abandon the values that GOT ME to this config file in the first place");
966 } else {
967 mr_free(bkpinfo->netfs_mount);
968 bkpinfo->netfs_mount = read_cfg_var(g_mondo_cfg_file, "netfs-server-mount");
969
970 mr_free(bkpinfo->netfs_remote_dir);
971 bkpinfo->netfs_remote_dir = read_cfg_var(g_mondo_cfg_file, "netfs-server-path");
972
973 if (bkpinfo->netfs_mount != NULL) {
974 log_msg(2, "netfs_mount is %s", bkpinfo->netfs_mount);
975 }
976 if (bkpinfo->netfs_remote_dir != NULL) {
977 log_msg(2, "netfs_remote_dir is %s", bkpinfo->netfs_remote_dir);
978 }
979 if (bkpinfo->netfs_proto != NULL) {
980 log_msg(2, "netfs_proto is %s", bkpinfo->netfs_proto);
981 }
982 }
983 tmp1 = call_program_and_get_last_line_of_output("cat " CMDLINE);
984 if (strstr(tmp1, "pxe")) {
985 mr_free(tmp1);
986 /* We need to override values in PXE mode as it's
987 * already done in start-netfs */
988 envtmp1 = getenv("netfsmount");
989 if (envtmp1 == NULL) {
990 fatal_error("no netfsmount variable in environment");
991 }
992 envtmp2 = getenv("dirimg");
993 if (envtmp2 == NULL) {
994 fatal_error("no dirimg variable in environment");
995 }
996 mr_free(bkpinfo->netfs_mount);
997 mr_asprintf(bkpinfo->netfs_mount, "%s", envtmp1);
998
999 mr_free(bkpinfo->netfs_remote_dir);
1000 mr_asprintf(bkpinfo->netfs_remote_dir, "%s", envtmp2);
1001 } else {
1002 mr_free(tmp1);
1003 }
1004
1005} else if (bkpinfo->backup_media_type == iso) {
1006 /* Patch by Conor Daly 23-june-2004
1007 * to correctly mount iso-dev and set a sensible
1008 * isodir in disaster recovery mode
1009 */
1010 mr_asprintf(old_isodir, "%s", bkpinfo->isodir);
1011 iso_mnt = read_cfg_var(g_mondo_cfg_file, "iso-mnt");
1012 iso_path = read_cfg_var(g_mondo_cfg_file, "isodir");
1013 mr_free(bkpinfo->isodir);
1014 mr_asprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1015 mr_free(iso_mnt);
1016
1017 if (!bkpinfo->isodir[0]) {
1018 mr_free(bkpinfo->isodir);
1019 bkpinfo->isodir = old_isodir;
1020 } else {
1021 mr_free(old_isodir);
1022 }
1023 if (!bkpinfo->disaster_recovery) {
1024 if (strcmp(old_isodir, bkpinfo->isodir)) {
1025 log_it("user nominated isodir %s differs from archive, keeping user's choice: %s\n", bkpinfo->isodir, old_isodir );
1026 mr_free(bkpinfo->isodir);
1027 bkpinfo->isodir = old_isodir;
1028 } else {
1029 mr_free(old_isodir);
1030 }
1031 }
1032 mr_free(g_isodir_device);
1033 g_isodir_device = read_cfg_var(g_mondo_cfg_file, "iso-dev");
1034 log_msg(2, "isodir=%s; iso-dev=%s", bkpinfo->isodir, g_isodir_device);
1035
1036 if (bkpinfo->disaster_recovery) {
1037 if (is_this_device_mounted(g_isodir_device)) {
1038 log_msg(2, "NB: isodir is already mounted");
1039 /* Find out where it's mounted */
1040 mr_asprintf(command, "mount | grep -E '^%s' | tail -n1 | cut -d' ' -f3", g_isodir_device);
1041 log_it("command = %s", command);
1042 iso_mnt = call_program_and_get_last_line_of_output(command);
1043 log_it("res of it = %s", iso_mnt);
1044 mr_free(command);
1045 } else {
1046 mr_asprintf(iso_mnt, "/tmp/isodir");
1047 mr_asprintf(tmp1, "mkdir -p %s", iso_mnt);
1048 run_program_and_log_output(tmp1, 5);
1049 mr_free(tmp1);
1050
1051 mr_asprintf(tmp1, "mount %s %s", g_isodir_device, iso_mnt);
1052 if (run_program_and_log_output(tmp1, 3)) {
1053 log_msg(1, "Unable to mount isodir. Perhaps this is really a CD backup?");
1054 bkpinfo->backup_media_type = cdr;
1055 mr_free(bkpinfo->media_device);
1056 mr_asprintf(bkpinfo->media_device, "/dev/cdrom"); /* superfluous */
1057 if (mount_media()) {
1058 mr_free(tmp1);
1059 fatal_error("Unable to mount isodir. Failed to mount CD-ROM as well.");
1060 } else {
1061 log_msg(1, "You backed up to disk, then burned some CDs.");
1062 }
1063 }
1064 mr_free(tmp1);
1065 }
1066 /* bkpinfo->isodir should now be the true path to prefix-1.iso etc... */
1067 if (bkpinfo->backup_media_type == iso) {
1068 mr_free(bkpinfo->isodir);
1069 mr_asprintf(tmp1, "%s%s", iso_mnt, iso_path);
1070 bkpinfo->isodir = tmp1;
1071 }
1072 mr_free(iso_mnt);
1073 }
1074 mr_free(iso_path);
1075}
1076
1077if (media_specified_by_user != none) {
1078 if (g_restoring_live_from_cd) {
1079 if (bkpinfo->backup_media_type != media_specified_by_user) {
1080 log_msg(2,
1081 "bkpinfo->backup_media_type != media_specified_by_user, so I'd better ask :)");
1082 interactively_obtain_media_parameters_from_user(FALSE);
1083 media_specified_by_user = bkpinfo->backup_media_type;
1084 get_cfg_file_from_archive();
1085 /*
1086 if (media_specified_by_user != cdr && media_specified_by_user == cdrw)
1087 { g_restoring_live_from_cd = FALSE; }
1088 */
1089 }
1090 }
1091 bkpinfo->backup_media_type = media_specified_by_user;
1092}
1093g_backup_media_type = bkpinfo->backup_media_type;
1094paranoid_free(value);
1095paranoid_free(tmp);
1096return (0);
1097
1098}
1099
1100/**************************************************************************
1101*END_READ_CFG_FILE_INTO_BKPINFO *
1102**************************************************************************/
1103
1104
1105
1106
1107/**
1108 * Allow the user to edit the filelist and biggielist.
1109 * The filelist is unlinked after it is read.
1110 * @param bkpinfo The backup information structure. Fields used:
1111 * - @c bkpinfo->backup_media_type
1112 * - @c bkpinfo->isodir
1113 * - @c bkpinfo->media_device
1114 * - @c bkpinfo->tmpdir
1115 * @return The filelist structure containing the information read from disk.
1116 */
1117struct
1118s_node *process_filelist_and_biggielist()
1119{
1120struct s_node *filelist;
1121
1122/** add mallocs**/
1123char *command = NULL;
1124char *tmp;
1125char *tmp1 = NULL;
1126int res = 0;
1127pid_t pid;
1128bool extract_mountlist_stub = FALSE;
1129
1130assert(bkpinfo != NULL);
1131malloc_string(tmp);
1132
1133/* If those files already exist, do not overwrite them later on */
1134if (does_file_exist("/"MOUNTLIST_FNAME_STUB)) {
1135 extract_mountlist_stub = FALSE;
1136} else {
1137 extract_mountlist_stub = TRUE;
1138}
1139
1140if (does_file_exist(g_filelist_full)
1141&& does_file_exist(g_biggielist_txt)) {
1142 log_msg(1, "%s exists", g_filelist_full);
1143 log_msg(1, "%s exists", g_biggielist_txt);
1144 log_msg(2,
1145 "Filelist and biggielist already recovered from media. Yay!");
1146} else {
1147 getcwd(tmp, MAX_STR_LEN);
1148 chdir(bkpinfo->tmpdir);
1149 log_msg(1, "chdir(%s)", bkpinfo->tmpdir);
1150 log_to_screen("Extracting filelist and biggielist from media...");
1151 unlink("/tmp/filelist.full");
1152 unlink(FILELIST_FULL_STUB);
1153 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
1154 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);
1155 log_msg(1, "tarcommand = %s", command);
1156 run_program_and_log_output(command, 1);
1157 mr_free(command);
1158
1159 if (!does_file_exist(FILELIST_FULL_STUB)) {
1160 /* Doing that allow us to remain compatible with pre-2.2.5 versions */
1161 log_msg(2, "pre-2.2.4 compatible mode on");
1162 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);
1163 log_msg(1, "tarcommand = %s", command);
1164 run_program_and_log_output(command, 1);
1165 mr_free(command);
1166 }
1167 } else {
1168 log_msg(2, "Calling insist_on_this_cd_number; bkpinfo->isodir=%s", bkpinfo->isodir);
1169 insist_on_this_cd_number(1);
1170 log_msg(2, "Back from iotcn");
1171 run_program_and_log_output("mount", 1);
1172 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);
1173
1174 log_msg(1, "tarcommand = %s", command);
1175 run_program_and_log_output(command, 1);
1176 mr_free(command);
1177
1178 if (!does_file_exist(FILELIST_FULL_STUB)) {
1179 /* Doing that allow us to remain compatible with pre-2.2.5 versions */
1180 log_msg(2, "pre-2.2.4 compatible mode on");
1181 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);
1182
1183 log_msg(1, "tarcommand = %s", command);
1184 run_program_and_log_output(command, 1);
1185 mr_free(command);
1186 }
1187 if (!does_file_exist(BIGGIELIST_TXT_STUB)) {
1188 fatal_error
1189 ("all.tar.gz did not include " BIGGIELIST_TXT_STUB);
1190 }
1191 if (!does_file_exist(FILELIST_FULL_STUB)) {
1192 fatal_error
1193 ("all.tar.gz did not include " FILELIST_FULL_STUB);
1194 }
1195 }
1196 mr_asprintf(command, "cp -f %s %s", MONDO_CFG_FILE_STUB, g_mondo_cfg_file);
1197 run_program_and_log_output(command, FALSE);
1198 mr_free(command);
1199
1200 mr_asprintf(command, "cp -f %s/%s %s", bkpinfo->tmpdir, BIGGIELIST_TXT_STUB, g_biggielist_txt);
1201 log_msg(1, "command = %s", command);
1202 paranoid_system(command);
1203 mr_free(command);
1204
1205 mr_asprintf(command, "ln -sf %s/%s %s", bkpinfo->tmpdir, FILELIST_FULL_STUB, g_filelist_full);
1206 log_msg(1, "command = %s", command);
1207 paranoid_system(command);
1208 mr_free(command);
1209}
1210
1211if (am_I_in_disaster_recovery_mode()
1212 &&
1213 /* If it was there, do not overwrite it */
1214 (extract_mountlist_stub)
1215 &&
1216 ask_me_yes_or_no("Do you want to retrieve the mountlist as well?")) {
1217 mr_asprintf(command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB, bkpinfo->tmpdir);
1218 paranoid_system(command);
1219 mr_free(command);
1220 }
1221
1222 chdir(tmp);
1223
1224 if (!does_file_exist(g_biggielist_txt)) {
1225 log_msg(1, "Warning - %s not found", g_biggielist_txt);
1226 }
1227 if (!does_file_exist(g_filelist_full)) {
1228 log_msg(1, "Warning - %s does not exist", g_filelist_full);
1229 }
1230// popup_and_OK("Wonderful.");
1231
1232 log_msg(2, "Forking");
1233 pid = fork();
1234 switch (pid) {
1235 case -1:
1236 fatal_error("Forking error");
1237 break;
1238
1239 case 0:
1240 log_to_screen("Pre-processing filelist");
1241 if (!does_file_exist(g_biggielist_txt)) {
1242 mr_asprintf(command, "echo -n > %s", g_biggielist_txt);
1243 paranoid_system(command);
1244 mr_free(command);
1245 }
1246 mr_asprintf(command, "grep -E '^/dev/.*' %s > %s", g_biggielist_txt, g_filelist_imagedevs);
1247 paranoid_system(command);
1248 mr_free(command);
1249 exit(0);
1250 break;
1251
1252 default:
1253 open_evalcall_form("Pre-processing filelist");
1254 while (!waitpid(pid, (int *) 0, WNOHANG)) {
1255 usleep(100000);
1256 update_evalcall_form(0);
1257 }
1258 }
1259 close_evalcall_form();
1260
1261 log_msg(3, "loading filelist");
1262 filelist = load_filelist(g_filelist_full);
1263 log_msg(3, "deleting original filelist");
1264 unlink(g_filelist_full);
1265 if (g_text_mode) {
1266 printf("Restore which directory? --> ");
1267 mr_getline(tmp1, stdin);
1268 toggle_path_selection(filelist, tmp1, TRUE);
1269 if (strlen(tmp1) == 0) {
1270 res = 1;
1271 } else {
1272 res = 0;
1273 }
1274 mr_free(tmp1);
1275 } else {
1276 res = edit_filelist(filelist);
1277 }
1278 if (res) {
1279 log_msg(2, "User hit 'cancel'. Freeing filelist and aborting.");
1280 free_filelist(filelist);
1281 return (NULL);
1282 }
1283 ask_about_these_imagedevs(g_filelist_imagedevs, g_imagedevs_restthese);
1284 close_evalcall_form();
1285
1286 // NB: It's not necessary to add g_biggielist_txt to the filelist.full
1287 // file. The filelist.full file already contains the filename of EVERY
1288 // file backed up - regular and biggie files.
1289
1290 // However, we do want to make sure the imagedevs selected by the user
1291 // are flagged for restoring.
1292 if (length_of_file(g_imagedevs_restthese) > 2) {
1293 add_list_of_files_to_filelist(filelist, g_imagedevs_restthese,
1294 TRUE);
1295 }
1296
1297 paranoid_free(tmp);
1298 return (filelist);
1299}
1300
1301/**************************************************************************
1302 *END_ PROCESS_FILELIST_AND_BIGGIELIST *
1303 **************************************************************************/
1304
1305
1306
1307
1308/**
1309 * Make a backup copy of <tt>path_root</tt>/<tt>filename</tt>.
1310 * The backup filename is the filename of the original with ".pristine" added.
1311 * @param path_root The place where the filesystem is mounted (e.g. MNT_RESTORING).
1312 * @param filename The filename (absolute path) within @p path_root.
1313 * @return 0 for success, nonzero for failure.
1314 */
1315int backup_crucial_file(char *path_root, char *filename)
1316{
1317 char *tmp = NULL;
1318 char *command = NULL;
1319 int res;
1320
1321 assert(path_root != NULL);
1322 assert_string_is_neither_NULL_nor_zerolength(filename);
1323
1324 mr_asprintf(tmp, "%s/%s", path_root, filename);
1325 mr_asprintf(command, "cp -f %s %s.pristine", tmp, tmp);
1326 mr_free(tmp);
1327
1328 res = run_program_and_log_output(command, 5);
1329 mr_free(command);
1330 return (res);
1331}
1332
1333void offer_to_make_initrd() {
1334
1335if (bkpinfo->restore_mode != nuke) {
1336 if (ask_me_yes_or_no
1337 ("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 ?")) {
1338 log_msg(1,"Launching shell for manual initrd recreation");
1339 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.");
1340 mvaddstr_and_log_it(g_currentY, 0, "Modifying initrd...");
1341 if (!g_text_mode) {
1342 newtSuspend();
1343 }
1344 (void)system("chroot " MNT_RESTORING);
1345 if (!g_text_mode) {
1346 newtResume();
1347 }
1348 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1349 } else {
1350 return;
1351 }
1352} else {
1353 log_to_screen("Non-interactive mode: no way to give you the keyboard so that you re-generate your initrd. Hope it's OK");
1354 log_msg(1,"Non-interactive mode: no way to give you the keyboard so that you re-generate your initrd. Hope it's OK");
1355}
1356}
1357
1358
1359/**
1360 * Install the user's boot loader in the MBR.
1361 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported.
1362 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1363 * @return 0 for success, nonzero for failure.
1364 */
1365int run_boot_loader(bool offer_to_hack_scripts)
1366{
1367 int res;
1368 int retval = 0;
1369
1370 /** malloc *******/
1371 char *device = NULL;
1372 char *name = NULL;
1373 char *cmd = NULL;
1374
1375 /* In order to have a working bootloader, we need to have all devices
1376 * ready in the chroot. If they are not there (udev) then copy them from
1377 * the current /dev location
1378 */
1379 mr_asprintf(cmd,"tar cf - /dev | ( cd %s ; tar xf - )",MNT_RESTORING);
1380 run_program_and_log_output(cmd, 3);
1381 paranoid_free(cmd);
1382
1383 backup_crucial_file(MNT_RESTORING, "/etc/fstab");
1384 backup_crucial_file(MNT_RESTORING, "/boot/grub/menu.lst");
1385 backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf");
1386 backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf");
1387 backup_crucial_file(MNT_RESTORING, "/boot/grub/device.map");
1388 backup_crucial_file(MNT_RESTORING, "/etc/mtab");
1389 device = read_cfg_var(g_mondo_cfg_file, "bootloader.device");
1390 name = read_cfg_var(g_mondo_cfg_file, "bootloader.name");
1391 log_msg(2, "run_boot_loader: device='%s', name='%s'", device, name);
1392 sync();
1393
1394 offer_to_make_initrd();
1395 if (!strcmp(name, "LILO")) {
1396 res = run_lilo(offer_to_hack_scripts);
1397 } else if (!strcmp(name, "ELILO")) {
1398 res = run_elilo(offer_to_hack_scripts);
1399 } else if (!strcmp(name, "GRUB")) {
1400 res = run_grub(offer_to_hack_scripts, device);
1401 } else if (!strcmp(name, "RAW")) {
1402 res = run_raw_mbr(offer_to_hack_scripts, device);
1403 }
1404#ifdef __FreeBSD__
1405 else if (!strcmp(name, "BOOT0")) {
1406 mr_asprintf(tmp, "boot0cfg -B %s", device);
1407 res = run_program_and_log_output(tmp, FALSE);
1408 paranoid_free(tmp);
1409 } else {
1410 mr_asprintf(tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device);
1411 if (!system(tmp)) {
1412 mr_free(tmp);
1413 mr_asprintf(tmp, MNT_RESTORING "/sbin/fdisk -B %s", device);
1414 res = run_program_and_log_output(tmp, 3);
1415 } else {
1416 log_msg(1, "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");
1417 }
1418 mr_free(tmp);
1419 }
1420#else
1421 else {
1422 log_to_screen
1423 ("Unable to determine type of boot loader. Defaulting to LILO.");
1424 res = run_lilo(offer_to_hack_scripts);
1425 }
1426#endif
1427 mr_free(device);
1428 mr_free(name);
1429
1430 retval += res;
1431 if (res) {
1432 log_to_screen("Your boot loader returned an error");
1433 } else {
1434 log_to_screen("Your boot loader ran OK");
1435 }
1436 return (retval);
1437}
1438
1439/**************************************************************************
1440 *END_ RUN_BOOT_LOADER *
1441 **************************************************************************/
1442
1443
1444
1445/**
1446 * Attempt to find the user's editor.
1447 * @return The editor found ("vi" if none could be found).
1448 * @note The returned string points to static storage that will be overwritten with each call.
1449 */
1450char *find_my_editor(void) {
1451
1452 char *tmp = NULL;
1453 static char output[MAX_STR_LEN];
1454
1455 tmp = find_home_of_exe("pico");
1456 if (tmp) {
1457 strcpy(output, "pico");
1458 } else {
1459 mr_free(tmp);
1460 tmp = find_home_of_exe("nano");
1461 if (tmp) {
1462 strcpy(output, "nano");
1463 } else {
1464 mr_free(tmp);
1465 tmp = find_home_of_exe("joe");
1466 if (tmp) {
1467 strcpy(output, "joe");
1468 } else {
1469 strcpy(output, "vi");
1470 }
1471 }
1472 }
1473 mr_free(tmp);
1474
1475 tmp = find_home_of_exe(output);
1476 if (!tmp) {
1477 log_msg(2, " (find_my_editor) --- warning - %s not found", output);
1478 }
1479 mr_free(tmp);
1480 return (output);
1481}
1482
1483
1484/**
1485 * Install GRUB on @p bd.
1486 * @param offer_to_run_stabgrub If TRUE, then offer to hack the user's fstab for them.
1487 * @param bd The boot device where GRUB is installed.
1488 * @return 0 for success, nonzero for failure.
1489 */
1490int run_grub(bool offer_to_run_stabgrub, char *bd)
1491{
1492 /** malloc **/
1493 char *command = NULL;
1494 char *boot_device = NULL;
1495 char *rootdev;
1496 char *rootdrive;
1497 char *conffile;
1498 char *tmp = NULL;
1499 char *editor = NULL;
1500 char *p = NULL;
1501
1502 int res = 0;
1503 bool done;
1504
1505 malloc_string(rootdev);
1506 malloc_string(rootdrive);
1507 malloc_string(conffile);
1508 assert_string_is_neither_NULL_nor_zerolength(bd);
1509 mr_asprintf(boot_device, "%s", bd);
1510
1511 if (offer_to_run_stabgrub
1512 && ask_me_yes_or_no("Did you change the mountlist or cloned the system ?")) {
1513 /* interactive mode */
1514 mvaddstr_and_log_it(g_currentY,
1515 0,
1516 "Modifying fstab, mtab, device.map and menu.lst, and running GRUB... ");
1517 for (done = FALSE; !done;) {
1518 p = popup_and_get_string("Boot device", "Please confirm/enter the boot device. If in doubt, try /dev/hda", boot_device);
1519 if (p == NULL) {
1520 done = TRUE;
1521 mr_free(p);
1522 /* we want some warnings later on */
1523 res = 1;
1524 continue;
1525 }
1526 mr_asprintf(command, "stabgrub-me %s", p);
1527 mr_free(p);
1528
1529 res = run_program_and_log_output(command, 1);
1530 mr_free(command);
1531
1532 if (res) {
1533 popup_and_OK
1534 ("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.");
1535 newtSuspend();
1536 system("chroot " MNT_RESTORING);
1537 newtResume();
1538 popup_and_OK("Thank you.");
1539 } else {
1540 done = TRUE;
1541 }
1542 popup_and_OK("You will now edit fstab, mtab, device.map and menu.lst");
1543 if (!g_text_mode) {
1544 newtSuspend();
1545 }
1546 mr_asprintf(editor, "%s", find_my_editor());
1547
1548 mr_asprintf(tmp, "chroot %s %s /etc/fstab", MNT_RESTORING, editor);
1549 paranoid_system(tmp);
1550 mr_free(tmp);
1551
1552 mr_asprintf(tmp, "chroot %s %s /etc/mtab", MNT_RESTORING, editor);
1553 paranoid_system(tmp);
1554 mr_free(tmp);
1555
1556 mr_asprintf(tmp, "chroot %s %s /boot/grub/menu.lst", MNT_RESTORING, editor);
1557 paranoid_system(tmp);
1558 mr_free(tmp);
1559
1560 mr_asprintf(tmp, "chroot %s %s /boot/grub/device.map", MNT_RESTORING, editor);
1561 paranoid_system(tmp);
1562 mr_free(tmp);
1563 mr_free(editor);
1564
1565 if (!g_text_mode) {
1566 newtResume();
1567 }
1568 }
1569 } else {
1570 /* nuke mode */
1571 if (!run_program_and_log_output("which grub-MR", FALSE)) {
1572 log_msg(1, "Yay! grub-MR found...");
1573 mr_asprintf(command, "grub-MR %s /tmp/mountlist.txt", boot_device);
1574 log_msg(1, "command = %s", command);
1575 } else {
1576 mr_asprintf(command, "chroot " MNT_RESTORING " grub-install %s", boot_device);
1577 log_msg(1, "WARNING - grub-MR not found; using grub-install");
1578 }
1579 mvaddstr_and_log_it(g_currentY,
1580 0,
1581 "Running GRUB... ");
1582 log_it("%s",command);
1583 res = run_program_and_log_output(command, 1);
1584 mr_free(command);
1585
1586 if (res) {
1587 popup_and_OK
1588 ("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.");
1589 newtSuspend();
1590 system("chroot " MNT_RESTORING);
1591 newtResume();
1592 popup_and_OK("Thank you.");
1593 }
1594 }
1595 mr_free(boot_device);
1596
1597 if (res) {
1598 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1599 log_to_screen
1600 ("GRUB ran w/error(s). See %s for more info.", MONDO_LOGFILE);
1601 log_msg(1, "Type:-");
1602 log_msg(1, " mount-me");
1603 log_msg(1, " chroot " MNT_RESTORING);
1604 log_msg(1, " mount /boot");
1605 log_msg(1, " grub-install '(hd0)'");
1606 log_msg(1, " exit");
1607 log_msg(1, " unmount-me");
1608 log_msg(1,
1609 "If you're really stuck, please e-mail the mailing list.");
1610 } else {
1611 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1612 }
1613 paranoid_free(rootdev);
1614 paranoid_free(rootdrive);
1615 paranoid_free(conffile);
1616
1617 return (res);
1618}
1619
1620/**************************************************************************
1621 *END_RUN_GRUB *
1622 **************************************************************************/
1623
1624
1625/**
1626 * Install ELILO on the user's boot drive (determined by elilo.conf).
1627 * @param offer_to_run_stabelilo If TRUE, then offer to hack the user's fstab for them.
1628 * @return 0 for success, nonzero for failure.
1629 */
1630int run_elilo(bool offer_to_run_stabelilo)
1631{
1632 /** malloc **/
1633 char *command = NULL;
1634 char *tmp = NULL;
1635 char *editor = NULL;
1636
1637 int res;
1638 int done;
1639
1640 if (offer_to_run_stabelilo
1641 && ask_me_yes_or_no("Did you change the mountlist or cloned the system ?"))
1642
1643 /* interactive mode */
1644 {
1645 mvaddstr_and_log_it(g_currentY,
1646 0,
1647 "Modifying fstab and elilo.conf... ");
1648 mr_asprintf(command, "stabelilo-me");
1649 res = run_program_and_log_output(command, 3);
1650 mr_free(command);
1651
1652 if (res) {
1653 popup_and_OK
1654 ("You will now edit fstab and elilo.conf, to make sure they match your new mountlist.");
1655 for (done = FALSE; !done;) {
1656 if (!g_text_mode) {
1657 newtSuspend();
1658 }
1659 mr_asprintf(editor, "%s", find_my_editor());
1660
1661 mr_asprintf(tmp, "chroot %s %s /etc/fstab", MNT_RESTORING, editor);
1662 paranoid_system(tmp);
1663 mr_free(tmp);
1664
1665 mr_asprintf(tmp, "chroot %s %s /etc/elilo.conf", MNT_RESTORING, editor);
1666 paranoid_system(tmp);
1667 mr_free(tmp);
1668
1669 mr_free(editor);
1670
1671 if (!g_text_mode) {
1672 newtResume();
1673 }
1674// newtCls();
1675 if (ask_me_yes_or_no("Edit them again?")) {
1676 continue;
1677 }
1678 done = TRUE;
1679 }
1680 } else {
1681 log_to_screen("elilo.conf and fstab were modified OK");
1682 }
1683 } else
1684 /* nuke mode */
1685 {
1686 res = TRUE;
1687 }
1688 return (res);
1689}
1690
1691/**************************************************************************
1692 *END_RUN_ELILO *
1693 **************************************************************************/
1694
1695
1696/**
1697 * Install LILO on the user's boot drive (determined by /etc/lilo.conf).
1698 * @param offer_to_run_stablilo If TRUE, then offer to hack the user's fstab for them.
1699 * @return 0 for success, nonzero for failure.
1700 */
1701int run_lilo(bool offer_to_run_stablilo)
1702{
1703 /** malloc **/
1704 char *command = NULL;
1705 char *tmp = NULL;
1706 char *editor = NULL;
1707
1708 int res;
1709 int done;
1710 bool run_lilo_M = FALSE;
1711
1712 if (!run_program_and_log_output
1713 ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) {
1714 run_lilo_M = TRUE;
1715 }
1716
1717 if (offer_to_run_stablilo
1718 && ask_me_yes_or_no("Did you change the mountlist or cloned the system ?"))
1719
1720 /* interactive mode */
1721 {
1722 mvaddstr_and_log_it(g_currentY,
1723 0,
1724 "Modifying fstab and lilo.conf, and running LILO... ");
1725 mr_asprintf(command, "stablilo-me");
1726 res = run_program_and_log_output(command, 3);
1727 mr_free(command);
1728
1729 if (res) {
1730 popup_and_OK
1731 ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist.");
1732 for (done = FALSE; !done;) {
1733 if (!g_text_mode) {
1734 newtSuspend();
1735 }
1736 mr_asprintf(editor, "%s", find_my_editor());
1737
1738 mr_asprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1739 paranoid_system(tmp);
1740 mr_free(tmp);
1741
1742 mr_asprintf(tmp, "%s " MNT_RESTORING "/etc/lilo.conf", editor);
1743 paranoid_system(tmp);
1744 mr_free(tmp);
1745
1746 mr_free(editor);
1747
1748 if (!g_text_mode) {
1749 newtResume();
1750 }
1751// newtCls();
1752 if (ask_me_yes_or_no("Edit them again?")) {
1753 continue;
1754 }
1755 res =
1756 run_program_and_log_output("chroot " MNT_RESTORING
1757 " lilo -L", 3);
1758 if (res) {
1759 res =
1760 run_program_and_log_output("chroot " MNT_RESTORING
1761 " lilo", 3);
1762 }
1763 if (res) {
1764 done =
1765 ask_me_yes_or_no
1766 ("LILO failed. Re-edit system files?");
1767 } else {
1768 done = TRUE;
1769 }
1770 }
1771 } else {
1772 log_to_screen("lilo.conf and fstab were modified OK");
1773 }
1774 } else
1775 /* nuke mode */
1776 {
1777 mvaddstr_and_log_it(g_currentY,
1778 0,
1779 "Running LILO... ");
1780 res =
1781 run_program_and_log_output("chroot " MNT_RESTORING " lilo -L",
1782 3);
1783 if (res) {
1784 res =
1785 run_program_and_log_output("chroot " MNT_RESTORING " lilo",
1786 3);
1787 }
1788 if (res) {
1789 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1790 log_to_screen
1791 ("Failed to re-jig fstab and/or lilo. Edit/run manually, please.");
1792 } else {
1793 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1794 }
1795 }
1796 if (run_lilo_M) {
1797 run_program_and_log_output("chroot " MNT_RESTORING
1798 " lilo -M /dev/hda", 3);
1799 run_program_and_log_output("chroot " MNT_RESTORING
1800 " lilo -M /dev/sda", 3);
1801 }
1802 return (res);
1803}
1804
1805/**************************************************************************
1806 *END_RUN_LILO *
1807 **************************************************************************/
1808
1809
1810/**
1811 * Install a raw MBR onto @p bd.
1812 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1813 * @param bd The device to copy the stored MBR to.
1814 * @return 0 for success, nonzero for failure.
1815 */
1816int run_raw_mbr(bool offer_to_hack_scripts, char *bd)
1817{
1818 /** malloc **/
1819 char *command = NULL;
1820 char *boot_device = NULL;
1821 char *tmp = NULL;
1822 char *editor;
1823 char *p = NULL;
1824 int res;
1825 int done;
1826
1827 assert_string_is_neither_NULL_nor_zerolength(bd);
1828
1829 mr_asprintf(boot_device, "%s", bd);
1830
1831 if (offer_to_hack_scripts
1832 && ask_me_yes_or_no("Did you change the mountlist or cloned the system ?")) {
1833 /* interactive mode */
1834 mvaddstr_and_log_it(g_currentY, 0,
1835 "Modifying fstab and restoring MBR... ");
1836 for (done = FALSE; !done;) {
1837 if (!run_program_and_log_output("which vi", FALSE)) {
1838 popup_and_OK("You will now edit fstab");
1839 if (!g_text_mode) {
1840 newtSuspend();
1841 }
1842 mr_asprintf(editor, "%s", find_my_editor());
1843 mr_asprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1844 mr_free(editor);
1845
1846 paranoid_system(tmp);
1847 mr_free(tmp);
1848 if (!g_text_mode) {
1849 newtResume();
1850 }
1851 }
1852 p = popup_and_get_string("Boot device", "Please confirm/enter the boot device. If in doubt, try /dev/hda", boot_device);
1853 if (p == NULL) {
1854 done = TRUE;
1855 mr_free(p);
1856 /* we want some warnings later on */
1857 res = 1;
1858 continue;
1859 }
1860 mr_asprintf(command, "stabraw-me %s", p);
1861 mr_free(p);
1862
1863 res = run_program_and_log_output(command, 3);
1864 mr_free(command);
1865
1866 if (res) {
1867 done = ask_me_yes_or_no("Modifications failed. Re-try?");
1868 } else {
1869 done = TRUE;
1870 }
1871 }
1872 } else {
1873 /* nuke mode */
1874 mr_asprintf(command, "raw-MR %s /tmp/mountlist.txt", boot_device);
1875 log_msg(2, "run_raw_mbr() --- command='%s'", command);
1876
1877 mvaddstr_and_log_it(g_currentY, 0,
1878 "Restoring MBR... ");
1879 res = run_program_and_log_output(command, 3);
1880 mr_free(command);
1881 }
1882 mr_free(boot_device);
1883
1884 if (res) {
1885 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1886 log_to_screen
1887 ("MBR+fstab processed w/error(s). See %s for more info.", MONDO_LOGFILE);
1888 } else {
1889 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1890 }
1891 return (res);
1892}
1893
1894/**************************************************************************
1895 *END_RUN_RAW_MBR *
1896 **************************************************************************/
1897
1898
1899
1900/**
1901 * malloc() and set sensible defaults for the mondorestore filename variables.
1902 * @param bkpinfo The backup information structure. Fields used:
1903 * - @c bkpinfo->tmpdir
1904 * - @c bkpinfo->disaster_recovery
1905 */
1906void setup_MR_global_filenames()
1907{
1908 assert(bkpinfo != NULL);
1909
1910 malloc_string(g_biggielist_txt);
1911 malloc_string(g_filelist_full);
1912 malloc_string(g_filelist_imagedevs);
1913 malloc_string(g_imagedevs_restthese);
1914 malloc_string(g_mondo_cfg_file);
1915 malloc_string(g_mountlist_fname);
1916 malloc_string(g_mondo_home);
1917
1918 sprintf(g_biggielist_txt, "%s/%s", bkpinfo->tmpdir, BIGGIELIST_TXT_STUB);
1919 sprintf(g_filelist_full, "%s/%s", bkpinfo->tmpdir, FILELIST_FULL_STUB);
1920 sprintf(g_filelist_imagedevs, "%s/tmp/filelist.imagedevs", bkpinfo->tmpdir);
1921 sprintf(g_imagedevs_restthese, "%s/tmp/imagedevs.restore-these", bkpinfo->tmpdir);
1922 if (bkpinfo->disaster_recovery) {
1923 sprintf(g_mondo_cfg_file, "/%s", MONDO_CFG_FILE_STUB);
1924 sprintf(g_mountlist_fname, "/%s", MOUNTLIST_FNAME_STUB);
1925 } else {
1926 sprintf(g_mondo_cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
1927 sprintf(g_mountlist_fname, "%s/%s", bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
1928 }
1929}
1930
1931/**************************************************************************
1932 *END_SET_GLOBAL_FILENAME *
1933 **************************************************************************/
1934
1935
1936/**
1937 * Copy @p input_file (containing the result of a compare) to @p output_file,
1938 * deleting spurious "changes" along the way.
1939 * @param output_file The output file to write with spurious changes removed.
1940 * @param input_file The input file, a list of changed files created by a compare.
1941 */
1942void streamline_changes_file(char *output_file, char *input_file)
1943{
1944 FILE *fin;
1945 FILE *fout;
1946 char *incoming = NULL;
1947
1948 assert_string_is_neither_NULL_nor_zerolength(output_file);
1949 assert_string_is_neither_NULL_nor_zerolength(input_file);
1950
1951 if (!(fin = fopen(input_file, "r"))) {
1952 log_OS_error(input_file);
1953 return;
1954 }
1955 if (!(fout = fopen(output_file, "w"))) {
1956 fatal_error("cannot open output_file");
1957 }
1958 for (mr_getline(incoming, fin); !feof(fin); mr_getline(incoming, fin)) {
1959 if (strncmp(incoming, "etc/adjtime", 11)
1960 && strncmp(incoming, "etc/mtab", 8)
1961 && strncmp(incoming, "tmp/", 4)
1962 && strncmp(incoming, "boot/map", 8)
1963 && !strstr(incoming, "incheckentry")
1964 && strncmp(incoming, "etc/mail/statistics", 19)
1965 && strncmp(incoming, "var/", 4))
1966 fprintf(fout, "%s", incoming); /* don't need \n here, for some reason.. */
1967 mr_free(incoming);
1968 }
1969 mr_free(incoming);
1970 paranoid_fclose(fout);
1971 paranoid_fclose(fin);
1972}
1973
1974/**************************************************************************
1975 *END_STREAMLINE_CHANGES_FILE *
1976 **************************************************************************/
1977
1978
1979/**
1980 * Give the user twenty seconds to press Ctrl-Alt-Del before we nuke their drives.
1981 */
1982void twenty_seconds_til_yikes()
1983{
1984 int i;
1985 /* MALLOC * */
1986 char *tmp = NULL;
1987
1988 if (does_file_exist("/tmp/NOPAUSE")) {
1989 return;
1990 }
1991 open_progress_form("CAUTION",
1992 "Be advised: I am about to ERASE your hard disk(s)!",
1993 "You may press Ctrl+Alt+Del to abort safely.",
1994 "", 20);
1995 for (i = 0; i < 20; i++) {
1996 g_current_progress = i;
1997 mr_asprintf(tmp, "You have %d seconds left to abort.", 20 - i);
1998 update_progress_form(tmp);
1999 mr_free(tmp);
2000 sleep(1);
2001 }
2002 close_progress_form();
2003}
2004
2005/**************************************************************************
2006 *END_TWENTY_SECONDS_TIL_YIKES *
2007 **************************************************************************/
2008
2009
2010/**
2011 * Unmount all devices in @p p_external_copy_of_mountlist.
2012 * @param p_external_copy_of_mountlist The mountlist to guide the devices to unmount.
2013 * @return 0 for success, nonzero for failure.
2014 */
2015int unmount_all_devices(struct mountlist_itself
2016 *p_external_copy_of_mountlist)
2017{
2018 struct mountlist_itself *mountlist;
2019 int retval = 0, lino, res = 0, i;
2020 char *command = NULL;
2021 char *tmp = NULL;
2022
2023 assert(p_external_copy_of_mountlist != NULL);
2024
2025 mountlist = malloc(sizeof(struct mountlist_itself));
2026 memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
2027 sizeof(struct mountlist_itself));
2028 sort_mountlist_by_mountpoint(mountlist, 0);
2029
2030 run_program_and_log_output("df -m -P", 3);
2031 mvaddstr_and_log_it(g_currentY, 0, "Unmounting devices ");
2032 open_progress_form("Unmounting devices",
2033 "Unmounting all devices that were mounted,",
2034 "in preparation for the post-restoration reboot.",
2035 "", mountlist->entries);
2036 chdir("/");
2037 for (i = 0;
2038 i < 10
2039 &&
2040 run_program_and_log_output
2041 ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
2042 i++) {
2043 sleep(1);
2044 log_msg(2, "Waiting for buffer() to finish");
2045 }
2046
2047 sync();
2048
2049 mr_asprintf(tmp, "cp -f %s " MNT_RESTORING "/var/log", MONDO_LOGFILE);
2050 if (run_program_and_log_output(tmp, FALSE)) {
2051 log_msg(1,
2052 "Error. Failed to copy log to PC's /var/log dir. (Mounted read-only?)");
2053 }
2054 paranoid_free(tmp);
2055 if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2056 run_program_and_log_output("mkdir -p " MNT_RESTORING
2057 "/mnt/.boot.d", 5);
2058 }
2059
2060 /* Unmounting the local /proc and /sys first */
2061 run_program_and_log_output("umount " MNT_RESTORING "/proc",3);
2062 run_program_and_log_output("umount " MNT_RESTORING "/sys",3);
2063
2064 for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2065 if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2066 continue;
2067 }
2068 mr_asprintf(tmp, "Unmounting device %s ", mountlist->el[lino].device);
2069 update_progress_form(tmp);
2070
2071 if (is_this_device_mounted(mountlist->el[lino].device)) {
2072 if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
2073 mr_asprintf(command, "swapoff %s", mountlist->el[lino].device);
2074 } else {
2075 if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
2076 mr_asprintf(command, "umount %s/", MNT_RESTORING);
2077 log_msg(3,
2078 "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2079 } else {
2080 mr_asprintf(command, "umount " MNT_RESTORING "%s", mountlist->el[lino].mountpoint);
2081
2082 /* To support latest Ubuntu where /var is a separate FS
2083 * Cf: http://linux.derkeiler.com/Mailing-Lists/Ubuntu/2007-04/msg01319.html
2084 * we need to create some dirs under the real / before unmounting it */
2085 if (!strcmp(mountlist->el[lino].mountpoint, "/")) {
2086 run_program_and_log_output("mkdir -p " MNT_RESTORING "/var/lock", FALSE);
2087 run_program_and_log_output("mkdir -p " MNT_RESTORING "/var/run", FALSE);
2088 }
2089 }
2090 }
2091 log_msg(10, "The 'umount' command is '%s'", command);
2092 res = run_program_and_log_output(command, 3);
2093 mr_free(command);
2094 } else {
2095 mr_strcat(tmp, "...not mounted anyway :-) OK");
2096 res = 0;
2097 }
2098 g_current_progress++;
2099 if (res) {
2100 mr_strcat(tmp, "...Failed");
2101 retval++;
2102 log_to_screen(tmp);
2103 } else {
2104 log_msg(2, tmp);
2105 }
2106 paranoid_free(tmp);
2107 }
2108 close_progress_form();
2109 if (retval) {
2110 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2111 } else {
2112 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2113 }
2114 if (retval) {
2115 log_to_screen("Unable to unmount some of your partitions.");
2116 } else {
2117 log_to_screen("All partitions were unmounted OK.");
2118 }
2119 free(mountlist);
2120 return (retval);
2121}
2122
2123/**************************************************************************
2124 *END_UNMOUNT_ALL_DEVICES *
2125 **************************************************************************/
2126
2127
2128
2129/**
2130 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2131 * to the ./tmp/ directory.
2132 * @param dev The tape device to read from.
2133 * @return 0 for success, nonzero for failure.
2134 */
2135int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2136{
2137 char *command = NULL;
2138 int res = 0;
2139
2140 if (bkpinfo->use_obdr) {
2141 skip_obdr();
2142 } else {
2143 // BCO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
2144 set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size);
2145 }
2146
2147 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);
2148 log_msg(2, "command = '%s'", command);
2149 res = run_program_and_log_output(command, -1);
2150 mr_free(command);
2151
2152 if (res != 0) {
2153 if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2154 res = 0;
2155 } else {
2156 /* Doing that allow us to remain compatible with pre-2.2.5 versions */
2157 log_msg(2, "pre-2.2.4 compatible mode on");
2158 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);
2159 log_msg(2, "command = '%s'", command);
2160 res = run_program_and_log_output(command, -1);
2161 mr_free(command);
2162
2163 if ((res != 0) && (does_file_exist(MONDO_CFG_FILE_STUB))) {
2164 res = 0;
2165 }
2166 }
2167 }
2168 return (res);
2169}
2170
2171
2172
2173/**
2174 * Get the configuration file from the floppy, tape, or CD.
2175 * @param bkpinfo The backup information structure. Fields used:
2176 * - @c bkpinfo->backup_media_type
2177 * - @c bkpinfo->media_device
2178 * - @c bkpinfo->tmpdir
2179 * @return 0 for success, nonzero for failure.
2180 */
2181int get_cfg_file_from_archive()
2182{
2183 int retval = 0;
2184
2185 /** malloc *****/
2186 char *device;
2187 char *command = NULL;
2188 char *cfg_file = NULL;
2189 char *mounted_cfgf_path;
2190 char *tmp = NULL;
2191 char *tmp1 = NULL;
2192 char *mountpt = NULL;
2193 char *ramdisk_fname;
2194 char *mountlist_file = NULL;
2195 bool extract_mountlist_stub = FALSE;
2196 bool extract_i_want_my_lvm = FALSE;
2197
2198 bool try_plan_B;
2199
2200 assert(bkpinfo != NULL);
2201 malloc_string(mounted_cfgf_path);
2202 malloc_string(ramdisk_fname);
2203 malloc_string(device);
2204 log_msg(2, "gcffa --- starting");
2205 log_to_screen("I'm thinking...");
2206 mr_asprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
2207 device[0] = '\0';
2208 chdir(bkpinfo->tmpdir);
2209 mr_asprintf(cfg_file, "%s", MONDO_CFG_FILE_STUB);
2210 unlink(cfg_file); // cfg_file[] is missing the '/' at the start, FYI, by intent
2211 mr_free(cfg_file);
2212
2213 unlink(FILELIST_FULL_STUB);
2214 unlink(BIGGIELIST_TXT_STUB);
2215 mr_asprintf(command, "mkdir -p %s", mountpt);
2216 run_program_and_log_output(command, FALSE);
2217 mr_free(command);
2218
2219 mr_asprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2220 mr_asprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2221 log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
2222 mr_free(mountpt);
2223
2224 if (!does_file_exist(cfg_file)) {
2225 log_msg(2, "gcffa --- we don't have cfg file yet.");
2226 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2227 try_plan_B = TRUE;
2228 } else {
2229 log_msg(2, "gcffa --- calling mount_media now :)");
2230 if (!mount_media()) {
2231 log_msg(2,
2232 "gcffa --- managed to mount CD; so, no need for Plan B");
2233 try_plan_B = FALSE;
2234 } else {
2235 try_plan_B = TRUE;
2236 }
2237 if (what_number_cd_is_this() > 1) {
2238 insist_on_this_cd_number((g_current_media_number = 1));
2239 }
2240 }
2241 if (try_plan_B) {
2242 log_msg(2, "gcffa --- OK, switching to Plan B");
2243 chdir(bkpinfo->tmpdir);
2244 run_program_and_log_output("mkdir -p tmp", FALSE);
2245
2246 if (! bkpinfo->media_device) {
2247 mr_asprintf(bkpinfo->media_device, "/dev/st0");
2248 log_msg(2, "media_device is blank; assuming %s", bkpinfo->media_device);
2249 }
2250 mr_asprintf(tmp, "%s", bkpinfo->media_device);
2251 if (extract_cfg_file_and_mountlist_from_tape_dev (bkpinfo->media_device)) {
2252 mr_free(bkpinfo->media_device);
2253 mr_asprintf(bkpinfo->media_device, "/dev/st0");
2254 if (extract_cfg_file_and_mountlist_from_tape_dev (bkpinfo->media_device)) {
2255 mr_free(bkpinfo->media_device);
2256 mr_asprintf(bkpinfo->media_device, "/dev/osst0");
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/ht0");
2260 if (extract_cfg_file_and_mountlist_from_tape_dev (bkpinfo->media_device)) {
2261 log_msg(3, "I tried lots of devices but none worked.");
2262 mr_free(bkpinfo->media_device);
2263 mr_asprintf(bkpinfo->media_device, "%s", tmp);
2264 }
2265 }
2266 }
2267 }
2268 mr_free(tmp);
2269
2270 if (!does_file_exist("tmp/mondo-restore.cfg")) {
2271 log_to_screen("Cannot find config info on media");
2272 return (1);
2273 }
2274 } else {
2275 if (does_file_exist("/"MOUNTLIST_FNAME_STUB)) {
2276 extract_mountlist_stub = FALSE;
2277 } else {
2278 extract_mountlist_stub = TRUE;
2279 }
2280 if (does_file_exist("/"IWANTMYLVM_STUB)) {
2281 extract_i_want_my_lvm = FALSE;
2282 } else {
2283 extract_i_want_my_lvm = TRUE;
2284 }
2285
2286 log_msg(2,
2287 "gcffa --- Plan B, a.k.a. untarring some file from all.tar.gz");
2288 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
2289 run_program_and_log_output(command, TRUE);
2290 mr_free(command);
2291
2292 if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2293 /* Doing that allow us to remain compatible with pre-2.2.5 versions */
2294 log_msg(2, "pre-2.2.4 compatible mode on");
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 fatal_error
2301 ("Please reinsert the disk/CD and try again.");
2302 }
2303 }
2304 }
2305 }
2306 if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2307 log_msg(1, "gcffa --- great! We've got the config file");
2308 tmp = call_program_and_get_last_line_of_output("pwd");
2309 mr_strcat(tmp, "/%s", MONDO_CFG_FILE_STUB);
2310 mr_asprintf(command, "cp -f %s %s", tmp, cfg_file);
2311 log_it("%s",command);
2312 if (strcmp(tmp, cfg_file) && run_program_and_log_output(command, 1)) {
2313 log_msg(1, "... but an error occurred when I tried to move it to %s", cfg_file);
2314 } else {
2315 log_msg(1, "... and I moved it successfully to %s", cfg_file);
2316 }
2317 mr_free(command);
2318
2319 tmp1 = call_program_and_get_last_line_of_output("pwd");
2320 mr_asprintf(command, "cp -f %s/%s %s", tmp1, MOUNTLIST_FNAME_STUB, mountlist_file);
2321 mr_free(tmp1);
2322
2323 log_it("%s",command);
2324 if (extract_mountlist_stub) {
2325 if (strcmp(tmp, cfg_file) && run_program_and_log_output(command, 1)) {
2326 log_msg(1, "Failed to get mountlist");
2327 } else {
2328 log_msg(1, "Got mountlist too");
2329
2330 mr_free(command);
2331 mr_asprintf(command, "cp -f %s %s", mountlist_file, g_mountlist_fname);
2332 if (run_program_and_log_output(command, 1)) {
2333 log_msg(1, "Failed to copy mountlist to /tmp");
2334 } else {
2335 log_msg(1, "Copied mountlist to /tmp as well OK");
2336 mr_free(command);
2337 mr_asprintf(command, "cp -f %s /tmp/",IWANTMYLVM_STUB);
2338 run_program_and_log_output(command, 1);
2339 }
2340 }
2341 }
2342 mr_free(tmp);
2343 mr_free(command);
2344 }
2345 run_program_and_log_output("umount " MNT_CDROM, FALSE);
2346 if (!does_file_exist(cfg_file)) {
2347 log_it("%s",cfg_file);
2348 log_msg(1, "%s not found", cfg_file);
2349 log_to_screen
2350 ("Oh dear. Unable to recover configuration file from boot disk");
2351 return (1);
2352 }
2353
2354 log_to_screen("Recovered mondo-restore.cfg");
2355 if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2356 log_to_screen("...but not mountlist.txt - a pity, really...");
2357 }
2358 else {
2359 /* Is this code really useful ??? */
2360 if (extract_mountlist_stub) {
2361 mr_asprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2362 run_program_and_log_output(command, FALSE);
2363 mr_free(command);
2364 }
2365 }
2366
2367 mr_asprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2368 mr_free(cfg_file);
2369
2370 run_program_and_log_output(command, FALSE);
2371 mr_free(command);
2372
2373 if (extract_mountlist_stub) {
2374 mr_asprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2375 run_program_and_log_output(command, FALSE);
2376 mr_free(command);
2377 }
2378 mr_free(mountlist_file);
2379
2380 mr_asprintf(command, "cp -f etc/raidtab /etc/");
2381 run_program_and_log_output(command, FALSE);
2382 mr_free(command);
2383
2384 if (extract_i_want_my_lvm) {
2385 mr_asprintf(command, "cp -f %s /tmp/",IWANTMYLVM_STUB);
2386 run_program_and_log_output(command, FALSE);
2387 mr_free(command);
2388 }
2389 g_backup_media_type = bkpinfo->backup_media_type;
2390 paranoid_free(device);
2391 paranoid_free(mounted_cfgf_path);
2392 paranoid_free(ramdisk_fname);
2393 return (retval);
2394}
2395
2396/**************************************************************************
2397 *END_GET_CFG_FILE_FROM_ARCHIVE *
2398 **************************************************************************/
2399
2400/* @} - end restoreUtilityGroup */
2401
2402void wait_until_software_raids_are_prepped(char *mdstat_file,
2403 int wait_for_percentage)
2404{
2405 struct raidlist_itself *raidlist;
2406 int unfinished_mdstat_devices = 9999, i;
2407 char *screen_message = NULL;
2408
2409 raidlist = malloc(sizeof(struct raidlist_itself));
2410
2411 assert(wait_for_percentage <= 100);
2412 log_it("wait_until_software_raids_are_prepped");
2413 while (unfinished_mdstat_devices > 0) {
2414 // FIXME: Prefix '/dev/' should really be dynamic!
2415 if (parse_mdstat(raidlist, "/dev/")) {
2416 log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2417 log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2418 return;
2419 }
2420 for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2421 if (raidlist->el[i].progress < wait_for_percentage) {
2422 unfinished_mdstat_devices++;
2423 if (raidlist->el[i].progress == -1) // delayed while another partition inits
2424 {
2425 continue;
2426 }
2427 log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2428 mr_asprintf(screen_message, "Sync'ing %s", raidlist->el[i].raid_device);
2429 open_evalcall_form(screen_message);
2430 mr_free(screen_message);
2431
2432 while (raidlist->el[i].progress < wait_for_percentage) {
2433 log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2434 update_evalcall_form(raidlist->el[i].progress);
2435 sleep(2);
2436 // FIXME: Prefix '/dev/' should really be dynamic!
2437 if (parse_mdstat(raidlist, "/dev/")) {
2438 break;
2439 }
2440 }
2441 close_evalcall_form();
2442 }
2443 }
2444 }
2445 paranoid_free(raidlist);
2446}
2447
2448
Note: See TracBrowser for help on using the repository browser.