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

Last change on this file since 2644 was 2644, checked in by Bruno Cornec, 14 years ago

r3867@localhost: bruno | 2010-06-10 01:35:22 +0200

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