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

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

r3369@localhost: bruno | 2009-08-18 16:57:27 +0200

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