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

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

Removal of g_mondo_home useless and used MONDO_SHARE instead

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