source: MondoRescue/trunk/mondo/mondo/mondorestore/mondo-rstr-tools.c@ 729

Last change on this file since 729 was 729, checked in by Bruno Cornec, 18 years ago

merge -r686:728 $SVN_M/branches/stable

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