source: MondoRescue/branches/3.2/mondo/src/mondorestore/mondo-rstr-tools.c@ 3297

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