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

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

strip_spaces => mr_strip_spaces in mr_str.c and corrected at the same time :-)

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