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

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

Should fix #63, , and add the required interface in mondorestore to handle the new way of dealing with ACLs and XATTRs

  • Property svn:keywords set to Id
File size: 80.6 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 "../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{
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 strcpy(bkpinfo->zip_exe, "lzop");
1139 strcpy(bkpinfo->zip_suffix, "lzo");
1140 } else {
1141 read_cfg_var(cfg_file, "use-comp", value);
1142 if (strstr(value, "yes")) {
1143 bkpinfo->use_lzo = FALSE;
1144 strcpy(bkpinfo->zip_exe, "bzip2");
1145 strcpy(bkpinfo->zip_suffix, "bz2");
1146 } else {
1147 bkpinfo->zip_exe[0] = bkpinfo->zip_suffix[0] = '\0';
1148 }
1149 }
1150
1151 value[0] = '\0';
1152 read_cfg_var(cfg_file, "differential", value);
1153 if (!strcmp(value, "yes") || !strcmp(value, "1")) {
1154 bkpinfo->differential = TRUE;
1155 }
1156 log_msg(2, "differential var = '%s'", value);
1157 if (bkpinfo->differential) {
1158 log_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
1159 } else {
1160 log_msg(2, "This is a regular (full) backup");
1161 }
1162
1163 read_cfg_var(g_mondo_cfg_file, "please-dont-eject", tmp);
1164 if (tmp[0]
1165 ||
1166 strstr(call_program_and_get_last_line_of_output
1167 ("cat /proc/cmdline"), "donteject")) {
1168 bkpinfo->please_dont_eject = TRUE;
1169 log_msg(2, "Ok, I shan't eject when restoring! Groovy.");
1170 }
1171
1172 if (bkpinfo->backup_media_type == nfs) {
1173 if (!cfgf) {
1174 log_msg(2, "nfs_mount remains %s", bkpinfo->nfs_mount);
1175 log_msg(2, "nfs_remote_dir remains %s",
1176 bkpinfo->nfs_remote_dir);
1177 log_msg(2,
1178 "...cos it wouldn't make sense to abandon the values that GOT ME to this config file in the first place");
1179 } else {
1180 read_cfg_var(g_mondo_cfg_file, "nfs-server-mount",
1181 bkpinfo->nfs_mount);
1182 read_cfg_var(g_mondo_cfg_file, "nfs-server-path",
1183 bkpinfo->nfs_remote_dir);
1184 log_msg(2, "nfs_mount is %s", bkpinfo->nfs_mount);
1185 log_msg(2, "nfs_remote_dir is %s", bkpinfo->nfs_remote_dir);
1186 }
1187 if (strstr(call_program_and_get_last_line_of_output
1188 ("cat /proc/cmdline"), "pxe")) {
1189 /* We need to override values in PXE mode as it's
1190 * already done in start-nfs */
1191 envtmp1 = getenv("nfsmount");
1192 if (envtmp1 == NULL) {
1193 fatal_error("no nfsmount variable in environment");
1194 }
1195 envtmp2 = getenv("dirimg");
1196 if (envtmp2 == NULL) {
1197 fatal_error("no dirimg variable in environment");
1198 }
1199 strcpy(bkpinfo->nfs_mount,envtmp1);
1200 strcpy(bkpinfo->nfs_remote_dir,envtmp2);
1201 }
1202 } else if (bkpinfo->backup_media_type == iso) {
1203 /* Patch by Conor Daly 23-june-2004
1204 * to correctly mount iso-dev and set a sensible
1205 * isodir in disaster recovery mode
1206 */
1207 strcpy(old_isodir, bkpinfo->isodir);
1208 read_cfg_var(g_mondo_cfg_file, "iso-mnt", iso_mnt);
1209 read_cfg_var(g_mondo_cfg_file, "isodir", iso_path);
1210 sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1211 if (!bkpinfo->isodir[0]) {
1212 strcpy(bkpinfo->isodir, old_isodir);
1213 }
1214 if (!bkpinfo->disaster_recovery) {
1215 if (strcmp(old_isodir, bkpinfo->isodir)) {
1216 log_it
1217 ("user nominated isodir differs from archive, keeping user's choice: %s %s\n",
1218 old_isodir, bkpinfo->isodir);
1219 strcpy(bkpinfo->isodir, old_isodir);
1220 }
1221 }
1222 read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
1223 log_msg(2, "isodir=%s; iso-dev=%s", bkpinfo->isodir,
1224 g_isodir_device);
1225 if (bkpinfo->disaster_recovery) {
1226 if (is_this_device_mounted(g_isodir_device)) {
1227 log_msg(2, "NB: isodir is already mounted");
1228 /* Find out where it's mounted */
1229 sprintf(command,
1230 "mount | grep -E '^%s' | tail -n1 | cut -d' ' -f3",
1231 g_isodir_device);
1232 log_it("command = %s", command);
1233 log_it("res of it = %s",
1234 call_program_and_get_last_line_of_output(command));
1235 sprintf(iso_mnt, "%s",
1236 call_program_and_get_last_line_of_output(command));
1237 } else {
1238 sprintf(iso_mnt, "/tmp/isodir");
1239 sprintf(tmp, "mkdir -p %s", iso_mnt);
1240 run_program_and_log_output(tmp, 5);
1241 sprintf(tmp, "mount %s %s", g_isodir_device, iso_mnt);
1242 if (run_program_and_log_output(tmp, 3)) {
1243 log_msg(1,
1244 "Unable to mount isodir. Perhaps this is really a CD backup?");
1245 bkpinfo->backup_media_type = cdr;
1246 strcpy(bkpinfo->media_device, "/dev/cdrom"); /* superfluous */
1247 bkpinfo->isodir[0] = iso_mnt[0] = iso_path[0] = '\0';
1248 if (mount_cdrom(bkpinfo)) {
1249 fatal_error
1250 ("Unable to mount isodir. Failed to mount CD-ROM as well.");
1251 } else {
1252 log_msg(1,
1253 "You backed up to disk, then burned some CDs.");
1254 }
1255 }
1256 }
1257 /* bkpinfo->isodir should now be the true path to prefix-1.iso etc... */
1258 if (bkpinfo->backup_media_type == iso) {
1259 sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1260 }
1261 }
1262 }
1263
1264 if (media_specified_by_user != none) {
1265 if (g_restoring_live_from_cd) {
1266 if (bkpinfo->backup_media_type != media_specified_by_user) {
1267 log_msg(2,
1268 "bkpinfo->backup_media_type != media_specified_by_user, so I'd better ask :)");
1269 interactively_obtain_media_parameters_from_user(bkpinfo,
1270 FALSE);
1271 media_specified_by_user = bkpinfo->backup_media_type;
1272 get_cfg_file_from_archive(bkpinfo);
1273/*
1274 if (media_specified_by_user != cdr && media_specified_by_user == cdrw)
1275 { g_restoring_live_from_cd = FALSE; }
1276*/
1277 }
1278 }
1279 bkpinfo->backup_media_type = media_specified_by_user;
1280 }
1281 g_backup_media_type = bkpinfo->backup_media_type;
1282 paranoid_free(value);
1283 paranoid_free(tmp);
1284 paranoid_free(command);
1285 paranoid_free(iso_mnt);
1286 paranoid_free(iso_path);
1287 paranoid_free(old_isodir);
1288 return (0);
1289
1290}
1291
1292/**************************************************************************
1293 *END_READ_CFG_FILE_INTO_BKPINFO *
1294 **************************************************************************/
1295
1296
1297
1298
1299/**
1300 * Allow the user to edit the filelist and biggielist.
1301 * The filelist is unlinked after it is read.
1302 * @param bkpinfo The backup information structure. Fields used:
1303 * - @c bkpinfo->backup_media_type
1304 * - @c bkpinfo->isodir
1305 * - @c bkpinfo->media_device
1306 * - @c bkpinfo->tmpdir
1307 * @return The filelist structure containing the information read from disk.
1308 */
1309struct
1310s_node *process_filelist_and_biggielist(struct s_bkpinfo *bkpinfo)
1311{
1312 struct s_node *filelist;
1313
1314 /** add mallocs**/
1315 char *command;
1316 char *tmp;
1317 int res = 0;
1318 pid_t pid;
1319
1320 assert(bkpinfo != NULL);
1321 malloc_string(command);
1322 malloc_string(tmp);
1323
1324 if (does_file_exist(g_filelist_full)
1325 && does_file_exist(g_biggielist_txt)) {
1326 log_msg(1, "%s exists", g_filelist_full);
1327 log_msg(1, "%s exists", g_biggielist_txt);
1328 log_msg(2,
1329 "Filelist and biggielist already recovered from media. Yay!");
1330 } else {
1331 getcwd(tmp, MAX_STR_LEN);
1332 chdir(bkpinfo->tmpdir);
1333 log_msg(1, "chdir(%s)", bkpinfo->tmpdir);
1334 log_to_screen("Extracting filelist and biggielist from media...");
1335 unlink("/tmp/filelist.full");
1336 unlink("/" FILELIST_FULL_STUB);
1337 unlink("/tmp/i-want-my-lvm");
1338 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
1339 sprintf(command,
1340 "tar -zxf %s %s %s %s %s %s",
1341 bkpinfo->media_device,
1342 MOUNTLIST_FNAME_STUB,
1343 BIGGIELIST_TXT_STUB,
1344 FILELIST_FULL_STUB,
1345 "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1346 log_msg(1, "tarcommand = %s", command);
1347 run_program_and_log_output(command, 1);
1348 } else {
1349 log_msg(2,
1350 "Calling insist_on_this_cd_number; bkpinfo->isodir=%s",
1351 bkpinfo->isodir);
1352 insist_on_this_cd_number(bkpinfo, 1);
1353 log_msg(2, "Back from iotcn");
1354 run_program_and_log_output("mount", 1);
1355 sprintf(command,
1356 "tar -zxf %s/images/all.tar.gz %s %s %s %s %s",
1357 MNT_CDROM,
1358 MOUNTLIST_FNAME_STUB,
1359 BIGGIELIST_TXT_STUB,
1360 FILELIST_FULL_STUB,
1361 "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1362
1363 log_msg(1, "tarcommand = %s", command);
1364 run_program_and_log_output(command, 1);
1365// popup_and_OK("Press ENTER to continue");
1366 if (!does_file_exist(BIGGIELIST_TXT_STUB)) {
1367 fatal_error
1368 ("all.tar.gz did not include tmp/biggielist.txt");
1369 }
1370 if (!does_file_exist(FILELIST_FULL_STUB)) {
1371 fatal_error
1372 ("all.tar.gz did not include tmp/filelist.full.gz");
1373 }
1374 }
1375 sprintf(command, "cp -f %s %s", MONDO_CFG_FILE_STUB,
1376 g_mondo_cfg_file);
1377 run_program_and_log_output(command, FALSE);
1378
1379 sprintf(command, "cp -f %s/%s %s", bkpinfo->tmpdir,
1380 BIGGIELIST_TXT_STUB, g_biggielist_txt);
1381 log_msg(1, "command = %s", command);
1382 paranoid_system(command);
1383 sprintf(command, "ln -sf %s/%s %s", bkpinfo->tmpdir,
1384 FILELIST_FULL_STUB, g_filelist_full);
1385 log_msg(1, "command = %s", command);
1386 paranoid_system(command);
1387 }
1388
1389 if (am_I_in_disaster_recovery_mode()
1390 &&
1391 ask_me_yes_or_no("Do you want to retrieve the mountlist as well?"))
1392 {
1393// sprintf(command, "cp -f tmp/mountlist.txt /tmp");
1394 sprintf(command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB,
1395 bkpinfo->tmpdir);
1396 paranoid_system(command);
1397 }
1398
1399 chdir(tmp);
1400
1401 if (!does_file_exist(g_biggielist_txt)) {
1402 log_msg(1, "Warning - %s not found", g_biggielist_txt);
1403 }
1404 if (!does_file_exist(g_filelist_full)) {
1405 log_msg(1, "Warning - %s does not exist", g_filelist_full);
1406 }
1407// popup_and_OK("Wonderful.");
1408
1409 log_msg(2, "Forking");
1410 pid = fork();
1411 switch (pid) {
1412 case -1:
1413 fatal_error("Forking error");
1414 break;
1415
1416 case 0:
1417 log_to_screen("Pre-processing filelist");
1418 if (!does_file_exist(g_biggielist_txt)) {
1419 sprintf(command, "> %s", g_biggielist_txt);
1420 paranoid_system(command);
1421 }
1422 sprintf(command, "grep -E '^/dev/.*' %s > %s",
1423 g_biggielist_txt, g_filelist_imagedevs);
1424 paranoid_system(command);
1425 exit(0);
1426 break;
1427
1428 default:
1429 open_evalcall_form("Pre-processing filelist");
1430 while (!waitpid(pid, (int *) 0, WNOHANG)) {
1431 usleep(100000);
1432 update_evalcall_form(0);
1433 }
1434 }
1435 close_evalcall_form();
1436
1437 log_msg(3, "loading filelist");
1438 filelist = load_filelist(g_filelist_full);
1439 log_msg(3, "deleting original filelist");
1440 unlink(g_filelist_full);
1441 if (g_text_mode) {
1442 printf("Restore which directory? --> ");
1443 fgets(tmp, sizeof(tmp), stdin);
1444 toggle_path_selection(filelist, tmp, TRUE);
1445 if (strlen(tmp) == 0) {
1446 res = 1;
1447 } else {
1448 res = 0;
1449 }
1450 } else {
1451 res = edit_filelist(filelist);
1452 }
1453 if (res) {
1454 log_msg(2, "User hit 'cancel'. Freeing filelist and aborting.");
1455 free_filelist(filelist);
1456 return (NULL);
1457 }
1458 ask_about_these_imagedevs(g_filelist_imagedevs, g_imagedevs_restthese);
1459 close_evalcall_form();
1460
1461 // NB: It's not necessary to add g_biggielist_txt to the filelist.full
1462 // file. The filelist.full file already contains the filename of EVERY
1463 // file backed up - regular and biggie files.
1464
1465 // However, we do want to make sure the imagedevs selected by the user
1466 // are flagged for restoring.
1467 if (length_of_file(g_imagedevs_restthese) > 2) {
1468 add_list_of_files_to_filelist(filelist, g_imagedevs_restthese,
1469 TRUE);
1470 }
1471
1472 paranoid_free(command);
1473 paranoid_free(tmp);
1474 return (filelist);
1475}
1476
1477/**************************************************************************
1478 *END_ PROCESS_FILELIST_AND_BIGGIELIST *
1479 **************************************************************************/
1480
1481
1482
1483
1484/**
1485 * Make a backup copy of <tt>path_root</tt>/<tt>filename</tt>.
1486 * The backup filename is the filename of the original with ".pristine" added.
1487 * @param path_root The place where the filesystem is mounted (e.g. MNT_RESTORING).
1488 * @param filename The filename (absolute path) within @p path_root.
1489 * @return 0 for success, nonzero for failure.
1490 */
1491int backup_crucial_file(char *path_root, char *filename)
1492{
1493 char *tmp;
1494 char *command;
1495 int res;
1496
1497 malloc_string(tmp);
1498 malloc_string(command);
1499 assert(path_root != NULL);
1500 assert_string_is_neither_NULL_nor_zerolength(filename);
1501
1502 sprintf(tmp, "%s/%s", path_root, filename);
1503 sprintf(command, "cp -f %s %s.pristine", tmp, tmp);
1504
1505 res = run_program_and_log_output(command, 5);
1506 paranoid_free(tmp);
1507 paranoid_free(command);
1508 return (res);
1509}
1510
1511
1512/**
1513 * Install the user's boot loader in the MBR.
1514 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported.
1515 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1516 * @return 0 for success, nonzero for failure.
1517 */
1518int run_boot_loader(bool offer_to_hack_scripts)
1519{
1520 int res;
1521 int retval = 0;
1522
1523 /** malloc *******/
1524 char *device;
1525 char *tmp;
1526 char *name;
1527
1528 malloc_string(device);
1529 malloc_string(tmp);
1530 malloc_string(name);
1531 backup_crucial_file(MNT_RESTORING, "/etc/fstab");
1532 backup_crucial_file(MNT_RESTORING, "/etc/grub.conf");
1533 backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf");
1534 backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf");
1535 read_cfg_var(g_mondo_cfg_file, "bootloader.device", device);
1536 read_cfg_var(g_mondo_cfg_file, "bootloader.name", name);
1537 sprintf(tmp, "run_boot_loader: device='%s', name='%s'", device, name);
1538 log_msg(2, tmp);
1539 system("sync");
1540 if (!strcmp(name, "LILO")) {
1541 res = run_lilo(offer_to_hack_scripts);
1542 } else if (!strcmp(name, "ELILO")) {
1543 res = run_elilo(offer_to_hack_scripts);
1544 } else if (!strcmp(name, "GRUB")) {
1545// 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?")))
1546// {
1547 res = run_grub(offer_to_hack_scripts, device);
1548// unlink(DO_MBR_PLEASE);
1549// }
1550// else
1551// {
1552// log_msg(1, "Not running run_grub(). Was a bad idea anyway.");
1553// res = 1;
1554// }
1555 } else if (!strcmp(name, "RAW")) {
1556 res = run_raw_mbr(offer_to_hack_scripts, device);
1557 }
1558#ifdef __FreeBSD__
1559 else if (!strcmp(name, "BOOT0")) {
1560 sprintf(tmp, "boot0cfg -B %s", device);
1561 res = run_program_and_log_output(tmp, FALSE);
1562 } else {
1563 sprintf(tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device);
1564 if (!system(tmp)) {
1565 sprintf(tmp, MNT_RESTORING "/sbin/fdisk -B %s", device);
1566 res = run_program_and_log_output(tmp, 3);
1567 } else {
1568 log_msg(1,
1569 "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");
1570 }
1571 }
1572#else
1573 else {
1574 log_to_screen
1575 ("Unable to determine type of boot loader. Defaulting to LILO.");
1576 res = run_lilo(offer_to_hack_scripts);
1577 }
1578#endif
1579 retval += res;
1580 if (res) {
1581 log_to_screen("Your boot loader returned an error");
1582 } else {
1583 log_to_screen("Your boot loader ran OK");
1584 }
1585 paranoid_free(device);
1586 paranoid_free(tmp);
1587 paranoid_free(name);
1588 return (retval);
1589}
1590
1591/**************************************************************************
1592 *END_ RUN_BOOT_LOADER *
1593 **************************************************************************/
1594
1595
1596
1597/**
1598 * Attempt to find the user's editor.
1599 * @return The editor found ("vi" if none could be found).
1600 * @note The returned string points to static storage that will be overwritten with each call.
1601 */
1602char *find_my_editor(void)
1603{
1604 static char output[MAX_STR_LEN];
1605 if (find_home_of_exe("pico")) {
1606 strcpy(output, "pico");
1607 } else if (find_home_of_exe("nano")) {
1608 strcpy(output, "nano");
1609 } else if (find_home_of_exe("e3em")) {
1610 strcpy(output, "e3em");
1611 } else if (find_home_of_exe("e3vi")) {
1612 strcpy(output, "e3vi");
1613 } else {
1614 strcpy(output, "vi");
1615 }
1616 if (!find_home_of_exe(output)) {
1617 log_msg(2, " (find_my_editor) --- warning - %s not found", output);
1618 }
1619 return (output);
1620}
1621
1622
1623/**
1624 * Install GRUB on @p bd.
1625 * @param offer_to_run_stabgrub If TRUE, then offer to hack the user's fstab for them.
1626 * @param bd The boot device where GRUB is installed.
1627 * @return 0 for success, nonzero for failure.
1628 */
1629int run_grub(bool offer_to_run_stabgrub, char *bd)
1630{
1631 /** malloc **/
1632 char *command;
1633 char *boot_device;
1634 char *rootdev;
1635 char *rootdrive;
1636 char *conffile;
1637 char *tmp;
1638 char *editor;
1639
1640 int res;
1641 int done;
1642
1643 malloc_string(command);
1644 malloc_string(boot_device);
1645 malloc_string(tmp);
1646 malloc_string(editor);
1647 malloc_string(rootdev);
1648 malloc_string(rootdrive);
1649 malloc_string(conffile);
1650 assert_string_is_neither_NULL_nor_zerolength(bd);
1651 strcpy(editor, "vi"); // find_my_editor() );
1652 strcpy(boot_device, bd);
1653
1654 if (!run_program_and_log_output("which grub-MR", FALSE)) {
1655 log_msg(1, "Yay! grub-MR found...");
1656 sprintf(command, "grub-MR %s /tmp/mountlist.txt", boot_device);
1657 log_msg(1, "command = %s", command);
1658 } else {
1659 sprintf(command, "chroot " MNT_RESTORING " grub-install %s",
1660 boot_device);
1661 log_msg(1, "WARNING - grub-MR not found; using grub-install");
1662 }
1663 if (offer_to_run_stabgrub
1664 && ask_me_yes_or_no("Did you change the mountlist?"))
1665 /* interactive mode */
1666 {
1667 mvaddstr_and_log_it(g_currentY,
1668 0,
1669 "Modifying fstab and grub.conf, and running GRUB... ");
1670 for (done = FALSE; !done;) {
1671 popup_and_get_string("Boot device",
1672 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1673 boot_device, MAX_STR_LEN / 4);
1674 sprintf(command, "stabgrub-me %s", boot_device);
1675 res = run_program_and_log_output(command, 1);
1676 if (res) {
1677 popup_and_OK
1678 ("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.");
1679 newtSuspend();
1680 system("chroot " MNT_RESTORING);
1681 newtResume();
1682 popup_and_OK("Thank you.");
1683 } else {
1684 done = TRUE;
1685 }
1686 popup_and_OK("You will now edit fstab and grub.conf");
1687 if (!g_text_mode) {
1688 newtSuspend();
1689 }
1690 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1691 paranoid_system(tmp);
1692 sprintf(tmp, "%s " MNT_RESTORING "/etc/grub.conf", editor);
1693 paranoid_system(tmp);
1694 if (!g_text_mode) {
1695 newtResume();
1696 }
1697 }
1698 } else
1699 /* nuke mode */
1700 {
1701 mvaddstr_and_log_it(g_currentY,
1702 0,
1703 "Running GRUB... ");
1704 iamhere(command);
1705 res = run_program_and_log_output(command, 1);
1706 if (res) {
1707 popup_and_OK
1708 ("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.");
1709 newtSuspend();
1710 system("chroot " MNT_RESTORING);
1711 newtResume();
1712 popup_and_OK("Thank you.");
1713 }
1714 }
1715 if (res) {
1716 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1717 log_to_screen
1718 ("GRUB ran w/error(s). See /tmp/mondo-restore.log for more info.");
1719 log_msg(1, "Type:-");
1720 log_msg(1, " mount-me");
1721 log_msg(1, " chroot " MNT_RESTORING);
1722 log_msg(1, " mount /boot");
1723 log_msg(1, " grub-install '(hd0)'");
1724 log_msg(1, " exit");
1725 log_msg(1, " unmount-me");
1726 log_msg(1,
1727 "If you're really stuck, please e-mail the mailing list.");
1728 } else {
1729 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1730 }
1731 paranoid_free(rootdev);
1732 paranoid_free(rootdrive);
1733 paranoid_free(conffile);
1734 paranoid_free(command);
1735 paranoid_free(boot_device);
1736 paranoid_free(tmp);
1737 paranoid_free(editor);
1738
1739 return (res);
1740}
1741
1742/**************************************************************************
1743 *END_RUN_GRUB *
1744 **************************************************************************/
1745
1746
1747/**
1748 * Install ELILO on the user's boot drive (determined by elilo.conf).
1749 * @param offer_to_run_stabelilo If TRUE, then offer to hack the user's fstab for them.
1750 * @return 0 for success, nonzero for failure.
1751 */
1752int run_elilo(bool offer_to_run_stabelilo)
1753{
1754 /** malloc **/
1755 char *command;
1756 char *tmp;
1757 char *editor;
1758
1759 int res;
1760 int done;
1761
1762 malloc_string(command);
1763 malloc_string(tmp);
1764 malloc_string(editor);
1765 strcpy(editor, find_my_editor());
1766 if (offer_to_run_stabelilo
1767 && ask_me_yes_or_no("Did you change the mountlist?"))
1768
1769 /* interactive mode */
1770 {
1771 mvaddstr_and_log_it(g_currentY,
1772 0,
1773 "Modifying fstab and elilo.conf... ");
1774 sprintf(command, "stabelilo-me");
1775 res = run_program_and_log_output(command, 3);
1776 if (res) {
1777 popup_and_OK
1778 ("You will now edit fstab and elilo.conf, to make sure they match your new mountlist.");
1779 for (done = FALSE; !done;) {
1780 if (!g_text_mode) {
1781 newtSuspend();
1782 }
1783 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1784 paranoid_system(tmp);
1785 sprintf(tmp, "%s " MNT_RESTORING "/etc/elilo.conf",
1786 editor);
1787 paranoid_system(tmp);
1788 if (!g_text_mode) {
1789 newtResume();
1790 }
1791// newtCls();
1792 if (ask_me_yes_or_no("Edit them again?")) {
1793 continue;
1794 }
1795 done = TRUE;
1796 }
1797 } else {
1798 log_to_screen("elilo.conf and fstab were modified OK");
1799 }
1800 } else
1801 /* nuke mode */
1802 {
1803 res = TRUE;
1804 }
1805 paranoid_free(command);
1806 paranoid_free(tmp);
1807 paranoid_free(editor);
1808 return (res);
1809}
1810
1811/**************************************************************************
1812 *END_RUN_ELILO *
1813 **************************************************************************/
1814
1815
1816/**
1817 * Install LILO on the user's boot drive (determined by /etc/lilo.conf).
1818 * @param offer_to_run_stablilo If TRUE, then offer to hack the user's fstab for them.
1819 * @return 0 for success, nonzero for failure.
1820 */
1821int run_lilo(bool offer_to_run_stablilo)
1822{
1823 /** malloc **/
1824 char *command;
1825 char *tmp;
1826 char *editor;
1827
1828 int res;
1829 int done;
1830 bool run_lilo_M = FALSE;
1831 malloc_string(command);
1832 malloc_string(tmp);
1833 malloc_string(editor);
1834
1835 if (!run_program_and_log_output
1836 ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) {
1837 run_lilo_M = TRUE;
1838 }
1839
1840 strcpy(editor, find_my_editor());
1841 if (offer_to_run_stablilo
1842 && ask_me_yes_or_no("Did you change the mountlist?"))
1843
1844 /* interactive mode */
1845 {
1846 mvaddstr_and_log_it(g_currentY,
1847 0,
1848 "Modifying fstab and lilo.conf, and running LILO... ");
1849 sprintf(command, "stablilo-me");
1850 res = run_program_and_log_output(command, 3);
1851 if (res) {
1852 popup_and_OK
1853 ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist.");
1854 for (done = FALSE; !done;) {
1855 if (!g_text_mode) {
1856 newtSuspend();
1857 }
1858 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1859 paranoid_system(tmp);
1860 sprintf(tmp, "%s " MNT_RESTORING "/etc/lilo.conf", editor);
1861 paranoid_system(tmp);
1862 if (!g_text_mode) {
1863 newtResume();
1864 }
1865// newtCls();
1866 if (ask_me_yes_or_no("Edit them again?")) {
1867 continue;
1868 }
1869 res =
1870 run_program_and_log_output("chroot " MNT_RESTORING
1871 " lilo -L", 3);
1872 if (res) {
1873 res =
1874 run_program_and_log_output("chroot " MNT_RESTORING
1875 " lilo", 3);
1876 }
1877 if (res) {
1878 done =
1879 ask_me_yes_or_no
1880 ("LILO failed. Re-edit system files?");
1881 } else {
1882 done = TRUE;
1883 }
1884 }
1885 } else {
1886 log_to_screen("lilo.conf and fstab were modified OK");
1887 }
1888 } else
1889 /* nuke mode */
1890 {
1891 mvaddstr_and_log_it(g_currentY,
1892 0,
1893 "Running LILO... ");
1894 res =
1895 run_program_and_log_output("chroot " MNT_RESTORING " lilo -L",
1896 3);
1897 if (res) {
1898 res =
1899 run_program_and_log_output("chroot " MNT_RESTORING " lilo",
1900 3);
1901 }
1902 if (res) {
1903 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1904 log_to_screen
1905 ("Failed to re-jig fstab and/or lilo. Edit/run manually, please.");
1906 } else {
1907 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1908 }
1909 }
1910 if (run_lilo_M) {
1911 run_program_and_log_output("chroot " MNT_RESTORING
1912 " lilo -M /dev/hda", 3);
1913 run_program_and_log_output("chroot " MNT_RESTORING
1914 " lilo -M /dev/sda", 3);
1915 }
1916 paranoid_free(command);
1917 paranoid_free(tmp);
1918 paranoid_free(editor);
1919 return (res);
1920}
1921
1922/**************************************************************************
1923 *END_RUN_LILO *
1924 **************************************************************************/
1925
1926
1927/**
1928 * Install a raw MBR onto @p bd.
1929 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1930 * @param bd The device to copy the stored MBR to.
1931 * @return 0 for success, nonzero for failure.
1932 */
1933int run_raw_mbr(bool offer_to_hack_scripts, char *bd)
1934{
1935 /** malloc **/
1936 char *command;
1937 char *boot_device;
1938 char *tmp;
1939 char *editor;
1940 int res;
1941 int done;
1942
1943 malloc_string(command);
1944 malloc_string(boot_device);
1945 malloc_string(tmp);
1946 malloc_string(editor);
1947 assert_string_is_neither_NULL_nor_zerolength(bd);
1948
1949 strcpy(editor, find_my_editor());
1950 strcpy(boot_device, bd);
1951 sprintf(command, "raw-MR %s /tmp/mountlist.txt", boot_device);
1952 log_msg(2, "run_raw_mbr() --- command='%s'", command);
1953
1954 if (offer_to_hack_scripts
1955 && ask_me_yes_or_no("Did you change the mountlist?"))
1956 /* interactive mode */
1957 {
1958 mvaddstr_and_log_it(g_currentY, 0,
1959 "Modifying fstab and restoring MBR... ");
1960 for (done = FALSE; !done;) {
1961 if (!run_program_and_log_output("which vi", FALSE)) {
1962 popup_and_OK("You will now edit fstab");
1963 if (!g_text_mode) {
1964 newtSuspend();
1965 }
1966 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1967 paranoid_system(tmp);
1968 if (!g_text_mode) {
1969 newtResume();
1970 }
1971// newtCls();
1972 }
1973 popup_and_get_string("Boot device",
1974 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1975 boot_device, MAX_STR_LEN / 4);
1976 sprintf(command, "stabraw-me %s", boot_device);
1977 res = run_program_and_log_output(command, 3);
1978 if (res) {
1979 done = ask_me_yes_or_no("Modifications failed. Re-try?");
1980 } else {
1981 done = TRUE;
1982 }
1983 }
1984 } else
1985 /* nuke mode */
1986 {
1987 mvaddstr_and_log_it(g_currentY, 0,
1988 "Restoring MBR... ");
1989 res = run_program_and_log_output(command, 3);
1990 }
1991 if (res) {
1992 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1993 log_to_screen
1994 ("MBR+fstab processed w/error(s). See /tmp/mondo-restore.log for more info.");
1995 } else {
1996 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1997 }
1998 paranoid_free(command);
1999 paranoid_free(boot_device);
2000 paranoid_free(tmp);
2001 paranoid_free(editor);
2002 return (res);
2003}
2004
2005/**************************************************************************
2006 *END_RUN_RAW_MBR *
2007 **************************************************************************/
2008
2009
2010
2011
2012
2013/**
2014 * Turn signal trapping on or off.
2015 * @param on If TRUE, then do full cleanup when we receive a signal; if FALSE, then
2016 * print a message and exit immediately.
2017 */
2018void set_signals(int on)
2019{
2020 int signals[] =
2021 { SIGKILL, SIGPIPE, SIGTERM, SIGHUP, SIGTRAP, SIGABRT, SIGINT,
2022SIGSTOP, 0 };
2023 int i;
2024 for (i = 0; signals[i]; i++) {
2025 if (on) {
2026 signal(signals[i], terminate_daemon);
2027 } else {
2028 signal(signals[i], termination_in_progress);
2029 }
2030 }
2031}
2032
2033/**************************************************************************
2034 *END_SET_SIGNALS *
2035 **************************************************************************/
2036
2037
2038/**
2039 * malloc() and set sensible defaults for the mondorestore filename variables.
2040 * @param bkpinfo The backup information structure. Fields used:
2041 * - @c bkpinfo->tmpdir
2042 * - @c bkpinfo->disaster_recovery
2043 */
2044void setup_MR_global_filenames(struct s_bkpinfo *bkpinfo)
2045{
2046 char *temppath;
2047
2048 assert(bkpinfo != NULL);
2049
2050 malloc_string(g_biggielist_txt);
2051 malloc_string(g_filelist_full);
2052 malloc_string(g_filelist_imagedevs);
2053 malloc_string(g_imagedevs_restthese);
2054 malloc_string(g_mondo_cfg_file);
2055 malloc_string(g_mountlist_fname);
2056 malloc_string(g_mondo_home);
2057 malloc_string(g_tmpfs_mountpt);
2058 malloc_string(g_isodir_device);
2059 malloc_string(g_isodir_format);
2060
2061 temppath = bkpinfo->tmpdir;
2062
2063 sprintf(g_biggielist_txt, "%s/%s", temppath, BIGGIELIST_TXT_STUB);
2064 sprintf(g_filelist_full, "%s/%s", temppath, FILELIST_FULL_STUB);
2065 sprintf(g_filelist_imagedevs, "%s/tmp/filelist.imagedevs", temppath);
2066// sprintf(g_imagedevs_pot, "%s/tmp/imagedevs.pot", temppath);
2067 sprintf(g_imagedevs_restthese, "%s/tmp/imagedevs.restore-these",
2068 temppath);
2069 if (bkpinfo->disaster_recovery) {
2070 sprintf(g_mondo_cfg_file, "/%s", MONDO_CFG_FILE_STUB);
2071 sprintf(g_mountlist_fname, "/%s", MOUNTLIST_FNAME_STUB);
2072 } else {
2073 sprintf(g_mondo_cfg_file, "%s/%s", temppath, MONDO_CFG_FILE_STUB);
2074 sprintf(g_mountlist_fname, "%s/%s", temppath,
2075 MOUNTLIST_FNAME_STUB);
2076 }
2077}
2078
2079/**************************************************************************
2080 *END_SET_GLOBAL_FILENAME *
2081 **************************************************************************/
2082
2083
2084/**
2085 * Copy @p input_file (containing the result of a compare) to @p output_file,
2086 * deleting spurious "changes" along the way.
2087 * @param output_file The output file to write with spurious changes removed.
2088 * @param input_file The input file, a list of changed files created by a compare.
2089 */
2090void streamline_changes_file(char *output_file, char *input_file)
2091{
2092 FILE *fin;
2093 FILE *fout;
2094 /** malloc **/
2095 char *incoming;
2096
2097 assert_string_is_neither_NULL_nor_zerolength(output_file);
2098 assert_string_is_neither_NULL_nor_zerolength(input_file);
2099 malloc_string(incoming);
2100
2101 if (!(fin = fopen(input_file, "r"))) {
2102 log_OS_error(input_file);
2103 return;
2104 }
2105 if (!(fout = fopen(output_file, "w"))) {
2106 fatal_error("cannot open output_file");
2107 }
2108 for (fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin);
2109 fgets(incoming, MAX_STR_LEN - 1, fin)) {
2110 if (strncmp(incoming, "etc/adjtime", 11)
2111 && strncmp(incoming, "etc/mtab", 8)
2112 && strncmp(incoming, "tmp/", 4)
2113 && strncmp(incoming, "boot/map", 8)
2114 && !strstr(incoming, "incheckentry")
2115 && strncmp(incoming, "etc/mail/statistics", 19)
2116 && strncmp(incoming, "var/", 4))
2117 fprintf(fout, "%s", incoming); /* don't need \n here, for some reason.. */
2118 }
2119 paranoid_fclose(fout);
2120 paranoid_fclose(fin);
2121 paranoid_free(incoming);
2122}
2123
2124/**************************************************************************
2125 *END_STREAMLINE_CHANGES_FILE *
2126 **************************************************************************/
2127
2128
2129/**
2130 * Exit due to a signal (normal cleanup).
2131 * @param sig The signal we're exiting due to.
2132 */
2133void terminate_daemon(int sig)
2134{
2135 log_to_screen
2136 ("Mondorestore is terminating in response to a signal from the OS");
2137 paranoid_MR_finish(254);
2138}
2139
2140/**************************************************************************
2141 *END_TERMINATE_DAEMON *
2142 **************************************************************************/
2143
2144
2145/**
2146 * Give the user twenty seconds to press Ctrl-Alt-Del before we nuke their drives.
2147 */
2148void twenty_seconds_til_yikes()
2149{
2150 int i;
2151 /* MALLOC * */
2152 char *tmp;
2153
2154 malloc_string(tmp);
2155 if (does_file_exist("/tmp/NOPAUSE")) {
2156 return;
2157 }
2158 open_progress_form("CAUTION",
2159 "Be advised: I am about to ERASE your hard disk(s)!",
2160 "You may press Ctrl+Alt+Del to abort safely.",
2161 "", 20);
2162 for (i = 0; i < 20; i++) {
2163 g_current_progress = i;
2164 sprintf(tmp, "You have %d seconds left to abort.", 20 - i);
2165 update_progress_form(tmp);
2166 sleep(1);
2167 }
2168 close_progress_form();
2169 paranoid_free(tmp);
2170}
2171
2172/**************************************************************************
2173 *END_TWENTY_SECONDS_TIL_YIKES *
2174 **************************************************************************/
2175
2176
2177
2178
2179
2180/**
2181 * Exit due to a signal (no cleanup).
2182 * @param sig The signal we're exiting due to.
2183 */
2184void termination_in_progress(int sig)
2185{
2186 log_msg(1, "Termination in progress");
2187 usleep(1000);
2188 pthread_exit(0);
2189}
2190
2191/**************************************************************************
2192 *END_TERMINATION_IN_PROGRESS *
2193 **************************************************************************/
2194
2195
2196
2197/**
2198 * Unmount all devices in @p p_external_copy_of_mountlist.
2199 * @param p_external_copy_of_mountlist The mountlist to guide the devices to unmount.
2200 * @return 0 for success, nonzero for failure.
2201 */
2202int unmount_all_devices(struct mountlist_itself
2203 *p_external_copy_of_mountlist)
2204{
2205 struct mountlist_itself *mountlist;
2206 int retval = 0, lino, res = 0, i;
2207 char *command;
2208 char *tmp;
2209
2210 malloc_string(command);
2211 malloc_string(tmp);
2212 assert(p_external_copy_of_mountlist != NULL);
2213
2214 mountlist = malloc(sizeof(struct mountlist_itself));
2215 memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
2216 sizeof(struct mountlist_itself));
2217 sort_mountlist_by_mountpoint(mountlist, 0);
2218
2219 run_program_and_log_output("df -m", 3);
2220 mvaddstr_and_log_it(g_currentY, 0, "Unmounting devices ");
2221 open_progress_form("Unmounting devices",
2222 "Unmounting all devices that were mounted,",
2223 "in preparation for the post-restoration reboot.",
2224 "", mountlist->entries);
2225 chdir("/");
2226 for (i = 0;
2227 i < 10
2228 &&
2229 run_program_and_log_output
2230 ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
2231 i++) {
2232 sleep(1);
2233 log_msg(2, "Waiting for buffer() to finish");
2234 }
2235
2236 paranoid_system("sync");
2237
2238 if (run_program_and_log_output
2239 ("cp -f /tmp/mondo-restore.log " MNT_RESTORING "/tmp/", FALSE)) {
2240 log_msg(1,
2241 "Error. Failed to copy log to PC's /tmp dir. (Mounted read-only?)");
2242 }
2243 if (run_program_and_log_output
2244 ("cp -f /tmp/mondo-restore.log " MNT_RESTORING "/root/", FALSE)) {
2245 log_msg(1,
2246 "Error. Failed to copy log to PC's /root dir. (Mounted read-only?)");
2247 }
2248 if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2249 run_program_and_log_output("mkdir -p " MNT_RESTORING
2250 "/mnt/.boot.d", 5);
2251 }
2252 for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2253 if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2254 continue;
2255 }
2256 sprintf(tmp, "Unmounting device %s ", mountlist->el[lino].device);
2257
2258 update_progress_form(tmp);
2259 if (is_this_device_mounted(mountlist->el[lino].device)) {
2260 if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
2261 sprintf(command, "swapoff %s", mountlist->el[lino].device);
2262 } else {
2263 if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
2264 sprintf(command, "umount %s/", MNT_RESTORING);
2265 log_msg(3,
2266 "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2267 } else {
2268 sprintf(command, "umount " MNT_RESTORING "%s",
2269 mountlist->el[lino].mountpoint);
2270 }
2271 }
2272 log_msg(10, "The 'umount' command is '%s'", command);
2273 res = run_program_and_log_output(command, 3);
2274 } else {
2275 strcat(tmp, "...not mounted anyway :-) OK");
2276 res = 0;
2277 }
2278 g_current_progress++;
2279 if (res) {
2280 strcat(tmp, "...Failed");
2281 retval++;
2282 log_to_screen(tmp);
2283 } else {
2284 log_msg(2, tmp);
2285 }
2286 }
2287 close_progress_form();
2288 if (retval) {
2289 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2290 } else {
2291 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2292 }
2293 if (retval) {
2294 log_to_screen("Unable to unmount some of your partitions.");
2295 } else {
2296 log_to_screen("All partitions were unmounted OK.");
2297 }
2298 free(mountlist);
2299 paranoid_free(command);
2300 paranoid_free(tmp);
2301 return (retval);
2302}
2303
2304/**************************************************************************
2305 *END_UNMOUNT_ALL_DEVICES *
2306 **************************************************************************/
2307
2308
2309
2310/**
2311 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2312 * to the ./tmp/ directory.
2313 * @param dev The tape device to read from.
2314 * @return 0 for success, nonzero for failure.
2315 */
2316int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2317{
2318 char *command;
2319 int res = 0;
2320 // BCO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
2321 long tape_block_size = 32768;
2322
2323 malloc_string(command);
2324
2325 // tar -zxvf-
2326 sprintf(command,
2327 "dd if=%s bs=%ld count=%ld 2> /dev/null | tar -zx %s %s %s %s %s",
2328 dev,
2329 tape_block_size,
2330 1024L * 1024 * 32 / tape_block_size,
2331 MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB,
2332 BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, "tmp/i-want-my-lvm");
2333 log_msg(2, "command = '%s'", command);
2334 res = run_program_and_log_output(command, -1);
2335 if (res != 0 && does_file_exist(MONDO_CFG_FILE_STUB)) {
2336 res = 0;
2337 }
2338 paranoid_free(command);
2339 return (res);
2340}
2341
2342
2343
2344/**
2345 * Get the configuration file from the floppy, tape, or CD.
2346 * @param bkpinfo The backup information structure. Fields used:
2347 * - @c bkpinfo->backup_media_type
2348 * - @c bkpinfo->media_device
2349 * - @c bkpinfo->tmpdir
2350 * @return 0 for success, nonzero for failure.
2351 */
2352int get_cfg_file_from_archive(struct s_bkpinfo *bkpinfo)
2353{
2354 int retval = 0;
2355
2356 /** malloc *****/
2357 char *device;
2358 char *command;
2359 char *cfg_file;
2360 char *mounted_cfgf_path;
2361 char *tmp;
2362 char *mountpt;
2363 char *ramdisk_fname;
2364 char *mountlist_file;
2365 int res;
2366
2367 bool try_plan_B;
2368
2369 assert(bkpinfo != NULL);
2370 malloc_string(cfg_file);
2371 malloc_string(mounted_cfgf_path);
2372 malloc_string(mountpt);
2373 malloc_string(ramdisk_fname);
2374 malloc_string(mountlist_file);
2375 malloc_string(device);
2376 malloc_string(command);
2377 malloc_string(tmp);
2378 log_msg(2, "gcffa --- starting");
2379 log_to_screen("I'm thinking...");
2380 sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
2381 device[0] = '\0';
2382 chdir(bkpinfo->tmpdir);
2383 strcpy(cfg_file, MONDO_CFG_FILE_STUB);
2384 unlink(cfg_file); // cfg_file[] is missing the '/' at the start, FYI, by intent
2385 unlink(FILELIST_FULL_STUB);
2386 unlink(BIGGIELIST_TXT_STUB);
2387 unlink("tmp/i-want-my-lvm");
2388 sprintf(command, "mkdir -p %s", mountpt);
2389 run_program_and_log_output(command, FALSE);
2390
2391// unlink( "tmp/mondo-restore.cfg" ); // superfluous, surely?
2392
2393 sprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2394 sprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir,
2395 MOUNTLIST_FNAME_STUB);
2396 // make_hole_for_file( cfg_file );
2397 // make_hole_for_file( mountlist_file);
2398 log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
2399
2400 /* Floppy? */
2401 sprintf(tmp, "mkdir -p %s", mountpt);
2402 run_program_and_log_output(tmp, FALSE);
2403 sprintf(tmp, "mkdir -p %s/tmp", bkpinfo->tmpdir);
2404 run_program_and_log_output(tmp, FALSE);
2405
2406 sprintf(command, "mount /dev/fd0u1722 %s", mountpt);
2407 sprintf(tmp,
2408 "(sleep 15; kill `ps | grep \"%s\" | cut -d' ' -f1` 2> /dev/null) &",
2409 command);
2410 log_msg(1, "tmp = '%s'", tmp);
2411 system(tmp);
2412 res = run_program_and_log_output(command, FALSE);
2413 if (res) {
2414 sprintf(command, "mount /dev/fd0H1440 %s", mountpt);
2415 res = run_program_and_log_output(command, FALSE);
2416 }
2417 if (res) {
2418 try_plan_B = TRUE;
2419 } else {
2420 try_plan_B = TRUE;
2421 log_msg(2,
2422 "Mounted floppy OK but I don't trust it because the archives might contain more up-to-date config file than the floppy does.");
2423// NB: If busybox does not support 'mount -o loop' then Plan A WILL NOT WORK.
2424 log_msg(2, "Processing floppy (plan A?)");
2425 sprintf(ramdisk_fname, "%s/mindi.rdz", mountpt);
2426 if (!does_file_exist(ramdisk_fname)) {
2427 sprintf(ramdisk_fname, "%s/initrd.img", mountpt);
2428 }
2429 if (!does_file_exist(ramdisk_fname)) {
2430 log_msg(2,
2431 "Cannot find ramdisk file on mountpoint. Are you sure that's a boot disk in the drive?");
2432 }
2433 if (extract_config_file_from_ramdisk
2434 (bkpinfo, ramdisk_fname, cfg_file, mountlist_file)) {
2435 log_msg(2,
2436 "Warning - failed to extract config file from ramdisk. I think this boot disk is mangled.");
2437 }
2438 sprintf(command, "umount %s", mountpt);
2439 run_program_and_log_output(command, 5);
2440 unlink(ramdisk_fname);
2441 }
2442 if (!does_file_exist(cfg_file)) {
2443 log_msg(2, "gcffa --- we don't have cfg file yet.");
2444 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2445 try_plan_B = TRUE;
2446 } else {
2447 log_msg(2, "gcffa --- calling mount_cdrom now :)");
2448 if (!mount_cdrom(bkpinfo)) {
2449 log_msg(2,
2450 "gcffa --- managed to mount CD; so, no need for Plan B");
2451 try_plan_B = FALSE;
2452 } else {
2453 try_plan_B = TRUE;
2454 }
2455 if (what_number_cd_is_this(bkpinfo) > 1) {
2456 insist_on_this_cd_number(bkpinfo,
2457 (g_current_media_number = 1));
2458 }
2459 }
2460 if (try_plan_B) {
2461 log_msg(2, "gcffa --- OK, switching to Plan B");
2462 chdir(bkpinfo->tmpdir);
2463 run_program_and_log_output("mkdir -p tmp", FALSE);
2464
2465 if (strlen(bkpinfo->media_device) == 0) {
2466 strcpy(bkpinfo->media_device, "/dev/st0");
2467 log_msg(2, "media_device is blank; assuming %s");
2468 }
2469 strcpy(tmp, bkpinfo->media_device);
2470 if (extract_cfg_file_and_mountlist_from_tape_dev
2471 (bkpinfo->media_device)) {
2472 strcpy(bkpinfo->media_device, "/dev/st0");
2473 if (extract_cfg_file_and_mountlist_from_tape_dev
2474 (bkpinfo->media_device)) {
2475 strcpy(bkpinfo->media_device, "/dev/osst0");
2476 if (extract_cfg_file_and_mountlist_from_tape_dev
2477 (bkpinfo->media_device)) {
2478 strcpy(bkpinfo->media_device, "/dev/ht0");
2479 if (extract_cfg_file_and_mountlist_from_tape_dev
2480 (bkpinfo->media_device)) {
2481 log_msg(3,
2482 "I tried lots of devices but none worked.");
2483 strcpy(bkpinfo->media_device, tmp);
2484 }
2485 }
2486 }
2487 }
2488
2489 if (!does_file_exist("tmp/mondo-restore.cfg")) {
2490 log_to_screen("Cannot find config info on tape/CD/floppy");
2491 return (1);
2492 }
2493 } else {
2494 log_msg(2,
2495 "gcffa --- looking at mounted CD for mindi-boot.2880.img");
2496 sprintf(command,
2497 "mount " MNT_CDROM
2498 "/images/mindi-boot.2880.img -o loop %s", mountpt);
2499 sprintf(mounted_cfgf_path, "%s/%s", mountpt, cfg_file);
2500 if (!does_file_exist(mounted_cfgf_path)) {
2501 log_msg(2,
2502 "gcffa --- Plan C, a.k.a. untarring some file from all.tar.gz");
2503 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
2504 run_program_and_log_output(command, TRUE);
2505 if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2506 fatal_error
2507 ("Please reinsert the disk/CD and try again.");
2508 }
2509 }
2510 }
2511 }
2512 if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2513 log_msg(1, "gcffa --- great! We've got the config file");
2514 sprintf(tmp, "%s/%s",
2515 call_program_and_get_last_line_of_output("pwd"),
2516 MONDO_CFG_FILE_STUB);
2517 sprintf(command, "cp -f %s %s", tmp, cfg_file);
2518 iamhere(command);
2519 if (strcmp(tmp, cfg_file)
2520 && run_program_and_log_output(command, 1)) {
2521 log_msg(1,
2522 "... but an error occurred when I tried to move it to %s",
2523 cfg_file);
2524 } else {
2525 log_msg(1, "... and I moved it successfully to %s", cfg_file);
2526 }
2527 sprintf(command, "cp -f %s/%s %s",
2528 call_program_and_get_last_line_of_output("pwd"),
2529 MOUNTLIST_FNAME_STUB, mountlist_file);
2530 iamhere(command);
2531 if (strcmp(tmp, cfg_file)
2532 && run_program_and_log_output(command, 1)) {
2533 log_msg(1, "Failed to get mountlist");
2534 } else {
2535 log_msg(1, "Got mountlist too");
2536 sprintf(command, "cp -f %s %s", mountlist_file,
2537 g_mountlist_fname);
2538 if (run_program_and_log_output(command, 1)) {
2539 log_msg(1, "Failed to copy mountlist to /tmp");
2540 } else {
2541 log_msg(1, "Copied mountlist to /tmp as well OK");
2542 sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2543 run_program_and_log_output(command, 1);
2544/* sprintf(command, "grep \" lvm \" %s", g_mountlist_fname);
2545 if (!run_program_and_log_output(command, 5) && !does_file_exist("/tmp/i-want-my-lvm"))
2546 {
2547 log_msg(1, "Warning. You want LVM but I don't have i-want-my-lvm. FIXME.");
2548 }
2549 else if (run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2550 {
2551 log_msg(1, "Warning. You don't want LVM but i-want-my-lvm exists. I'll delete it. Cool.");
2552 do_my_funky_lvm_stuff(TRUE, FALSE); // ...after I stop any LVMs :)
2553 stop_raid_device("/dev/md0");
2554 stop_raid_device("/dev/md1");
2555 stop_raid_device("/dev/md2");
2556 unlink("/tmp/i-want-my-lvm");
2557 }
2558 else if (!run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2559 {
2560 log_msg(1, "You had better pray that i-want-my-lvm patches your mountlist. FIXME.");
2561 }
2562*/
2563 }
2564 }
2565 }
2566 run_program_and_log_output("umount " MNT_CDROM, FALSE);
2567 if (!does_file_exist(cfg_file)) {
2568 iamhere(cfg_file);
2569 log_msg(1, "%s not found", cfg_file);
2570 log_to_screen
2571 ("Oh dear. Unable to recover configuration file from boot disk");
2572 return (1);
2573 }
2574
2575 log_to_screen("Recovered mondo-restore.cfg");
2576 if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2577 log_to_screen("...but not mountlist.txt - a pity, really...");
2578 }
2579/* start SAH */
2580 else {
2581 sprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB,
2582 bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2583 run_program_and_log_output(command, FALSE);
2584 }
2585/*--commented out by SAH
2586 sprintf( command, "cp -f %s %s/%s", cfg_file, bkpinfo->tmpdir, MONDO_CFG_FILE_STUB );
2587 run_program_and_log_output( command, FALSE );
2588 sprintf( command, "cp -f %s %s/%s", mountlist_file, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB );
2589 run_program_and_log_output( command, FALSE );
2590*/
2591/* end SAH */
2592
2593 sprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2594 run_program_and_log_output(command, FALSE);
2595 sprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2596 run_program_and_log_output(command, FALSE);
2597 sprintf(command, "cp -f etc/raidtab /etc/");
2598 run_program_and_log_output(command, FALSE);
2599 sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2600 run_program_and_log_output(command, FALSE);
2601 g_backup_media_type = bkpinfo->backup_media_type;
2602 paranoid_free(device);
2603 paranoid_free(command);
2604 paranoid_free(tmp);
2605 paranoid_free(cfg_file);
2606 paranoid_free(mounted_cfgf_path);
2607 paranoid_free(mountpt);
2608 paranoid_free(ramdisk_fname);
2609 paranoid_free(mountlist_file);
2610 return (retval);
2611}
2612
2613/**************************************************************************
2614 *END_GET_CFG_FILE_FROM_ARCHIVE *
2615 **************************************************************************/
2616
2617/* @} - end restoreUtilityGroup */
2618
2619
2620/***************************************************************************
2621 * F@ *
2622 * () -- Hugo Rabson *
2623 * *
2624 * Purpose: *
2625 * *
2626 * Called by: *
2627 * Params: - - *
2628 * Returns: 0=success; nonzero=failure *
2629 ***************************************************************************/
2630
2631
2632
2633void wait_until_software_raids_are_prepped(char *mdstat_file,
2634 int wait_for_percentage)
2635{
2636 struct raidlist_itself *raidlist;
2637 int unfinished_mdstat_devices = 9999, i;
2638 char *screen_message;
2639
2640 malloc_string(screen_message);
2641 raidlist = malloc(sizeof(struct raidlist_itself));
2642
2643 assert(wait_for_percentage <= 100);
2644 iamhere("wait_until_software_raids_are_prepped");
2645 while (unfinished_mdstat_devices > 0) {
2646 // FIXME: Prefix '/dev/' should really be dynamic!
2647 if (parse_mdstat(raidlist, "/dev/")) {
2648 log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2649 log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2650 return;
2651 }
2652 for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2653 if (raidlist->el[i].progress < wait_for_percentage) {
2654 unfinished_mdstat_devices++;
2655 if (raidlist->el[i].progress == -1) // delayed while another partition inits
2656 {
2657 continue;
2658 }
2659 log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2660 sprintf(screen_message, "Sync'ing %s",
2661 raidlist->el[i].raid_device);
2662 open_evalcall_form(screen_message);
2663 while (raidlist->el[i].progress < wait_for_percentage) {
2664 log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2665 update_evalcall_form(raidlist->el[i].progress);
2666 sleep(2);
2667 // FIXME: Prefix '/dev/' should really be dynamic!
2668 if (parse_mdstat(raidlist, "/dev/")) {
2669 break;
2670 }
2671 }
2672 close_evalcall_form();
2673 }
2674 }
2675 }
2676 paranoid_free(screen_message);
2677 paranoid_free(raidlist);
2678}
Note: See TracBrowser for help on using the repository browser.