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

Last change on this file since 688 was 688, checked in by bcornec, 18 years ago

Huge memory management patch.
Still not finished but a lot as been done.
What remains is around some functions returning strings, and some structure members.
(Could not finish due to laptop failure !)

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