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

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

Still linker fixes (grrr)

  • Property svn:keywords set to Id
File size: 76.9 KB
Line 
1/***************************************************************************
2 * $Id: mondo-rstr-tools.c 1125 2007-02-09 23:38:20Z 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
39extern struct s_bkpinfo *g_bkpinfo_DONTUSETHIS;
40
41extern t_bkptype g_backup_media_type;
42
43extern int g_partition_table_locked_up;
44
45/* Should we use or not extended attributes and acl when restoring */
46char *g_getfattr = NULL;
47char *g_getfacl = NULL;
48
49/**
50 * @addtogroup restoreUtilityGroup
51 * @{
52 */
53/**
54 * Free the malloc()s for the filename variables.
55 */
56void free_MR_global_filenames(void)
57{
58 mr_free(g_biggielist_txt);
59 mr_free(g_filelist_full);
60 mr_free(g_filelist_imagedevs);
61// mr_free (g_imagedevs_pot );
62 mr_free(g_imagedevs_restthese);
63 mr_free(g_mondo_cfg_file);
64 mr_free(g_mountlist_fname);
65 mr_free(g_mondo_home);
66 mr_free(g_tmpfs_mountpt);
67 mr_free(g_isodir_device);
68 mr_free(g_isodir_format);
69
70}
71
72
73
74/**
75 * Ask the user which imagedevs from the list contained in @p infname should
76 * actually be restored.
77 * @param infname The file containing a list of all imagedevs.
78 * @param outfname The location of the output file containing the imagedevs the user wanted to restore.
79 * @ingroup restoreUtilityGroup
80 */
81void ask_about_these_imagedevs(char *infname, char *outfname)
82{
83 FILE *fin;
84 FILE *fout;
85 /************************************************************************
86 * allocate memory regions. test and set -sab 16 feb 2003 *
87 ************************************************************************/
88 char *incoming_ptr;
89 char *question_ptr;
90
91 char incoming[MAX_STR_LEN] = "\0";
92 char question[MAX_STR_LEN];
93
94 assert_string_is_neither_NULL_nor_zerolength(infname);
95 assert_string_is_neither_NULL_nor_zerolength(outfname);
96
97 incoming_ptr = mr_malloc(sizeof(incoming));
98 question_ptr = mr_malloc(sizeof(question));
99
100 memset(incoming_ptr, '\0', sizeof(incoming));
101 memset(question_ptr, '\0', sizeof(question));
102
103
104
105 if (!(fin = fopen(infname, "r"))) {
106 fatal_error("Cannot openin infname");
107 }
108 if (!(fout = fopen(outfname, "w"))) {
109 fatal_error("Cannot openin outfname");
110 }
111 for (fgets(incoming_ptr, MAX_STR_LEN, fin);
112 !feof(fin); fgets(incoming_ptr, MAX_STR_LEN, fin)) {
113 strip_spaces(incoming_ptr);
114
115 if (incoming[0] == '\0') {
116 continue;
117 }
118
119 sprintf(question_ptr,
120 "Should I restore the image of %s ?", incoming_ptr);
121
122 if (ask_me_yes_or_no(question_ptr)) {
123 fprintf(fout, "%s\n", incoming_ptr);
124 }
125 }
126
127 /*** free memory ***********/
128 mr_free(incoming_ptr);
129 incoming_ptr = NULL;
130 mr_free(question_ptr);
131 question_ptr = NULL;
132
133
134 paranoid_fclose(fout);
135 paranoid_fclose(fin);
136}
137
138/**************************************************************************
139 *ASK_ABOUT_THESE_IMAGEDEVS *
140 **************************************************************************/
141
142
143
144
145
146
147
148
149/**
150 * Extract @c mondo-restore.cfg and @c mountlist.txt from @p ramdisk_fname.
151 * @param bkpinfo The backup information structure. @c tmpdir is the only field used.
152 * @param ramdisk_fname The filename of the @b compressed ramdisk to look in.
153 * @param output_cfg_file Where to put the configuration file extracted.
154 * @param output_mountlist_file Where to put the mountlist file extracted.
155 * @return 0 for success, nonzero for failure.
156 * @ingroup restoreUtilityGroup
157 */
158int
159extract_config_file_from_ramdisk(struct s_bkpinfo *bkpinfo,
160 char *ramdisk_fname,
161 char *output_cfg_file,
162 char *output_mountlist_file)
163{
164 char *mountpt;
165 char *command;
166 char *orig_fname;
167 int retval = 0;
168
169 assert(bkpinfo != NULL);
170 malloc_string(mountpt);
171 malloc_string(command);
172 malloc_string(orig_fname);
173 assert_string_is_neither_NULL_nor_zerolength(ramdisk_fname);
174 assert_string_is_neither_NULL_nor_zerolength(output_cfg_file);
175 assert_string_is_neither_NULL_nor_zerolength(output_mountlist_file);
176 sprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);
177 sprintf(command, "mkdir -p %s", mountpt);
178 run_program_and_log_output(command, FALSE);
179 sprintf(command, "gzip -dc %s > %s/mindi.rd 2> /dev/null",
180 ramdisk_fname, bkpinfo->tmpdir);
181
182 run_program_and_log_output(command, FALSE);
183 sprintf(command, "umount %s", mountpt);
184
185 run_program_and_log_output(command, FALSE);
186
187 sprintf(command, "mount -o loop %s/mindi.rd -t ext2 %s",
188 bkpinfo->tmpdir, mountpt);
189
190 run_program_and_log_output(command, FALSE);
191
192 sprintf(command, "mkdir -p %s/tmp", bkpinfo->tmpdir);
193
194 run_program_and_log_output(command, FALSE);
195
196 sprintf(command, "cp -f %s/%s %s", // %s/%s becomes {mountpt}/tmp/m*ndo-restore.cfg
197 mountpt, g_mondo_cfg_file, output_cfg_file);
198 run_program_and_log_output(command, FALSE);
199
200 sprintf(orig_fname, "%s/%s", mountpt, g_mountlist_fname);
201 if (does_file_exist(orig_fname)) {
202 sprintf(command, "cp -f %s %s", orig_fname, output_mountlist_file);
203 run_program_and_log_output(command, FALSE);
204 }
205 sprintf(command, "umount %s", mountpt);
206 run_program_and_log_output(command, FALSE);
207 if (!does_file_exist(output_cfg_file)
208 || (!does_file_exist(output_mountlist_file)
209 && does_file_exist(orig_fname))) {
210 mr_msg(2, "Failed to extract %s and/or %s from ramdisk",
211 output_cfg_file, output_mountlist_file);
212 retval = 1;
213 } else {
214 retval = 0;
215 }
216 mr_free(mountpt);
217 mr_free(command);
218 mr_free(orig_fname);
219 return (retval);
220
221}
222
223
224
225
226/**
227 * Keep trying to get mondo-restore.cfg from the archive, until the user gives up.
228 * @param bkpinfo The backup information structure.
229 */
230void get_cfg_file_from_archive_or_bust(struct s_bkpinfo *bkpinfo)
231{
232 while (get_cfg_file_from_archive(bkpinfo)) {
233 if (!ask_me_yes_or_no
234 ("Failed to find config file/archives. Choose another source?"))
235 {
236 fatal_error("Could not find config file/archives. Aborting.");
237 }
238 interactively_obtain_media_parameters_from_user(bkpinfo, FALSE);
239 }
240}
241
242
243/**
244 * Determine whether @p list_fname contains a line containing @p f.
245 * @param f The line to search for.
246 * @param list_fname The file to search in.
247 * @param preamble Ignore this beginning part of @p f ("" to disable).
248 * @return TRUE if it's in the list, FALSE if it's not.
249 */
250bool is_file_in_list(char *f, char *list_fname, char *preamble)
251{
252
253 /** needs malloc **/
254 char *command;
255 char *file;
256 char *tmp;
257 int res;
258
259 malloc_string(command);
260 malloc_string(file);
261 malloc_string(tmp);
262 assert_string_is_neither_NULL_nor_zerolength(f);
263 assert_string_is_neither_NULL_nor_zerolength(list_fname);
264 assert(preamble != NULL);
265
266 if (strncmp(preamble, f, strlen(preamble)) == 0) {
267 strcpy(file, f + strlen(preamble));
268 } else {
269 strcpy(file, f);
270 }
271 if (file[0] == '/' && file[1] == '/') {
272 strcpy(tmp, file);
273 strcpy(file, tmp + 1);
274 }
275 sprintf(tmp,
276 "Checking to see if f=%s, file=%s, is in the list of biggiefiles",
277 f, file);
278 mr_msg(2, tmp);
279 sprintf(command, "grep -E '^%s$' %s", file, list_fname);
280 res = run_program_and_log_output(command, FALSE);
281 mr_free(command);
282 mr_free(file);
283 mr_free(tmp);
284 if (res) {
285 return (FALSE);
286 } else {
287 return (TRUE);
288 }
289}
290
291/**************************************************************************
292 *END_IS_FILE_IN_LIST *
293 **************************************************************************/
294
295
296
297/**
298 * Set up an ISO backup.
299 * @param bkpinfo The backup information structure. Fields used:
300 * - @c bkpinfo->backup_media_type
301 * - @c bkpinfo->disaster_recovery
302 * - @c bkpinfo->isodir
303 * @param nuke_me_please If TRUE, we're in nuke mode; if FALSE we're in interactive mode.
304 * @return 0 for success, nonzero for failure.
305 */
306int iso_fiddly_bits(struct s_bkpinfo *bkpinfo, bool nuke_me_please)
307{
308 char *mount_isodir_command, *tmp, *command;
309 int retval = 0, i;
310 bool already_mounted = FALSE;
311
312 assert(bkpinfo != NULL);
313 malloc_string(mount_isodir_command);
314 malloc_string(tmp);
315 malloc_string(command);
316 g_ISO_restore_mode = TRUE;
317 read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
318 if (bkpinfo->disaster_recovery) {
319/* Patch Conor Daly 26-june-2004
320 * Don't let this clobber an existing bkpinfo->isodir */
321 if (!bkpinfo->isodir[0]) {
322 strcpy(bkpinfo->isodir, "/tmp/isodir");
323 }
324/* End patch */
325 sprintf(command, "mkdir -p %s", bkpinfo->isodir);
326 run_program_and_log_output(command, 5);
327 mr_msg(2, "Setting isodir to %s", bkpinfo->isodir);
328 }
329
330 if (!get_isodir_info
331 (g_isodir_device, g_isodir_format, bkpinfo->isodir,
332 nuke_me_please)) {
333 return (1);
334 }
335 paranoid_system("umount " MNT_CDROM " 2> /dev/null"); /* just in case */
336
337 if (is_this_device_mounted(g_isodir_device)) {
338 log_to_screen("WARNING - isodir is already mounted");
339 already_mounted = TRUE;
340 } else {
341 sprintf(mount_isodir_command, "mount %s", g_isodir_device);
342 if (strlen(g_isodir_format) > 1) {
343 sprintf(mount_isodir_command + strlen(mount_isodir_command),
344 " -t %s", g_isodir_format);
345 }
346 strcat(mount_isodir_command, " -o ro ");
347 strcat(mount_isodir_command, bkpinfo->isodir);
348 run_program_and_log_output("df -m", FALSE);
349 sprintf(tmp,
350 "The 'mount' command is '%s'. PLEASE report this command to be if you have problems, ok?",
351 mount_isodir_command);
352 mr_msg(1, tmp);
353 if (run_program_and_log_output(mount_isodir_command, FALSE)) {
354 popup_and_OK
355 ("Cannot mount the device where the ISO files are stored.");
356 return (1);
357 }
358 log_to_screen
359 ("I have mounted the device where the ISO files are stored.");
360 }
361 if (!IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
362 mount_cdrom(bkpinfo);
363 }
364 i = what_number_cd_is_this(bkpinfo); /* has the side-effect of calling mount_cdrom() */
365 sprintf(tmp, "%s #%d has been mounted via loopback mount",
366 media_descriptor_string(bkpinfo->backup_media_type), i);
367 mr_msg(1, tmp);
368 if (i < 0) {
369 popup_and_OK
370 ("Cannot find ISO images in the directory you specified.");
371 retval = 1;
372 }
373 mr_msg(2, "%ld: bkpinfo->isodir is now %s", __LINE__,
374 bkpinfo->isodir);
375 mr_free(mount_isodir_command);
376 mr_free(tmp);
377 mr_free(command);
378 return (retval);
379}
380
381
382
383
384/**
385 * Kill all Petris processes.
386 */
387void kill_petris(void)
388{
389 char *command;
390 malloc_string(command);
391 sprintf(command,
392 "kill `ps 2> /dev/null | grep petris 2> /dev/null | grep -v grep | cut -d' ' -f2` 2> /dev/null");
393 paranoid_system(command);
394 mr_free(command);
395}
396
397/**************************************************************************
398 *END_KILL_PETRIS *
399 **************************************************************************/
400
401
402/**
403 * (Disabled) Modify rc.local to fix some things on first boot.
404 * This function currently doesn't do anything except make sure /tmp has the
405 * right permissions.
406 * @param path The path to /etc on the user's filesystem.
407 * @return 0 for success, nonzero for failure.
408 */
409int modify_rclocal_one_time(char *path)
410{
411 /** malloc **/
412 char *rclocal_fname;
413 char *newfile_fname;
414 char *tmp;
415
416 malloc_string(rclocal_fname);
417 malloc_string(newfile_fname);
418 malloc_string(tmp);
419 assert_string_is_neither_NULL_nor_zerolength(path);
420
421 sprintf(rclocal_fname, "%s/rc.local", path);
422
423// sprintf(tmp, "chmod 1777 %s/tmp", MNT_RESTORING);
424// run_program_and_log_output( tmp, FALSE );
425 return (0); /* remove this line to open the floodgates... */
426
427 if (!does_file_exist(rclocal_fname)) {
428 sprintf(rclocal_fname, "%s/rc.d/rc.local", path);
429 }
430 if (!does_file_exist(rclocal_fname)) {
431 mr_free(rclocal_fname);
432 mr_free(newfile_fname);
433 mr_free(tmp);
434 return (1);
435 }
436 sprintf(newfile_fname, "%s/rc.local.mondorescue", path);
437 sprintf(tmp, "grep mondorescue %s > /dev/null 2> /dev/null",
438 rclocal_fname);
439 if (system(tmp)) {
440 sprintf(tmp, "echo \"[ -e %s ] && %s\n\" >> %s",
441 newfile_fname, newfile_fname, rclocal_fname);
442
443 paranoid_system(tmp);
444 }
445 sprintf(tmp, "echo -en \"#!/bin/sh\
446\\n\
447\\n\
448grep -v mondorescue %s > %s\\n\
449rm -f /var/lock/subsys/*xfs*\\n\
450rm -f /var/run/xfs.*\\n\
451killall xfs\\n\
452service xfs start\\n\
453yes | rm -f %s\\n\
454\" > %s", rclocal_fname, rclocal_fname, newfile_fname, newfile_fname);
455 sprintf(tmp, "chmod +x \"%s\"", newfile_fname);
456 run_program_and_log_output(tmp, FALSE);
457 mr_free(rclocal_fname);
458 mr_free(newfile_fname);
459 mr_free(tmp);
460 return (0);
461}
462
463/**************************************************************************
464 *END_ MODIFY_RCLOCAL_ONE_TIME *
465 **************************************************************************/
466
467
468
469
470
471/**
472 * Mount all devices in @p p_external_copy_of_mountlist on @p MNT_RESTORING.
473 * @param p_external_copy_of_mountlist The mountlist containing devices to be mounted.
474 * @param writeable If TRUE, then mount read-write; if FALSE mount read-only.
475 * @return The number of errors encountered (0 for success).
476 */
477int mount_all_devices(struct mountlist_itself
478 *p_external_copy_of_mountlist, bool writeable)
479{
480 int retval = 0, lino, res;
481 char *tmp, *these_failed, *format;
482 struct mountlist_itself *mountlist;
483
484 malloc_string(tmp);
485 malloc_string(format);
486 malloc_string(these_failed);
487 assert(p_external_copy_of_mountlist != NULL);
488 mountlist = (struct mountlist_itself *)mr_malloc(sizeof(struct mountlist_itself));
489 memcpy((void *) mountlist, (void *) p_external_copy_of_mountlist,
490 sizeof(struct mountlist_itself));
491 sort_mountlist_by_mountpoint(mountlist, 0);
492
493 /** menset **/
494 these_failed[0] = '\0';
495
496 mvaddstr_and_log_it(g_currentY, 0, "Mounting devices ");
497 open_progress_form("Mounting devices",
498 "I am now mounting all the drives.",
499 "This should not take long.",
500 "", mountlist->entries);
501
502 for (lino = 0; lino < mountlist->entries; lino++) {
503 if (!strcmp(mountlist->el[lino].device, "/proc")) {
504 mr_msg(1,
505 "Again with the /proc - why is this in your mountlist?");
506 } else if (is_this_device_mounted(mountlist->el[lino].device)) {
507 sprintf(tmp, "%s is already mounted",
508 mountlist->el[lino].device);
509 log_to_screen(tmp);
510 } else if (strcmp(mountlist->el[lino].mountpoint, "none")
511 && strcmp(mountlist->el[lino].mountpoint, "lvm")
512 && strcmp(mountlist->el[lino].mountpoint, "raid")
513 && strcmp(mountlist->el[lino].mountpoint, "image")) {
514 sprintf(tmp, "Mounting %s", mountlist->el[lino].device);
515 update_progress_form(tmp);
516 strcpy(format, mountlist->el[lino].format);
517 if (!strcmp(format, "ext3")) {
518 strcpy(format, "ext2");
519 }
520 res = mount_device(mountlist->el[lino].device,
521 mountlist->el[lino].mountpoint,
522 format, writeable);
523 retval += res;
524 if (res) {
525 strcat(these_failed, mountlist->el[lino].device);
526 strcat(these_failed, " ");
527 }
528 }
529 g_current_progress++;
530 }
531 close_progress_form();
532 run_program_and_log_output("df -m", TRUE);
533 if (retval) {
534 if (g_partition_table_locked_up > 0) {
535 log_to_screen
536 ("fdisk's ictol() call to refresh its copy of the partition table causes the kernel to");
537 log_to_screen
538 ("lock up the partition table. You might have to reboot and use Interactive Mode to");
539 log_to_screen
540 ("format and restore *without* partitioning first. Sorry for the inconvenience.");
541 }
542 sprintf(tmp, "Could not mount devices %s- shall I abort?",
543 these_failed);
544 if (!ask_me_yes_or_no(tmp)) {
545 retval = 0;
546 log_to_screen
547 ("Continuing, although some devices failed to be mounted");
548 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
549 } else {
550 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
551 log_to_screen
552 ("Unable to mount some or all of your partitions.");
553 }
554 } else {
555 log_to_screen("All partitions were mounted OK.");
556 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
557 }
558 run_program_and_log_output("df -m", 3);
559 mr_free(mountlist);
560 mr_free(tmp);
561 mr_free(format);
562 mr_free(these_failed);
563 return (retval);
564}
565
566 /**************************************************************************
567 *END_MOUNT_ALL_DEVICES *
568 **************************************************************************/
569
570
571/**
572 * Mount the CD-ROM device at /mnt/cdrom.
573 * @param bkpinfo The backup information structure. Fields used:
574 * - @c bkpinfo->backup_media_type
575 * - @c bkpinfo->disaster_recovery
576 * - @c bkpinfo->isodir
577 * - @c bkpinfo->media_device
578 * @return 0 for success, nonzero for failure.
579 */
580int mount_cdrom(struct s_bkpinfo *bkpinfo)
581{
582 char *mount_cmd;
583 int i, res;
584#ifdef __FreeBSD__
585 char mdd[32];
586 char *mddev = mdd;
587#endif
588
589 malloc_string(mount_cmd);
590 assert(bkpinfo != NULL);
591
592 if (bkpinfo->backup_media_type == tape
593 || bkpinfo->backup_media_type == udev) {
594 mr_msg(8, "Tape/udev. Therefore, no need to mount CDROM.");
595 mr_free(mount_cmd);
596 return 0;
597 }
598
599 if (!run_program_and_log_output("mount | grep -F " MNT_CDROM, FALSE)) {
600 mr_msg(2, "mount_cdrom() - CD already mounted. Fair enough.");
601 mr_free(mount_cmd);
602 return (0);
603 }
604
605 if (bkpinfo->backup_media_type == nfs) {
606 mr_msg(2, "Mounting for NFS thingy");
607 mr_msg(2, "isodir = %s", bkpinfo->isodir);
608 if ((!bkpinfo->isodir[0] || !strcmp(bkpinfo->isodir, "/"))
609 && am_I_in_disaster_recovery_mode()) {
610 strcpy(bkpinfo->isodir, "/tmp/isodir");
611 mr_msg(1, "isodir is being set to %s", bkpinfo->isodir);
612 }
613#ifdef __FreeBSD__
614 sprintf(mount_cmd, "/mnt/isodir/%s/%s/%s-%d.iso", bkpinfo->isodir,
615 bkpinfo->nfs_remote_dir, bkpinfo->prefix, g_current_media_number);
616 mddev = make_vn(mount_cmd);
617 sprintf(mount_cmd, "mount_cd9660 -r %s " MNT_CDROM, mddev);
618#else
619 sprintf(mount_cmd, "mount %s/%s/%s-%d.iso -t iso9660 -o loop,ro %s",
620 bkpinfo->isodir, bkpinfo->nfs_remote_dir,
621 bkpinfo->prefix, g_current_media_number, MNT_CDROM);
622#endif
623
624 } else
625 if (bkpinfo->backup_media_type == iso) {
626#ifdef __FreeBSD__
627 sprintf(mount_cmd, "%s/%s-%d.iso", bkpinfo->isodir,
628 bkpinfo->prefix, g_current_media_number);
629 mddev = make_vn(mount_cmd);
630 sprintf(mount_cmd, "mount_cd9660 -r %s %s", mddev, MNT_CDROM);
631#else
632 sprintf(mount_cmd, "mount %s/%s-%d.iso -t iso9660 -o loop,ro %s",
633 bkpinfo->isodir, bkpinfo->prefix, g_current_media_number, MNT_CDROM);
634#endif
635 } else if (strstr(bkpinfo->media_device, "/dev/"))
636#ifdef __FreeBSD__
637 {
638 sprintf(mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device,
639 MNT_CDROM);
640 }
641#else
642 {
643 sprintf(mount_cmd, "mount %s -t iso9660 -o ro %s",
644 bkpinfo->media_device, MNT_CDROM);
645 }
646#endif
647
648 else {
649 if (bkpinfo->disaster_recovery
650 && does_file_exist("/tmp/CDROM-LIVES-HERE")) {
651 strcpy(bkpinfo->media_device,
652 last_line_of_file("/tmp/CDROM-LIVES-HERE"));
653 } else {
654 find_cdrom_device(bkpinfo->media_device, TRUE);
655 }
656
657#ifdef __FreeBSD__
658 sprintf(mount_cmd, "mount_cd9660 -r %s %s", bkpinfo->media_device,
659 MNT_CDROM);
660#else
661 sprintf(mount_cmd, "mount %s -t iso9660 -o ro %s",
662 bkpinfo->media_device, MNT_CDROM);
663#endif
664
665 }
666 mr_msg(2, "(mount_cdrom) --- command = %s", mount_cmd);
667 for (i = 0; i < 2; i++) {
668 res = run_program_and_log_output(mount_cmd, FALSE);
669 if (!res) {
670 break;
671 } else {
672 mr_msg(2, "Failed to mount CD-ROM drive.");
673 sleep(5);
674 run_program_and_log_output("sync", FALSE);
675 }
676 }
677 if (res) {
678 mr_msg(2, "Failed, despite %d attempts", i);
679 } else {
680 mr_msg(2, "Mounted CD-ROM drive OK");
681 }
682 mr_free(mount_cmd);
683 return (res);
684}
685
686
687
688
689
690/**************************************************************************
691 *END_MOUNT_CDROM *
692 **************************************************************************/
693
694
695/**
696 * Mount @p device at @p mpt as @p format.
697 * @param device The device (/dev entry) to mount.
698 * @param mpt The directory to mount it on.
699 * @param format The filesystem type of @p device.
700 * @param writeable If TRUE, mount read-write; if FALSE, mount read-only.
701 * @return 0 for success, nonzero for failure.
702 */
703int mount_device(char *device, char *mpt, char *format, bool writeable)
704{
705 int res = 0;
706
707 /** malloc **/
708 char *tmp, *command, *mountdir, *mountpoint, *additional_parameters;
709
710 assert_string_is_neither_NULL_nor_zerolength(device);
711 assert_string_is_neither_NULL_nor_zerolength(mpt);
712 assert(format != NULL);
713 malloc_string(tmp);
714 malloc_string(command);
715 malloc_string(mountdir);
716 malloc_string(mountpoint);
717 malloc_string(additional_parameters);
718
719 if (!strcmp(mpt, "/1")) {
720 strcpy(mountpoint, "/");
721 mr_msg(3, "Mommm! SME is being a dildo!");
722 } else {
723 strcpy(mountpoint, mpt);
724 }
725
726 if (!strcmp(mountpoint, "lvm")) {
727 return (0);
728 }
729 if (!strcmp(mountpoint, "image")) {
730 return (0);
731 }
732 sprintf(tmp, "Mounting device %s ", device);
733 mr_msg(1, tmp);
734 if (writeable) {
735 strcpy(additional_parameters, "-o rw");
736 } else {
737 strcpy(additional_parameters, "-o ro");
738 }
739 if (find_home_of_exe("setfattr")) {
740 strcat(additional_parameters, ",user_xattr");
741 }
742 if (find_home_of_exe("setfacl")) {
743 strcat(additional_parameters, ",acl");
744 }
745
746 if (!strcmp(mountpoint, "swap")) {
747 sprintf(command, "swapon %s", device);
748 } else {
749 if (!strcmp(mountpoint, "/")) {
750 strcpy(mountdir, MNT_RESTORING);
751 } else {
752 sprintf(mountdir, "%s%s", MNT_RESTORING, mountpoint);
753 }
754 sprintf(command, "mkdir -p %s", mountdir);
755 run_program_and_log_output(command, FALSE);
756 sprintf(command, "mount -t %s %s %s %s 2>> %s", format, device,
757 additional_parameters, mountdir, MONDO_LOGFILE);
758 mr_msg(2, "command='%s'", command);
759 }
760 res = run_program_and_log_output(command, TRUE);
761 if (res && (strstr(command, "xattr") || strstr(command, "acl"))) {
762 mr_msg(1, "Re-trying without the fancy extra parameters");
763 sprintf(command, "mount -t %s %s %s 2>> %s", format, device,
764 mountdir, MONDO_LOGFILE);
765 res = run_program_and_log_output(command, TRUE);
766 }
767 if (res) {
768 mr_msg(1, "Unable to mount device %s (type %s) at %s", device,
769 format, mountdir);
770 mr_msg(1, "command was '%s'", command);
771 if (!strcmp(mountpoint, "swap")) {
772 log_to_screen(tmp);
773 } else {
774 mr_msg(2, "Retrying w/o the '-t' switch");
775 sprintf(command, "mount %s %s 2>> %s", device, mountdir,
776 MONDO_LOGFILE);
777 mr_msg(2, "2nd command = '%s'", command);
778 res = run_program_and_log_output(command, TRUE);
779 if (res == 0) {
780 mr_msg(1,
781 "That's OK. I called mount w/o a filesystem type and it worked fine in the end.");
782 } else {
783 log_to_screen(tmp);
784 }
785 }
786 }
787 if (res && !strcmp(mountpoint, "swap")) {
788 mr_msg(2, "That's ok. It's just a swap partition.");
789 mr_msg(2, "Non-fatal error. Returning 0.");
790 res = 0;
791 }
792
793 mr_free(tmp);
794 mr_free(command);
795 mr_free(mountdir);
796 mr_free(mountpoint);
797 mr_free(additional_parameters);
798
799 return (res);
800}
801
802/**************************************************************************
803 *END_MOUNT_DEVICE *
804 **************************************************************************/
805
806
807
808/**
809 * Fix some miscellaneous things in the filesystem so the system will come
810 * up correctly on the first boot.
811 */
812void protect_against_braindead_sysadmins()
813{
814 run_program_and_log_output("touch " MNT_RESTORING "/var/log/pacct",
815 FALSE);
816 run_program_and_log_output("touch " MNT_RESTORING "/var/account/pacct",
817 FALSE);
818 if (run_program_and_log_output("ls " MNT_RESTORING " /tmp", FALSE)) {
819 run_program_and_log_output("chmod 1777 " MNT_RESTORING "/tmp",
820 FALSE);
821 }
822 run_program_and_log_output("mkdir -p " MNT_RESTORING
823 "/var/run/console", FALSE);
824 run_program_and_log_output("chmod 777 " MNT_RESTORING "/dev/null",
825 FALSE);
826 run_program_and_log_output("cd " MNT_RESTORING
827 "; 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",
828 TRUE);
829 run_program_and_log_output("rm -f " MNT_RESTORING "/var/run/*.pid",
830 TRUE);
831 run_program_and_log_output("rm -f " MNT_RESTORING "/var/lock/subsys/*",
832 TRUE);
833}
834
835/**************************************************************************
836 *END_PROTECT_AGAINST_BRAINDEAD_SYSADMINS *
837 **************************************************************************/
838
839
840
841
842/**
843 * Fill out @p bkpinfo based on @p cfg_file.
844 * @param cfg_file The mondo-restore.cfg file to read into @p bkpinfo.
845 * @param bkpinfo The backup information structure to fill out with information
846 * from @p cfg_file.
847 * @return 0 for success, nonzero for failure.
848 */
849int read_cfg_file_into_bkpinfo(char *cfgf, struct s_bkpinfo *bkpinfo)
850{
851 /** add mallocs **/
852 char *value = NULL;
853 char *tmp = NULL;
854 char *envtmp1 = NULL;
855 char *envtmp2 = NULL;
856 char *command = NULL;
857 char *iso_mnt = NULL;
858 char *iso_path = NULL;
859 char *old_isodir = NULL;
860 char cfg_file[100];
861 t_bkptype media_specified_by_user;
862
863 malloc_string(command);
864 malloc_string(iso_mnt);
865 malloc_string(iso_path);
866 malloc_string(old_isodir);
867 malloc_string(value);
868 malloc_string(tmp);
869// assert_string_is_neither_NULL_nor_zerolength(cfg_file);
870 assert(bkpinfo != NULL);
871
872 if (!cfgf) {
873 strcpy(cfg_file, g_mondo_cfg_file);
874 } else {
875 strcpy(cfg_file, cfgf);
876 }
877
878 media_specified_by_user = bkpinfo->backup_media_type; // or 'none', if not specified
879
880 if (0 == read_cfg_var(cfg_file, "backup-media-type", value)) {
881 if (!strcmp(value, "cdstream")) {
882 bkpinfo->backup_media_type = cdstream;
883 } else if (!strcmp(value, "cdr")) {
884 bkpinfo->backup_media_type = cdr;
885 } else if (!strcmp(value, "cdrw")) {
886 bkpinfo->backup_media_type = cdrw;
887 } else if (!strcmp(value, "dvd")) {
888 bkpinfo->backup_media_type = dvd;
889 } else if (!strcmp(value, "iso")) {
890/*
891 if (am_I_in_disaster_recovery_mode()
892 && !run_program_and_log_output("mount /dev/cdrom "MNT_CDROM, 1)
893 && does_file_exist(MNT_CDROM"/archives/filelist.0"))
894*/
895
896// Patch by Conor Daly - 2004/07/12
897 bkpinfo->backup_media_type = iso;
898 if (am_I_in_disaster_recovery_mode()) {
899 /* Check to see if CD is already mounted before mounting it... */
900 if (!is_this_device_mounted("/dev/cdrom")) {
901 mr_msg(2,
902 "NB: CDROM device not mounted, mounting...");
903 run_program_and_log_output("mount /dev/cdrom "
904 MNT_CDROM, 1);
905 }
906 if (does_file_exist(MNT_CDROM "/archives/filelist.0")) {
907 bkpinfo->backup_media_type = cdr;
908 run_program_and_log_output("umount " MNT_CDROM, 1);
909 log_it
910 ("Re-jigging configuration AGAIN. CD-R, not ISO.");
911 }
912 }
913 if (read_cfg_var(cfg_file, "iso-prefix", value) == 0) {
914 strcpy(bkpinfo->prefix,value);
915 } else {
916 strcpy(bkpinfo->prefix,STD_PREFIX);
917 }
918 } else if (!strcmp(value, "nfs")) {
919 bkpinfo->backup_media_type = nfs;
920 if (read_cfg_var(cfg_file, "iso-prefix", value) == 0) {
921 strcpy(bkpinfo->prefix,value);
922 } else {
923 strcpy(bkpinfo->prefix,STD_PREFIX);
924 }
925 if (strstr(call_program_and_get_last_line_of_output
926 ("cat /proc/cmdline"), "pxe")) {
927 /* We need to override prefix value in PXE mode as it's
928 * already done in start-nfs */
929 envtmp1 = getenv("imgname");
930 if (envtmp1 == NULL) {
931 fatal_error("no imgname variable in environment");
932 }
933 strcpy(bkpinfo->prefix,envtmp1);
934 }
935
936 } else if (!strcmp(value, "tape")) {
937 bkpinfo->backup_media_type = tape;
938 } else if (!strcmp(value, "udev")) {
939 bkpinfo->backup_media_type = udev;
940 } else {
941 fatal_error("UNKNOWN bkp-media-type");
942 }
943 } else {
944 fatal_error("backup-media-type not specified!");
945 }
946 if (bkpinfo->disaster_recovery) {
947 if (bkpinfo->backup_media_type == cdstream) {
948 sprintf(bkpinfo->media_device, "/dev/cdrom");
949// bkpinfo->media_size[0] = -1;
950 bkpinfo->media_size[0] = 1999 * 1024;
951 bkpinfo->media_size[1] = 650; /* good guess */
952 } else if (bkpinfo->backup_media_type == tape
953 || bkpinfo->backup_media_type == udev) {
954 if (read_cfg_var(cfg_file, "media-dev", value)) {
955 fatal_error("Cannot get tape device name from cfg file");
956 }
957 strcpy(bkpinfo->media_device, value);
958 read_cfg_var(cfg_file, "media-size", value);
959 bkpinfo->media_size[1] = atol(value);
960 sprintf(tmp, "Backup medium is TAPE --- dev=%s",
961 bkpinfo->media_device);
962 mr_msg(2, tmp);
963 } else {
964 strcpy(bkpinfo->media_device, "/dev/cdrom"); /* we don't really need this var */
965 bkpinfo->media_size[0] = 1999 * 1024; /* 650, probably, but we don't need this var anyway */
966 bkpinfo->media_size[1] = 1999 * 1024; /* 650, probably, but we don't need this var anyway */
967 mr_msg(2, "Backup medium is CD-R[W]");
968 }
969 } else {
970 mr_msg(2,
971 "Not in Disaster Recovery Mode. No need to derive device name from config file.");
972 }
973
974 read_cfg_var(cfg_file, "use-star", value);
975 if (strstr(value, "yes")) {
976 bkpinfo->use_star = TRUE;
977 mr_msg(1, "Goody! ... bkpinfo->use_star is now true.");
978 }
979
980 read_cfg_var(cfg_file, "acl", value);
981 if (strstr(value, "yes")) {
982 mr_asprintf(&g_getfacl,"setfacl");
983 mr_msg(1, "We will restore ACLs");
984 if (! find_home_of_exe("setfacl")) {
985 mr_msg(1, "Unable to restore ACLs as no setfacl found");
986 }
987 }
988 read_cfg_var(cfg_file, "xattr", value);
989 if (strstr(value, "yes")) {
990 mr_asprintf(&g_getfattr,"setfattr");
991 mr_msg(1, "We will restore XATTRs");
992 if (! find_home_of_exe("setfattr")) {
993 mr_msg(1, "Unable to restore XATTRs as no setfattr found");
994 }
995 }
996
997 if (0 == read_cfg_var(cfg_file, "internal-tape-block-size", value)) {
998 bkpinfo->internal_tape_block_size = atol(value);
999 mr_msg(1, "Internal tape block size has been custom-set to %ld",
1000 bkpinfo->internal_tape_block_size);
1001 } else {
1002 bkpinfo->internal_tape_block_size =
1003 DEFAULT_INTERNAL_TAPE_BLOCK_SIZE;
1004 mr_msg(1, "Internal tape block size = default (%ld)",
1005 DEFAULT_INTERNAL_TAPE_BLOCK_SIZE);
1006 }
1007
1008 read_cfg_var(cfg_file, "use-lzo", value);
1009 if (strstr(value, "yes")) {
1010 bkpinfo->use_lzo = TRUE;
1011 bkpinfo->use_gzip = FALSE;
1012 strcpy(bkpinfo->zip_exe, "lzop");
1013 strcpy(bkpinfo->zip_suffix, "lzo");
1014 } else {
1015 read_cfg_var(cfg_file, "use-gzip", value);
1016 if (strstr(value, "yes")) {
1017 bkpinfo->use_lzo = FALSE;
1018 bkpinfo->use_gzip = TRUE;
1019 strcpy(bkpinfo->zip_exe, "gzip");
1020 strcpy(bkpinfo->zip_suffix, "gz");
1021 } else {
1022 read_cfg_var(cfg_file, "use-comp", value);
1023 if (strstr(value, "yes")) {
1024 bkpinfo->use_lzo = FALSE;
1025 bkpinfo->use_gzip = FALSE;
1026 strcpy(bkpinfo->zip_exe, "bzip2");
1027 strcpy(bkpinfo->zip_suffix, "bz2");
1028 } else {
1029 bkpinfo->zip_exe[0] = bkpinfo->zip_suffix[0] = '\0';
1030 }
1031 }
1032 }
1033
1034 value[0] = '\0';
1035 read_cfg_var(cfg_file, "differential", value);
1036 if (!strcmp(value, "yes") || !strcmp(value, "1")) {
1037 bkpinfo->differential = TRUE;
1038 }
1039 mr_msg(2, "differential var = '%s'", value);
1040 if (bkpinfo->differential) {
1041 mr_msg(2, "THIS IS A DIFFERENTIAL BACKUP");
1042 } else {
1043 mr_msg(2, "This is a regular (full) backup");
1044 }
1045
1046 read_cfg_var(g_mondo_cfg_file, "please-dont-eject", tmp);
1047 if (tmp[0]
1048 ||
1049 strstr(call_program_and_get_last_line_of_output
1050 ("cat /proc/cmdline"), "donteject")) {
1051 bkpinfo->please_dont_eject = TRUE;
1052 mr_msg(2, "Ok, I shan't eject when restoring! Groovy.");
1053 }
1054
1055 if (bkpinfo->backup_media_type == nfs) {
1056 if (!cfgf) {
1057 mr_msg(2, "nfs_mount remains %s", bkpinfo->nfs_mount);
1058 mr_msg(2, "nfs_remote_dir remains %s",
1059 bkpinfo->nfs_remote_dir);
1060 mr_msg(2,
1061 "...cos it wouldn't make sense to abandon the values that GOT ME to this config file in the first place");
1062 } else {
1063 read_cfg_var(g_mondo_cfg_file, "nfs-server-mount",
1064 bkpinfo->nfs_mount);
1065 read_cfg_var(g_mondo_cfg_file, "nfs-server-path",
1066 bkpinfo->nfs_remote_dir);
1067 mr_msg(2, "nfs_mount is %s", bkpinfo->nfs_mount);
1068 mr_msg(2, "nfs_remote_dir is %s", bkpinfo->nfs_remote_dir);
1069 }
1070 if (strstr(call_program_and_get_last_line_of_output
1071 ("cat /proc/cmdline"), "pxe")) {
1072 /* We need to override values in PXE mode as it's
1073 * already done in start-nfs */
1074 envtmp1 = getenv("nfsmount");
1075 if (envtmp1 == NULL) {
1076 fatal_error("no nfsmount variable in environment");
1077 }
1078 envtmp2 = getenv("dirimg");
1079 if (envtmp2 == NULL) {
1080 fatal_error("no dirimg variable in environment");
1081 }
1082 strcpy(bkpinfo->nfs_mount,envtmp1);
1083 strcpy(bkpinfo->nfs_remote_dir,envtmp2);
1084 }
1085 } else if (bkpinfo->backup_media_type == iso) {
1086 /* Patch by Conor Daly 23-june-2004
1087 * to correctly mount iso-dev and set a sensible
1088 * isodir in disaster recovery mode
1089 */
1090 strcpy(old_isodir, bkpinfo->isodir);
1091 read_cfg_var(g_mondo_cfg_file, "iso-mnt", iso_mnt);
1092 read_cfg_var(g_mondo_cfg_file, "isodir", iso_path);
1093 sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1094 if (!bkpinfo->isodir[0]) {
1095 strcpy(bkpinfo->isodir, old_isodir);
1096 }
1097 if (!bkpinfo->disaster_recovery) {
1098 if (strcmp(old_isodir, bkpinfo->isodir)) {
1099 log_it
1100 ("user nominated isodir differs from archive, keeping user's choice: %s %s\n",
1101 old_isodir, bkpinfo->isodir);
1102 strcpy(bkpinfo->isodir, old_isodir);
1103 }
1104 }
1105 read_cfg_var(g_mondo_cfg_file, "iso-dev", g_isodir_device);
1106 mr_msg(2, "isodir=%s; iso-dev=%s", bkpinfo->isodir,
1107 g_isodir_device);
1108 if (bkpinfo->disaster_recovery) {
1109 if (is_this_device_mounted(g_isodir_device)) {
1110 mr_msg(2, "NB: isodir is already mounted");
1111 /* Find out where it's mounted */
1112 sprintf(command,
1113 "mount | grep -E '^%s' | tail -n1 | cut -d' ' -f3",
1114 g_isodir_device);
1115 log_it("command = %s", command);
1116 log_it("res of it = %s",
1117 call_program_and_get_last_line_of_output(command));
1118 sprintf(iso_mnt, "%s",
1119 call_program_and_get_last_line_of_output(command));
1120 } else {
1121 sprintf(iso_mnt, "/tmp/isodir");
1122 sprintf(tmp, "mkdir -p %s", iso_mnt);
1123 run_program_and_log_output(tmp, 5);
1124 sprintf(tmp, "mount %s %s", g_isodir_device, iso_mnt);
1125 if (run_program_and_log_output(tmp, 3)) {
1126 mr_msg(1,
1127 "Unable to mount isodir. Perhaps this is really a CD backup?");
1128 bkpinfo->backup_media_type = cdr;
1129 strcpy(bkpinfo->media_device, "/dev/cdrom"); /* superfluous */
1130 bkpinfo->isodir[0] = iso_mnt[0] = iso_path[0] = '\0';
1131 if (mount_cdrom(bkpinfo)) {
1132 fatal_error
1133 ("Unable to mount isodir. Failed to mount CD-ROM as well.");
1134 } else {
1135 mr_msg(1,
1136 "You backed up to disk, then burned some CDs.");
1137 }
1138 }
1139 }
1140 /* bkpinfo->isodir should now be the true path to prefix-1.iso etc... */
1141 if (bkpinfo->backup_media_type == iso) {
1142 sprintf(bkpinfo->isodir, "%s%s", iso_mnt, iso_path);
1143 }
1144 }
1145 }
1146
1147 if (media_specified_by_user != none) {
1148 if (g_restoring_live_from_cd) {
1149 if (bkpinfo->backup_media_type != media_specified_by_user) {
1150 mr_msg(2,
1151 "bkpinfo->backup_media_type != media_specified_by_user, so I'd better ask :)");
1152 interactively_obtain_media_parameters_from_user(bkpinfo,
1153 FALSE);
1154 media_specified_by_user = bkpinfo->backup_media_type;
1155 get_cfg_file_from_archive(bkpinfo);
1156/*
1157 if (media_specified_by_user != cdr && media_specified_by_user == cdrw)
1158 { g_restoring_live_from_cd = FALSE; }
1159*/
1160 }
1161 }
1162 bkpinfo->backup_media_type = media_specified_by_user;
1163 }
1164 g_backup_media_type = bkpinfo->backup_media_type;
1165 mr_free(value);
1166 mr_free(tmp);
1167 mr_free(command);
1168 mr_free(iso_mnt);
1169 mr_free(iso_path);
1170 mr_free(old_isodir);
1171 return (0);
1172
1173}
1174
1175/**************************************************************************
1176 *END_READ_CFG_FILE_INTO_BKPINFO *
1177 **************************************************************************/
1178
1179
1180
1181
1182/**
1183 * Allow the user to edit the filelist and biggielist.
1184 * The filelist is unlinked after it is read.
1185 * @param bkpinfo The backup information structure. Fields used:
1186 * - @c bkpinfo->backup_media_type
1187 * - @c bkpinfo->isodir
1188 * - @c bkpinfo->media_device
1189 * - @c bkpinfo->tmpdir
1190 * @return The filelist structure containing the information read from disk.
1191 */
1192struct
1193s_node *process_filelist_and_biggielist(struct s_bkpinfo *bkpinfo)
1194{
1195 struct s_node *filelist;
1196
1197 /** add mallocs**/
1198 char *command;
1199 char *tmp;
1200 int res = 0;
1201 pid_t pid;
1202
1203 assert(bkpinfo != NULL);
1204 malloc_string(command);
1205 malloc_string(tmp);
1206
1207 if (does_file_exist(g_filelist_full)
1208 && does_file_exist(g_biggielist_txt)) {
1209 mr_msg(1, "%s exists", g_filelist_full);
1210 mr_msg(1, "%s exists", g_biggielist_txt);
1211 mr_msg(2,
1212 "Filelist and biggielist already recovered from media. Yay!");
1213 } else {
1214 getcwd(tmp, MAX_STR_LEN);
1215 chdir(bkpinfo->tmpdir);
1216 mr_msg(1, "chdir(%s)", bkpinfo->tmpdir);
1217 log_to_screen("Extracting filelist and biggielist from media...");
1218 unlink("/tmp/filelist.full");
1219 unlink("/" FILELIST_FULL_STUB);
1220 unlink("/tmp/i-want-my-lvm");
1221 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {
1222 sprintf(command,
1223 "tar -zxf %s %s %s %s %s %s",
1224 bkpinfo->media_device,
1225 MOUNTLIST_FNAME_STUB,
1226 BIGGIELIST_TXT_STUB,
1227 FILELIST_FULL_STUB,
1228 "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1229 mr_msg(1, "tarcommand = %s", command);
1230 run_program_and_log_output(command, 1);
1231 } else {
1232 mr_msg(2,
1233 "Calling insist_on_this_cd_number; bkpinfo->isodir=%s",
1234 bkpinfo->isodir);
1235 insist_on_this_cd_number(bkpinfo, 1);
1236 mr_msg(2, "Back from iotcn");
1237 run_program_and_log_output("mount", 1);
1238 sprintf(command,
1239 "tar -zxf %s/images/all.tar.gz %s %s %s %s %s",
1240 MNT_CDROM,
1241 MOUNTLIST_FNAME_STUB,
1242 BIGGIELIST_TXT_STUB,
1243 FILELIST_FULL_STUB,
1244 "tmp/i-want-my-lvm", MONDO_CFG_FILE_STUB);
1245
1246 mr_msg(1, "tarcommand = %s", command);
1247 run_program_and_log_output(command, 1);
1248// popup_and_OK("Press ENTER to continue");
1249 if (!does_file_exist(BIGGIELIST_TXT_STUB)) {
1250 fatal_error
1251 ("all.tar.gz did not include tmp/biggielist.txt");
1252 }
1253 if (!does_file_exist(FILELIST_FULL_STUB)) {
1254 fatal_error
1255 ("all.tar.gz did not include tmp/filelist.full.gz");
1256 }
1257 }
1258 sprintf(command, "cp -f %s %s", MONDO_CFG_FILE_STUB,
1259 g_mondo_cfg_file);
1260 run_program_and_log_output(command, FALSE);
1261
1262 sprintf(command, "cp -f %s/%s %s", bkpinfo->tmpdir,
1263 BIGGIELIST_TXT_STUB, g_biggielist_txt);
1264 mr_msg(1, "command = %s", command);
1265 paranoid_system(command);
1266 sprintf(command, "ln -sf %s/%s %s", bkpinfo->tmpdir,
1267 FILELIST_FULL_STUB, g_filelist_full);
1268 mr_msg(1, "command = %s", command);
1269 paranoid_system(command);
1270 }
1271
1272 if (am_I_in_disaster_recovery_mode()
1273 &&
1274 ask_me_yes_or_no("Do you want to retrieve the mountlist as well?"))
1275 {
1276// sprintf(command, "cp -f tmp/mountlist.txt /tmp");
1277 sprintf(command, "ln -sf %s/%s /tmp", MOUNTLIST_FNAME_STUB,
1278 bkpinfo->tmpdir);
1279 paranoid_system(command);
1280 }
1281
1282 chdir(tmp);
1283
1284 if (!does_file_exist(g_biggielist_txt)) {
1285 mr_msg(1, "Warning - %s not found", g_biggielist_txt);
1286 }
1287 if (!does_file_exist(g_filelist_full)) {
1288 mr_msg(1, "Warning - %s does not exist", g_filelist_full);
1289 }
1290// popup_and_OK("Wonderful.");
1291
1292 mr_msg(2, "Forking");
1293 pid = fork();
1294 switch (pid) {
1295 case -1:
1296 fatal_error("Forking error");
1297 break;
1298
1299 case 0:
1300 log_to_screen("Pre-processing filelist");
1301 if (!does_file_exist(g_biggielist_txt)) {
1302 sprintf(command, "> %s", g_biggielist_txt);
1303 paranoid_system(command);
1304 }
1305 sprintf(command, "grep -E '^/dev/.*' %s > %s",
1306 g_biggielist_txt, g_filelist_imagedevs);
1307 paranoid_system(command);
1308 exit(0);
1309 break;
1310
1311 default:
1312 open_evalcall_form("Pre-processing filelist");
1313 while (!waitpid(pid, (int *) 0, WNOHANG)) {
1314 usleep(100000);
1315 update_evalcall_form(0);
1316 }
1317 }
1318 close_evalcall_form();
1319
1320 mr_msg(3, "loading filelist");
1321 filelist = load_filelist(g_filelist_full);
1322 mr_msg(3, "deleting original filelist");
1323 unlink(g_filelist_full);
1324 if (g_text_mode) {
1325 printf("Restore which directory? --> ");
1326 fgets(tmp, sizeof(tmp), stdin);
1327 toggle_path_selection(filelist, tmp, TRUE);
1328 if (strlen(tmp) == 0) {
1329 res = 1;
1330 } else {
1331 res = 0;
1332 }
1333 } else {
1334 res = edit_filelist(filelist);
1335 }
1336 if (res) {
1337 mr_msg(2, "User hit 'cancel'. Freeing filelist and aborting.");
1338 free_filelist(filelist);
1339 return (NULL);
1340 }
1341 ask_about_these_imagedevs(g_filelist_imagedevs, g_imagedevs_restthese);
1342 close_evalcall_form();
1343
1344 // NB: It's not necessary to add g_biggielist_txt to the filelist.full
1345 // file. The filelist.full file already contains the filename of EVERY
1346 // file backed up - regular and biggie files.
1347
1348 // However, we do want to make sure the imagedevs selected by the user
1349 // are flagged for restoring.
1350 if (length_of_file(g_imagedevs_restthese) > 2) {
1351 add_list_of_files_to_filelist(filelist, g_imagedevs_restthese,
1352 TRUE);
1353 }
1354
1355 mr_free(command);
1356 mr_free(tmp);
1357 return (filelist);
1358}
1359
1360/**************************************************************************
1361 *END_ PROCESS_FILELIST_AND_BIGGIELIST *
1362 **************************************************************************/
1363
1364
1365
1366
1367/**
1368 * Make a backup copy of <tt>path_root</tt>/<tt>filename</tt>.
1369 * The backup filename is the filename of the original with ".pristine" added.
1370 * @param path_root The place where the filesystem is mounted (e.g. MNT_RESTORING).
1371 * @param filename The filename (absolute path) within @p path_root.
1372 * @return 0 for success, nonzero for failure.
1373 */
1374int backup_crucial_file(char *path_root, char *filename)
1375{
1376 char *tmp;
1377 char *command;
1378 int res;
1379
1380 malloc_string(tmp);
1381 malloc_string(command);
1382 assert(path_root != NULL);
1383 assert_string_is_neither_NULL_nor_zerolength(filename);
1384
1385 sprintf(tmp, "%s/%s", path_root, filename);
1386 sprintf(command, "cp -f %s %s.pristine", tmp, tmp);
1387
1388 res = run_program_and_log_output(command, 5);
1389 mr_free(tmp);
1390 mr_free(command);
1391 return (res);
1392}
1393
1394
1395/**
1396 * Install the user's boot loader in the MBR.
1397 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported.
1398 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1399 * @return 0 for success, nonzero for failure.
1400 */
1401int run_boot_loader(bool offer_to_hack_scripts)
1402{
1403 int res;
1404 int retval = 0;
1405
1406 /** malloc *******/
1407 char *device;
1408 char *tmp;
1409 char *name;
1410
1411 malloc_string(device);
1412 malloc_string(tmp);
1413 malloc_string(name);
1414 backup_crucial_file(MNT_RESTORING, "/etc/fstab");
1415 backup_crucial_file(MNT_RESTORING, "/etc/grub.conf");
1416 backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf");
1417 backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf");
1418 read_cfg_var(g_mondo_cfg_file, "bootloader.device", device);
1419 read_cfg_var(g_mondo_cfg_file, "bootloader.name", name);
1420 sprintf(tmp, "run_boot_loader: device='%s', name='%s'", device, name);
1421 mr_msg(2, tmp);
1422 system("sync");
1423 if (!strcmp(name, "LILO")) {
1424 res = run_lilo(offer_to_hack_scripts);
1425 } else if (!strcmp(name, "ELILO")) {
1426 res = run_elilo(offer_to_hack_scripts);
1427 } else if (!strcmp(name, "GRUB")) {
1428// 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?")))
1429// {
1430 res = run_grub(offer_to_hack_scripts, device);
1431// unlink(DO_MBR_PLEASE);
1432// }
1433// else
1434// {
1435// mr_msg(1, "Not running run_grub(). Was a bad idea anyway.");
1436// res = 1;
1437// }
1438 } else if (!strcmp(name, "RAW")) {
1439 res = run_raw_mbr(offer_to_hack_scripts, device);
1440 }
1441#ifdef __FreeBSD__
1442 else if (!strcmp(name, "BOOT0")) {
1443 sprintf(tmp, "boot0cfg -B %s", device);
1444 res = run_program_and_log_output(tmp, FALSE);
1445 } else {
1446 sprintf(tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device);
1447 if (!system(tmp)) {
1448 sprintf(tmp, MNT_RESTORING "/sbin/fdisk -B %s", device);
1449 res = run_program_and_log_output(tmp, 3);
1450 } else {
1451 mr_msg(1,
1452 "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");
1453 }
1454 }
1455#else
1456 else {
1457 log_to_screen
1458 ("Unable to determine type of boot loader. Defaulting to LILO.");
1459 res = run_lilo(offer_to_hack_scripts);
1460 }
1461#endif
1462 retval += res;
1463 if (res) {
1464 log_to_screen("Your boot loader returned an error");
1465 } else {
1466 log_to_screen("Your boot loader ran OK");
1467 }
1468 mr_free(device);
1469 mr_free(tmp);
1470 mr_free(name);
1471 return (retval);
1472}
1473
1474/**************************************************************************
1475 *END_ RUN_BOOT_LOADER *
1476 **************************************************************************/
1477
1478
1479
1480/**
1481 * Attempt to find the user's editor.
1482 * @return The editor found ("vi" if none could be found).
1483 * @note The returned string points to static storage that will be overwritten with each call.
1484 */
1485char *find_my_editor(void)
1486{
1487 static char output[MAX_STR_LEN];
1488 if (find_home_of_exe("pico")) {
1489 strcpy(output, "pico");
1490 } else if (find_home_of_exe("nano")) {
1491 strcpy(output, "nano");
1492 } else if (find_home_of_exe("e3em")) {
1493 strcpy(output, "e3em");
1494 } else if (find_home_of_exe("e3vi")) {
1495 strcpy(output, "e3vi");
1496 } else {
1497 strcpy(output, "vi");
1498 }
1499 if (!find_home_of_exe(output)) {
1500 mr_msg(2, " (find_my_editor) --- warning - %s not found", output);
1501 }
1502 return (output);
1503}
1504
1505
1506/**
1507 * Install GRUB on @p bd.
1508 * @param offer_to_run_stabgrub If TRUE, then offer to hack the user's fstab for them.
1509 * @param bd The boot device where GRUB is installed.
1510 * @return 0 for success, nonzero for failure.
1511 */
1512int run_grub(bool offer_to_run_stabgrub, char *bd)
1513{
1514 /** malloc **/
1515 char *command;
1516 char *boot_device;
1517 char *rootdev;
1518 char *rootdrive;
1519 char *conffile;
1520 char *tmp;
1521 char *editor;
1522
1523 int res;
1524 int done;
1525
1526 malloc_string(command);
1527 malloc_string(boot_device);
1528 malloc_string(tmp);
1529 malloc_string(editor);
1530 malloc_string(rootdev);
1531 malloc_string(rootdrive);
1532 malloc_string(conffile);
1533 assert_string_is_neither_NULL_nor_zerolength(bd);
1534 strcpy(editor, "vi"); // find_my_editor() );
1535 strcpy(boot_device, bd);
1536
1537 if (!run_program_and_log_output("which grub-MR", FALSE)) {
1538 mr_msg(1, "Yay! grub-MR found...");
1539 sprintf(command, "grub-MR %s /tmp/mountlist.txt", boot_device);
1540 mr_msg(1, "command = %s", command);
1541 } else {
1542 sprintf(command, "chroot " MNT_RESTORING " grub-install %s",
1543 boot_device);
1544 mr_msg(1, "WARNING - grub-MR not found; using grub-install");
1545 }
1546 if (offer_to_run_stabgrub
1547 && ask_me_yes_or_no("Did you change the mountlist?"))
1548 /* interactive mode */
1549 {
1550 mvaddstr_and_log_it(g_currentY,
1551 0,
1552 "Modifying fstab and grub.conf, and running GRUB... ");
1553 for (done = FALSE; !done;) {
1554 popup_and_get_string("Boot device",
1555 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1556 boot_device, MAX_STR_LEN / 4);
1557 sprintf(command, "stabgrub-me %s", boot_device);
1558 res = run_program_and_log_output(command, 1);
1559 if (res) {
1560 popup_and_OK
1561 ("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.");
1562 newtSuspend();
1563 system("chroot " MNT_RESTORING);
1564 newtResume();
1565 popup_and_OK("Thank you.");
1566 } else {
1567 done = TRUE;
1568 }
1569 popup_and_OK("You will now edit fstab and grub.conf");
1570 if (!g_text_mode) {
1571 newtSuspend();
1572 }
1573 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1574 paranoid_system(tmp);
1575 sprintf(tmp, "%s " MNT_RESTORING "/etc/grub.conf", editor);
1576 paranoid_system(tmp);
1577 if (!g_text_mode) {
1578 newtResume();
1579 }
1580 }
1581 } else
1582 /* nuke mode */
1583 {
1584 mvaddstr_and_log_it(g_currentY,
1585 0,
1586 "Running GRUB... ");
1587 iamhere(command);
1588 res = run_program_and_log_output(command, 1);
1589 if (res) {
1590 popup_and_OK
1591 ("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.");
1592 newtSuspend();
1593 system("chroot " MNT_RESTORING);
1594 newtResume();
1595 popup_and_OK("Thank you.");
1596 }
1597 }
1598 if (res) {
1599 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1600 log_to_screen
1601 ("GRUB ran w/error(s). See /tmp/mondo-restore.log for more info.");
1602 mr_msg(1, "Type:-");
1603 mr_msg(1, " mount-me");
1604 mr_msg(1, " chroot " MNT_RESTORING);
1605 mr_msg(1, " mount /boot");
1606 mr_msg(1, " grub-install '(hd0)'");
1607 mr_msg(1, " exit");
1608 mr_msg(1, " unmount-me");
1609 mr_msg(1,
1610 "If you're really stuck, please e-mail the mailing list.");
1611 } else {
1612 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1613 }
1614 mr_free(rootdev);
1615 mr_free(rootdrive);
1616 mr_free(conffile);
1617 mr_free(command);
1618 mr_free(boot_device);
1619 mr_free(tmp);
1620 mr_free(editor);
1621
1622 return (res);
1623}
1624
1625/**************************************************************************
1626 *END_RUN_GRUB *
1627 **************************************************************************/
1628
1629
1630/**
1631 * Install ELILO on the user's boot drive (determined by elilo.conf).
1632 * @param offer_to_run_stabelilo If TRUE, then offer to hack the user's fstab for them.
1633 * @return 0 for success, nonzero for failure.
1634 */
1635int run_elilo(bool offer_to_run_stabelilo)
1636{
1637 /** malloc **/
1638 char *command;
1639 char *tmp;
1640 char *editor;
1641
1642 int res;
1643 int done;
1644
1645 malloc_string(command);
1646 malloc_string(tmp);
1647 malloc_string(editor);
1648 strcpy(editor, find_my_editor());
1649 if (offer_to_run_stabelilo
1650 && ask_me_yes_or_no("Did you change the mountlist?"))
1651
1652 /* interactive mode */
1653 {
1654 mvaddstr_and_log_it(g_currentY,
1655 0,
1656 "Modifying fstab and elilo.conf... ");
1657 sprintf(command, "stabelilo-me");
1658 res = run_program_and_log_output(command, 3);
1659 if (res) {
1660 popup_and_OK
1661 ("You will now edit fstab and elilo.conf, to make sure they match your new mountlist.");
1662 for (done = FALSE; !done;) {
1663 if (!g_text_mode) {
1664 newtSuspend();
1665 }
1666 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1667 paranoid_system(tmp);
1668 sprintf(tmp, "%s " MNT_RESTORING "/etc/elilo.conf",
1669 editor);
1670 paranoid_system(tmp);
1671 if (!g_text_mode) {
1672 newtResume();
1673 }
1674// newtCls();
1675 if (ask_me_yes_or_no("Edit them again?")) {
1676 continue;
1677 }
1678 done = TRUE;
1679 }
1680 } else {
1681 log_to_screen("elilo.conf and fstab were modified OK");
1682 }
1683 } else
1684 /* nuke mode */
1685 {
1686 res = TRUE;
1687 }
1688 mr_free(command);
1689 mr_free(tmp);
1690 mr_free(editor);
1691 return (res);
1692}
1693
1694/**************************************************************************
1695 *END_RUN_ELILO *
1696 **************************************************************************/
1697
1698
1699/**
1700 * Install LILO on the user's boot drive (determined by /etc/lilo.conf).
1701 * @param offer_to_run_stablilo If TRUE, then offer to hack the user's fstab for them.
1702 * @return 0 for success, nonzero for failure.
1703 */
1704int run_lilo(bool offer_to_run_stablilo)
1705{
1706 /** malloc **/
1707 char *command;
1708 char *tmp;
1709 char *editor;
1710
1711 int res;
1712 int done;
1713 bool run_lilo_M = FALSE;
1714 malloc_string(command);
1715 malloc_string(tmp);
1716 malloc_string(editor);
1717
1718 if (!run_program_and_log_output
1719 ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) {
1720 run_lilo_M = TRUE;
1721 }
1722
1723 strcpy(editor, find_my_editor());
1724 if (offer_to_run_stablilo
1725 && ask_me_yes_or_no("Did you change the mountlist?"))
1726
1727 /* interactive mode */
1728 {
1729 mvaddstr_and_log_it(g_currentY,
1730 0,
1731 "Modifying fstab and lilo.conf, and running LILO... ");
1732 sprintf(command, "stablilo-me");
1733 res = run_program_and_log_output(command, 3);
1734 if (res) {
1735 popup_and_OK
1736 ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist.");
1737 for (done = FALSE; !done;) {
1738 if (!g_text_mode) {
1739 newtSuspend();
1740 }
1741 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1742 paranoid_system(tmp);
1743 sprintf(tmp, "%s " MNT_RESTORING "/etc/lilo.conf", editor);
1744 paranoid_system(tmp);
1745 if (!g_text_mode) {
1746 newtResume();
1747 }
1748// newtCls();
1749 if (ask_me_yes_or_no("Edit them again?")) {
1750 continue;
1751 }
1752 res =
1753 run_program_and_log_output("chroot " MNT_RESTORING
1754 " lilo -L", 3);
1755 if (res) {
1756 res =
1757 run_program_and_log_output("chroot " MNT_RESTORING
1758 " lilo", 3);
1759 }
1760 if (res) {
1761 done =
1762 ask_me_yes_or_no
1763 ("LILO failed. Re-edit system files?");
1764 } else {
1765 done = TRUE;
1766 }
1767 }
1768 } else {
1769 log_to_screen("lilo.conf and fstab were modified OK");
1770 }
1771 } else
1772 /* nuke mode */
1773 {
1774 mvaddstr_and_log_it(g_currentY,
1775 0,
1776 "Running LILO... ");
1777 res =
1778 run_program_and_log_output("chroot " MNT_RESTORING " lilo -L",
1779 3);
1780 if (res) {
1781 res =
1782 run_program_and_log_output("chroot " MNT_RESTORING " lilo",
1783 3);
1784 }
1785 if (res) {
1786 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1787 log_to_screen
1788 ("Failed to re-jig fstab and/or lilo. Edit/run manually, please.");
1789 } else {
1790 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1791 }
1792 }
1793 if (run_lilo_M) {
1794 run_program_and_log_output("chroot " MNT_RESTORING
1795 " lilo -M /dev/hda", 3);
1796 run_program_and_log_output("chroot " MNT_RESTORING
1797 " lilo -M /dev/sda", 3);
1798 }
1799 mr_free(command);
1800 mr_free(tmp);
1801 mr_free(editor);
1802 return (res);
1803}
1804
1805/**************************************************************************
1806 *END_RUN_LILO *
1807 **************************************************************************/
1808
1809
1810/**
1811 * Install a raw MBR onto @p bd.
1812 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.
1813 * @param bd The device to copy the stored MBR to.
1814 * @return 0 for success, nonzero for failure.
1815 */
1816int run_raw_mbr(bool offer_to_hack_scripts, char *bd)
1817{
1818 /** malloc **/
1819 char *command;
1820 char *boot_device;
1821 char *tmp;
1822 char *editor;
1823 int res;
1824 int done;
1825
1826 malloc_string(command);
1827 malloc_string(boot_device);
1828 malloc_string(tmp);
1829 malloc_string(editor);
1830 assert_string_is_neither_NULL_nor_zerolength(bd);
1831
1832 strcpy(editor, find_my_editor());
1833 strcpy(boot_device, bd);
1834 sprintf(command, "raw-MR %s /tmp/mountlist.txt", boot_device);
1835 mr_msg(2, "run_raw_mbr() --- command='%s'", command);
1836
1837 if (offer_to_hack_scripts
1838 && ask_me_yes_or_no("Did you change the mountlist?"))
1839 /* interactive mode */
1840 {
1841 mvaddstr_and_log_it(g_currentY, 0,
1842 "Modifying fstab and restoring MBR... ");
1843 for (done = FALSE; !done;) {
1844 if (!run_program_and_log_output("which vi", FALSE)) {
1845 popup_and_OK("You will now edit fstab");
1846 if (!g_text_mode) {
1847 newtSuspend();
1848 }
1849 sprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor);
1850 paranoid_system(tmp);
1851 if (!g_text_mode) {
1852 newtResume();
1853 }
1854// newtCls();
1855 }
1856 popup_and_get_string("Boot device",
1857 "Please confirm/enter the boot device. If in doubt, try /dev/hda",
1858 boot_device, MAX_STR_LEN / 4);
1859 sprintf(command, "stabraw-me %s", boot_device);
1860 res = run_program_and_log_output(command, 3);
1861 if (res) {
1862 done = ask_me_yes_or_no("Modifications failed. Re-try?");
1863 } else {
1864 done = TRUE;
1865 }
1866 }
1867 } else
1868 /* nuke mode */
1869 {
1870 mvaddstr_and_log_it(g_currentY, 0,
1871 "Restoring MBR... ");
1872 res = run_program_and_log_output(command, 3);
1873 }
1874 if (res) {
1875 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
1876 log_to_screen
1877 ("MBR+fstab processed w/error(s). See /tmp/mondo-restore.log for more info.");
1878 } else {
1879 mvaddstr_and_log_it(g_currentY++, 74, "Done.");
1880 }
1881 mr_free(command);
1882 mr_free(boot_device);
1883 mr_free(tmp);
1884 mr_free(editor);
1885 return (res);
1886}
1887
1888/**************************************************************************
1889 *END_RUN_RAW_MBR *
1890 **************************************************************************/
1891
1892
1893
1894
1895
1896/**
1897 * Turn signal trapping on or off.
1898 * @param on If TRUE, then do full cleanup when we receive a signal; if FALSE, then
1899 * print a message and exit immediately.
1900 */
1901void set_signals(int on)
1902{
1903 int signals[] =
1904 { SIGKILL, SIGPIPE, SIGTERM, SIGHUP, SIGTRAP, SIGABRT, SIGINT,
1905SIGSTOP, 0 };
1906 int i;
1907 for (i = 0; signals[i]; i++) {
1908 if (on) {
1909 signal(signals[i], terminate_daemon);
1910 } else {
1911 signal(signals[i], termination_in_progress);
1912 }
1913 }
1914}
1915
1916/**************************************************************************
1917 *END_SET_SIGNALS *
1918 **************************************************************************/
1919
1920
1921/**
1922 * malloc() and set sensible defaults for the mondorestore filename variables.
1923 * @param bkpinfo The backup information structure. Fields used:
1924 * - @c bkpinfo->tmpdir
1925 * - @c bkpinfo->disaster_recovery
1926 */
1927void setup_MR_global_filenames(struct s_bkpinfo *bkpinfo)
1928{
1929 char *temppath;
1930
1931 assert(bkpinfo != NULL);
1932
1933 malloc_string(g_biggielist_txt);
1934 malloc_string(g_filelist_full);
1935 malloc_string(g_filelist_imagedevs);
1936 malloc_string(g_imagedevs_restthese);
1937 malloc_string(g_mondo_cfg_file);
1938 malloc_string(g_mountlist_fname);
1939 malloc_string(g_mondo_home);
1940 malloc_string(g_tmpfs_mountpt);
1941 malloc_string(g_isodir_device);
1942 malloc_string(g_isodir_format);
1943
1944 temppath = bkpinfo->tmpdir;
1945
1946 sprintf(g_biggielist_txt, "%s/%s", temppath, BIGGIELIST_TXT_STUB);
1947 sprintf(g_filelist_full, "%s/%s", temppath, FILELIST_FULL_STUB);
1948 sprintf(g_filelist_imagedevs, "%s/tmp/filelist.imagedevs", temppath);
1949// sprintf(g_imagedevs_pot, "%s/tmp/imagedevs.pot", temppath);
1950 sprintf(g_imagedevs_restthese, "%s/tmp/imagedevs.restore-these",
1951 temppath);
1952 if (bkpinfo->disaster_recovery) {
1953 sprintf(g_mondo_cfg_file, "/%s", MONDO_CFG_FILE_STUB);
1954 sprintf(g_mountlist_fname, "/%s", MOUNTLIST_FNAME_STUB);
1955 } else {
1956 sprintf(g_mondo_cfg_file, "%s/%s", temppath, MONDO_CFG_FILE_STUB);
1957 sprintf(g_mountlist_fname, "%s/%s", temppath,
1958 MOUNTLIST_FNAME_STUB);
1959 }
1960}
1961
1962/**************************************************************************
1963 *END_SET_GLOBAL_FILENAME *
1964 **************************************************************************/
1965
1966
1967/**
1968 * Copy @p input_file (containing the result of a compare) to @p output_file,
1969 * deleting spurious "changes" along the way.
1970 * @param output_file The output file to write with spurious changes removed.
1971 * @param input_file The input file, a list of changed files created by a compare.
1972 */
1973void streamline_changes_file(char *output_file, char *input_file)
1974{
1975 FILE *fin;
1976 FILE *fout;
1977 /** malloc **/
1978 char *incoming;
1979
1980 assert_string_is_neither_NULL_nor_zerolength(output_file);
1981 assert_string_is_neither_NULL_nor_zerolength(input_file);
1982 malloc_string(incoming);
1983
1984 if (!(fin = fopen(input_file, "r"))) {
1985 log_OS_error(input_file);
1986 return;
1987 }
1988 if (!(fout = fopen(output_file, "w"))) {
1989 fatal_error("cannot open output_file");
1990 }
1991 for (fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin);
1992 fgets(incoming, MAX_STR_LEN - 1, fin)) {
1993 if (strncmp(incoming, "etc/adjtime", 11)
1994 && strncmp(incoming, "etc/mtab", 8)
1995 && strncmp(incoming, "tmp/", 4)
1996 && strncmp(incoming, "boot/map", 8)
1997 && !strstr(incoming, "incheckentry")
1998 && strncmp(incoming, "etc/mail/statistics", 19)
1999 && strncmp(incoming, "var/", 4))
2000 fprintf(fout, "%s", incoming); /* don't need \n here, for some reason.. */
2001 }
2002 paranoid_fclose(fout);
2003 paranoid_fclose(fin);
2004 mr_free(incoming);
2005}
2006
2007/**************************************************************************
2008 *END_STREAMLINE_CHANGES_FILE *
2009 **************************************************************************/
2010
2011
2012/**
2013 * Exit due to a signal (normal cleanup).
2014 * @param sig The signal we're exiting due to.
2015 */
2016void terminate_daemon(int sig)
2017{
2018 log_to_screen
2019 ("Mondorestore is terminating in response to a signal from the OS");
2020 paranoid_MR_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.