source: MondoRescue/branches/stable/mondo/src/mondorestore/mondo-rstr-tools.c@ 1067

Last change on this file since 1067 was 1067, checked in by Bruno Cornec, 17 years ago

my-stuff.h is referred to in include now

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