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

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

Removes some malloc_string static allocation

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