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

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

merge -r902:913 $SVN_M/branches/stable

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