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

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