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

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

merge -r938:954 $SVN_M/branches/stable

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