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

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

r3342@localhost: bruno | 2009-08-14 00:46:51 +0200

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