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

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

Suppress g_bkpinfo_DONTUSETHIS (Idea from M. Loiseleur)

  • Property svn:keywords set to Id
File size: 76.8 KB
Line 
1/***************************************************************************
2 * $Id: mondo-rstr-tools.c 1166 2007-02-14 22:33:50Z 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#include "mr_msg.h"
16
17extern bool g_sigpipe_caught;
18extern bool g_ISO_restore_mode; /* are we in Iso Mode? */
19extern bool g_I_have_just_nuked;
20extern char *g_tmpfs_mountpt;
21extern char *g_isodir_device;
22extern char *g_isodir_format;
23extern long g_current_progress, g_maximum_progress;
24extern char *g_biggielist_txt; // where 'biggielist.txt' is stored, on ramdisk / tempdir;
25 // biggielist.txt is the list of big files stored on the
26 // backup media set in question
27extern char *g_filelist_full; // filelist.full.gz is the list of all regular files
28 // (excluding big files) stored on the backup media set
29extern char *g_biggielist_pot; // list of big files which _could_ be restored, if the
30 // user chooses them
31extern char *g_filelist_imagedevs; // list of devices (e.g. /dev/hda1, /dev/sda5) which
32 // were archived as images, not just /dev entries
33 // ... e.g. NTFS, BeOS partitions
34extern char *g_imagedevs_restthese; // of the imagedevs listed in FILELIST_IMAGEDEVS,
35 // restore only these
36extern char *g_mondo_cfg_file; // where m*ndo-restore.cfg (the config file) is stored
37extern char *g_mountlist_fname; // where mountlist.txt (the mountlist file) is stored
38extern char *g_mondo_home; // homedir of Mondo; usually /usr/local/share/mondo
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(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 free_MR_global_filenames();
2020 finish(254);
2021}
2022
2023/**************************************************************************
2024 *END_TERMINATE_DAEMON *
2025 **************************************************************************/
2026
2027
2028/**
2029 * Give the user twenty seconds to press Ctrl-Alt-Del before we nuke their drives.
2030 */
2031void twenty_seconds_til_yikes()
2032{
2033 int i;
2034 /* MALLOC * */
2035 char *tmp;
2036
2037 malloc_string(tmp);
2038 if (does_file_exist("/tmp/NOPAUSE")) {
2039 return;
2040 }
2041 open_progress_form("CAUTION",
2042 "Be advised: I am about to ERASE your hard disk(s)!",
2043 "You may press Ctrl+Alt+Del to abort safely.",
2044 "", 20);
2045 for (i = 0; i < 20; i++) {
2046 g_current_progress = i;
2047 sprintf(tmp, "You have %d seconds left to abort.", 20 - i);
2048 update_progress_form(tmp);
2049 sleep(1);
2050 }
2051 close_progress_form();
2052 mr_free(tmp);
2053}
2054
2055/**************************************************************************
2056 *END_TWENTY_SECONDS_TIL_YIKES *
2057 **************************************************************************/
2058
2059
2060
2061
2062
2063/**
2064 * Exit due to a signal (no cleanup).
2065 * @param sig The signal we're exiting due to.
2066 */
2067void termination_in_progress(int sig)
2068{
2069 mr_msg(1, "Termination in progress");
2070 usleep(1000);
2071 pthread_exit(0);
2072}
2073
2074/**************************************************************************
2075 *END_TERMINATION_IN_PROGRESS *
2076 **************************************************************************/
2077
2078
2079
2080/**
2081 * Unmount all devices in @p p_external_copy_of_mountlist.
2082 * @param p_external_copy_of_mountlist The mountlist to guide the devices to unmount.
2083 * @return 0 for success, nonzero for failure.
2084 */
2085int unmount_all_devices(struct mountlist_itself
2086 *p_external_copy_of_mountlist)
2087{
2088 struct mountlist_itself *mountlist;
2089 int retval = 0, lino, res = 0, i;
2090 char *command;
2091 char *tmp;
2092
2093 malloc_string(command);
2094 malloc_string(tmp);
2095 assert(p_external_copy_of_mountlist != NULL);
2096
2097 mountlist = (struct mountlist_itself *)mr_malloc(sizeof(struct mountlist_itself));
2098 memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
2099 sizeof(struct mountlist_itself));
2100 sort_mountlist_by_mountpoint(mountlist, 0);
2101
2102 run_program_and_log_output("df -m", 3);
2103 mvaddstr_and_log_it(g_currentY, 0, "Unmounting devices ");
2104 open_progress_form("Unmounting devices",
2105 "Unmounting all devices that were mounted,",
2106 "in preparation for the post-restoration reboot.",
2107 "", mountlist->entries);
2108 chdir("/");
2109 for (i = 0;
2110 i < 10
2111 &&
2112 run_program_and_log_output
2113 ("ps | grep buffer | grep -v \"grep buffer\"", TRUE) == 0;
2114 i++) {
2115 sleep(1);
2116 mr_msg(2, "Waiting for buffer() to finish");
2117 }
2118
2119 paranoid_system("sync");
2120
2121 if (run_program_and_log_output
2122 ("cp -f /tmp/mondo-restore.log " MNT_RESTORING "/tmp/", FALSE)) {
2123 mr_msg(1,
2124 "Error. Failed to copy log to PC's /tmp dir. (Mounted read-only?)");
2125 }
2126 if (run_program_and_log_output
2127 ("cp -f /tmp/mondo-restore.log " MNT_RESTORING "/root/", FALSE)) {
2128 mr_msg(1,
2129 "Error. Failed to copy log to PC's /root dir. (Mounted read-only?)");
2130 }
2131 if (does_file_exist("/tmp/DUMBASS-GENTOO")) {
2132 run_program_and_log_output("mkdir -p " MNT_RESTORING
2133 "/mnt/.boot.d", 5);
2134 }
2135 for (lino = mountlist->entries - 1; lino >= 0; lino--) {
2136 if (!strcmp(mountlist->el[lino].mountpoint, "lvm")) {
2137 continue;
2138 }
2139 sprintf(tmp, "Unmounting device %s ", mountlist->el[lino].device);
2140
2141 update_progress_form(tmp);
2142 if (is_this_device_mounted(mountlist->el[lino].device)) {
2143 if (!strcmp(mountlist->el[lino].mountpoint, "swap")) {
2144 sprintf(command, "swapoff %s", mountlist->el[lino].device);
2145 } else {
2146 if (!strcmp(mountlist->el[lino].mountpoint, "/1")) {
2147 sprintf(command, "umount %s/", MNT_RESTORING);
2148 mr_msg(3,
2149 "Well, I know a certain kitty-kitty who'll be sleeping with Mommy tonight...");
2150 } else {
2151 sprintf(command, "umount " MNT_RESTORING "%s",
2152 mountlist->el[lino].mountpoint);
2153 }
2154 }
2155 mr_msg(10, "The 'umount' command is '%s'", command);
2156 res = run_program_and_log_output(command, 3);
2157 } else {
2158 strcat(tmp, "...not mounted anyway :-) OK");
2159 res = 0;
2160 }
2161 g_current_progress++;
2162 if (res) {
2163 strcat(tmp, "...Failed");
2164 retval++;
2165 log_to_screen(tmp);
2166 } else {
2167 mr_msg(2, tmp);
2168 }
2169 }
2170 close_progress_form();
2171 if (retval) {
2172 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
2173 } else {
2174 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
2175 }
2176 if (retval) {
2177 log_to_screen("Unable to unmount some of your partitions.");
2178 } else {
2179 log_to_screen("All partitions were unmounted OK.");
2180 }
2181 mr_free(mountlist);
2182 mr_free(command);
2183 mr_free(tmp);
2184 return (retval);
2185}
2186
2187/**************************************************************************
2188 *END_UNMOUNT_ALL_DEVICES *
2189 **************************************************************************/
2190
2191
2192
2193/**
2194 * Extract mondo-restore.cfg and the mountlist from the tape inserted
2195 * to the ./tmp/ directory.
2196 * @param dev The tape device to read from.
2197 * @return 0 for success, nonzero for failure.
2198 */
2199int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)
2200{
2201 char *command;
2202 int res = 0;
2203 // BCO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0
2204 long tape_block_size = 32768;
2205
2206 malloc_string(command);
2207
2208 // tar -zxvf-
2209 sprintf(command,
2210 "dd if=%s bs=%ld count=%ld 2> /dev/null | tar -zx %s %s %s %s %s",
2211 dev,
2212 tape_block_size,
2213 1024L * 1024 * 32 / tape_block_size,
2214 MOUNTLIST_FNAME_STUB, MONDO_CFG_FILE_STUB,
2215 BIGGIELIST_TXT_STUB, FILELIST_FULL_STUB, "tmp/i-want-my-lvm");
2216 mr_msg(2, "command = '%s'", command);
2217 res = run_program_and_log_output(command, -1);
2218 if (res != 0 && does_file_exist(MONDO_CFG_FILE_STUB)) {
2219 res = 0;
2220 }
2221 mr_free(command);
2222 return (res);
2223}
2224
2225
2226
2227/**
2228 * Get the configuration file from the floppy, tape, or CD.
2229 * @param bkpinfo The backup information structure. Fields used:
2230 * - @c bkpinfo->backup_media_type
2231 * - @c bkpinfo->media_device
2232 * - @c bkpinfo->tmpdir
2233 * @return 0 for success, nonzero for failure.
2234 */
2235int get_cfg_file_from_archive(struct s_bkpinfo *bkpinfo)
2236{
2237 int retval = 0;
2238
2239 /** malloc *****/
2240 char *device;
2241 char *command;
2242 char *cfg_file;
2243 char *mounted_cfgf_path;
2244 char *tmp;
2245 char *mountpt;
2246 char *ramdisk_fname;
2247 char *mountlist_file;
2248 int res;
2249
2250 bool try_plan_B;
2251
2252 assert(bkpinfo != NULL);
2253 malloc_string(cfg_file);
2254 malloc_string(mounted_cfgf_path);
2255 malloc_string(mountpt);
2256 malloc_string(ramdisk_fname);
2257 malloc_string(mountlist_file);
2258 malloc_string(device);
2259 malloc_string(command);
2260 malloc_string(tmp);
2261 mr_msg(2, "gcffa --- starting");
2262 log_to_screen("I'm thinking...");
2263 sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
2264 device[0] = '\0';
2265 chdir(bkpinfo->tmpdir);
2266 strcpy(cfg_file, MONDO_CFG_FILE_STUB);
2267 unlink(cfg_file); // cfg_file[] is missing the '/' at the start, FYI, by intent
2268 unlink(FILELIST_FULL_STUB);
2269 unlink(BIGGIELIST_TXT_STUB);
2270 unlink("tmp/i-want-my-lvm");
2271 sprintf(command, "mkdir -p %s", mountpt);
2272 run_program_and_log_output(command, FALSE);
2273
2274// unlink( "tmp/mondo-restore.cfg" ); // superfluous, surely?
2275
2276 sprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);
2277 sprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir,
2278 MOUNTLIST_FNAME_STUB);
2279 // make_hole_for_file( cfg_file );
2280 // make_hole_for_file( mountlist_file);
2281 mr_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);
2282
2283 /* Floppy? */
2284 sprintf(tmp, "mkdir -p %s", mountpt);
2285 run_program_and_log_output(tmp, FALSE);
2286 sprintf(tmp, "mkdir -p %s/tmp", bkpinfo->tmpdir);
2287 run_program_and_log_output(tmp, FALSE);
2288
2289 sprintf(command, "mount /dev/fd0u1722 %s", mountpt);
2290 sprintf(tmp,
2291 "(sleep 15; kill `ps | grep \"%s\" | cut -d' ' -f1` 2> /dev/null) &",
2292 command);
2293 mr_msg(1, "tmp = '%s'", tmp);
2294 system(tmp);
2295 res = run_program_and_log_output(command, FALSE);
2296 if (res) {
2297 sprintf(command, "mount /dev/fd0H1440 %s", mountpt);
2298 res = run_program_and_log_output(command, FALSE);
2299 }
2300 if (res) {
2301 try_plan_B = TRUE;
2302 } else {
2303 try_plan_B = TRUE;
2304 mr_msg(2,
2305 "Mounted floppy OK but I don't trust it because the archives might contain more up-to-date config file than the floppy does.");
2306// NB: If busybox does not support 'mount -o loop' then Plan A WILL NOT WORK.
2307 mr_msg(2, "Processing floppy (plan A?)");
2308 sprintf(ramdisk_fname, "%s/mindi.rdz", mountpt);
2309 if (!does_file_exist(ramdisk_fname)) {
2310 sprintf(ramdisk_fname, "%s/initrd.img", mountpt);
2311 }
2312 if (!does_file_exist(ramdisk_fname)) {
2313 mr_msg(2,
2314 "Cannot find ramdisk file on mountpoint. Are you sure that's a boot disk in the drive?");
2315 }
2316 if (extract_config_file_from_ramdisk
2317 (bkpinfo, ramdisk_fname, cfg_file, mountlist_file)) {
2318 mr_msg(2,
2319 "Warning - failed to extract config file from ramdisk. I think this boot disk is mangled.");
2320 }
2321 sprintf(command, "umount %s", mountpt);
2322 run_program_and_log_output(command, 5);
2323 unlink(ramdisk_fname);
2324 }
2325 if (!does_file_exist(cfg_file)) {
2326 mr_msg(2, "gcffa --- we don't have cfg file yet.");
2327 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
2328 try_plan_B = TRUE;
2329 } else {
2330 mr_msg(2, "gcffa --- calling mount_cdrom now :)");
2331 if (!mount_cdrom(bkpinfo)) {
2332 mr_msg(2,
2333 "gcffa --- managed to mount CD; so, no need for Plan B");
2334 try_plan_B = FALSE;
2335 } else {
2336 try_plan_B = TRUE;
2337 }
2338 if (what_number_cd_is_this(bkpinfo) > 1) {
2339 insist_on_this_cd_number(bkpinfo,
2340 (g_current_media_number = 1));
2341 }
2342 }
2343 if (try_plan_B) {
2344 mr_msg(2, "gcffa --- OK, switching to Plan B");
2345 chdir(bkpinfo->tmpdir);
2346 run_program_and_log_output("mkdir -p tmp", FALSE);
2347
2348 if (strlen(bkpinfo->media_device) == 0) {
2349 strcpy(bkpinfo->media_device, "/dev/st0");
2350 mr_msg(2, "media_device is blank; assuming %s");
2351 }
2352 strcpy(tmp, bkpinfo->media_device);
2353 if (extract_cfg_file_and_mountlist_from_tape_dev
2354 (bkpinfo->media_device)) {
2355 strcpy(bkpinfo->media_device, "/dev/st0");
2356 if (extract_cfg_file_and_mountlist_from_tape_dev
2357 (bkpinfo->media_device)) {
2358 strcpy(bkpinfo->media_device, "/dev/osst0");
2359 if (extract_cfg_file_and_mountlist_from_tape_dev
2360 (bkpinfo->media_device)) {
2361 strcpy(bkpinfo->media_device, "/dev/ht0");
2362 if (extract_cfg_file_and_mountlist_from_tape_dev
2363 (bkpinfo->media_device)) {
2364 mr_msg(3,
2365 "I tried lots of devices but none worked.");
2366 strcpy(bkpinfo->media_device, tmp);
2367 }
2368 }
2369 }
2370 }
2371
2372 if (!does_file_exist("tmp/mondo-restore.cfg")) {
2373 log_to_screen("Cannot find config info on tape/CD/floppy");
2374 return (1);
2375 }
2376 } else {
2377 mr_msg(2,
2378 "gcffa --- looking at mounted CD for mindi-boot.2880.img");
2379 sprintf(command,
2380 "mount " MNT_CDROM
2381 "/images/mindi-boot.2880.img -o loop %s", mountpt);
2382 sprintf(mounted_cfgf_path, "%s/%s", mountpt, cfg_file);
2383 if (!does_file_exist(mounted_cfgf_path)) {
2384 mr_msg(2,
2385 "gcffa --- Plan C, a.k.a. untarring some file from all.tar.gz");
2386 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
2387 run_program_and_log_output(command, TRUE);
2388 if (!does_file_exist(MONDO_CFG_FILE_STUB)) {
2389 fatal_error
2390 ("Please reinsert the disk/CD and try again.");
2391 }
2392 }
2393 }
2394 }
2395 if (does_file_exist(MONDO_CFG_FILE_STUB)) {
2396 mr_msg(1, "gcffa --- great! We've got the config file");
2397 sprintf(tmp, "%s/%s",
2398 call_program_and_get_last_line_of_output("pwd"),
2399 MONDO_CFG_FILE_STUB);
2400 sprintf(command, "cp -f %s %s", tmp, cfg_file);
2401 iamhere(command);
2402 if (strcmp(tmp, cfg_file)
2403 && run_program_and_log_output(command, 1)) {
2404 mr_msg(1,
2405 "... but an error occurred when I tried to move it to %s",
2406 cfg_file);
2407 } else {
2408 mr_msg(1, "... and I moved it successfully to %s", cfg_file);
2409 }
2410 sprintf(command, "cp -f %s/%s %s",
2411 call_program_and_get_last_line_of_output("pwd"),
2412 MOUNTLIST_FNAME_STUB, mountlist_file);
2413 iamhere(command);
2414 if (strcmp(tmp, cfg_file)
2415 && run_program_and_log_output(command, 1)) {
2416 mr_msg(1, "Failed to get mountlist");
2417 } else {
2418 mr_msg(1, "Got mountlist too");
2419 sprintf(command, "cp -f %s %s", mountlist_file,
2420 g_mountlist_fname);
2421 if (run_program_and_log_output(command, 1)) {
2422 mr_msg(1, "Failed to copy mountlist to /tmp");
2423 } else {
2424 mr_msg(1, "Copied mountlist to /tmp as well OK");
2425 sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2426 run_program_and_log_output(command, 1);
2427/* sprintf(command, "grep \" lvm \" %s", g_mountlist_fname);
2428 if (!run_program_and_log_output(command, 5) && !does_file_exist("/tmp/i-want-my-lvm"))
2429 {
2430 mr_msg(1, "Warning. You want LVM but I don't have i-want-my-lvm. FIXME.");
2431 }
2432 else if (run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2433 {
2434 mr_msg(1, "Warning. You don't want LVM but i-want-my-lvm exists. I'll delete it. Cool.");
2435 do_my_funky_lvm_stuff(TRUE, FALSE); // ...after I stop any LVMs :)
2436 stop_raid_device("/dev/md0");
2437 stop_raid_device("/dev/md1");
2438 stop_raid_device("/dev/md2");
2439 unlink("/tmp/i-want-my-lvm");
2440 }
2441 else if (!run_program_and_log_output(command,5) && does_file_exist("/tmp/i-want-my-lvm"))
2442 {
2443 mr_msg(1, "You had better pray that i-want-my-lvm patches your mountlist. FIXME.");
2444 }
2445*/
2446 }
2447 }
2448 }
2449 run_program_and_log_output("umount " MNT_CDROM, FALSE);
2450 if (!does_file_exist(cfg_file)) {
2451 iamhere(cfg_file);
2452 mr_msg(1, "%s not found", cfg_file);
2453 log_to_screen
2454 ("Oh dear. Unable to recover configuration file from boot disk");
2455 return (1);
2456 }
2457
2458 log_to_screen("Recovered mondo-restore.cfg");
2459 if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {
2460 log_to_screen("...but not mountlist.txt - a pity, really...");
2461 }
2462/* start SAH */
2463 else {
2464 sprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB,
2465 bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);
2466 run_program_and_log_output(command, FALSE);
2467 }
2468/*--commented out by SAH
2469 sprintf( command, "cp -f %s %s/%s", cfg_file, bkpinfo->tmpdir, MONDO_CFG_FILE_STUB );
2470 run_program_and_log_output( command, FALSE );
2471 sprintf( command, "cp -f %s %s/%s", mountlist_file, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB );
2472 run_program_and_log_output( command, FALSE );
2473*/
2474/* end SAH */
2475
2476 sprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);
2477 run_program_and_log_output(command, FALSE);
2478 sprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);
2479 run_program_and_log_output(command, FALSE);
2480 sprintf(command, "cp -f etc/raidtab /etc/");
2481 run_program_and_log_output(command, FALSE);
2482 sprintf(command, "cp -f tmp/i-want-my-lvm /tmp/");
2483 run_program_and_log_output(command, FALSE);
2484 g_backup_media_type = bkpinfo->backup_media_type;
2485 mr_free(device);
2486 mr_free(command);
2487 mr_free(tmp);
2488 mr_free(cfg_file);
2489 mr_free(mounted_cfgf_path);
2490 mr_free(mountpt);
2491 mr_free(ramdisk_fname);
2492 mr_free(mountlist_file);
2493 return (retval);
2494}
2495
2496/**************************************************************************
2497 *END_GET_CFG_FILE_FROM_ARCHIVE *
2498 **************************************************************************/
2499
2500/* @} - end restoreUtilityGroup */
2501
2502
2503/***************************************************************************
2504 * F@ *
2505 * () -- Hugo Rabson *
2506 * *
2507 * Purpose: *
2508 * *
2509 * Called by: *
2510 * Params: - - *
2511 * Returns: 0=success; nonzero=failure *
2512 ***************************************************************************/
2513
2514
2515
2516void wait_until_software_raids_are_prepped(char *mdstat_file,
2517 int wait_for_percentage)
2518{
2519 struct raidlist_itself *raidlist;
2520 int unfinished_mdstat_devices = 9999, i;
2521 char *screen_message;
2522
2523 malloc_string(screen_message);
2524 raidlist = (struct raidlist_itself *)mr_malloc(sizeof(struct raidlist_itself));
2525
2526 assert(wait_for_percentage <= 100);
2527 iamhere("wait_until_software_raids_are_prepped");
2528 while (unfinished_mdstat_devices > 0) {
2529 // FIXME: Prefix '/dev/' should really be dynamic!
2530 if (parse_mdstat(raidlist, "/dev/")) {
2531 log_to_screen("Sorry, cannot read %s", MDSTAT_FILE);
2532 mr_msg(1,"Sorry, cannot read %s", MDSTAT_FILE);
2533 return;
2534 }
2535 for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) {
2536 if (raidlist->el[i].progress < wait_for_percentage) {
2537 unfinished_mdstat_devices++;
2538 if (raidlist->el[i].progress == -1) // delayed while another partition inits
2539 {
2540 continue;
2541 }
2542 mr_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i);
2543 sprintf(screen_message, "Sync'ing %s",
2544 raidlist->el[i].raid_device);
2545 open_evalcall_form(screen_message);
2546 while (raidlist->el[i].progress < wait_for_percentage) {
2547 mr_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress);
2548 update_evalcall_form(raidlist->el[i].progress);
2549 sleep(2);
2550 // FIXME: Prefix '/dev/' should really be dynamic!
2551 if (parse_mdstat(raidlist, "/dev/")) {
2552 break;
2553 }
2554 }
2555 close_evalcall_form();
2556 }
2557 }
2558 }
2559 mr_free(screen_message);
2560 mr_free(raidlist);
2561}
Note: See TracBrowser for help on using the repository browser.