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

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

log_msg => mr_msg for main files

  • Property svn:keywords set to Id
File size: 76.9 KB
Line 
1/***************************************************************************
2 * $Id: mondo-rstr-tools.c 1108 2007-02-07 23:10:16Z bruno $
3*/
4
5
6#include <pthread.h>
7#include "my-stuff.h"
8#include "../common/mondostructures.h"
9#include "../common/libmondo.h"
10#include "mr-externs.h"
11//#include "mondo-restore.h"
12//#include "mondo-rstr-compare-EXT.h"
13#include "mondo-rstr-tools.h"
14#include "mr_mem.h"
15
16extern bool g_sigpipe_caught;
17extern bool g_ISO_restore_mode; /* are we in Iso Mode? */
18extern bool g_I_have_just_nuked;
19extern char *g_tmpfs_mountpt;
20extern char *g_isodir_device;
21extern char *g_isodir_format;
22extern long g_current_progress, g_maximum_progress;
23extern char *g_biggielist_txt; // where 'biggielist.txt' is stored, on ramdisk / tempdir;
24 // biggielist.txt is the list of big files stored on the
25 // backup media set in question
26extern char *g_filelist_full; // filelist.full.gz is the list of all regular files
27 // (excluding big files) stored on the backup media set
28extern char *g_biggielist_pot; // list of big files which _could_ be restored, if the
29 // user chooses them
30extern char *g_filelist_imagedevs; // list of devices (e.g. /dev/hda1, /dev/sda5) which
31 // were archived as images, not just /dev entries
32 // ... e.g. NTFS, BeOS partitions
33extern char *g_imagedevs_restthese; // of the imagedevs listed in FILELIST_IMAGEDEVS,
34 // restore only these
35extern char *g_mondo_cfg_file; // where m*ndo-restore.cfg (the config file) is stored
36extern char *g_mountlist_fname; // where mountlist.txt (the mountlist file) is stored
37extern char *g_mondo_home; // homedir of Mondo; usually /usr/local/share/mondo
38extern struct s_bkpinfo *g_bkpinfo_DONTUSETHIS;
39
40extern t_bkptype g_backup_media_type;
41
42extern int g_partition_table_locked_up;
43
44/* Should we use or not extended attributes and acl when restoring */
45char *g_getfattr = NULL;
46char *g_getfacl = NULL;
47
48/**
49 * @addtogroup restoreUtilityGroup
50 * @{
51 */
52/**
53 * Free the malloc()s for the filename variables.
54 */
55void free_MR_global_filenames(void)
56{
57 mr_free(g_biggielist_txt);
58 mr_free(g_filelist_full);
59 mr_free(g_filelist_imagedevs);
60// mr_free (g_imagedevs_pot );
61 mr_free(g_imagedevs_restthese);
62 mr_free(g_mondo_cfg_file);
63 mr_free(g_mountlist_fname);
64 mr_free(g_mondo_home);
65 mr_free(g_tmpfs_mountpt);
66 mr_free(g_isodir_device);
67 mr_free(g_isodir_format);
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 */
80void ask_about_these_imagedevs(char *infname, char *outfname)
81{
82 FILE *fin;
83 FILE *fout;
84 /************************************************************************
85 * allocate memory regions. test and set -sab 16 feb 2003 *
86 ************************************************************************/
87 char *incoming_ptr;
88 char *question_ptr;
89
90 char incoming[MAX_STR_LEN] = "\0";
91 char question[MAX_STR_LEN];
92
93 assert_string_is_neither_NULL_nor_zerolength(infname);
94 assert_string_is_neither_NULL_nor_zerolength(outfname);
95
96 incoming_ptr = mr_malloc(sizeof(incoming));
97 question_ptr = mr_malloc(sizeof(question));
98
99 memset(incoming_ptr, '\0', sizeof(incoming));
100 memset(question_ptr, '\0', sizeof(question));
101
102
103
104 if (!(fin = fopen(infname, "r"))) {
105 fatal_error("Cannot openin infname");
106 }
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)) {
112 strip_spaces(incoming_ptr);
113
114 if (incoming[0] == '\0') {
115 continue;
116 }
117
118 sprintf(question_ptr,
119 "Should I restore the image of %s ?", incoming_ptr);
120
121 if (ask_me_yes_or_no(question_ptr)) {
122 fprintf(fout, "%s\n", incoming_ptr);
123 }
124 }
125
126 /*** free memory ***********/
127 mr_free(incoming_ptr);
128 incoming_ptr = NULL;
129 mr_free(question_ptr);
130 question_ptr = NULL;
131
132
133 paranoid_fclose(fout);
134 paranoid_fclose(fin);
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 */
157int
158extract_config_file_from_ramdisk(struct s_bkpinfo *bkpinfo,
159 char *ramdisk_fname,
160 char *output_cfg_file,
161 char *output_mountlist_file)
162{
163 char *mountpt;
164 char *command;
165 char *orig_fname;
166 int retval = 0;
167
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);
180
181 run_program_and_log_output(command, FALSE);
182 sprintf(command, "umount %s", mountpt);
183
184 run_program_and_log_output(command, FALSE);
185
186 sprintf(command, "mount -o loop %s/mindi.rd -t ext2 %s",
187 bkpinfo->tmpdir, mountpt);
188
189 run_program_and_log_output(command, FALSE);
190
191 sprintf(command, "mkdir -p %s/tmp", bkpinfo->tmpdir);
192
193 run_program_and_log_output(command, FALSE);
194
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);
198
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))) {
209 mr_msg(2, "Failed to extract %s and/or %s from ramdisk",
210 output_cfg_file, output_mountlist_file);
211 retval = 1;
212 } else {
213 retval = 0;
214 }
215 mr_free(mountpt);
216 mr_free(command);
217 mr_free(orig_fname);
218 return (retval);
219
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{
231 while (get_cfg_file_from_archive(bkpinfo)) {
232 if (!ask_me_yes_or_no
233 ("Failed to find config file/archives. Choose another source?"))
234 {
235 fatal_error("Could not find config file/archives. Aborting.");
236 }
237 interactively_obtain_media_parameters_from_user(bkpinfo, FALSE);
238 }
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 */
249bool is_file_in_list(char *f, char *list_fname, char *preamble)
250{
251
252 /** needs malloc **/
253 char *command;
254 char *file;
255 char *tmp;
256 int res;
257
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);
264
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);
277 mr_msg(2, tmp);
278 sprintf(command, "grep -E '^%s$' %s", file, list_fname);
279 res = run_program_and_log_output(command, FALSE);
280 mr_free(command);
281 mr_free(file);
282 mr_free(tmp);
283 if (res) {
284 return (FALSE);
285 } else {
286 return (TRUE);
287 }
288}
289
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{
307 char *mount_isodir_command, *tmp, *command;
308 int retval = 0, i;
309 bool already_mounted = FALSE;
310
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) {
318/* Patch Conor Daly 26-june-2004
319 * Don't let this clobber an existing bkpinfo->isodir */
320 if (!bkpinfo->isodir[0]) {
321 strcpy(bkpinfo->isodir, "/tmp/isodir");
322 }
323/* End patch */
324 sprintf(command, "mkdir -p %s", bkpinfo->isodir);
325 run_program_and_log_output(command, 5);
326 mr_msg(2, "Setting isodir to %s", bkpinfo->isodir);
327 }
328
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 */
335
336 if (is_this_device_mounted(g_isodir_device)) {
337 log_to_screen("WARNING - isodir is already mounted");
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);
347 run_program_and_log_output("df -m", FALSE);
348 sprintf(tmp,
349 "The 'mount' command is '%s'. PLEASE report this command to be if you have problems, ok?",
350 mount_isodir_command);
351 mr_msg(1, tmp);
352 if (run_program_and_log_output(mount_isodir_command, FALSE)) {
353 popup_and_OK
354 ("Cannot mount the device where the ISO files are stored.");
355 return (1);
356 }
357 log_to_screen
358 ("I have mounted the device where the ISO files are stored.");
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);
366 mr_msg(1, tmp);
367 if (i < 0) {
368 popup_and_OK
369 ("Cannot find ISO images in the directory you specified.");
370 retval = 1;
371 }
372 mr_msg(2, "%ld: bkpinfo->isodir is now %s", __LINE__,
373 bkpinfo->isodir);
374 mr_free(mount_isodir_command);
375 mr_free(tmp);
376 mr_free(command);
377 return (retval);
378}
379
380
381
382
383/**
384 * Kill all Petris processes.
385 */
386void kill_petris(void)
387{
388 char *command;
389 malloc_string(command);
390 sprintf(command,
391 "kill `ps 2> /dev/null | grep petris 2> /dev/null | grep -v grep | cut -d' ' -f2` 2> /dev/null");
392 paranoid_system(command);
393 mr_free(command);
394}
395
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 */
408int modify_rclocal_one_time(char *path)
409{
410 /** malloc **/
411 char *rclocal_fname;
412 char *newfile_fname;
413 char *tmp;
414
415 malloc_string(rclocal_fname);
416 malloc_string(newfile_fname);
417 malloc_string(tmp);
418 assert_string_is_neither_NULL_nor_zerolength(path);
419
420 sprintf(rclocal_fname, "%s/rc.local", path);
421
422// sprintf(tmp, "chmod 1777 %s/tmp", MNT_RESTORING);
423// run_program_and_log_output( tmp, FALSE );
424 return (0); /* remove this line to open the floodgates... */
425
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)) {
430 mr_free(rclocal_fname);
431 mr_free(newfile_fname);
432 mr_free(tmp);
433 return (1);
434 }
435 sprintf(newfile_fname, "%s/rc.local.mondorescue", path);
436 sprintf(tmp, "grep mondorescue %s > /dev/null 2> /dev/null",
437 rclocal_fname);
438 if (system(tmp)) {
439 sprintf(tmp, "echo \"[ -e %s ] && %s\n\" >> %s",
440 newfile_fname, newfile_fname, rclocal_fname);
441
442 paranoid_system(tmp);
443 }
444 sprintf(tmp, "echo -en \"#!/bin/sh\
445\\n\
446\\n\
447grep -v mondorescue %s > %s\\n\
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\
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);
456 mr_free(rclocal_fname);
457 mr_free(newfile_fname);
458 mr_free(tmp);
459 return (0);
460}
461
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 */
476int mount_all_devices(struct mountlist_itself
477 *p_external_copy_of_mountlist, bool writeable)
478{
479 int retval = 0, lino, res;
480 char *tmp, *these_failed, *format;
481 struct mountlist_itself *mountlist;
482
483 malloc_string(tmp);
484 malloc_string(format);
485 malloc_string(these_failed);
486 assert(p_external_copy_of_mountlist != NULL);
487 mountlist = (struct mountlist_itself *)mr_malloc(sizeof(struct mountlist_itself));
488 memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
489 sizeof(struct mountlist_itself));
490 sort_mountlist_by_mountpoint(mountlist, 0);
491
492 /** menset **/
493 these_failed[0] = '\0';
494
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.",
499 "", mountlist->entries);
500
501 for (lino = 0; lino < mountlist->entries; lino++) {
502 if (!strcmp(mountlist->el[lino].device, "/proc")) {
503 mr_msg(1,
504 "Again with the /proc - why is this in your mountlist?");
505 } else if (is_this_device_mounted(mountlist->el[lino].device)) {
506 sprintf(tmp, "%s is already mounted",
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++;
529 }
530 close_progress_form();
531 run_program_and_log_output("df -m", TRUE);
532 if (retval) {
533 if (g_partition_table_locked_up > 0) {
534 log_to_screen
535 ("fdisk's ictol() call to refresh its copy of the partition table causes the kernel to");
536 log_to_screen
537 ("lock up the partition table. You might have to reboot and use Interactive Mode to");
538 log_to_screen
539 ("format and restore *without* partitioning first. Sorry for the inconvenience.");
540 }
541 sprintf(tmp, "Could not mount devices %s- shall I abort?",
542 these_failed);
543 if (!ask_me_yes_or_no(tmp)) {
544 retval = 0;
545 log_to_screen
546 ("Continuing, although some devices failed to be mounted");
547 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
548 } else {
549 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
550 log_to_screen
551 ("Unable to mount some or all of your partitions.");
552 }
553 } else {
554 log_to_screen("All partitions were mounted OK.");
555 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
556 }
557 run_program_and_log_output("df -m", 3);
558 mr_free((void*) mountlist);
559 mr_free(tmp);
560 mr_free(format);
561 mr_free(these_failed);
562 return (retval);
563}
564
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{
581 char *mount_cmd;
582 int i, res;
583#ifdef __FreeBSD__
584 char mdd[32];
585 char *mddev = mdd;
586#endif
587
588 malloc_string(mount_cmd);
589 assert(bkpinfo != NULL);
590
591 if (bkpinfo->backup_media_type == tape
592 || bkpinfo->backup_media_type == udev) {
593 mr_msg(8, "Tape/udev. Therefore, no need to mount CDROM.");
594 mr_free(mount_cmd);
595 return 0;
596 }
597
598 if (!run_program_and_log_output("mount | grep -F " MNT_CDROM, FALSE)) {
599 mr_msg(2, "mount_cdrom() - CD already mounted. Fair enough.");
600 mr_free(mount_cmd);
601 return (0);
602 }
603
604 if (bkpinfo->backup_media_type == nfs) {
605 mr_msg(2, "Mounting for NFS thingy");
606 mr_msg(2, "isodir = %s", bkpinfo->isodir);
607 if ((!bkpinfo->isodir[0] || !strcmp(bkpinfo->isodir, "/"))
608 && am_I_in_disaster_recovery_mode()) {
609 strcpy(bkpinfo->isodir, "/tmp/isodir");
610 mr_msg(1, "isodir is being set to %s", bkpinfo->isodir);
611 }
612#ifdef __FreeBSD__
613 sprintf(mount_cmd, "/mnt/isodir/%s/%s/%s-%d.iso", bkpinfo->isodir,
614 bkpinfo->nfs_remote_dir, bkpinfo->prefix, g_current_media_number);
615 mddev = make_vn(mount_cmd);
616 sprintf(mount_cmd, "mount_cd9660 -r %s " MNT_CDROM, mddev);
617#else
618 sprintf(mount_cmd, "mount %s/%s/%s-%d.iso -t iso9660 -o loop,ro %s",
619 bkpinfo->isodir, bkpinfo->nfs_remote_dir,
620 bkpinfo->prefix, g_current_media_number, MNT_CDROM);
621#endif
622
623 } else
624 if (bkpinfo->backup_media_type == iso) {
625#ifdef __FreeBSD__
626 sprintf(mount_cmd, "%s/%s-%d.iso", bkpinfo->isodir,
627 bkpinfo->prefix, g_current_media_number);
628 mddev = make_vn(mount_cmd);
629 sprintf(mount_cmd, "mount_cd9660 -r %s %s", mddev, MNT_CDROM);
630#else
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);
633#endif
634 } else if (strstr(bkpinfo->media_device, "/dev/"))
635#ifdef __FreeBSD__
636 {
637 sprintf(mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device,
638 MNT_CDROM);
639 }
640#else
641 {
642 sprintf(mount_cmd, "mount %s -t iso9660 -o ro %s",
643 bkpinfo->media_device, MNT_CDROM);
644 }
645#endif
646
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 }
655
656#ifdef __FreeBSD__
657 sprintf(mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device,
658 MNT_CDROM);
659#else
660 sprintf(mount_cmd, "mount %s -t iso9660 -o ro %s",
661 bkpinfo->media_device, MNT_CDROM);
662#endif
663
664 }
665 mr_msg(2, "(mount_cdrom) --- command = %s", mount_cmd);
666 for (i = 0; i < 2; i++) {
667 res = run_program_and_log_output(mount_cmd, FALSE);
668 if (!res) {
669 break;
670 } else {
671 mr_msg(2, "Failed to mount CD-ROM drive.");
672 sleep(5);
673 run_program_and_log_output("sync", FALSE);
674 }
675 }
676 if (res) {
677 mr_msg(2, "Failed, despite %d attempts", i);
678 } else {
679 mr_msg(2, "Mounted CD-ROM drive OK");
680 }
681 mr_free(mount_cmd);
682 return (res);
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 */
702int mount_device(char *device, char *mpt, char *format, bool writeable)
703{
704 int res = 0;
705
706 /** malloc **/
707 char *tmp, *command, *mountdir, *mountpoint, *additional_parameters;
708
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);
717
718 if (!strcmp(mpt, "/1")) {
719 strcpy(mountpoint, "/");
720 mr_msg(3, "Mommm! SME is being a dildo!");
721 } else {
722 strcpy(mountpoint, mpt);
723 }
724
725 if (!strcmp(mountpoint, "lvm")) {
726 return (0);
727 }
728 if (!strcmp(mountpoint, "image")) {
729 return (0);
730 }
731 sprintf(tmp, "Mounting device %s ", device);
732 mr_msg(1, tmp);
733 if (writeable) {
734 strcpy(additional_parameters, "-o rw");
735 } else {
736 strcpy(additional_parameters, "-o ro");
737 }
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 }
744
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);
757 mr_msg(2, "command='%s'", command);
758 }
759 res = run_program_and_log_output(command, TRUE);
760 if (res && (strstr(command, "xattr") || strstr(command, "acl"))) {
761 mr_msg(1, "Re-trying without the fancy extra parameters");
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) {
767 mr_msg(1, "Unable to mount device %s (type %s) at %s", device,
768 format, mountdir);
769 mr_msg(1, "command was '%s'", command);
770 if (!strcmp(mountpoint, "swap")) {
771 log_to_screen(tmp);
772 } else {
773 mr_msg(2, "Retrying w/o the '-t' switch");
774 sprintf(command, "mount %s %s 2>> %s", device, mountdir,
775 MONDO_LOGFILE);
776 mr_msg(2, "2nd command = '%s'", command);
777 res = run_program_and_log_output(command, TRUE);
778 if (res == 0) {
779 mr_msg(1,
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")) {
787 mr_msg(2, "That's ok. It's just a swap partition.");
788 mr_msg(2, "Non-fatal error. Returning 0.");
789 res = 0;
790 }
791
792 mr_free(tmp);
793 mr_free(command);
794 mr_free(mountdir);
795 mr_free(mountpoint);
796 mr_free(additional_parameters);
797
798 return (res);
799}
800
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 */
811void protect_against_braindead_sysadmins()
812{
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
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",
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);
832}
833
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 */
848int read_cfg_file_into_bkpinfo(char *cfgf, struct s_bkpinfo *bkpinfo)
849{
850 /** add mallocs **/
851 char *value = NULL;
852 char *tmp = NULL;
853 char *envtmp1 = NULL;
854 char *envtmp2 = NULL;
855 char *command = NULL;
856 char *iso_mnt = NULL;
857 char *iso_path = NULL;
858 char *old_isodir = NULL;
859 char cfg_file[100];
860 t_bkptype media_specified_by_user;
861
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);
868// assert_string_is_neither_NULL_nor_zerolength(cfg_file);
869 assert(bkpinfo != NULL);
870
871 if (!cfgf) {
872 strcpy(cfg_file, g_mondo_cfg_file);
873 } else {
874 strcpy(cfg_file, cfgf);
875 }
876
877 media_specified_by_user = bkpinfo->backup_media_type; // or 'none', if not specified
878
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")) {
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
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")) {
900 mr_msg(2,
901 "NB: CDROM device not mounted, mounting...");
902 run_program_and_log_output("mount /dev/cdrom "
903 MNT_CDROM, 1);
904 }
905 if (does_file_exist(MNT_CDROM "/archives/filelist.0")) {
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 }
911 }
912 if (read_cfg_var(cfg_file, "iso-prefix", value) == 0) {
913 strcpy(bkpinfo->prefix,value);
914 } else {
915 strcpy(bkpinfo->prefix,STD_PREFIX);
916 }
917 } else if (!strcmp(value, "nfs")) {
918 bkpinfo->backup_media_type = nfs;
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 }
924 if (strstr(call_program_and_get_last_line_of_output
925 ("cat /proc/cmdline"), "pxe")) {
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);
933 }
934
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!");
944 }
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);
961 mr_msg(2, tmp);
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 */
966 mr_msg(2, "Backup medium is CD-R[W]");
967 }
968 } else {
969 mr_msg(2,
970 "Not in Disaster Recovery Mode. No need to derive device name from config file.");
971 }
972
973 read_cfg_var(cfg_file, "use-star", value);
974 if (strstr(value, "yes")) {
975 bkpinfo->use_star = TRUE;
976 mr_msg(1, "Goody! ... bkpinfo->use_star is now true.");
977 }
978
979 read_cfg_var(cfg_file, "acl", value);
980 if (strstr(value, "yes")) {
981 mr_asprintf(&g_getfacl,"setfacl");
982 mr_msg(1, "We will restore ACLs");
983 if (! find_home_of_exe("setfacl")) {
984 mr_msg(1, "Unable to restore ACLs as no setfacl found");
985 }
986 }
987 read_cfg_var(cfg_file, "xattr", value);
988 if (strstr(value, "yes")) {
989 mr_asprintf(&g_getfattr,"setfattr");
990 mr_msg(1, "We will restore XATTRs");
991 if (! find_home_of_exe("setfattr")) {
992 mr_msg(1, "Unable to restore XATTRs as no setfattr found");
993 }
994 }
995
996 if (0 == read_cfg_var(cfg_file, "internal-tape-block-size", value)) {
997 bkpinfo->internal_tape_block_size = atol(value);
998 mr_msg(1, "Internal tape block size has been custom-set to %ld",
999 bkpinfo->internal_tape_block_size);
1000 } else {
1001 bkpinfo->internal_tape_block_size =
1002 DEFAULT_INTERNAL_TAPE_BLOCK_SIZE;
1003 mr_msg(1, "Internal tape block size = default (%ld)",
1004 DEFAULT_INTERNAL_TAPE_BLOCK_SIZE);
1005 }
1006
1007 read_cfg_var(cfg_file, "use-lzo", value);
1008 if (strstr(value, "yes")) {
1009 bkpinfo->use_lzo = TRUE;
1010 bkpinfo->use_gzip = FALSE;
1011 strcpy(bkpinfo->zip_exe, "lzop");
1012 strcpy(bkpinfo->zip_suffix, "lzo");
1013 } else {
1014 read_cfg_var(cfg_file, "use-gzip", value);
1015 if (strstr(value, "yes")) {
1016 bkpinfo->use_lzo = FALSE;
1017 bkpinfo->use_gzip = TRUE;
1018 strcpy(bkpinfo->zip_exe, "gzip");
1019 strcpy(bkpinfo->zip_suffix, "gz");
1020 } else {
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 }
1030 }
1031 }
1032
1033 value[0] = '\0';
1034 read_cfg_var(cfg_file, "differential", value);
1035 if (!strcmp(value, "yes") || !strcmp(value, "1")) {
1036 bkpinfo->differential = TRUE;
1037 }
1038 mr_msg(2, "differential var = '%s'", value);
1039 if (bkpinfo->differential) {
1040 mr_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
1041 } else {
1042 mr_msg(2, "This is a regular (full) backup");
1043 }
1044
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;
1051 mr_msg(2, "Ok, I shan't eject when restoring! Groovy.");
1052 }
1053
1054 if (bkpinfo->backup_media_type == nfs) {
1055 if (!cfgf) {
1056 mr_msg(2, "nfs_mount remains %s", bkpinfo->nfs_mount);
1057 mr_msg(2, "nfs_remote_dir remains %s",
1058 bkpinfo->nfs_remote_dir);
1059 mr_msg(2,
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);
1066 mr_msg(2, "nfs_mount is %s", bkpinfo->nfs_mount);
1067 mr_msg(2, "nfs_remote_dir is %s", bkpinfo->nfs_remote_dir);
1068 }
1069 if (strstr(call_program_and_get_last_line_of_output
1070 ("cat /proc/cmdline"), "pxe")) {
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");
1076 }
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 }
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);
1105 mr_msg(2, "isodir=%s; iso-dev=%s", bkpinfo->isodir,
1106 g_isodir_device);
1107 if (bkpinfo->disaster_recovery) {
1108 if (is_this_device_mounted(g_isodir_device)) {
1109 mr_msg(2, "NB: isodir is already mounted");
1110 /* Find out where it's mounted */
1111 sprintf(command,
1112 "mount | grep -E '^%s' | tail -n1 | cut -d' ' -f3",
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)) {
1125 mr_msg(1,
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 {
1134 mr_msg(1,
1135 "You backed up to disk, then burned some CDs.");
1136 }
1137 }
1138 }
1139 /* bkpinfo->isodir should now be the true path to prefix-1.iso etc... */
1140 if (bkpinfo->backup_media_type == iso) {
1141 sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1142 }
1143 }
1144 }
1145
1146 if (media_specified_by_user != none) {
1147 if (g_restoring_live_from_cd) {
1148 if (bkpinfo->backup_media_type != media_specified_by_user) {
1149 mr_msg(2,
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);
1155/*
1156 if (media_specified_by_user != cdr && media_specified_by_user == cdrw)
1157 { g_restoring_live_from_cd = FALSE; }
1158*/
1159 }
1160 }
1161 bkpinfo->backup_media_type = media_specified_by_user;
1162 }
1163 g_backup_media_type = bkpinfo->backup_media_type;
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);
1170 return (0);
1171
1172}
1173
1174/**************************************************************************
1175 *END_READ_CFG_FILE_INTO_BKPINFO *
1176 **************************************************************************/
1177
1178
1179
1180
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
1192s_node *process_filelist_and_biggielist(struct s_bkpinfo *bkpinfo)
1193{
1194 struct s_node *filelist;
1195
1196 /** add mallocs**/
1197 char *command;
1198 char *tmp;
1199 int res = 0;
1200 pid_t pid;
1201
1202 assert(bkpinfo != NULL);
1203 malloc_string(command);
1204 malloc_string(tmp);
1205
1206 if (does_file_exist(g_filelist_full)
1207 && does_file_exist(g_biggielist_txt)) {
1208 mr_msg(1, "%s exists", g_filelist_full);
1209 mr_msg(1, "%s exists", g_biggielist_txt);
1210 mr_msg(2,
1211 "Filelist and biggielist already recovered from media. Yay!");
1212 } else {
1213 getcwd(tmp, MAX_STR_LEN);
1214 chdir(bkpinfo->tmpdir);
1215 mr_msg(1, "chdir(%s)", bkpinfo->tmpdir);
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);
1228 mr_msg(1, "tarcommand = %s", command);
1229 run_program_and_log_output(command, 1);
1230 } else {
1231 mr_msg(2,
1232 "Calling insist_on_this_cd_number; bkpinfo->isodir=%s",
1233 bkpinfo->isodir);
1234 insist_on_this_cd_number(bkpinfo, 1);
1235 mr_msg(2, "Back from iotcn");
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);
1244
1245 mr_msg(1, "tarcommand = %s", command);
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);
1260
1261 sprintf(command, "cp -f %s/%s %s", bkpinfo->tmpdir,
1262 BIGGIELIST_TXT_STUB, g_biggielist_txt);
1263 mr_msg(1, "command = %s", command);
1264 paranoid_system(command);
1265 sprintf(command, "ln -sf %s/%s %s", bkpinfo->tmpdir,
1266 FILELIST_FULL_STUB, g_filelist_full);
1267 mr_msg(1, "command = %s", command);
1268 paranoid_system(command);
1269 }
1270
1271 if (am_I_in_disaster_recovery_mode()
1272 &&
1273 ask_me_yes_or_no("Do you want to retrieve the mountlist as well?"))
1274 {
1275// sprintf(command, "cp -f tmp/mountlist.txt /tmp");
1276 sprintf(command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB,
1277 bkpinfo->tmpdir);
1278 paranoid_system(command);
1279 }
1280
1281 chdir(tmp);
1282
1283 if (!does_file_exist(g_biggielist_txt)) {
1284 mr_msg(1, "Warning - %s not found", g_biggielist_txt);
1285 }
1286 if (!does_file_exist(g_filelist_full)) {
1287 mr_msg(1, "Warning - %s does not exist", g_filelist_full);
1288 }
1289// popup_and_OK("Wonderful.");
1290
1291 mr_msg(2, "Forking");
1292 pid = fork();
1293 switch (pid) {
1294 case -1:
1295 fatal_error("Forking error");
1296 break;
1297
1298 case 0:
1299 log_to_screen("Pre-processing filelist");
1300 if (!does_file_exist(g_biggielist_txt)) {
1301 sprintf(command, "> %s", g_biggielist_txt);
1302 paranoid_system(command);
1303 }
1304 sprintf(command, "grep -E '^/dev/.*' %s > %s",
1305 g_biggielist_txt, g_filelist_imagedevs);
1306 paranoid_system(command);
1307 exit(0);
1308 break;
1309
1310 default:
1311 open_evalcall_form("Pre-processing filelist");
1312 while (!waitpid(pid, (int *) 0, WNOHANG)) {
1313 usleep(100000);
1314 update_evalcall_form(0);
1315 }
1316 }
1317 close_evalcall_form();
1318
1319 mr_msg(3, "loading filelist");
1320 filelist = load_filelist(g_filelist_full);
1321 mr_msg(3, "deleting original filelist");
1322 unlink(g_filelist_full);
1323 if (g_text_mode) {
1324 printf("Restore which directory? --> ");
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);
1334 }
1335 if (res) {
1336 mr_msg(2, "User hit 'cancel'. Freeing filelist and aborting.");
1337 free_filelist(filelist);
1338 return (NULL);
1339 }
1340 ask_about_these_imagedevs(g_filelist_imagedevs, g_imagedevs_restthese);
1341 close_evalcall_form();
1342
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.
1346
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 }
1353
1354 mr_free(command);
1355 mr_free(tmp);
1356 return (filelist);
1357}
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 */
1373int backup_crucial_file(char *path_root, char *filename)
1374{
1375 char *tmp;
1376 char *command;
1377 int res;
1378
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);
1388 mr_free(tmp);
1389 mr_free(command);
1390 return (res);
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 */
1400int run_boot_loader(bool offer_to_hack_scripts)
1401{
1402 int res;
1403 int retval = 0;
1404
1405 /** malloc *******/
1406 char *device;
1407 char *tmp;
1408 char *name;
1409
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);
1420 mr_msg(2, tmp);
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")) {
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// {
1429 res = run_grub(offer_to_hack_scripts, device);
1430// unlink(DO_MBR_PLEASE);
1431// }
1432// else
1433// {
1434// mr_msg(1, "Not running run_grub(). Was a bad idea anyway.");
1435// res = 1;
1436// }
1437 } else if (!strcmp(name, "RAW")) {
1438 res = run_raw_mbr(offer_to_hack_scripts, device);
1439 }
1440#ifdef __FreeBSD__
1441 else if (!strcmp(name, "BOOT0")) {
1442 sprintf(tmp, "boot0cfg -B %s", device);
1443 res = run_program_and_log_output(tmp, FALSE);
1444 } else {
1445 sprintf(tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device);
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 {
1450 mr_msg(1,
1451 "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");
1452 }
1453 }
1454#else
1455 else {
1456 log_to_screen
1457 ("Unable to determine type of boot loader. Defaulting to LILO.");
1458 res = run_lilo(offer_to_hack_scripts);
1459 }
1460#endif
1461 retval += res;
1462 if (res) {
1463 log_to_screen("Your boot loader returned an error");
1464 } else {
1465 log_to_screen("Your boot loader ran OK");
1466 }
1467 mr_free(device);
1468 mr_free(tmp);
1469 mr_free(name);
1470 return (retval);
1471}
1472
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{
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)) {
1499 mr_msg(2, " (find_my_editor) --- warning - %s not found", output);
1500 }
1501 return (output);
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 */
1511int run_grub(bool offer_to_run_stabgrub, char *bd)
1512{
1513 /** malloc **/
1514 char *command;
1515 char *boot_device;
1516 char *rootdev;
1517 char *rootdrive;
1518 char *conffile;
1519 char *tmp;
1520 char *editor;
1521
1522 int res;
1523 int done;
1524
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)) {
1537 mr_msg(1, "Yay! grub-MR found...");
1538 sprintf(command, "grub-MR %s /tmp/mountlist.txt", boot_device);
1539 mr_msg(1, "command = %s", command);
1540 } else {
1541 sprintf(command, "chroot " MNT_RESTORING " grub-install %s",
1542 boot_device);
1543 mr_msg(1, "WARNING - grub-MR not found; using grub-install");
1544 }
1545 if (offer_to_run_stabgrub
1546 && ask_me_yes_or_no("Did you change the mountlist?"))
1547 /* interactive mode */
1548 {
1549 mvaddstr_and_log_it(g_currentY,
1550 0,
1551 "Modifying fstab and grub.conf, and running GRUB... ");
1552 for (done = FALSE; !done;) {
1553 popup_and_get_string("Boot device",
1554 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
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
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.");
1561 newtSuspend();
1562 system("chroot " MNT_RESTORING);
1563 newtResume();
1564 popup_and_OK("Thank you.");
1565 } else {
1566 done = TRUE;
1567 }
1568 popup_and_OK("You will now edit fstab and grub.conf");
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,
1585 "Running GRUB... ");
1586 iamhere(command);
1587 res = run_program_and_log_output(command, 1);
1588 if (res) {
1589 popup_and_OK
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.");
1591 newtSuspend();
1592 system("chroot " MNT_RESTORING);
1593 newtResume();
1594 popup_and_OK("Thank you.");
1595 }
1596 }
1597 if (res) {
1598 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1599 log_to_screen
1600 ("GRUB ran w/error(s). See /tmp/mondo-restore.log for more info.");
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,
1609 "If you're really stuck, please e-mail the mailing list.");
1610 } else {
1611 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1612 }
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);
1620
1621 return (res);
1622}
1623
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 */
1634int run_elilo(bool offer_to_run_stabelilo)
1635{
1636 /** malloc **/
1637 char *command;
1638 char *tmp;
1639 char *editor;
1640
1641 int res;
1642 int done;
1643
1644 malloc_string(command);
1645 malloc_string(tmp);
1646 malloc_string(editor);
1647 strcpy(editor, find_my_editor());
1648 if (offer_to_run_stabelilo
1649 && ask_me_yes_or_no("Did you change the mountlist?"))
1650
1651 /* interactive mode */
1652 {
1653 mvaddstr_and_log_it(g_currentY,
1654 0,
1655 "Modifying fstab and elilo.conf... ");
1656 sprintf(command, "stabelilo-me");
1657 res = run_program_and_log_output(command, 3);
1658 if (res) {
1659 popup_and_OK
1660 ("You will now edit fstab and elilo.conf, to make sure they match your new mountlist.");
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 }
1673// newtCls();
1674 if (ask_me_yes_or_no("Edit them again?")) {
1675 continue;
1676 }
1677 done = TRUE;
1678 }
1679 } else {
1680 log_to_screen("elilo.conf and fstab were modified OK");
1681 }
1682 } else
1683 /* nuke mode */
1684 {
1685 res = TRUE;
1686 }
1687 mr_free(command);
1688 mr_free(tmp);
1689 mr_free(editor);
1690 return (res);
1691}
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 */
1703int run_lilo(bool offer_to_run_stablilo)
1704{
1705 /** malloc **/
1706 char *command;
1707 char *tmp;
1708 char *editor;
1709
1710 int res;
1711 int done;
1712 bool run_lilo_M = FALSE;
1713 malloc_string(command);
1714 malloc_string(tmp);
1715 malloc_string(editor);
1716
1717 if (!run_program_and_log_output
1718 ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) {
1719 run_lilo_M = TRUE;
1720 }
1721
1722 strcpy(editor, find_my_editor());
1723 if (offer_to_run_stablilo
1724 && ask_me_yes_or_no("Did you change the mountlist?"))
1725
1726 /* interactive mode */
1727 {
1728 mvaddstr_and_log_it(g_currentY,
1729 0,
1730 "Modifying fstab and lilo.conf, and running LILO... ");
1731 sprintf(command, "stablilo-me");
1732 res = run_program_and_log_output(command, 3);
1733 if (res) {
1734 popup_and_OK
1735 ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist.");
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 }
1747// newtCls();
1748 if (ask_me_yes_or_no("Edit them again?")) {
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
1762 ("LILO failed. Re-edit system files?");
1763 } else {
1764 done = TRUE;
1765 }
1766 }
1767 } else {
1768 log_to_screen("lilo.conf and fstab were modified OK");
1769 }
1770 } else
1771 /* nuke mode */
1772 {
1773 mvaddstr_and_log_it(g_currentY,
1774 0,
1775 "Running LILO... ");
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);
1783 }
1784 if (res) {
1785 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1786 log_to_screen
1787 ("Failed to re-jig fstab and/or lilo. Edit/run manually, please.");
1788 } else {
1789 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1790 }
1791 }
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);
1797 }
1798 mr_free(command);
1799 mr_free(tmp);
1800 mr_free(editor);
1801 return (res);
1802}
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 */
1815int run_raw_mbr(bool offer_to_hack_scripts, char *bd)
1816{
1817 /** malloc **/
1818 char *command;
1819 char *boot_device;
1820 char *tmp;
1821 char *editor;
1822 int res;
1823 int done;
1824
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);
1830
1831 strcpy(editor, find_my_editor());
1832 strcpy(boot_device, bd);
1833 sprintf(command, "raw-MR %s /tmp/mountlist.txt", boot_device);
1834 mr_msg(2, "run_raw_mbr() --- command='%s'", command);
1835
1836 if (offer_to_hack_scripts
1837 && ask_me_yes_or_no("Did you change the mountlist?"))
1838 /* interactive mode */
1839 {
1840 mvaddstr_and_log_it(g_currentY, 0,
1841 "Modifying fstab and restoring MBR... ");
1842 for (done = FALSE; !done;) {
1843 if (!run_program_and_log_output("which vi", FALSE)) {
1844 popup_and_OK("You will now edit fstab");
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 }
1853// newtCls();
1854 }
1855 popup_and_get_string("Boot device",
1856 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
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) {
1861 done = ask_me_yes_or_no("Modifications failed. Re-try?");
1862 } else {
1863 done = TRUE;
1864 }
1865 }
1866 } else
1867 /* nuke mode */
1868 {
1869 mvaddstr_and_log_it(g_currentY, 0,
1870 "Restoring MBR... ");
1871 res = run_program_and_log_output(command, 3);
1872 }
1873 if (res) {
1874 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1875 log_to_screen
1876 ("MBR+fstab processed w/error(s). See /tmp/mondo-restore.log for more info.");
1877 } else {
1878 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1879 }
1880 mr_free(command);
1881 mr_free(boot_device);
1882 mr_free(tmp);
1883 mr_free(editor);
1884 return (res);
1885}
1886
1887/**************************************************************************
1888 *END_RUN_RAW_MBR *
1889 **************************************************************************/
1890
1891
1892
1893
1894
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 */
1900void set_signals(int on)
1901{
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 }
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 */
1926void setup_MR_global_filenames(struct s_bkpinfo *bkpinfo)
1927{
1928 char *temppath;
1929
1930 assert(bkpinfo != NULL);
1931
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_mondo_home);
1939 malloc_string(g_tmpfs_mountpt);
1940 malloc_string(g_isodir_device);
1941 malloc_string(g_isodir_format);
1942
1943 temppath = bkpinfo->tmpdir;
1944
1945 sprintf(g_biggielist_txt, "%s/%s", temppath, BIGGIELIST_TXT_STUB);
1946 sprintf(g_filelist_full, "%s/%s", temppath, FILELIST_FULL_STUB);
1947 sprintf(g_filelist_imagedevs, "%s/tmp/filelist.imagedevs", temppath);
1948// sprintf(g_imagedevs_pot, "%s/tmp/imagedevs.pot", temppath);
1949 sprintf(g_imagedevs_restthese, "%s/tmp/imagedevs.restore-these",
1950 temppath);
1951 if (bkpinfo->disaster_recovery) {
1952 sprintf(g_mondo_cfg_file, "/%s", MONDO_CFG_FILE_STUB);
1953 sprintf(g_mountlist_fname, "/%s", MOUNTLIST_FNAME_STUB);
1954 } else {
1955 sprintf(g_mondo_cfg_file, "%s/%s", temppath, MONDO_CFG_FILE_STUB);
1956 sprintf(g_mountlist_fname, "%s/%s", temppath,
1957 MOUNTLIST_FNAME_STUB);
1958 }
1959}
1960
1961/**************************************************************************
1962 *END_SET_GLOBAL_FILENAME *
1963 **************************************************************************/
1964
1965
1966/**
1967 * Copy @p input_file (containing the result of a compare) to @p output_file,
1968 * deleting spurious "changes" along the way.
1969 * @param output_file The output file to write with spurious changes removed.
1970 * @param input_file The input file, a list of changed files created by a compare.
1971 */
1972void streamline_changes_file(char *output_file, char *input_file)
1973{
1974 FILE *fin;
1975 FILE *fout;
1976 /** malloc **/
1977 char *incoming;
1978
1979 assert_string_is_neither_NULL_nor_zerolength(output_file);
1980 assert_string_is_neither_NULL_nor_zerolength(input_file);
1981 malloc_string(incoming);
1982
1983 if (!(fin = fopen(input_file, "r"))) {
1984 log_OS_error(input_file);
1985 return;
1986 }
1987 if (!(fout = fopen(output_file, "w"))) {
1988 fatal_error("cannot open output_file");
1989 }
1990 for (fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin);
1991 fgets(incoming, MAX_STR_LEN - 1, fin)) {
1992 if (strncmp(incoming, "etc/adjtime", 11)
1993 && strncmp(incoming, "etc/mtab", 8)
1994 && strncmp(incoming, "tmp/", 4)
1995 && strncmp(incoming, "boot/map", 8)
1996 && !strstr(incoming, "incheckentry")
1997 && strncmp(incoming, "etc/mail/statistics", 19)
1998 && strncmp(incoming, "var/", 4))
1999 fprintf(fout, "%s", incoming); /* don't need \n here, for some reason.. */
2000 }
2001 paranoid_fclose(fout);
2002 paranoid_fclose(fin);
2003 mr_free(incoming);
2004}
2005
2006/**************************************************************************
2007 *END_STREAMLINE_CHANGES_FILE *
2008 **************************************************************************/
2009
2010
2011/**
2012 * Exit due to a signal (normal cleanup).
2013 * @param sig The signal we're exiting due to.
2014 */
2015void terminate_daemon(int sig)
2016{
2017 log_to_screen
2018 ("Mondorestore is terminating in response to a signal from the OS");
2019 paranoid_MR_finish(254);
2020}
2021
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 */
2030void twenty_seconds_til_yikes()
2031{
2032 int i;
2033 /* MALLOC * */
2034 char *tmp;
2035
2036 malloc_string(tmp);
2037 if (does_file_exist("/tmp/NOPAUSE")) {
2038 return;
2039 }
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.",
2043 "", 20);
2044 for (i = 0; i < 20; i++) {
2045 g_current_progress = i;
2046 sprintf(tmp, "You have %d seconds left to abort.", 20 - i);
2047 update_progress_form(tmp);
2048 sleep(1);
2049 }
2050 close_progress_form();
2051 mr_free(tmp);
2052}
2053
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 */
2066void termination_in_progress(int sig)
2067{
2068 mr_msg(1, "Termination in progress");
2069 usleep(1000);
2070 pthread_exit(0);
2071}
2072
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 */
2084int unmount_all_devices(struct mountlist_itself
2085 *p_external_copy_of_mountlist)
2086{
2087 struct mountlist_itself *mountlist;
2088 int retval = 0, lino, res = 0, i;
2089 char *command;
2090 char *tmp;
2091
2092 malloc_string(command);
2093 malloc_string(tmp);
2094 assert(p_external_copy_of_mountlist != NULL);
2095
2096 mountlist = (struct mountlist_itself *)mr_malloc(sizeof(struct mountlist_itself));
2097 memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
2098 sizeof(struct mountlist_itself));
2099 sort_mountlist_by_mountpoint(mountlist, 0);
2100
2101 run_program_and_log_output("df -m", 3);
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.",
2106 "", mountlist->entries);
2107 chdir("/");
2108 for (i = 0;
2109 i < 10
2110 &&
2111 run_program_and_log_output
2112 ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
2113 i++) {
2114 sleep(1);
2115 mr_msg(2, "Waiting for buffer() to finish");
2116 }
2117
2118 paranoid_system("sync");
2119
2120 if (run_program_and_log_output
2121 ("cp -f /tmp/mondo-restore.log " MNT_RESTORING "/tmp/", FALSE)) {
2122 mr_msg(1,
2123 "Error. Failed to copy log to PC's /tmp dir. (Mounted read-only?)");
2124 }
2125 if (run_program_and_log_output
2126 ("cp -f /tmp/mondo-restore.log " MNT_RESTORING "/root/", FALSE)) {
2127 mr_msg(1,
2128 "Error. Failed to copy log to PC's /root dir. (Mounted read-only?)");
2129 }
2130 if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2131 run_program_and_log_output("mkdir -p " MNT_RESTORING
2132 "/mnt/.boot.d", 5);
2133 }
2134 for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2135 if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2136 continue;
2137 }
2138 sprintf(tmp, "Unmounting device %s ", mountlist->el[lino].device);
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);
2147 mr_msg(3,
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 }
2154 mr_msg(10, "The 'umount' command is '%s'", command);
2155 res = run_program_and_log_output(command, 3);
2156 } else {
2157 strcat(tmp, "...not mounted anyway :-) OK");
2158 res = 0;
2159 }
2160 g_current_progress++;
2161 if (res) {
2162 strcat(tmp, "...Failed");
2163 retval++;
2164 log_to_screen(tmp);
2165 } else {
2166 mr_msg(2, tmp);
2167 }
2168 }
2169 close_progress_form();
2170 if (retval) {
2171 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2172 } else {
2173 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2174 }
2175 if (retval) {
2176 log_to_screen("Unable to unmount some of your partitions.");
2177 } else {
2178 log_to_screen("All partitions were unmounted OK.");
2179 }
2180 mr_free((void*) mountlist);
2181 mr_free(command);
2182 mr_free(tmp);
2183 return (retval);
2184}
2185
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 */
2198int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2199{
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;
2204
2205 malloc_string(command);
2206
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");
2215 mr_msg(2, "command = '%s'", command);
2216 res = run_program_and_log_output(command, -1);
2217 if (res != 0 && does_file_exist(MONDO_CFG_FILE_STUB)) {
2218 res = 0;
2219 }
2220 mr_free(command);
2221 return (res);
2222}
2223
2224
2225
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 */
2234int get_cfg_file_from_archive(struct s_bkpinfo *bkpinfo)
2235{
2236 int retval = 0;
2237
2238 /** malloc *****/
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;
2248
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);
2260 mr_msg(2, "gcffa --- starting");
2261 log_to_screen("I'm thinking...");
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
2273// unlink( "tmp/mondo-restore.cfg" ); // superfluous, surely?
2274
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);
2280 mr_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
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,
2290 "(sleep 15; kill `ps | grep \"%s\" | cut -d' ' -f1` 2> /dev/null) &",
2291 command);
2292 mr_msg(1, "tmp = '%s'", tmp);
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;
2303 mr_msg(2,
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.");
2305// NB: If busybox does not support 'mount -o loop' then Plan A WILL NOT WORK.
2306 mr_msg(2, "Processing floppy (plan A?)");
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)) {
2312 mr_msg(2,
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)) {
2317 mr_msg(2,
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)) {
2325 mr_msg(2, "gcffa --- we don't have cfg file yet.");
2326 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2327 try_plan_B = TRUE;
2328 } else {
2329 mr_msg(2, "gcffa --- calling mount_cdrom now :)");
2330 if (!mount_cdrom(bkpinfo)) {
2331 mr_msg(2,
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) {
2343 mr_msg(2, "gcffa --- OK, switching to Plan B");
2344 chdir(bkpinfo->tmpdir);
2345 run_program_and_log_output("mkdir -p tmp", FALSE);
2346
2347 if (strlen(bkpinfo->media_device) == 0) {
2348 strcpy(bkpinfo->media_device, "/dev/st0");
2349 mr_msg(2, "media_device is blank; assuming %s");
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)) {
2363 mr_msg(3,
2364 "I tried lots of devices but none worked.");
2365 strcpy(bkpinfo->media_device, tmp);
2366 }
2367 }
2368 }
2369 }
2370
2371 if (!does_file_exist("tmp/mondo-restore.cfg")) {
2372 log_to_screen("Cannot find config info on tape/CD/floppy");
2373 return (1);
2374 }
2375 } else {
2376 mr_msg(2,
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)) {
2383 mr_msg(2,
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 }
2392 }
2393 }
2394 if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2395 mr_msg(1, "gcffa --- great! We've got the config file");
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)) {
2403 mr_msg(1,
2404 "... but an error occurred when I tried to move it to %s",
2405 cfg_file);
2406 } else {
2407 mr_msg(1, "... and I moved it successfully to %s", cfg_file);
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)) {
2415 mr_msg(1, "Failed to get mountlist");
2416 } else {
2417 mr_msg(1, "Got mountlist too");
2418 sprintf(command, "cp -f %s %s", mountlist_file,
2419 g_mountlist_fname);
2420 if (run_program_and_log_output(command, 1)) {
2421 mr_msg(1, "Failed to copy mountlist to /tmp");
2422 } else {
2423 mr_msg(1, "Copied mountlist to /tmp as well OK");
2424 sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2425 run_program_and_log_output(command, 1);
2426/* sprintf(command, "grep \" lvm \" %s", g_mountlist_fname);
2427 if (!run_program_and_log_output(command, 5) && !does_file_exist("/tmp/i-want-my-lvm"))
2428 {
2429 mr_msg(1, "Warning. You want LVM but I don't have i-want-my-lvm. FIXME.");
2430 }
2431 else if (run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2432 {
2433 mr_msg(1, "Warning. You don't want LVM but i-want-my-lvm exists. I'll delete it. Cool.");
2434 do_my_funky_lvm_stuff(TRUE, FALSE); // ...after I stop any LVMs :)
2435 stop_raid_device("/dev/md0");
2436 stop_raid_device("/dev/md1");
2437 stop_raid_device("/dev/md2");
2438 unlink("/tmp/i-want-my-lvm");
2439 }
2440 else if (!run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2441 {
2442 mr_msg(1, "You had better pray that i-want-my-lvm patches your mountlist. FIXME.");
2443 }
2444*/
2445 }
2446 }
2447 }
2448 run_program_and_log_output("umount " MNT_CDROM, FALSE);
2449 if (!does_file_exist(cfg_file)) {
2450 iamhere(cfg_file);
2451 mr_msg(1, "%s not found", cfg_file);
2452 log_to_screen
2453 ("Oh dear. Unable to recover configuration file from boot disk");
2454 return (1);
2455 }
2456
2457 log_to_screen("Recovered mondo-restore.cfg");
2458 if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2459 log_to_screen("...but not mountlist.txt - a pity, really...");
2460 }
2461/* start SAH */
2462 else {
2463 sprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB,
2464 bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2465 run_program_and_log_output(command, FALSE);
2466 }
2467/*--commented out by SAH
2468 sprintf( command, "cp -f %s %s/%s", cfg_file, bkpinfo->tmpdir, MONDO_CFG_FILE_STUB );
2469 run_program_and_log_output( command, FALSE );
2470 sprintf( command, "cp -f %s %s/%s", mountlist_file, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB );
2471 run_program_and_log_output( command, FALSE );
2472*/
2473/* end SAH */
2474
2475 sprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2476 run_program_and_log_output(command, FALSE);
2477 sprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2478 run_program_and_log_output(command, FALSE);
2479 sprintf(command, "cp -f etc/raidtab /etc/");
2480 run_program_and_log_output(command, FALSE);
2481 sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2482 run_program_and_log_output(command, FALSE);
2483 g_backup_media_type = bkpinfo->backup_media_type;
2484 mr_free(device);
2485 mr_free(command);
2486 mr_free(tmp);
2487 mr_free(cfg_file);
2488 mr_free(mounted_cfgf_path);
2489 mr_free(mountpt);
2490 mr_free(ramdisk_fname);
2491 mr_free(mountlist_file);
2492 return (retval);
2493}
2494
2495/**************************************************************************
2496 *END_GET_CFG_FILE_FROM_ARCHIVE *
2497 **************************************************************************/
2498
2499/* @} - end restoreUtilityGroup */
2500
2501
2502/***************************************************************************
2503 * F@ *
2504 * () -- Hugo Rabson *
2505 * *
2506 * Purpose: *
2507 * *
2508 * Called by: *
2509 * Params: - - *
2510 * Returns: 0=success; nonzero=failure *
2511 ***************************************************************************/
2512
2513
2514
2515void wait_until_software_raids_are_prepped(char *mdstat_file,
2516 int wait_for_percentage)
2517{
2518 struct raidlist_itself *raidlist;
2519 int unfinished_mdstat_devices = 9999, i;
2520 char *screen_message;
2521
2522 malloc_string(screen_message);
2523 raidlist = (struct raidlist_itself *)mr_malloc(sizeof(struct raidlist_itself));
2524
2525 assert(wait_for_percentage <= 100);
2526 iamhere("wait_until_software_raids_are_prepped");
2527 while (unfinished_mdstat_devices > 0) {
2528 // FIXME: Prefix '/dev/' should really be dynamic!
2529 if (parse_mdstat(raidlist, "/dev/")) {
2530 log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2531 mr_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2532 return;
2533 }
2534 for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2535 if (raidlist->el[i].progress < wait_for_percentage) {
2536 unfinished_mdstat_devices++;
2537 if (raidlist->el[i].progress == -1) // delayed while another partition inits
2538 {
2539 continue;
2540 }
2541 mr_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2542 sprintf(screen_message, "Sync'ing %s",
2543 raidlist->el[i].raid_device);
2544 open_evalcall_form(screen_message);
2545 while (raidlist->el[i].progress < wait_for_percentage) {
2546 mr_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2547 update_evalcall_form(raidlist->el[i].progress);
2548 sleep(2);
2549 // FIXME: Prefix '/dev/' should really be dynamic!
2550 if (parse_mdstat(raidlist, "/dev/")) {
2551 break;
2552 }
2553 }
2554 close_evalcall_form();
2555 }
2556 }
2557 }
2558 mr_free(screen_message);
2559 mr_free((void*) raidlist);
2560}
Note: See TracBrowser for help on using the repository browser.