source: MondoRescue/branches/2.2.2/mondo/src/mondorestore/mondo-rstr-tools.c@ 1242

Last change on this file since 1242 was 1242, checked in by Bruno Cornec, 17 years ago
  • Fix a bug for tape mangement where block size was missing during extract (Michel Loiseleur)
  • Property svn:keywords set to Id
File size: 79.4 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,
26call 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
51manually if automatic GRUB installation fails
52
5306/15
54- Added check for different 'isodir' chosen by user than stored in the archive
55Conor 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),
68use 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;
81saves 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
88during 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
108of calling grub-install
109
11010/10
111- don't leave copies of filelist.full lying around, clogging up
112the 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 "../common/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{
176paranoid_free(g_biggielist_txt);
177paranoid_free(g_filelist_full);
178paranoid_free(g_filelist_imagedevs);
179// paranoid_free (g_imagedevs_pot );
180paranoid_free(g_imagedevs_restthese);
181paranoid_free(g_mondo_cfg_file);
182paranoid_free(g_mountlist_fname);
183paranoid_free(g_mondo_home);
184paranoid_free(g_tmpfs_mountpt);
185paranoid_free(g_isodir_device);
186paranoid_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{
201FILE *fin;
202FILE *fout;
203/************************************************************************
204* allocate memory regions. test and set -sab 16 feb 2003 *
205************************************************************************/
206char *incoming_ptr;
207char *question_ptr;
208
209char incoming[MAX_STR_LEN] = "\0";
210char question[MAX_STR_LEN];
211
212assert_string_is_neither_NULL_nor_zerolength(infname);
213assert_string_is_neither_NULL_nor_zerolength(outfname);
214
215incoming_ptr = malloc(sizeof(incoming));
216if (incoming_ptr == NULL) {
217fprintf(stderr, "Out of Memory\n");
218exit(EXIT_FAILURE);
219}
220
221question_ptr = malloc(sizeof(question));
222if (question_ptr == NULL) {
223fprintf(stderr, "Out of Memory\n");
224exit(EXIT_FAILURE);
225}
226
227memset(incoming_ptr, '\0', sizeof(incoming));
228memset(question_ptr, '\0', sizeof(question));
229
230
231
232if (!(fin = fopen(infname, "r"))) {
233fatal_error("Cannot openin infname");
234}
235if (!(fout = fopen(outfname, "w"))) {
236fatal_error("Cannot openin outfname");
237}
238for (fgets(incoming_ptr, MAX_STR_LEN, fin);
239 !feof(fin); fgets(incoming_ptr, MAX_STR_LEN, fin)) {
240strip_spaces(incoming_ptr);
241
242if (incoming[0] == '\0') {
243 continue;
244}
245
246sprintf(question_ptr,
247 "Should I restore the image of %s ?", incoming_ptr);
248
249if (ask_me_yes_or_no(question_ptr)) {
250 fprintf(fout, "%s\n", incoming_ptr);
251}
252}
253
254/*** free memory ***********/
255paranoid_free(incoming_ptr);
256incoming_ptr = NULL;
257paranoid_free(question_ptr);
258question_ptr = NULL;
259
260
261paranoid_fclose(fout);
262paranoid_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{
291char *mountpt;
292char *command;
293char *orig_fname;
294int retval = 0;
295
296assert(bkpinfo != NULL);
297malloc_string(mountpt);
298malloc_string(command);
299malloc_string(orig_fname);
300assert_string_is_neither_NULL_nor_zerolength(ramdisk_fname);
301assert_string_is_neither_NULL_nor_zerolength(output_cfg_file);
302assert_string_is_neither_NULL_nor_zerolength(output_mountlist_file);
303sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
304sprintf(command, "mkdir -p %s", mountpt);
305run_program_and_log_output(command, FALSE);
306sprintf(command, "gzip -dc %s > %s/mindi.rd 2> /dev/null",
307 ramdisk_fname, bkpinfo->tmpdir);
308
309run_program_and_log_output(command, FALSE);
310sprintf(command, "umount %s", mountpt);
311
312run_program_and_log_output(command, FALSE);
313
314sprintf(command, "mount -o loop %s/mindi.rd -t ext2 %s",
315 bkpinfo->tmpdir, mountpt);
316
317run_program_and_log_output(command, FALSE);
318
319sprintf(command, "mkdir -p %s/tmp", bkpinfo->tmpdir);
320
321run_program_and_log_output(command, FALSE);
322
323sprintf(command, "cp -f %s/%s %s", // %s/%s becomes {mountpt}/tmp/m*ndo-restore.cfg
324 mountpt, g_mondo_cfg_file, output_cfg_file);
325run_program_and_log_output(command, FALSE);
326
327sprintf(orig_fname, "%s/%s", mountpt, g_mountlist_fname);
328if (does_file_exist(orig_fname)) {
329sprintf(command, "cp -f %s %s", orig_fname, output_mountlist_file);
330run_program_and_log_output(command, FALSE);
331}
332sprintf(command, "umount %s", mountpt);
333run_program_and_log_output(command, FALSE);
334if (!does_file_exist(output_cfg_file)
335|| (!does_file_exist(output_mountlist_file)
336 && does_file_exist(orig_fname))) {
337log_msg(2, "Failed to extract %s and/or %s from ramdisk",
338 output_cfg_file, output_mountlist_file);
339retval = 1;
340} else {
341retval = 0;
342}
343paranoid_free(mountpt);
344paranoid_free(command);
345paranoid_free(orig_fname);
346return (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{
359while (get_cfg_file_from_archive(bkpinfo)) {
360if (!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}
365interactively_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 **/
381char *command;
382char *file;
383char *tmp;
384int res;
385
386malloc_string(command);
387malloc_string(file);
388malloc_string(tmp);
389assert_string_is_neither_NULL_nor_zerolength(f);
390assert_string_is_neither_NULL_nor_zerolength(list_fname);
391assert(preamble != NULL);
392
393if (strncmp(preamble, f, strlen(preamble)) == 0) {
394strcpy(file, f + strlen(preamble));
395} else {
396strcpy(file, f);
397}
398if (file[0] == '/' && file[1] == '/') {
399strcpy(tmp, file);
400strcpy(file, tmp + 1);
401}
402sprintf(tmp,
403 "Checking to see if f=%s, file=%s, is in the list of biggiefiles",
404 f, file);
405log_msg(2, tmp);
406sprintf(command, "grep -E '^%s$' %s", file, list_fname);
407res = run_program_and_log_output(command, FALSE);
408paranoid_free(command);
409paranoid_free(file);
410paranoid_free(tmp);
411if (res) {
412return (FALSE);
413} else {
414return (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{
435char *mount_isodir_command, *tmp, *command;
436int retval = 0, i;
437bool already_mounted = FALSE;
438
439assert(bkpinfo != NULL);
440malloc_string(mount_isodir_command);
441malloc_string(tmp);
442malloc_string(command);
443g_ISO_restore_mode = TRUE;
444read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
445if (bkpinfo->disaster_recovery) {
446/* Patch Conor Daly 26-june-2004
447* Don't let this clobber an existing bkpinfo->isodir */
448if (!bkpinfo->isodir[0]) {
449 strcpy(bkpinfo->isodir, "/tmp/isodir");
450}
451/* End patch */
452sprintf(command, "mkdir -p %s", bkpinfo->isodir);
453run_program_and_log_output(command, 5);
454log_msg(2, "Setting isodir to %s", bkpinfo->isodir);
455}
456
457if (!get_isodir_info
458(g_isodir_device, g_isodir_format, bkpinfo->isodir,
459 nuke_me_please)) {
460return (1);
461}
462paranoid_system("umount " MNT_CDROM " 2> /dev/null"); /* just in case */
463
464if (is_this_device_mounted(g_isodir_device)) {
465log_to_screen("WARNING - isodir is already mounted");
466already_mounted = TRUE;
467} else {
468sprintf(mount_isodir_command, "mount %s", g_isodir_device);
469if (strlen(g_isodir_format) > 1) {
470 sprintf(mount_isodir_command + strlen(mount_isodir_command),
471 " -t %s", g_isodir_format);
472}
473strcat(mount_isodir_command, " -o ro ");
474strcat(mount_isodir_command, bkpinfo->isodir);
475run_program_and_log_output("df -m", FALSE);
476sprintf(tmp,
477 "The 'mount' command is '%s'. PLEASE report this command to be if you have problems, ok?",
478 mount_isodir_command);
479log_msg(1, tmp);
480if (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}
485log_to_screen
486 ("I have mounted the device where the ISO files are stored.");
487}
488if (!IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
489mount_cdrom(bkpinfo);
490}
491i = what_number_cd_is_this(bkpinfo); /* has the side-effect of calling mount_cdrom() */
492sprintf(tmp, "%s #%d has been mounted via loopback mount",
493 media_descriptor_string(bkpinfo->backup_media_type), i);
494log_msg(1, tmp);
495if (i < 0) {
496popup_and_OK
497 ("Cannot find ISO images in the directory you specified.");
498retval = 1;
499}
500log_msg(2, "%ld: bkpinfo->isodir is now %s", __LINE__,
501 bkpinfo->isodir);
502paranoid_free(mount_isodir_command);
503paranoid_free(tmp);
504paranoid_free(command);
505return (retval);
506}
507
508
509
510
511/**
512* Kill all Petris processes.
513*/
514void kill_petris(void)
515{
516char *command;
517malloc_string(command);
518sprintf(command,
519 "kill `ps 2> /dev/null | grep petris 2> /dev/null | grep -v grep | cut -d' ' -f2` 2> /dev/null");
520paranoid_system(command);
521paranoid_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 **/
539char *rclocal_fname;
540char *newfile_fname;
541char *tmp;
542
543malloc_string(rclocal_fname);
544malloc_string(newfile_fname);
545malloc_string(tmp);
546assert_string_is_neither_NULL_nor_zerolength(path);
547
548sprintf(rclocal_fname, "%s/rc.local", path);
549
550// sprintf(tmp, "chmod 1777 %s/tmp", MNT_RESTORING);
551// run_program_and_log_output( tmp, FALSE );
552return (0); /* remove this line to open the floodgates... */
553
554if (!does_file_exist(rclocal_fname)) {
555sprintf(rclocal_fname, "%s/rc.d/rc.local", path);
556}
557if (!does_file_exist(rclocal_fname)) {
558paranoid_free(rclocal_fname);
559paranoid_free(newfile_fname);
560paranoid_free(tmp);
561return (1);
562}
563sprintf(newfile_fname, "%s/rc.local.mondorescue", path);
564sprintf(tmp, "grep mondorescue %s > /dev/null 2> /dev/null",
565 rclocal_fname);
566if (system(tmp)) {
567sprintf(tmp, "echo \"[ -e %s ] && %s\n\" >> %s",
568 newfile_fname, newfile_fname, rclocal_fname);
569
570paranoid_system(tmp);
571}
572sprintf(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);
582sprintf(tmp, "chmod +x \"%s\"", newfile_fname);
583run_program_and_log_output(tmp, FALSE);
584paranoid_free(rclocal_fname);
585paranoid_free(newfile_fname);
586paranoid_free(tmp);
587return (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{
607int retval = 0, lino, res;
608char *tmp, *these_failed, *format;
609struct mountlist_itself *mountlist;
610
611malloc_string(tmp);
612malloc_string(format);
613malloc_string(these_failed);
614assert(p_external_copy_of_mountlist != NULL);
615mountlist = malloc(sizeof(struct mountlist_itself));
616memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
617 sizeof(struct mountlist_itself));
618sort_mountlist_by_mountpoint(mountlist, 0);
619
620/** menset **/
621these_failed[0] = '\0';
622
623mvaddstr_and_log_it(g_currentY, 0, "Mounting devices ");
624open_progress_form("Mounting devices",
625 "I am now mounting all the drives.",
626 "This should not take long.",
627 "", mountlist->entries);
628
629for (lino = 0; lino < mountlist->entries; lino++) {
630if (!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}
656g_current_progress++;
657}
658close_progress_form();
659run_program_and_log_output("df -m", TRUE);
660if (retval) {
661if (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}
669sprintf(tmp, "Could not mount devices %s- shall I abort?",
670 these_failed);
671if (!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 {
682log_to_screen("All partitions were mounted OK.");
683mvaddstr_and_log_it(g_currentY++, 74, "Done.");
684}
685run_program_and_log_output("df -m", 3);
686paranoid_free(mountlist);
687paranoid_free(tmp);
688paranoid_free(format);
689paranoid_free(these_failed);
690return (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{
709char *mount_cmd;
710int i, res;
711#ifdef __FreeBSD__
712char mdd[32];
713char *mddev = mdd;
714#endif
715
716malloc_string(mount_cmd);
717assert(bkpinfo != NULL);
718
719if (bkpinfo->backup_media_type == tape
720|| bkpinfo->backup_media_type == udev) {
721log_msg(8, "Tape/udev. Therefore, no need to mount CDROM.");
722paranoid_free(mount_cmd);
723return 0;
724}
725
726if (!run_program_and_log_output("mount | grep -F " MNT_CDROM, FALSE)) {
727log_msg(2, "mount_cdrom() - CD already mounted. Fair enough.");
728paranoid_free(mount_cmd);
729return (0);
730}
731
732if (bkpinfo->backup_media_type == nfs) {
733log_msg(2, "Mounting for NFS thingy");
734log_msg(2, "isodir = %s", bkpinfo->isodir);
735if ((!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__
741sprintf(mount_cmd, "/mnt/isodir/%s/%s/%s-%d.iso", bkpinfo->isodir,
742 bkpinfo->nfs_remote_dir, bkpinfo->prefix, g_current_media_number);
743mddev = make_vn(mount_cmd);
744sprintf(mount_cmd, "mount_cd9660 -r %s " MNT_CDROM, mddev);
745#else
746sprintf(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
752if (bkpinfo->backup_media_type == iso) {
753#ifdef __FreeBSD__
754sprintf(mount_cmd, "%s/%s-%d.iso", bkpinfo->isodir,
755 bkpinfo->prefix, g_current_media_number);
756mddev = make_vn(mount_cmd);
757sprintf(mount_cmd, "mount_cd9660 -r %s %s", mddev, MNT_CDROM);
758#else
759sprintf(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{
765sprintf(mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device,
766 MNT_CDROM);
767}
768#else
769{
770sprintf(mount_cmd, "mount %s -t iso9660 -o ro %s",
771 bkpinfo->media_device, MNT_CDROM);
772}
773#endif
774
775else {
776if (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__
785sprintf(mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device,
786 MNT_CDROM);
787#else
788sprintf(mount_cmd, "mount %s -t iso9660 -o ro %s",
789 bkpinfo->media_device, MNT_CDROM);
790#endif
791
792}
793log_msg(2, "(mount_cdrom) --- command = %s", mount_cmd);
794for (i = 0; i < 2; i++) {
795res = run_program_and_log_output(mount_cmd, FALSE);
796if (!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}
804if (res) {
805log_msg(2, "Failed, despite %d attempts", i);
806} else {
807log_msg(2, "Mounted CD-ROM drive OK");
808}
809paranoid_free(mount_cmd);
810return (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{
832int res = 0;
833
834/** malloc **/
835char *tmp, *command, *mountdir, *mountpoint, *additional_parameters;
836
837assert_string_is_neither_NULL_nor_zerolength(device);
838assert_string_is_neither_NULL_nor_zerolength(mpt);
839assert(format != NULL);
840malloc_string(tmp);
841malloc_string(command);
842malloc_string(mountdir);
843malloc_string(mountpoint);
844malloc_string(additional_parameters);
845
846if (!strcmp(mpt, "/1")) {
847strcpy(mountpoint, "/");
848log_msg(3, "Mommm! SME is being a dildo!");
849} else {
850strcpy(mountpoint, mpt);
851}
852
853if (!strcmp(mountpoint, "lvm")) {
854return (0);
855}
856if (!strcmp(mountpoint, "image")) {
857return (0);
858}
859sprintf(tmp, "Mounting device %s ", device);
860log_msg(1, tmp);
861if (writeable) {
862strcpy(additional_parameters, "-o rw");
863} else {
864strcpy(additional_parameters, "-o ro");
865}
866if (find_home_of_exe("setfattr")) {
867strcat(additional_parameters, ",user_xattr");
868}
869if (find_home_of_exe("setfacl")) {
870strcat(additional_parameters, ",acl");
871}
872
873if (!strcmp(mountpoint, "swap")) {
874sprintf(command, "swapon %s", device);
875} else {
876if (!strcmp(mountpoint, "/")) {
877 strcpy(mountdir, MNT_RESTORING);
878} else {
879 sprintf(mountdir, "%s%s", MNT_RESTORING, mountpoint);
880}
881sprintf(command, "mkdir -p %s", mountdir);
882run_program_and_log_output(command, FALSE);
883sprintf(command, "mount -t %s %s %s %s 2>> %s", format, device,
884 additional_parameters, mountdir, MONDO_LOGFILE);
885log_msg(2, "command='%s'", command);
886}
887res = run_program_and_log_output(command, TRUE);
888if (res && (strstr(command, "xattr") || strstr(command, "acl"))) {
889log_msg(1, "Re-trying without the fancy extra parameters");
890sprintf(command, "mount -t %s %s %s 2>> %s", format, device,
891 mountdir, MONDO_LOGFILE);
892res = run_program_and_log_output(command, TRUE);
893}
894if (res) {
895log_msg(1, "Unable to mount device %s (type %s) at %s", device,
896 format, mountdir);
897log_msg(1, "command was '%s'", command);
898if (!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}
914if (res && !strcmp(mountpoint, "swap")) {
915log_msg(2, "That's ok. It's just a swap partition.");
916log_msg(2, "Non-fatal error. Returning 0.");
917res = 0;
918}
919
920paranoid_free(tmp);
921paranoid_free(command);
922paranoid_free(mountdir);
923paranoid_free(mountpoint);
924paranoid_free(additional_parameters);
925
926return (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{
941run_program_and_log_output("touch " MNT_RESTORING "/var/log/pacct",
942 FALSE);
943run_program_and_log_output("touch " MNT_RESTORING "/var/account/pacct",
944 FALSE);
945if (run_program_and_log_output("ls " MNT_RESTORING " /tmp", FALSE)) {
946run_program_and_log_output("chmod 1777 " MNT_RESTORING "/tmp",
947 FALSE);
948}
949run_program_and_log_output("mkdir -p " MNT_RESTORING
950 "/var/run/console", FALSE);
951run_program_and_log_output("chmod 777 " MNT_RESTORING "/dev/null",
952 FALSE);
953run_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);
956run_program_and_log_output("rm -f " MNT_RESTORING "/var/run/*.pid",
957 TRUE);
958run_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 **/
979char *value = NULL;
980char *tmp = NULL;
981char *envtmp1 = NULL;
982char *envtmp2 = NULL;
983char *command = NULL;
984char *iso_mnt = NULL;
985char *iso_path = NULL;
986char *old_isodir = NULL;
987char cfg_file[100];
988t_bkptype media_specified_by_user;
989
990malloc_string(command);
991malloc_string(iso_mnt);
992malloc_string(iso_path);
993malloc_string(old_isodir);
994malloc_string(value);
995malloc_string(tmp);
996// assert_string_is_neither_NULL_nor_zerolength(cfg_file);
997assert(bkpinfo != NULL);
998
999if (!cfgf) {
1000strcpy(cfg_file, g_mondo_cfg_file);
1001} else {
1002strcpy(cfg_file, cfgf);
1003}
1004
1005media_specified_by_user = bkpinfo->backup_media_type; // or 'none', if not specified
1006
1007if (0 == read_cfg_var(cfg_file, "backup-media-type", value)) {
1008if (!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/*
1018if (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 {
1071fatal_error("backup-media-type not specified!");
1072}
1073if (bkpinfo->disaster_recovery) {
1074if (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 {
1097log_msg(2,
1098 "Not in Disaster Recovery Mode. No need to derive device name from config file.");
1099}
1100
1101read_cfg_var(cfg_file, "use-star", value);
1102if (strstr(value, "yes")) {
1103bkpinfo->use_star = TRUE;
1104log_msg(1, "Goody! ... bkpinfo->use_star is now true.");
1105}
1106
1107read_cfg_var(cfg_file, "acl", value);
1108if (strstr(value, "TRUE")) {
1109asprintf(&g_getfacl,"setfacl");
1110log_msg(1, "We will restore ACLs");
1111if (! find_home_of_exe("setfacl")) {
1112 log_msg(1, "Unable to restore ACLs as no setfacl found");
1113}
1114}
1115read_cfg_var(cfg_file, "xattr", value);
1116if (strstr(value, "TRUE")) {
1117asprintf(&g_getfattr,"setfattr");
1118log_msg(1, "We will restore XATTRs");
1119if (! find_home_of_exe("setfattr")) {
1120 log_msg(1, "Unable to restore XATTRs as no setfattr found");
1121}
1122}
1123
1124if (0 == read_cfg_var(cfg_file, "internal-tape-block-size", value)) {
1125bkpinfo->internal_tape_block_size = atol(value);
1126log_msg(1, "Internal tape block size has been custom-set to %ld",
1127 bkpinfo->internal_tape_block_size);
1128} else {
1129bkpinfo->internal_tape_block_size =
1130 DEFAULT_INTERNAL_TAPE_BLOCK_SIZE;
1131log_msg(1, "Internal tape block size = default (%ld)",
1132 DEFAULT_INTERNAL_TAPE_BLOCK_SIZE);
1133}
1134
1135read_cfg_var(cfg_file, "use-lzo", value);
1136if (strstr(value, "yes")) {
1137bkpinfo->use_lzo = TRUE;
1138bkpinfo->use_gzip = FALSE;
1139strcpy(bkpinfo->zip_exe, "lzop");
1140strcpy(bkpinfo->zip_suffix, "lzo");
1141} else {
1142read_cfg_var(cfg_file, "use-gzip", value);
1143if (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
1161value[0] = '\0';
1162read_cfg_var(cfg_file, "differential", value);
1163if (!strcmp(value, "yes") || !strcmp(value, "1")) {
1164bkpinfo->differential = TRUE;
1165}
1166log_msg(2, "differential var = '%s'", value);
1167if (bkpinfo->differential) {
1168log_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
1169} else {
1170log_msg(2, "This is a regular (full) backup");
1171}
1172
1173read_cfg_var(g_mondo_cfg_file, "please-dont-eject", tmp);
1174if (tmp[0]
1175||
1176strstr(call_program_and_get_last_line_of_output
1177 ("cat /proc/cmdline"), "donteject")) {
1178bkpinfo->please_dont_eject = TRUE;
1179log_msg(2, "Ok, I shan't eject when restoring! Groovy.");
1180}
1181
1182if (bkpinfo->backup_media_type == nfs) {
1183if (!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}
1197if (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 */
1217strcpy(old_isodir, bkpinfo->isodir);
1218read_cfg_var(g_mondo_cfg_file, "iso-mnt", iso_mnt);
1219read_cfg_var(g_mondo_cfg_file, "isodir", iso_path);
1220sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1221if (!bkpinfo->isodir[0]) {
1222 strcpy(bkpinfo->isodir, old_isodir);
1223}
1224if (!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}
1232read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
1233log_msg(2, "isodir=%s; iso-dev=%s", bkpinfo->isodir,
1234 g_isodir_device);
1235if (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
1274if (media_specified_by_user != none) {
1275if (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}
1289bkpinfo->backup_media_type = media_specified_by_user;
1290}
1291g_backup_media_type = bkpinfo->backup_media_type;
1292paranoid_free(value);
1293paranoid_free(tmp);
1294paranoid_free(command);
1295paranoid_free(iso_mnt);
1296paranoid_free(iso_path);
1297paranoid_free(old_isodir);
1298return (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{
1322struct s_node *filelist;
1323
1324/** add mallocs**/
1325char *command;
1326char *tmp;
1327int res = 0;
1328pid_t pid;
1329
1330assert(bkpinfo != NULL);
1331malloc_string(command);
1332malloc_string(tmp);
1333
1334if (does_file_exist(g_filelist_full)
1335&& does_file_exist(g_biggielist_txt)) {
1336log_msg(1, "%s exists", g_filelist_full);
1337log_msg(1, "%s exists", g_biggielist_txt);
1338log_msg(2,
1339 "Filelist and biggielist already recovered from media. Yay!");
1340} else {
1341getcwd(tmp, MAX_STR_LEN);
1342chdir(bkpinfo->tmpdir);
1343log_msg(1, "chdir(%s)", bkpinfo->tmpdir);
1344log_to_screen("Extracting filelist and biggielist from media...");
1345unlink("/tmp/filelist.full");
1346unlink("/" FILELIST_FULL_STUB);
1347unlink("/tmp/i-want-my-lvm");
1348if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
1349 sprintf(command,
1350 "tar -b %ld -zxf %s %s %s %s %s %s",
1351 bkpinfo->internal_tape_block_size,
1352 bkpinfo->media_device,
1353 MOUNTLIST_FNAME_STUB,
1354 BIGGIELIST_TXT_STUB,
1355 FILELIST_FULL_STUB,
1356 "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1357 log_msg(1, "tarcommand = %s", command);
1358 run_program_and_log_output(command, 1);
1359} else {
1360 log_msg(2,
1361 "Calling insist_on_this_cd_number; bkpinfo->isodir=%s",
1362 bkpinfo->isodir);
1363 insist_on_this_cd_number(bkpinfo, 1);
1364 log_msg(2, "Back from iotcn");
1365 run_program_and_log_output("mount", 1);
1366 sprintf(command,
1367 "tar -zxf %s/images/all.tar.gz %s %s %s %s %s",
1368 MNT_CDROM,
1369 MOUNTLIST_FNAME_STUB,
1370 BIGGIELIST_TXT_STUB,
1371 FILELIST_FULL_STUB,
1372 "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1373
1374 log_msg(1, "tarcommand = %s", command);
1375 run_program_and_log_output(command, 1);
1376// popup_and_OK("Press ENTER to continue");
1377 if (!does_file_exist(BIGGIELIST_TXT_STUB)) {
1378 fatal_error
1379 ("all.tar.gz did not include tmp/biggielist.txt");
1380 }
1381 if (!does_file_exist(FILELIST_FULL_STUB)) {
1382 fatal_error
1383 ("all.tar.gz did not include tmp/filelist.full.gz");
1384 }
1385}
1386sprintf(command, "cp -f %s %s", MONDO_CFG_FILE_STUB,
1387 g_mondo_cfg_file);
1388run_program_and_log_output(command, FALSE);
1389
1390sprintf(command, "cp -f %s/%s %s", bkpinfo->tmpdir,
1391 BIGGIELIST_TXT_STUB, g_biggielist_txt);
1392log_msg(1, "command = %s", command);
1393paranoid_system(command);
1394sprintf(command, "ln -sf %s/%s %s", bkpinfo->tmpdir,
1395 FILELIST_FULL_STUB, g_filelist_full);
1396log_msg(1, "command = %s", command);
1397paranoid_system(command);
1398}
1399
1400if (am_I_in_disaster_recovery_mode()
1401&&
1402ask_me_yes_or_no("Do you want to retrieve the mountlist as well?"))
1403{
1404// sprintf(command, "cp -f tmp/mountlist.txt /tmp");
1405sprintf(command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB,
1406 bkpinfo->tmpdir);
1407paranoid_system(command);
1408}
1409
1410chdir(tmp);
1411
1412if (!does_file_exist(g_biggielist_txt)) {
1413log_msg(1, "Warning - %s not found", g_biggielist_txt);
1414}
1415if (!does_file_exist(g_filelist_full)) {
1416log_msg(1, "Warning - %s does not exist", g_filelist_full);
1417}
1418// popup_and_OK("Wonderful.");
1419
1420log_msg(2, "Forking");
1421pid = fork();
1422switch (pid) {
1423case -1:
1424fatal_error("Forking error");
1425break;
1426
1427case 0:
1428log_to_screen("Pre-processing filelist");
1429if (!does_file_exist(g_biggielist_txt)) {
1430 sprintf(command, "echo -n > %s", g_biggielist_txt);
1431 paranoid_system(command);
1432 }
1433 sprintf(command, "grep -E '^/dev/.*' %s > %s",
1434 g_biggielist_txt, g_filelist_imagedevs);
1435 paranoid_system(command);
1436 exit(0);
1437 break;
1438
1439 default:
1440 open_evalcall_form("Pre-processing filelist");
1441 while (!waitpid(pid, (int *) 0, WNOHANG)) {
1442 usleep(100000);
1443 update_evalcall_form(0);
1444 }
1445 }
1446 close_evalcall_form();
1447
1448 log_msg(3, "loading filelist");
1449 filelist = load_filelist(g_filelist_full);
1450 log_msg(3, "deleting original filelist");
1451 unlink(g_filelist_full);
1452 if (g_text_mode) {
1453 printf("Restore which directory? --> ");
1454 fgets(tmp, sizeof(tmp), stdin);
1455 toggle_path_selection(filelist, tmp, TRUE);
1456 if (strlen(tmp) == 0) {
1457 res = 1;
1458 } else {
1459 res = 0;
1460 }
1461 } else {
1462 res = edit_filelist(filelist);
1463 }
1464 if (res) {
1465 log_msg(2, "User hit 'cancel'. Freeing filelist and aborting.");
1466 free_filelist(filelist);
1467 return (NULL);
1468 }
1469 ask_about_these_imagedevs(g_filelist_imagedevs, g_imagedevs_restthese);
1470 close_evalcall_form();
1471
1472 // NB: It's not necessary to add g_biggielist_txt to the filelist.full
1473 // file. The filelist.full file already contains the filename of EVERY
1474 // file backed up - regular and biggie files.
1475
1476 // However, we do want to make sure the imagedevs selected by the user
1477 // are flagged for restoring.
1478 if (length_of_file(g_imagedevs_restthese) > 2) {
1479 add_list_of_files_to_filelist(filelist, g_imagedevs_restthese,
1480 TRUE);
1481 }
1482
1483 paranoid_free(command);
1484 paranoid_free(tmp);
1485 return (filelist);
1486}
1487
1488/**************************************************************************
1489 *END_ PROCESS_FILELIST_AND_BIGGIELIST *
1490 **************************************************************************/
1491
1492
1493
1494
1495/**
1496 * Make a backup copy of <tt>path_root</tt>/<tt>filename</tt>.
1497 * The backup filename is the filename of the original with ".pristine" added.
1498 * @param path_root The place where the filesystem is mounted (e.g. MNT_RESTORING).
1499 * @param filename The filename (absolute path) within @p path_root.
1500 * @return 0 for success, nonzero for failure.
1501 */
1502int backup_crucial_file(char *path_root, char *filename)
1503{
1504 char *tmp;
1505 char *command;
1506 int res;
1507
1508 malloc_string(tmp);
1509 malloc_string(command);
1510 assert(path_root != NULL);
1511 assert_string_is_neither_NULL_nor_zerolength(filename);
1512
1513 sprintf(tmp, "%s/%s", path_root, filename);
1514 sprintf(command, "cp -f %s %s.pristine", tmp, tmp);
1515
1516 res = run_program_and_log_output(command, 5);
1517 paranoid_free(tmp);
1518 paranoid_free(command);
1519 return (res);
1520}
1521
1522
1523/**
1524 * Install the user's boot loader in the MBR.
1525 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported.
1526 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1527 * @return 0 for success, nonzero for failure.
1528 */
1529int run_boot_loader(bool offer_to_hack_scripts)
1530{
1531 int res;
1532 int retval = 0;
1533
1534 /** malloc *******/
1535 char *device;
1536 char *tmp;
1537 char *name;
1538
1539 malloc_string(device);
1540 malloc_string(tmp);
1541 malloc_string(name);
1542 backup_crucial_file(MNT_RESTORING, "/etc/fstab");
1543 backup_crucial_file(MNT_RESTORING, "/etc/grub.conf");
1544 backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf");
1545 backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf");
1546 read_cfg_var(g_mondo_cfg_file, "bootloader.device", device);
1547 read_cfg_var(g_mondo_cfg_file, "bootloader.name", name);
1548 sprintf(tmp, "run_boot_loader: device='%s', name='%s'", device, name);
1549 log_msg(2, tmp);
1550 system("sync");
1551 if (!strcmp(name, "LILO")) {
1552 res = run_lilo(offer_to_hack_scripts);
1553 } else if (!strcmp(name, "ELILO")) {
1554 res = run_elilo(offer_to_hack_scripts);
1555 } else if (!strcmp(name, "GRUB")) {
1556// 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?")))
1557// {
1558 res = run_grub(offer_to_hack_scripts, device);
1559// unlink(DO_MBR_PLEASE);
1560// }
1561// else
1562// {
1563// log_msg(1, "Not running run_grub(). Was a bad idea anyway.");
1564// res = 1;
1565// }
1566 } else if (!strcmp(name, "RAW")) {
1567 res = run_raw_mbr(offer_to_hack_scripts, device);
1568 }
1569#ifdef __FreeBSD__
1570 else if (!strcmp(name, "BOOT0")) {
1571 sprintf(tmp, "boot0cfg -B %s", device);
1572 res = run_program_and_log_output(tmp, FALSE);
1573 } else {
1574 sprintf(tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device);
1575 if (!system(tmp)) {
1576 sprintf(tmp, MNT_RESTORING "/sbin/fdisk -B %s", device);
1577 res = run_program_and_log_output(tmp, 3);
1578 } else {
1579 log_msg(1,
1580 "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");
1581 }
1582 }
1583#else
1584 else {
1585 log_to_screen
1586 ("Unable to determine type of boot loader. Defaulting to LILO.");
1587 res = run_lilo(offer_to_hack_scripts);
1588 }
1589#endif
1590 retval += res;
1591 if (res) {
1592 log_to_screen("Your boot loader returned an error");
1593 } else {
1594 log_to_screen("Your boot loader ran OK");
1595 }
1596 paranoid_free(device);
1597 paranoid_free(tmp);
1598 paranoid_free(name);
1599 return (retval);
1600}
1601
1602/**************************************************************************
1603 *END_ RUN_BOOT_LOADER *
1604 **************************************************************************/
1605
1606
1607
1608/**
1609 * Attempt to find the user's editor.
1610 * @return The editor found ("vi" if none could be found).
1611 * @note The returned string points to static storage that will be overwritten with each call.
1612 */
1613char *find_my_editor(void)
1614{
1615 static char output[MAX_STR_LEN];
1616 if (find_home_of_exe("pico")) {
1617 strcpy(output, "pico");
1618 } else if (find_home_of_exe("nano")) {
1619 strcpy(output, "nano");
1620 } else if (find_home_of_exe("e3em")) {
1621 strcpy(output, "e3em");
1622 } else if (find_home_of_exe("e3vi")) {
1623 strcpy(output, "e3vi");
1624 } else {
1625 strcpy(output, "vi");
1626 }
1627 if (!find_home_of_exe(output)) {
1628 log_msg(2, " (find_my_editor) --- warning - %s not found", output);
1629 }
1630 return (output);
1631}
1632
1633
1634/**
1635 * Install GRUB on @p bd.
1636 * @param offer_to_run_stabgrub If TRUE, then offer to hack the user's fstab for them.
1637 * @param bd The boot device where GRUB is installed.
1638 * @return 0 for success, nonzero for failure.
1639 */
1640int run_grub(bool offer_to_run_stabgrub, char *bd)
1641{
1642 /** malloc **/
1643 char *command;
1644 char *boot_device;
1645 char *rootdev;
1646 char *rootdrive;
1647 char *conffile;
1648 char *tmp;
1649 char *editor;
1650
1651 int res;
1652 int done;
1653
1654 malloc_string(command);
1655 malloc_string(boot_device);
1656 malloc_string(tmp);
1657 malloc_string(editor);
1658 malloc_string(rootdev);
1659 malloc_string(rootdrive);
1660 malloc_string(conffile);
1661 assert_string_is_neither_NULL_nor_zerolength(bd);
1662 strcpy(editor, "vi"); // find_my_editor() );
1663 strcpy(boot_device, bd);
1664
1665 if (!run_program_and_log_output("which grub-MR", FALSE)) {
1666 log_msg(1, "Yay! grub-MR found...");
1667 sprintf(command, "grub-MR %s /tmp/mountlist.txt", boot_device);
1668 log_msg(1, "command = %s", command);
1669 } else {
1670 sprintf(command, "chroot " MNT_RESTORING " grub-install %s",
1671 boot_device);
1672 log_msg(1, "WARNING - grub-MR not found; using grub-install");
1673 }
1674 if (offer_to_run_stabgrub
1675 && ask_me_yes_or_no("Did you change the mountlist?"))
1676 /* interactive mode */
1677 {
1678 mvaddstr_and_log_it(g_currentY,
1679 0,
1680 "Modifying fstab and grub.conf, and running GRUB... ");
1681 for (done = FALSE; !done;) {
1682 popup_and_get_string("Boot device",
1683 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1684 boot_device, MAX_STR_LEN / 4);
1685 sprintf(command, "stabgrub-me %s", boot_device);
1686 res = run_program_and_log_output(command, 1);
1687 if (res) {
1688 popup_and_OK
1689 ("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.");
1690 newtSuspend();
1691 system("chroot " MNT_RESTORING);
1692 newtResume();
1693 popup_and_OK("Thank you.");
1694 } else {
1695 done = TRUE;
1696 }
1697 popup_and_OK("You will now edit fstab and grub.conf");
1698 if (!g_text_mode) {
1699 newtSuspend();
1700 }
1701 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1702 paranoid_system(tmp);
1703 sprintf(tmp, "%s " MNT_RESTORING "/etc/grub.conf", editor);
1704 paranoid_system(tmp);
1705 if (!g_text_mode) {
1706 newtResume();
1707 }
1708 }
1709 } else
1710 /* nuke mode */
1711 {
1712 mvaddstr_and_log_it(g_currentY,
1713 0,
1714 "Running GRUB... ");
1715 iamhere(command);
1716 res = run_program_and_log_output(command, 1);
1717 if (res) {
1718 popup_and_OK
1719 ("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.");
1720 newtSuspend();
1721 system("chroot " MNT_RESTORING);
1722 newtResume();
1723 popup_and_OK("Thank you.");
1724 }
1725 }
1726 if (res) {
1727 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1728 log_to_screen
1729 ("GRUB ran w/error(s). See /tmp/mondo-restore.log for more info.");
1730 log_msg(1, "Type:-");
1731 log_msg(1, " mount-me");
1732 log_msg(1, " chroot " MNT_RESTORING);
1733 log_msg(1, " mount /boot");
1734 log_msg(1, " grub-install '(hd0)'");
1735 log_msg(1, " exit");
1736 log_msg(1, " unmount-me");
1737 log_msg(1,
1738 "If you're really stuck, please e-mail the mailing list.");
1739 } else {
1740 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1741 }
1742 paranoid_free(rootdev);
1743 paranoid_free(rootdrive);
1744 paranoid_free(conffile);
1745 paranoid_free(command);
1746 paranoid_free(boot_device);
1747 paranoid_free(tmp);
1748 paranoid_free(editor);
1749
1750 return (res);
1751}
1752
1753/**************************************************************************
1754 *END_RUN_GRUB *
1755 **************************************************************************/
1756
1757
1758/**
1759 * Install ELILO on the user's boot drive (determined by elilo.conf).
1760 * @param offer_to_run_stabelilo If TRUE, then offer to hack the user's fstab for them.
1761 * @return 0 for success, nonzero for failure.
1762 */
1763int run_elilo(bool offer_to_run_stabelilo)
1764{
1765 /** malloc **/
1766 char *command;
1767 char *tmp;
1768 char *editor;
1769
1770 int res;
1771 int done;
1772
1773 malloc_string(command);
1774 malloc_string(tmp);
1775 malloc_string(editor);
1776 strcpy(editor, find_my_editor());
1777 if (offer_to_run_stabelilo
1778 && ask_me_yes_or_no("Did you change the mountlist?"))
1779
1780 /* interactive mode */
1781 {
1782 mvaddstr_and_log_it(g_currentY,
1783 0,
1784 "Modifying fstab and elilo.conf... ");
1785 sprintf(command, "stabelilo-me");
1786 res = run_program_and_log_output(command, 3);
1787 if (res) {
1788 popup_and_OK
1789 ("You will now edit fstab and elilo.conf, to make sure they match your new mountlist.");
1790 for (done = FALSE; !done;) {
1791 if (!g_text_mode) {
1792 newtSuspend();
1793 }
1794 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1795 paranoid_system(tmp);
1796 sprintf(tmp, "%s " MNT_RESTORING "/etc/elilo.conf",
1797 editor);
1798 paranoid_system(tmp);
1799 if (!g_text_mode) {
1800 newtResume();
1801 }
1802// newtCls();
1803 if (ask_me_yes_or_no("Edit them again?")) {
1804 continue;
1805 }
1806 done = TRUE;
1807 }
1808 } else {
1809 log_to_screen("elilo.conf and fstab were modified OK");
1810 }
1811 } else
1812 /* nuke mode */
1813 {
1814 res = TRUE;
1815 }
1816 paranoid_free(command);
1817 paranoid_free(tmp);
1818 paranoid_free(editor);
1819 return (res);
1820}
1821
1822/**************************************************************************
1823 *END_RUN_ELILO *
1824 **************************************************************************/
1825
1826
1827/**
1828 * Install LILO on the user's boot drive (determined by /etc/lilo.conf).
1829 * @param offer_to_run_stablilo If TRUE, then offer to hack the user's fstab for them.
1830 * @return 0 for success, nonzero for failure.
1831 */
1832int run_lilo(bool offer_to_run_stablilo)
1833{
1834 /** malloc **/
1835 char *command;
1836 char *tmp;
1837 char *editor;
1838
1839 int res;
1840 int done;
1841 bool run_lilo_M = FALSE;
1842 malloc_string(command);
1843 malloc_string(tmp);
1844 malloc_string(editor);
1845
1846 if (!run_program_and_log_output
1847 ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) {
1848 run_lilo_M = TRUE;
1849 }
1850
1851 strcpy(editor, find_my_editor());
1852 if (offer_to_run_stablilo
1853 && ask_me_yes_or_no("Did you change the mountlist?"))
1854
1855 /* interactive mode */
1856 {
1857 mvaddstr_and_log_it(g_currentY,
1858 0,
1859 "Modifying fstab and lilo.conf, and running LILO... ");
1860 sprintf(command, "stablilo-me");
1861 res = run_program_and_log_output(command, 3);
1862 if (res) {
1863 popup_and_OK
1864 ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist.");
1865 for (done = FALSE; !done;) {
1866 if (!g_text_mode) {
1867 newtSuspend();
1868 }
1869 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1870 paranoid_system(tmp);
1871 sprintf(tmp, "%s " MNT_RESTORING "/etc/lilo.conf", editor);
1872 paranoid_system(tmp);
1873 if (!g_text_mode) {
1874 newtResume();
1875 }
1876// newtCls();
1877 if (ask_me_yes_or_no("Edit them again?")) {
1878 continue;
1879 }
1880 res =
1881 run_program_and_log_output("chroot " MNT_RESTORING
1882 " lilo -L", 3);
1883 if (res) {
1884 res =
1885 run_program_and_log_output("chroot " MNT_RESTORING
1886 " lilo", 3);
1887 }
1888 if (res) {
1889 done =
1890 ask_me_yes_or_no
1891 ("LILO failed. Re-edit system files?");
1892 } else {
1893 done = TRUE;
1894 }
1895 }
1896 } else {
1897 log_to_screen("lilo.conf and fstab were modified OK");
1898 }
1899 } else
1900 /* nuke mode */
1901 {
1902 mvaddstr_and_log_it(g_currentY,
1903 0,
1904 "Running LILO... ");
1905 res =
1906 run_program_and_log_output("chroot " MNT_RESTORING " lilo -L",
1907 3);
1908 if (res) {
1909 res =
1910 run_program_and_log_output("chroot " MNT_RESTORING " lilo",
1911 3);
1912 }
1913 if (res) {
1914 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1915 log_to_screen
1916 ("Failed to re-jig fstab and/or lilo. Edit/run manually, please.");
1917 } else {
1918 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1919 }
1920 }
1921 if (run_lilo_M) {
1922 run_program_and_log_output("chroot " MNT_RESTORING
1923 " lilo -M /dev/hda", 3);
1924 run_program_and_log_output("chroot " MNT_RESTORING
1925 " lilo -M /dev/sda", 3);
1926 }
1927 paranoid_free(command);
1928 paranoid_free(tmp);
1929 paranoid_free(editor);
1930 return (res);
1931}
1932
1933/**************************************************************************
1934 *END_RUN_LILO *
1935 **************************************************************************/
1936
1937
1938/**
1939 * Install a raw MBR onto @p bd.
1940 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1941 * @param bd The device to copy the stored MBR to.
1942 * @return 0 for success, nonzero for failure.
1943 */
1944int run_raw_mbr(bool offer_to_hack_scripts, char *bd)
1945{
1946 /** malloc **/
1947 char *command;
1948 char *boot_device;
1949 char *tmp;
1950 char *editor;
1951 int res;
1952 int done;
1953
1954 malloc_string(command);
1955 malloc_string(boot_device);
1956 malloc_string(tmp);
1957 malloc_string(editor);
1958 assert_string_is_neither_NULL_nor_zerolength(bd);
1959
1960 strcpy(editor, find_my_editor());
1961 strcpy(boot_device, bd);
1962 sprintf(command, "raw-MR %s /tmp/mountlist.txt", boot_device);
1963 log_msg(2, "run_raw_mbr() --- command='%s'", command);
1964
1965 if (offer_to_hack_scripts
1966 && ask_me_yes_or_no("Did you change the mountlist?"))
1967 /* interactive mode */
1968 {
1969 mvaddstr_and_log_it(g_currentY, 0,
1970 "Modifying fstab and restoring MBR... ");
1971 for (done = FALSE; !done;) {
1972 if (!run_program_and_log_output("which vi", FALSE)) {
1973 popup_and_OK("You will now edit fstab");
1974 if (!g_text_mode) {
1975 newtSuspend();
1976 }
1977 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1978 paranoid_system(tmp);
1979 if (!g_text_mode) {
1980 newtResume();
1981 }
1982// newtCls();
1983 }
1984 popup_and_get_string("Boot device",
1985 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1986 boot_device, MAX_STR_LEN / 4);
1987 sprintf(command, "stabraw-me %s", boot_device);
1988 res = run_program_and_log_output(command, 3);
1989 if (res) {
1990 done = ask_me_yes_or_no("Modifications failed. Re-try?");
1991 } else {
1992 done = TRUE;
1993 }
1994 }
1995 } else
1996 /* nuke mode */
1997 {
1998 mvaddstr_and_log_it(g_currentY, 0,
1999 "Restoring MBR... ");
2000 res = run_program_and_log_output(command, 3);
2001 }
2002 if (res) {
2003 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2004 log_to_screen
2005 ("MBR+fstab processed w/error(s). See /tmp/mondo-restore.log for more info.");
2006 } else {
2007 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2008 }
2009 paranoid_free(command);
2010 paranoid_free(boot_device);
2011 paranoid_free(tmp);
2012 paranoid_free(editor);
2013 return (res);
2014}
2015
2016/**************************************************************************
2017 *END_RUN_RAW_MBR *
2018 **************************************************************************/
2019
2020
2021
2022
2023
2024/**
2025 * Turn signal trapping on or off.
2026 * @param on If TRUE, then do full cleanup when we receive a signal; if FALSE, then
2027 * print a message and exit immediately.
2028 */
2029void set_signals(int on)
2030{
2031 int signals[] =
2032 { SIGKILL, SIGPIPE, SIGTERM, SIGHUP, SIGTRAP, SIGABRT, SIGINT,
2033SIGSTOP, 0 };
2034 int i;
2035 for (i = 0; signals[i]; i++) {
2036 if (on) {
2037 signal(signals[i], terminate_daemon);
2038 } else {
2039 signal(signals[i], termination_in_progress);
2040 }
2041 }
2042}
2043
2044/**************************************************************************
2045 *END_SET_SIGNALS *
2046 **************************************************************************/
2047
2048
2049/**
2050 * malloc() and set sensible defaults for the mondorestore filename variables.
2051 * @param bkpinfo The backup information structure. Fields used:
2052 * - @c bkpinfo->tmpdir
2053 * - @c bkpinfo->disaster_recovery
2054 */
2055void setup_MR_global_filenames(struct s_bkpinfo *bkpinfo)
2056{
2057 char *temppath;
2058
2059 assert(bkpinfo != NULL);
2060
2061 malloc_string(g_biggielist_txt);
2062 malloc_string(g_filelist_full);
2063 malloc_string(g_filelist_imagedevs);
2064 malloc_string(g_imagedevs_restthese);
2065 malloc_string(g_mondo_cfg_file);
2066 malloc_string(g_mountlist_fname);
2067 malloc_string(g_mondo_home);
2068 malloc_string(g_tmpfs_mountpt);
2069 malloc_string(g_isodir_device);
2070 malloc_string(g_isodir_format);
2071
2072 temppath = bkpinfo->tmpdir;
2073
2074 sprintf(g_biggielist_txt, "%s/%s", temppath, BIGGIELIST_TXT_STUB);
2075 sprintf(g_filelist_full, "%s/%s", temppath, FILELIST_FULL_STUB);
2076 sprintf(g_filelist_imagedevs, "%s/tmp/filelist.imagedevs", temppath);
2077// sprintf(g_imagedevs_pot, "%s/tmp/imagedevs.pot", temppath);
2078 sprintf(g_imagedevs_restthese, "%s/tmp/imagedevs.restore-these",
2079 temppath);
2080 if (bkpinfo->disaster_recovery) {
2081 sprintf(g_mondo_cfg_file, "/%s", MONDO_CFG_FILE_STUB);
2082 sprintf(g_mountlist_fname, "/%s", MOUNTLIST_FNAME_STUB);
2083 } else {
2084 sprintf(g_mondo_cfg_file, "%s/%s", temppath, MONDO_CFG_FILE_STUB);
2085 sprintf(g_mountlist_fname, "%s/%s", temppath,
2086 MOUNTLIST_FNAME_STUB);
2087 }
2088}
2089
2090/**************************************************************************
2091 *END_SET_GLOBAL_FILENAME *
2092 **************************************************************************/
2093
2094
2095/**
2096 * Copy @p input_file (containing the result of a compare) to @p output_file,
2097 * deleting spurious "changes" along the way.
2098 * @param output_file The output file to write with spurious changes removed.
2099 * @param input_file The input file, a list of changed files created by a compare.
2100 */
2101void streamline_changes_file(char *output_file, char *input_file)
2102{
2103 FILE *fin;
2104 FILE *fout;
2105 /** malloc **/
2106 char *incoming;
2107
2108 assert_string_is_neither_NULL_nor_zerolength(output_file);
2109 assert_string_is_neither_NULL_nor_zerolength(input_file);
2110 malloc_string(incoming);
2111
2112 if (!(fin = fopen(input_file, "r"))) {
2113 log_OS_error(input_file);
2114 return;
2115 }
2116 if (!(fout = fopen(output_file, "w"))) {
2117 fatal_error("cannot open output_file");
2118 }
2119 for (fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin);
2120 fgets(incoming, MAX_STR_LEN - 1, fin)) {
2121 if (strncmp(incoming, "etc/adjtime", 11)
2122 && strncmp(incoming, "etc/mtab", 8)
2123 && strncmp(incoming, "tmp/", 4)
2124 && strncmp(incoming, "boot/map", 8)
2125 && !strstr(incoming, "incheckentry")
2126 && strncmp(incoming, "etc/mail/statistics", 19)
2127 && strncmp(incoming, "var/", 4))
2128 fprintf(fout, "%s", incoming); /* don't need \n here, for some reason.. */
2129 }
2130 paranoid_fclose(fout);
2131 paranoid_fclose(fin);
2132 paranoid_free(incoming);
2133}
2134
2135/**************************************************************************
2136 *END_STREAMLINE_CHANGES_FILE *
2137 **************************************************************************/
2138
2139
2140/**
2141 * Exit due to a signal (normal cleanup).
2142 * @param sig The signal we're exiting due to.
2143 */
2144void terminate_daemon(int sig)
2145{
2146 log_to_screen
2147 ("Mondorestore is terminating in response to a signal from the OS");
2148 paranoid_MR_finish(254);
2149}
2150
2151/**************************************************************************
2152 *END_TERMINATE_DAEMON *
2153 **************************************************************************/
2154
2155
2156/**
2157 * Give the user twenty seconds to press Ctrl-Alt-Del before we nuke their drives.
2158 */
2159void twenty_seconds_til_yikes()
2160{
2161 int i;
2162 /* MALLOC * */
2163 char *tmp;
2164
2165 malloc_string(tmp);
2166 if (does_file_exist("/tmp/NOPAUSE")) {
2167 return;
2168 }
2169 open_progress_form("CAUTION",
2170 "Be advised: I am about to ERASE your hard disk(s)!",
2171 "You may press Ctrl+Alt+Del to abort safely.",
2172 "", 20);
2173 for (i = 0; i < 20; i++) {
2174 g_current_progress = i;
2175 sprintf(tmp, "You have %d seconds left to abort.", 20 - i);
2176 update_progress_form(tmp);
2177 sleep(1);
2178 }
2179 close_progress_form();
2180 paranoid_free(tmp);
2181}
2182
2183/**************************************************************************
2184 *END_TWENTY_SECONDS_TIL_YIKES *
2185 **************************************************************************/
2186
2187
2188
2189
2190
2191/**
2192 * Exit due to a signal (no cleanup).
2193 * @param sig The signal we're exiting due to.
2194 */
2195void termination_in_progress(int sig)
2196{
2197 log_msg(1, "Termination in progress");
2198 usleep(1000);
2199 pthread_exit(0);
2200}
2201
2202/**************************************************************************
2203 *END_TERMINATION_IN_PROGRESS *
2204 **************************************************************************/
2205
2206
2207
2208/**
2209 * Unmount all devices in @p p_external_copy_of_mountlist.
2210 * @param p_external_copy_of_mountlist The mountlist to guide the devices to unmount.
2211 * @return 0 for success, nonzero for failure.
2212 */
2213int unmount_all_devices(struct mountlist_itself
2214 *p_external_copy_of_mountlist)
2215{
2216 struct mountlist_itself *mountlist;
2217 int retval = 0, lino, res = 0, i;
2218 char *command;
2219 char *tmp;
2220
2221 malloc_string(command);
2222 malloc_string(tmp);
2223 assert(p_external_copy_of_mountlist != NULL);
2224
2225 mountlist = malloc(sizeof(struct mountlist_itself));
2226 memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
2227 sizeof(struct mountlist_itself));
2228 sort_mountlist_by_mountpoint(mountlist, 0);
2229
2230 run_program_and_log_output("df -m", 3);
2231 mvaddstr_and_log_it(g_currentY, 0, "Unmounting devices ");
2232 open_progress_form("Unmounting devices",
2233 "Unmounting all devices that were mounted,",
2234 "in preparation for the post-restoration reboot.",
2235 "", mountlist->entries);
2236 chdir("/");
2237 for (i = 0;
2238 i < 10
2239 &&
2240 run_program_and_log_output
2241 ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
2242 i++) {
2243 sleep(1);
2244 log_msg(2, "Waiting for buffer() to finish");
2245 }
2246
2247 paranoid_system("sync");
2248
2249 if (run_program_and_log_output
2250 ("cp -f /tmp/mondo-restore.log " MNT_RESTORING "/tmp/", FALSE)) {
2251 log_msg(1,
2252 "Error. Failed to copy log to PC's /tmp dir. (Mounted read-only?)");
2253 }
2254 if (run_program_and_log_output
2255 ("cp -f /tmp/mondo-restore.log " MNT_RESTORING "/root/", FALSE)) {
2256 log_msg(1,
2257 "Error. Failed to copy log to PC's /root dir. (Mounted read-only?)");
2258 }
2259 if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2260 run_program_and_log_output("mkdir -p " MNT_RESTORING
2261 "/mnt/.boot.d", 5);
2262 }
2263 for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2264 if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2265 continue;
2266 }
2267 sprintf(tmp, "Unmounting device %s ", mountlist->el[lino].device);
2268
2269 update_progress_form(tmp);
2270 if (is_this_device_mounted(mountlist->el[lino].device)) {
2271 if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
2272 sprintf(command, "swapoff %s", mountlist->el[lino].device);
2273 } else {
2274 if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
2275 sprintf(command, "umount %s/", MNT_RESTORING);
2276 log_msg(3,
2277 "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2278 } else {
2279 sprintf(command, "umount " MNT_RESTORING "%s",
2280 mountlist->el[lino].mountpoint);
2281 }
2282 }
2283 log_msg(10, "The 'umount' command is '%s'", command);
2284 res = run_program_and_log_output(command, 3);
2285 } else {
2286 strcat(tmp, "...not mounted anyway :-) OK");
2287 res = 0;
2288 }
2289 g_current_progress++;
2290 if (res) {
2291 strcat(tmp, "...Failed");
2292 retval++;
2293 log_to_screen(tmp);
2294 } else {
2295 log_msg(2, tmp);
2296 }
2297 }
2298 close_progress_form();
2299 if (retval) {
2300 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2301 } else {
2302 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2303 }
2304 if (retval) {
2305 log_to_screen("Unable to unmount some of your partitions.");
2306 } else {
2307 log_to_screen("All partitions were unmounted OK.");
2308 }
2309 free(mountlist);
2310 paranoid_free(command);
2311 paranoid_free(tmp);
2312 return (retval);
2313}
2314
2315/**************************************************************************
2316 *END_UNMOUNT_ALL_DEVICES *
2317 **************************************************************************/
2318
2319
2320
2321/**
2322 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2323 * to the ./tmp/ directory.
2324 * @param dev The tape device to read from.
2325 * @return 0 for success, nonzero for failure.
2326 */
2327int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2328{
2329 char *command;
2330 int res = 0;
2331 // BCO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
2332 long tape_block_size = 32768;
2333
2334 malloc_string(command);
2335
2336 // tar -zxvf-
2337 sprintf(command,
2338 "dd if=%s bs=%ld count=%ld 2> /dev/null | tar -zx %s %s %s %s %s",
2339 dev,
2340 tape_block_size,
2341 1024L * 1024 * 32 / tape_block_size,
2342 MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB,
2343 BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, "tmp/i-want-my-lvm");
2344 log_msg(2, "command = '%s'", command);
2345 res = run_program_and_log_output(command, -1);
2346 if (res != 0 && does_file_exist(MONDO_CFG_FILE_STUB)) {
2347 res = 0;
2348 }
2349 paranoid_free(command);
2350 return (res);
2351}
2352
2353
2354
2355/**
2356 * Get the configuration file from the floppy, tape, or CD.
2357 * @param bkpinfo The backup information structure. Fields used:
2358 * - @c bkpinfo->backup_media_type
2359 * - @c bkpinfo->media_device
2360 * - @c bkpinfo->tmpdir
2361 * @return 0 for success, nonzero for failure.
2362 */
2363int get_cfg_file_from_archive(struct s_bkpinfo *bkpinfo)
2364{
2365 int retval = 0;
2366
2367 /** malloc *****/
2368 char *device;
2369 char *command;
2370 char *cfg_file;
2371 char *mounted_cfgf_path;
2372 char *tmp;
2373 char *mountpt;
2374 char *ramdisk_fname;
2375 char *mountlist_file;
2376 int res;
2377
2378 bool try_plan_B;
2379
2380 assert(bkpinfo != NULL);
2381 malloc_string(cfg_file);
2382 malloc_string(mounted_cfgf_path);
2383 malloc_string(mountpt);
2384 malloc_string(ramdisk_fname);
2385 malloc_string(mountlist_file);
2386 malloc_string(device);
2387 malloc_string(command);
2388 malloc_string(tmp);
2389 log_msg(2, "gcffa --- starting");
2390 log_to_screen("I'm thinking...");
2391 sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
2392 device[0] = '\0';
2393 chdir(bkpinfo->tmpdir);
2394 strcpy(cfg_file, MONDO_CFG_FILE_STUB);
2395 unlink(cfg_file); // cfg_file[] is missing the '/' at the start, FYI, by intent
2396 unlink(FILELIST_FULL_STUB);
2397 unlink(BIGGIELIST_TXT_STUB);
2398 unlink("tmp/i-want-my-lvm");
2399 sprintf(command, "mkdir -p %s", mountpt);
2400 run_program_and_log_output(command, FALSE);
2401
2402// unlink( "tmp/mondo-restore.cfg" ); // superfluous, surely?
2403
2404 sprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2405 sprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir,
2406 MOUNTLIST_FNAME_STUB);
2407 // make_hole_for_file( cfg_file );
2408 // make_hole_for_file( mountlist_file);
2409 log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
2410
2411 /* Floppy? */
2412 sprintf(tmp, "mkdir -p %s", mountpt);
2413 run_program_and_log_output(tmp, FALSE);
2414 sprintf(tmp, "mkdir -p %s/tmp", bkpinfo->tmpdir);
2415 run_program_and_log_output(tmp, FALSE);
2416
2417 sprintf(command, "mount /dev/fd0u1722 %s", mountpt);
2418 sprintf(tmp,
2419 "(sleep 15; kill `ps | grep \"%s\" | cut -d' ' -f1` 2> /dev/null) &",
2420 command);
2421 log_msg(1, "tmp = '%s'", tmp);
2422 system(tmp);
2423 res = run_program_and_log_output(command, FALSE);
2424 if (res) {
2425 sprintf(command, "mount /dev/fd0H1440 %s", mountpt);
2426 res = run_program_and_log_output(command, FALSE);
2427 }
2428 if (res) {
2429 try_plan_B = TRUE;
2430 } else {
2431 try_plan_B = TRUE;
2432 log_msg(2,
2433 "Mounted floppy OK but I don't trust it because the archives might contain more up-to-date config file than the floppy does.");
2434// NB: If busybox does not support 'mount -o loop' then Plan A WILL NOT WORK.
2435 log_msg(2, "Processing floppy (plan A?)");
2436 sprintf(ramdisk_fname, "%s/mindi.rdz", mountpt);
2437 if (!does_file_exist(ramdisk_fname)) {
2438 sprintf(ramdisk_fname, "%s/initrd.img", mountpt);
2439 }
2440 if (!does_file_exist(ramdisk_fname)) {
2441 log_msg(2,
2442 "Cannot find ramdisk file on mountpoint. Are you sure that's a boot disk in the drive?");
2443 }
2444 if (extract_config_file_from_ramdisk
2445 (bkpinfo, ramdisk_fname, cfg_file, mountlist_file)) {
2446 log_msg(2,
2447 "Warning - failed to extract config file from ramdisk. I think this boot disk is mangled.");
2448 }
2449 sprintf(command, "umount %s", mountpt);
2450 run_program_and_log_output(command, 5);
2451 unlink(ramdisk_fname);
2452 }
2453 if (!does_file_exist(cfg_file)) {
2454 log_msg(2, "gcffa --- we don't have cfg file yet.");
2455 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2456 try_plan_B = TRUE;
2457 } else {
2458 log_msg(2, "gcffa --- calling mount_cdrom now :)");
2459 if (!mount_cdrom(bkpinfo)) {
2460 log_msg(2,
2461 "gcffa --- managed to mount CD; so, no need for Plan B");
2462 try_plan_B = FALSE;
2463 } else {
2464 try_plan_B = TRUE;
2465 }
2466 if (what_number_cd_is_this(bkpinfo) > 1) {
2467 insist_on_this_cd_number(bkpinfo,
2468 (g_current_media_number = 1));
2469 }
2470 }
2471 if (try_plan_B) {
2472 log_msg(2, "gcffa --- OK, switching to Plan B");
2473 chdir(bkpinfo->tmpdir);
2474 run_program_and_log_output("mkdir -p tmp", FALSE);
2475
2476 if (strlen(bkpinfo->media_device) == 0) {
2477 strcpy(bkpinfo->media_device, "/dev/st0");
2478 log_msg(2, "media_device is blank; assuming %s");
2479 }
2480 strcpy(tmp, bkpinfo->media_device);
2481 if (extract_cfg_file_and_mountlist_from_tape_dev
2482 (bkpinfo->media_device)) {
2483 strcpy(bkpinfo->media_device, "/dev/st0");
2484 if (extract_cfg_file_and_mountlist_from_tape_dev
2485 (bkpinfo->media_device)) {
2486 strcpy(bkpinfo->media_device, "/dev/osst0");
2487 if (extract_cfg_file_and_mountlist_from_tape_dev
2488 (bkpinfo->media_device)) {
2489 strcpy(bkpinfo->media_device, "/dev/ht0");
2490 if (extract_cfg_file_and_mountlist_from_tape_dev
2491 (bkpinfo->media_device)) {
2492 log_msg(3,
2493 "I tried lots of devices but none worked.");
2494 strcpy(bkpinfo->media_device, tmp);
2495 }
2496 }
2497 }
2498 }
2499
2500 if (!does_file_exist("tmp/mondo-restore.cfg")) {
2501 log_to_screen("Cannot find config info on tape/CD/floppy");
2502 return (1);
2503 }
2504 } else {
2505 log_msg(2,
2506 "gcffa --- looking at mounted CD for mindi-boot.2880.img");
2507 sprintf(command,
2508 "mount " MNT_CDROM
2509 "/images/mindi-boot.2880.img -o loop %s", mountpt);
2510 sprintf(mounted_cfgf_path, "%s/%s", mountpt, cfg_file);
2511 if (!does_file_exist(mounted_cfgf_path)) {
2512 log_msg(2,
2513 "gcffa --- Plan C, a.k.a. untarring some file from all.tar.gz");
2514 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
2515 run_program_and_log_output(command, TRUE);
2516 if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2517 fatal_error
2518 ("Please reinsert the disk/CD and try again.");
2519 }
2520 }
2521 }
2522 }
2523 if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2524 log_msg(1, "gcffa --- great! We've got the config file");
2525 sprintf(tmp, "%s/%s",
2526 call_program_and_get_last_line_of_output("pwd"),
2527 MONDO_CFG_FILE_STUB);
2528 sprintf(command, "cp -f %s %s", tmp, cfg_file);
2529 iamhere(command);
2530 if (strcmp(tmp, cfg_file)
2531 && run_program_and_log_output(command, 1)) {
2532 log_msg(1,
2533 "... but an error occurred when I tried to move it to %s",
2534 cfg_file);
2535 } else {
2536 log_msg(1, "... and I moved it successfully to %s", cfg_file);
2537 }
2538 sprintf(command, "cp -f %s/%s %s",
2539 call_program_and_get_last_line_of_output("pwd"),
2540 MOUNTLIST_FNAME_STUB, mountlist_file);
2541 iamhere(command);
2542 if (strcmp(tmp, cfg_file)
2543 && run_program_and_log_output(command, 1)) {
2544 log_msg(1, "Failed to get mountlist");
2545 } else {
2546 log_msg(1, "Got mountlist too");
2547 sprintf(command, "cp -f %s %s", mountlist_file,
2548 g_mountlist_fname);
2549 if (run_program_and_log_output(command, 1)) {
2550 log_msg(1, "Failed to copy mountlist to /tmp");
2551 } else {
2552 log_msg(1, "Copied mountlist to /tmp as well OK");
2553 sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2554 run_program_and_log_output(command, 1);
2555/* sprintf(command, "grep \" lvm \" %s", g_mountlist_fname);
2556 if (!run_program_and_log_output(command, 5) && !does_file_exist("/tmp/i-want-my-lvm"))
2557 {
2558 log_msg(1, "Warning. You want LVM but I don't have i-want-my-lvm. FIXME.");
2559 }
2560 else if (run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2561 {
2562 log_msg(1, "Warning. You don't want LVM but i-want-my-lvm exists. I'll delete it. Cool.");
2563 do_my_funky_lvm_stuff(TRUE, FALSE); // ...after I stop any LVMs :)
2564 stop_raid_device("/dev/md0");
2565 stop_raid_device("/dev/md1");
2566 stop_raid_device("/dev/md2");
2567 unlink("/tmp/i-want-my-lvm");
2568 }
2569 else if (!run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2570 {
2571 log_msg(1, "You had better pray that i-want-my-lvm patches your mountlist. FIXME.");
2572 }
2573*/
2574 }
2575 }
2576 }
2577 run_program_and_log_output("umount " MNT_CDROM, FALSE);
2578 if (!does_file_exist(cfg_file)) {
2579 iamhere(cfg_file);
2580 log_msg(1, "%s not found", cfg_file);
2581 log_to_screen
2582 ("Oh dear. Unable to recover configuration file from boot disk");
2583 return (1);
2584 }
2585
2586 log_to_screen("Recovered mondo-restore.cfg");
2587 if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2588 log_to_screen("...but not mountlist.txt - a pity, really...");
2589 }
2590/* start SAH */
2591 else {
2592 sprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB,
2593 bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2594 run_program_and_log_output(command, FALSE);
2595 }
2596/*--commented out by SAH
2597 sprintf( command, "cp -f %s %s/%s", cfg_file, bkpinfo->tmpdir, MONDO_CFG_FILE_STUB );
2598 run_program_and_log_output( command, FALSE );
2599 sprintf( command, "cp -f %s %s/%s", mountlist_file, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB );
2600 run_program_and_log_output( command, FALSE );
2601*/
2602/* end SAH */
2603
2604 sprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2605 run_program_and_log_output(command, FALSE);
2606 sprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2607 run_program_and_log_output(command, FALSE);
2608 sprintf(command, "cp -f etc/raidtab /etc/");
2609 run_program_and_log_output(command, FALSE);
2610 sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2611 run_program_and_log_output(command, FALSE);
2612 g_backup_media_type = bkpinfo->backup_media_type;
2613 paranoid_free(device);
2614 paranoid_free(command);
2615 paranoid_free(tmp);
2616 paranoid_free(cfg_file);
2617 paranoid_free(mounted_cfgf_path);
2618 paranoid_free(mountpt);
2619 paranoid_free(ramdisk_fname);
2620 paranoid_free(mountlist_file);
2621 return (retval);
2622}
2623
2624/**************************************************************************
2625 *END_GET_CFG_FILE_FROM_ARCHIVE *
2626 **************************************************************************/
2627
2628/* @} - end restoreUtilityGroup */
2629
2630
2631/***************************************************************************
2632 * F@ *
2633 * () -- Hugo Rabson *
2634 * *
2635 * Purpose: *
2636 * *
2637 * Called by: *
2638 * Params: - - *
2639 * Returns: 0=success; nonzero=failure *
2640 ***************************************************************************/
2641
2642
2643
2644void wait_until_software_raids_are_prepped(char *mdstat_file,
2645 int wait_for_percentage)
2646{
2647 struct raidlist_itself *raidlist;
2648 int unfinished_mdstat_devices = 9999, i;
2649 char *screen_message;
2650
2651 malloc_string(screen_message);
2652 raidlist = malloc(sizeof(struct raidlist_itself));
2653
2654 assert(wait_for_percentage <= 100);
2655 iamhere("wait_until_software_raids_are_prepped");
2656 while (unfinished_mdstat_devices > 0) {
2657 // FIXME: Prefix '/dev/' should really be dynamic!
2658 if (parse_mdstat(raidlist, "/dev/")) {
2659 log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2660 log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2661 return;
2662 }
2663 for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2664 if (raidlist->el[i].progress < wait_for_percentage) {
2665 unfinished_mdstat_devices++;
2666 if (raidlist->el[i].progress == -1) // delayed while another partition inits
2667 {
2668 continue;
2669 }
2670 log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2671 sprintf(screen_message, "Sync'ing %s",
2672 raidlist->el[i].raid_device);
2673 open_evalcall_form(screen_message);
2674 while (raidlist->el[i].progress < wait_for_percentage) {
2675 log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2676 update_evalcall_form(raidlist->el[i].progress);
2677 sleep(2);
2678 // FIXME: Prefix '/dev/' should really be dynamic!
2679 if (parse_mdstat(raidlist, "/dev/")) {
2680 break;
2681 }
2682 }
2683 close_evalcall_form();
2684 }
2685 }
2686 }
2687 paranoid_free(screen_message);
2688 paranoid_free(raidlist);
2689}
Note: See TracBrowser for help on using the repository browser.