Changeset 3879 in MondoRescue for branches/3.3/mondo/src/mondorestore
- Timestamp:
- Mar 9, 2024, 3:10:04 AM (2 years ago)
- Location:
- branches/3.3/mondo/src/mondorestore
- Files:
-
- 7 deleted
- 7 edited
-
Makefile.am (modified) (1 diff)
-
libmondo-mountlist.h (deleted)
-
mondo-prep.c (modified) (9 diffs)
-
mondo-rstr-compare.c (modified) (6 diffs)
-
mondo-rstr-compare.h (deleted)
-
mondo-rstr-mountlist.c (modified) (5 diffs)
-
mondo-rstr-newt.c (modified) (14 diffs)
-
mondo-rstr-newt.h (deleted)
-
mondo-rstr-tools.c (modified) (10 diffs)
-
mondo-rstr-tools.h (deleted)
-
mondoprep.h (deleted)
-
mondorestore-EXT.h (deleted)
-
mondorestore.c (modified) (9 diffs)
-
mr-externs.h (deleted)
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mondo/src/mondorestore/Makefile.am
r3564 r3879 7 7 8 8 ## Headers 9 noinst_HEADERS = mondorestore.h mondo-rstr-compare.h mondo-rstr-newt.h mondo-rstr-tools.h \ 10 mondorestore-EXT.h mr-externs.h \ 11 mondo-rstr-compare-EXT.h mondo-rstr-tools-EXT.h mondoprep.h \ 12 libmondo-mountlist.h libmondo-mountlist-EXT.h \ 13 mondorestore.h 9 noinst_HEADERS = mondorestore.h \ 10 mondo-rstr-compare-EXT.h mondo-rstr-tools-EXT.h \ 11 libmondo-mountlist-EXT.h 14 12 15 13 ## The program -
branches/3.3/mondo/src/mondorestore/mondo-prep.c
r3866 r3879 5 5 6 6 7 #include "my-stuff.h"8 #include "mr_mem.h"9 #include "../common/mondostructures.h"10 #include "mondoprep.h"11 #include "../common/libmondo.h"12 #include "../common/libmondo-tools-EXT.h"13 #include "mondo-rstr-tools-EXT.h"14 #include "libmondo-mountlist-EXT.h"15 7 #include <sys/ioctl.h> 16 8 #include <linux/hdreg.h> 17 9 #include <math.h> 10 #include "my-stuff.h" 11 #include "mr_mem.h" 12 #include "mondostructures.h" 13 #include "mondo-rstr-tools-EXT.h" 14 #include "libmondo-mountlist-EXT.h" 15 #include "libmondo-tools-EXT.h" 16 #include "libmondo-gui-EXT.h" 17 #include "libmondo-devices-EXT.h" 18 #include "libmondo-fork-EXT.h" 19 #include "libmondo-string-EXT.h" 20 #include "libmondo-files-EXT.h" 21 #include "newt-specific-EXT.h" 18 22 19 23 … … 32 36 #endif 33 37 34 #define ARCHIVES_PATH MNT_CDROM"/archives"35 38 #define MONDO_WAS_HERE "MONDOWOZEREMONDOWOZEREMONDOWOZEREhahahaMOJOJOJO" 36 39 … … 39 42 extern char *g_mountlist_fname; 40 43 extern long g_current_progress, g_maximum_progress; 41 42 44 extern bool g_text_mode; 45 extern int g_currentY; 46 43 47 44 48 extern void pause_for_N_seconds(int, char *); … … 628 632 629 633 634 635 /** 636 * Stop @p raid_device using @p raidstop. 637 * @param raid_device The software RAID device to stop. 638 * @return 0 for success, nonzero for failure. 639 */ 640 int stop_raid_device(char *raid_device) { 641 642 /** int *************************************************************/ 643 int res; 644 int retval = 0; 645 646 /** buffers *********************************************************/ 647 char *program = NULL; 648 649 /** end *************************************************************/ 650 651 assert_string_is_neither_NULL_nor_zerolength(raid_device); 652 653 #ifdef __FreeBSD__ 654 if (is_this_device_mounted(raid_device)) { 655 log_it("Can't stop %s when it's mounted!", raid_device); 656 return 1; 657 } 658 mr_asprintf(program, "vinum stop -f %s", raid_device); 659 #else 660 // use raidstop if it exists, otherwise use mdadm 661 if (run_program_and_log_output("which raidstop", FALSE)) { 662 mr_asprintf(program, "mdadm -S %s", raid_device); 663 } else { 664 mr_asprintf(program, "raidstop %s", raid_device); 665 } 666 #endif 667 log_msg(1, "program = %s", program); 668 res = run_program_and_log_output(program, 1); 669 if (g_fprep) { 670 fprintf(g_fprep, "%s\n", program); 671 } 672 mr_free(program); 673 674 if (res) { 675 log_msg(1, "Warning - failed to stop RAID device %s", raid_device); 676 } 677 retval += res; 678 return (retval); 679 } 680 681 682 683 int start_raid_device(char *raid_device) { 684 685 /** int *************************************************************/ 686 int res; 687 int retval = 0; 688 689 /** buffers *********************************************************/ 690 char *program = NULL; 691 692 /** end *************************************************************/ 693 694 assert_string_is_neither_NULL_nor_zerolength(raid_device); 695 696 #ifdef __FreeBSD__ 697 if (is_this_device_mounted(raid_device)) { 698 log_it("Can't start %s when it's mounted!", raid_device); 699 return 1; 700 } 701 mr_asprintf(program, "vinum start -f %s", raid_device); 702 #else 703 mr_asprintf(program, "raidstart %s", raid_device); 704 #endif 705 log_msg(1, "program = %s", program); 706 res = run_program_and_log_output(program, 1); 707 if (g_fprep) { 708 fprintf(g_fprep, "%s\n", program); 709 } 710 mr_free(program); 711 712 if (res) { 713 log_msg(1, "Warning - failed to start RAID device %s", raid_device); 714 } 715 retval += res; 716 sleep(1); 717 return (retval); 718 } 719 720 721 /** 722 * Decide which command we need to use to format a device of type @p format. 723 * @param format The filesystem type we are about to format. 724 * @param program Where to put the binary name for this format. 725 * @return 0 for success, nonzero for failure. 726 */ 727 char *which_format_command_do_i_need(char *format) { 728 729 char *program = NULL; 730 731 assert_string_is_neither_NULL_nor_zerolength(format); 732 733 if (strcmp(format, "swap") == 0) { 734 #ifdef __FreeBSD__ 735 mr_asprintf(program, "true"); 736 #else 737 mr_asprintf(program, "mkswap -f"); 738 #endif 739 } else if (strcmp(format, "vfat") == 0) { 740 #ifdef __FreeBSD__ 741 mr_asprintf(program, "newfs_msdos -F 32"); 742 #else 743 #ifdef __IA64__ 744 /* For EFI partitions on ia64 take fat16 745 * as we want to make small ones */ 746 mr_asprintf(program, "mkfs.vfat -F 16"); 747 #else 748 /* mkfs.vfat will make the best possible choice itself */ 749 /* should avoid problems with mr-label later on when used */ 750 mr_asprintf(program, "mkfs.vfat"); 751 #endif 752 #endif 753 #ifndef __FreeBSD__ 754 } else if (strcmp(format, "reiserfs") == 0) { 755 mr_asprintf(program, "mkreiserfs -ff"); 756 } else if (strcmp(format, "xfs") == 0) { 757 /* Cf: https://bugzilla.redhat.com/show_bug.cgi?id=1309498 */ 758 mr_asprintf(program, "mkfs.xfs -f -q -m crc=0 -n ftype=0"); 759 } else if (strcmp(format, "jfs") == 0) { 760 mr_asprintf(program, "mkfs.jfs"); 761 } else if (strcmp(format, "ext3") == 0) { 762 mr_asprintf(program, "mkfs -t ext3 -F -q"); 763 } else if (strcmp(format, "ext4") == 0) { 764 mr_asprintf(program, "mkfs -t ext4 -F -q"); 765 } else if (strcmp(format, "btrfs") == 0) { 766 mr_asprintf(program, "mkfs.btrfs -f"); 767 } else if (strcmp(format, "minix") == 0) { 768 mr_asprintf(program, "mkfs.minix"); 769 } else if (strcmp(format, "vmfs") == 0) { 770 mr_asprintf(program, "mkfs -t vmfs"); 771 } else if (strcmp(format, "ntfs") == 0) { 772 /* 773 * mkfs.ntfs treats the '-c' switch as 'specify cluster size' 774 * so the default "mkfs -t %s -c" command structure fails 775 */ 776 mr_asprintf(program, "mkfs -t ntfs"); 777 } else if (strcmp(format, "ocfs2") == 0) { 778 /* 779 * For existing OCFS2 volumes, mkfs.ocfs2 ensures the volume is not mounted on any node in the cluster before formatting. For that to work, mkfs.ocfs2 expects the O2CB cluster service to be running. Specify this option to disable this check. 780 * 781 */ 782 mr_asprintf(program, "mkfs -t ocfs2 -F"); 783 #endif 784 } else if (strcmp(format, "ext2") == 0) { 785 mr_asprintf(program, "mke2fs -F -q"); 786 } else { 787 #ifdef __FreeBSD__ 788 mr_asprintf(program, "newfs_%s", format); 789 #else 790 mr_asprintf(program, "mkfs -t %s -c", format); // -c checks for bad blocks 791 #endif 792 log_it("Unknown format (%s) - assuming '%s' will do", format, program); 793 } 794 return(program); 795 } 796 797 798 630 799 /** 631 800 * Format @p device as a @p format filesystem. … … 821 990 return (retval); 822 991 } 992 993 994 /** 995 * Stop all software RAID devices listed in @p mountlist. 996 * @param mountlist The mountlist to stop the RAID devices in. 997 * @return The number of errors encountered (0 for success). 998 * @bug @p mountlist is not used. 999 */ 1000 int stop_all_raid_devices(struct mountlist_itself *mountlist) { 1001 1002 /** int *************************************************************/ 1003 int retval = 0; 1004 1005 /** char ************************************************************/ 1006 char *incoming; 1007 #ifndef __FreeBSD__ 1008 char *dev; 1009 #endif 1010 /** pointers ********************************************************/ 1011 #ifndef __FreeBSD__ 1012 char *p; 1013 #endif 1014 FILE *fin; 1015 char *q; 1016 int i; 1017 1018 /** end ****************************************************************/ 1019 1020 malloc_string(incoming); 1021 assert(mountlist != NULL); 1022 1023 for (i = 0; i < 3; i++) { 1024 #ifdef __FreeBSD__ 1025 fin = popen("vinum list | grep '^[PVS]' | sed 's/S/1/;s/P/2/;s/V/3/' | sort | cut -d' ' -f2", "r"); 1026 if (!fin) { 1027 paranoid_free(incoming); 1028 return (1); 1029 } 1030 for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL); q = fgets(incoming, MAX_STR_LEN - 1, fin)) { 1031 retval += stop_raid_device(incoming); 1032 } 1033 #else 1034 fin = fopen("/proc/mdstat", "r"); 1035 if (!fin) { 1036 log_OS_error("/proc/mdstat"); 1037 paranoid_free(incoming); 1038 return (1); 1039 } 1040 for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL); q = fgets(incoming, MAX_STR_LEN - 1, fin)) { 1041 for (p = incoming; *p != '\0' && (*p != 'm' || *(p + 1) != 'd' || !isdigit(*(p + 2))); p++); 1042 if (*p != '\0') { 1043 malloc_string(dev); 1044 sprintf(dev, "/dev/%s", p); 1045 for (p = dev; *p > 32; p++); 1046 *p = '\0'; 1047 retval += stop_raid_device(dev); 1048 paranoid_free(dev); 1049 } 1050 } 1051 #endif 1052 } 1053 paranoid_fclose(fin); 1054 if (retval) { 1055 log_msg(1, "Warning - unable to stop some RAID devices"); 1056 } 1057 paranoid_free(incoming); 1058 paranoid_system("sync"); 1059 paranoid_system("sync"); 1060 paranoid_system("sync"); 1061 sleep(1); 1062 return (retval); 1063 } 1064 1065 823 1066 824 1067 … … 984 1227 paranoid_system("clear"); 985 1228 newtResume(); 1229 return (retval); 1230 } 1231 1232 1233 /** 1234 * Set the type of partition number @p partno on @p drive to @p format. 1235 * @param drive The drive to change the type of a partition on. 1236 * @param partno The partition number on @p drive to change the type of. 1237 * @param format The filesystem type this partition will eventually contain. 1238 * @param partsize The size of this partition, in @e bytes (used for vfat 1239 * type calculations). 1240 * @return 0 for success, nonzero for failure. 1241 */ 1242 int set_partition_type(FILE * pout_to_fdisk, const char *drive, int partno, const char *format, long long partsize) { 1243 1244 /** buffers *********************************************************/ 1245 char *partition = NULL; 1246 char *command = NULL; 1247 char *output = NULL; 1248 char *tmp = NULL; 1249 char *partcode = NULL; 1250 1251 /** pointers *********************************************************/ 1252 FILE *fout; 1253 1254 /** int **************************************************************/ 1255 int res = 0; 1256 1257 /** end **************************************************************/ 1258 1259 assert_string_is_neither_NULL_nor_zerolength(drive); 1260 assert(format != NULL); 1261 1262 partition = build_partition_name(drive, partno); 1263 if (strcmp(format, "swap") == 0) { 1264 mr_asprintf(partcode, "82"); 1265 } else if (strcmp(format, "vfat") == 0) { 1266 if (partsize / 1024 > 8192) { 1267 mr_asprintf(partcode, "c"); 1268 } else { 1269 mr_asprintf(partcode, "b"); 1270 } 1271 } else if (strcmp(format, "ext2") == 0 1272 || strcmp(format, "reiserfs") == 0 1273 || strcmp(format, "ext3") == 0 1274 || strcmp(format, "ext4") == 0 1275 || strcmp(format, "xfs") == 0 1276 || strcmp(format, "jfs") == 0 1277 || strcmp(format, "btrfs") == 0) { 1278 mr_asprintf(partcode, "83"); 1279 } else if (strcmp(format, "minix") == 0) { 1280 mr_asprintf(partcode, "81"); 1281 } else if (strcmp(format, "vmfs3") == 0) { 1282 mr_asprintf(partcode, "fb"); 1283 } else if (strcmp(format, "vmkcore") == 0) { 1284 mr_asprintf(partcode, "fc"); 1285 } else if (strcmp(format, "raid") == 0) { 1286 mr_asprintf(partcode, "fd"); 1287 } else if (strcmp(format, "ntfs") == 0) { 1288 mr_asprintf(partcode, "7"); 1289 } else if ((strcmp(format, "ufs") == 0) 1290 || (strcmp(format, "ffs") == 0)) { /* raid autodetect */ 1291 mr_asprintf(partcode, "a5"); 1292 } else if (strcmp(format, "lvm") == 0) { 1293 mr_asprintf(partcode, "8e"); 1294 } else if (format[0] == '\0') { /* LVM physical partition */ 1295 mr_asprintf(partcode, ""); 1296 } else if (strlen(format) >= 1 && strlen(format) <= 2) { 1297 mr_asprintf(partcode, "%s", format); 1298 } else { 1299 /* probably an image */ 1300 mr_asprintf(tmp, "Unknown format ('%s') - using supplied string anyway", format); 1301 mvaddstr_and_log_it(g_currentY++, 0, tmp); 1302 mr_free(tmp); 1303 1304 #ifdef __FreeBSD__ 1305 mr_asprintf(partcode, "%s", format); // was a5 1306 #else 1307 mr_asprintf(partcode, "%s", format); // was 83 1308 #endif 1309 } 1310 log_msg(1, "Setting %s's type to %s (%s)", partition, format, partcode); 1311 mr_free(partition); 1312 1313 if ((strcmp(partcode,"") != 0) && strcmp(partcode, "83")) { /* no need to set type if 83: 83 is default */ 1314 1315 if (pout_to_fdisk) { 1316 res = 0; 1317 fput_string_one_char_at_a_time(pout_to_fdisk, "t\n"); 1318 if (partno > 1 1319 || strstr(last_line_of_file(FDISK_LOG), " (1-4)")) { 1320 log_msg(5, "Specifying partno (%d) - yay", partno); 1321 mr_asprintf(tmp, "%d\n", partno); 1322 fput_string_one_char_at_a_time(pout_to_fdisk, tmp); 1323 log_msg(5, "A - last line = '%s'", last_line_of_file(FDISK_LOG)); 1324 mr_free(tmp); 1325 } 1326 1327 mr_asprintf(tmp, "%s\n", partcode); 1328 fput_string_one_char_at_a_time(pout_to_fdisk, tmp); 1329 mr_free(tmp); 1330 1331 log_msg(5, "B - last line = '%s'", 1332 last_line_of_file(FDISK_LOG)); 1333 fput_string_one_char_at_a_time(pout_to_fdisk, "\n"); 1334 log_msg(5, "C - last line = '%s'", 1335 last_line_of_file(FDISK_LOG)); 1336 1337 mr_asprintf(tmp, "%s", last_line_of_file(FDISK_LOG)); 1338 if (!strstr(tmp, " (m ")) { 1339 log_msg(1, "last line = '%s'; part type set failed", tmp); 1340 res++; 1341 fput_string_one_char_at_a_time(pout_to_fdisk, "\n"); 1342 } 1343 mr_free(tmp); 1344 1345 fput_string_one_char_at_a_time(pout_to_fdisk, "p\n"); 1346 } else { 1347 mr_asprintf(output, "t\n%d\n%s\nw\n", partno, partcode); 1348 mr_asprintf(command, "mr-parted2fdisk %s >> %s 2>> %s", drive, MONDO_LOGFILE, MONDO_LOGFILE); 1349 log_msg(5, "output = '%s'", output); 1350 log_msg(5, "partno=%d; partcode=%s", partno, partcode); 1351 log_msg(5, "command = '%s'", command); 1352 fout = popen(command, "w"); 1353 if (!fout) { 1354 log_OS_error(command); 1355 res = 1; 1356 } else { 1357 res = 0; 1358 fprintf(fout, "%s", output); 1359 paranoid_pclose(fout); 1360 } 1361 mr_free(command); 1362 paranoid_free(output); 1363 } 1364 } 1365 mr_free(partcode); 1366 1367 return (res); 1368 } 1369 1370 1371 /** 1372 * Create partition number @p partno on @p drive with @p fdisk. 1373 * @param drive The drive to create the partition on. 1374 // * @param partno The partition number of the new partition (1-4 are primary, >=5 is logical). 1375 * @param prev_partno The partition number of the most recently prepped partition. 1376 * @param format The filesystem type of this partition (used to set the type). 1377 * @param partsize The size of the partition in @e bytes. 1378 * @return 0 for success, nonzero for failure. 1379 */ 1380 int partition_device(FILE * pout_to_fdisk, const char *drive, int partno, int prev_partno, const char *format, long long partsize) { 1381 1382 /** int **************************************************************/ 1383 int retval = 0; 1384 int res = 0; 1385 1386 /** buffers **********************************************************/ 1387 char *program = NULL; 1388 char *partition_name = NULL; 1389 char *tmp = NULL; 1390 char *output = NULL; 1391 1392 /** pointers **********************************************************/ 1393 char *part_table_fmt = NULL; 1394 FILE *fout; 1395 1396 /** end ***************************************************************/ 1397 1398 assert_string_is_neither_NULL_nor_zerolength(drive); 1399 assert(format != NULL); 1400 1401 log_it("partition_device('%s', %d, %d, '%s', %lld) --- starting", drive, partno, prev_partno, format, partsize); 1402 1403 if (!strncmp(drive, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) { 1404 log_it("Not partitioning %s - it is a virtual drive", drive); 1405 return (0); 1406 } 1407 1408 partition_name = build_partition_name(drive, partno); 1409 if (partsize <= 0) { 1410 mr_asprintf(tmp, "Partitioning device %s (max size)", partition_name); 1411 } else { 1412 mr_asprintf(tmp, "Partitioning device %s (%lld MB)", partition_name, (long long) partsize / 1024); 1413 } 1414 update_progress_form(tmp); 1415 log_it(tmp); 1416 mr_free(tmp); 1417 1418 if (is_this_device_mounted(partition_name)) { 1419 log_to_screen("%s is mounted, and should not be partitioned", partition_name); 1420 mr_free(partition_name); 1421 return (1); 1422 } 1423 1424 1425 mr_asprintf(program, "mr-parted2fdisk %s >> %s 2>> %s", drive, MONDO_LOGFILE, MONDO_LOGFILE); 1426 1427 /* TODO: should not be called each time */ 1428 part_table_fmt = which_partition_format(drive); 1429 mr_asprintf(output, ""); 1430 1431 /* make it a primary/extended/logical */ 1432 if (partno <= 4) { 1433 mr_strcat(output, "n\np\n%d\n", partno); 1434 } else { 1435 /* MBR needs an extended partition if more than 4 partitions */ 1436 if (strcmp(part_table_fmt, "MBR") == 0) { 1437 if (partno == 5) { 1438 if (prev_partno >= 4) { 1439 log_to_screen("You need to leave at least one partition free, for 'extended/logical'"); 1440 mr_free(partition_name); 1441 paranoid_free(output); 1442 return (1); 1443 } else { 1444 mr_strcat(output, "n\ne\n%d\n\n\n", prev_partno + 1); 1445 } 1446 } 1447 mr_strcat(output, "n\nl\n"); 1448 } else { 1449 /* GPT allows more than 4 primary partitions */ 1450 mr_strcat(output, "n\np\n%d\n", partno); 1451 } 1452 } 1453 mr_free(part_table_fmt); 1454 1455 mr_strcat(output, "\n"); /*start block (ENTER for next free blk */ 1456 if (partsize > 0) { 1457 if (!strcmp(format, "7")) { 1458 log_msg(1, "Adding 512K, just in case"); 1459 partsize += 512; 1460 } 1461 mr_strcat(output, "+%lldK", (long long) (partsize)); 1462 } 1463 mr_strcat(output, "\n"); 1464 #if 0 1465 /* 1466 #endif 1467 log_it("PARTSIZE = +%ld",(long)partsize); 1468 log_it("---fdisk command---"); 1469 log_it(output); 1470 log_it("---end of fdisk---"); 1471 #if 0 1472 */ 1473 #endif 1474 1475 1476 if (pout_to_fdisk) { 1477 log_msg(1, "Doing the new all-in-one fdisk thing"); 1478 mr_strcat(output, "\n\np\n\n"); 1479 log_msg(1, "output = '%s'", output); 1480 fput_string_one_char_at_a_time(pout_to_fdisk, output); 1481 mr_asprintf(tmp, "%s", last_line_of_file(FDISK_LOG)); 1482 if (strstr(tmp, " (m ")) { 1483 log_msg(1, "Successfully created partition %d on %s", partno, drive); 1484 } else { 1485 log_msg(1, "last line = %s", tmp); 1486 log_msg(1, "Failed to create partition %d on %s; sending 'Enter'...", partno, drive); 1487 } 1488 mr_free(tmp); 1489 1490 if (!retval) { 1491 log_msg(1, "Trying to set partition %d type now on %s", partno, drive); 1492 retval = set_partition_type(pout_to_fdisk, drive, partno, format, partsize); 1493 if (retval) { 1494 log_msg(1, "Failed. Trying again..."); 1495 retval = set_partition_type(pout_to_fdisk, drive, partno, format, partsize); 1496 } 1497 } 1498 if (retval) { 1499 log_msg(1, "...but failed to set type"); 1500 } 1501 } else { 1502 mr_strcat(output, "w\n\n"); 1503 if (g_fprep) { 1504 fprintf(g_fprep, "echo \"%s\" | %s\n", output, program); 1505 } 1506 /* write to disk; close fdisk's stream */ 1507 if (!(fout = popen(program, "w"))) { 1508 log_OS_error("can't popen-out to program"); 1509 } else { 1510 fputs(output, fout); 1511 paranoid_pclose(fout); 1512 } 1513 1514 if (!does_partition_exist(drive, partno) && partsize > 0) { 1515 log_it("Vaccum-packing"); 1516 g_current_progress--; 1517 res = partition_device(pout_to_fdisk, drive, partno, prev_partno, format, -1); 1518 if (res) { 1519 log_it("Failed to vacuum-pack %s", partition_name); 1520 retval++; 1521 } else { 1522 retval = 0; 1523 } 1524 } 1525 if (does_partition_exist(drive, partno)) { 1526 retval = set_partition_type(pout_to_fdisk, drive, partno, format, partsize); 1527 if (retval) { 1528 log_it("Partitioned %s but failed to set its type", partition_name); 1529 } else { 1530 if (partsize > 0) { 1531 log_to_screen("Partition %s created+configured OK", partition_name); 1532 } else { 1533 log_it("Returning from a successful vacuum-pack"); 1534 } 1535 } 1536 } else { 1537 mr_asprintf(tmp, "Failed to partition %s", partition_name); 1538 if (partsize > 0) { 1539 log_to_screen(tmp); 1540 } else { 1541 log_it(tmp); 1542 } 1543 mr_free(tmp); 1544 retval++; 1545 } 1546 } 1547 mr_free(program); 1548 mr_free(output); 1549 mr_free(partition_name); 1550 1551 g_current_progress++; 1552 log_it("partition_device() --- leaving"); 986 1553 return (retval); 987 1554 } … … 1532 2099 } 1533 2100 1534 /**1535 * Create partition number @p partno on @p drive with @p fdisk.1536 * @param drive The drive to create the partition on.1537 // * @param partno The partition number of the new partition (1-4 are primary, >=5 is logical).1538 * @param prev_partno The partition number of the most recently prepped partition.1539 * @param format The filesystem type of this partition (used to set the type).1540 * @param partsize The size of the partition in @e bytes.1541 * @return 0 for success, nonzero for failure.1542 */1543 int partition_device(FILE * pout_to_fdisk, const char *drive, int partno, int prev_partno, const char *format, long long partsize) {1544 1545 /** int **************************************************************/1546 int retval = 0;1547 int res = 0;1548 1549 /** buffers **********************************************************/1550 char *program = NULL;1551 char *partition_name = NULL;1552 char *tmp = NULL;1553 char *output = NULL;1554 1555 /** pointers **********************************************************/1556 char *part_table_fmt = NULL;1557 FILE *fout;1558 1559 /** end ***************************************************************/1560 1561 assert_string_is_neither_NULL_nor_zerolength(drive);1562 assert(format != NULL);1563 1564 log_it("partition_device('%s', %d, %d, '%s', %lld) --- starting", drive, partno, prev_partno, format, partsize);1565 1566 if (!strncmp(drive, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) {1567 log_it("Not partitioning %s - it is a virtual drive", drive);1568 return (0);1569 }1570 1571 partition_name = build_partition_name(drive, partno);1572 if (partsize <= 0) {1573 mr_asprintf(tmp, "Partitioning device %s (max size)", partition_name);1574 } else {1575 mr_asprintf(tmp, "Partitioning device %s (%lld MB)", partition_name, (long long) partsize / 1024);1576 }1577 update_progress_form(tmp);1578 log_it(tmp);1579 mr_free(tmp);1580 1581 if (is_this_device_mounted(partition_name)) {1582 log_to_screen("%s is mounted, and should not be partitioned", partition_name);1583 mr_free(partition_name);1584 return (1);1585 }1586 1587 1588 mr_asprintf(program, "mr-parted2fdisk %s >> %s 2>> %s", drive, MONDO_LOGFILE, MONDO_LOGFILE);1589 1590 /* TODO: should not be called each time */1591 part_table_fmt = which_partition_format(drive);1592 mr_asprintf(output, "");1593 1594 /* make it a primary/extended/logical */1595 if (partno <= 4) {1596 mr_strcat(output, "n\np\n%d\n", partno);1597 } else {1598 /* MBR needs an extended partition if more than 4 partitions */1599 if (strcmp(part_table_fmt, "MBR") == 0) {1600 if (partno == 5) {1601 if (prev_partno >= 4) {1602 log_to_screen("You need to leave at least one partition free, for 'extended/logical'");1603 mr_free(partition_name);1604 paranoid_free(output);1605 return (1);1606 } else {1607 mr_strcat(output, "n\ne\n%d\n\n\n", prev_partno + 1);1608 }1609 }1610 mr_strcat(output, "n\nl\n");1611 } else {1612 /* GPT allows more than 4 primary partitions */1613 mr_strcat(output, "n\np\n%d\n", partno);1614 }1615 }1616 mr_free(part_table_fmt);1617 1618 mr_strcat(output, "\n"); /*start block (ENTER for next free blk */1619 if (partsize > 0) {1620 if (!strcmp(format, "7")) {1621 log_msg(1, "Adding 512K, just in case");1622 partsize += 512;1623 }1624 mr_strcat(output, "+%lldK", (long long) (partsize));1625 }1626 mr_strcat(output, "\n");1627 #if 01628 /*1629 #endif1630 log_it("PARTSIZE = +%ld",(long)partsize);1631 log_it("---fdisk command---");1632 log_it(output);1633 log_it("---end of fdisk---");1634 #if 01635 */1636 #endif1637 1638 1639 if (pout_to_fdisk) {1640 log_msg(1, "Doing the new all-in-one fdisk thing");1641 mr_strcat(output, "\n\np\n\n");1642 log_msg(1, "output = '%s'", output);1643 fput_string_one_char_at_a_time(pout_to_fdisk, output);1644 mr_asprintf(tmp, "%s", last_line_of_file(FDISK_LOG));1645 if (strstr(tmp, " (m ")) {1646 log_msg(1, "Successfully created partition %d on %s", partno, drive);1647 } else {1648 log_msg(1, "last line = %s", tmp);1649 log_msg(1, "Failed to create partition %d on %s; sending 'Enter'...", partno, drive);1650 }1651 mr_free(tmp);1652 1653 if (!retval) {1654 log_msg(1, "Trying to set partition %d type now on %s", partno, drive);1655 retval = set_partition_type(pout_to_fdisk, drive, partno, format, partsize);1656 if (retval) {1657 log_msg(1, "Failed. Trying again...");1658 retval = set_partition_type(pout_to_fdisk, drive, partno, format, partsize);1659 }1660 }1661 if (retval) {1662 log_msg(1, "...but failed to set type");1663 }1664 } else {1665 mr_strcat(output, "w\n\n");1666 if (g_fprep) {1667 fprintf(g_fprep, "echo \"%s\" | %s\n", output, program);1668 }1669 /* write to disk; close fdisk's stream */1670 if (!(fout = popen(program, "w"))) {1671 log_OS_error("can't popen-out to program");1672 } else {1673 fputs(output, fout);1674 paranoid_pclose(fout);1675 }1676 1677 if (!does_partition_exist(drive, partno) && partsize > 0) {1678 log_it("Vaccum-packing");1679 g_current_progress--;1680 res = partition_device(pout_to_fdisk, drive, partno, prev_partno, format, -1);1681 if (res) {1682 log_it("Failed to vacuum-pack %s", partition_name);1683 retval++;1684 } else {1685 retval = 0;1686 }1687 }1688 if (does_partition_exist(drive, partno)) {1689 retval = set_partition_type(pout_to_fdisk, drive, partno, format, partsize);1690 if (retval) {1691 log_it("Partitioned %s but failed to set its type", partition_name);1692 } else {1693 if (partsize > 0) {1694 log_to_screen("Partition %s created+configured OK", partition_name);1695 } else {1696 log_it("Returning from a successful vacuum-pack");1697 }1698 }1699 } else {1700 mr_asprintf(tmp, "Failed to partition %s", partition_name);1701 if (partsize > 0) {1702 log_to_screen(tmp);1703 } else {1704 log_it(tmp);1705 }1706 mr_free(tmp);1707 retval++;1708 }1709 }1710 mr_free(program);1711 mr_free(output);1712 mr_free(partition_name);1713 1714 g_current_progress++;1715 log_it("partition_device() --- leaving");1716 return (retval);1717 }1718 1719 1720 2101 1721 2102 /** … … 1789 2170 1790 2171 1791 1792 2172 /** 1793 * Set the type of partition number @p partno on @p drive to @p format. 1794 * @param drive The drive to change the type of a partition on. 1795 * @param partno The partition number on @p drive to change the type of. 1796 * @param format The filesystem type this partition will eventually contain. 1797 * @param partsize The size of this partition, in @e bytes (used for vfat 1798 * type calculations). 1799 * @return 0 for success, nonzero for failure. 2173 * Create a mountlist_reference structure for @p drive_name in @p mountlist. 2174 * @param mountlist The complete mountlist to get the drive references from. 2175 * @param drive_name The drive to put in @p drivemntlist. 2176 * @param drivemntlist The mountlist_reference structure to put the drive's entries in. 2177 * @note @p drivemntlist and @p drivemntlist->el must be allocated by the caller. 2178 * @author Ralph Grewe 1800 2179 */ 1801 int set_partition_type(FILE * pout_to_fdisk, const char *drive, int partno, const char *format, long long partsize) { 1802 1803 /** buffers *********************************************************/ 1804 char *partition = NULL; 1805 char *command = NULL; 1806 char *output = NULL; 1807 char *tmp = NULL; 1808 char *partcode = NULL; 1809 1810 /** pointers *********************************************************/ 1811 FILE *fout; 1812 1813 /** int **************************************************************/ 1814 int res = 0; 1815 1816 /** end **************************************************************/ 1817 1818 assert_string_is_neither_NULL_nor_zerolength(drive); 1819 assert(format != NULL); 1820 1821 partition = build_partition_name(drive, partno); 1822 if (strcmp(format, "swap") == 0) { 1823 mr_asprintf(partcode, "82"); 1824 } else if (strcmp(format, "vfat") == 0) { 1825 if (partsize / 1024 > 8192) { 1826 mr_asprintf(partcode, "c"); 1827 } else { 1828 mr_asprintf(partcode, "b"); 1829 } 1830 } else if (strcmp(format, "ext2") == 0 1831 || strcmp(format, "reiserfs") == 0 1832 || strcmp(format, "ext3") == 0 1833 || strcmp(format, "ext4") == 0 1834 || strcmp(format, "xfs") == 0 1835 || strcmp(format, "jfs") == 0 1836 || strcmp(format, "btrfs") == 0) { 1837 mr_asprintf(partcode, "83"); 1838 } else if (strcmp(format, "minix") == 0) { 1839 mr_asprintf(partcode, "81"); 1840 } else if (strcmp(format, "vmfs3") == 0) { 1841 mr_asprintf(partcode, "fb"); 1842 } else if (strcmp(format, "vmkcore") == 0) { 1843 mr_asprintf(partcode, "fc"); 1844 } else if (strcmp(format, "raid") == 0) { 1845 mr_asprintf(partcode, "fd"); 1846 } else if (strcmp(format, "ntfs") == 0) { 1847 mr_asprintf(partcode, "7"); 1848 } else if ((strcmp(format, "ufs") == 0) 1849 || (strcmp(format, "ffs") == 0)) { /* raid autodetect */ 1850 mr_asprintf(partcode, "a5"); 1851 } else if (strcmp(format, "lvm") == 0) { 1852 mr_asprintf(partcode, "8e"); 1853 } else if (format[0] == '\0') { /* LVM physical partition */ 1854 mr_asprintf(partcode, ""); 1855 } else if (strlen(format) >= 1 && strlen(format) <= 2) { 1856 mr_asprintf(partcode, "%s", format); 1857 } else { 1858 /* probably an image */ 1859 mr_asprintf(tmp, "Unknown format ('%s') - using supplied string anyway", format); 1860 mvaddstr_and_log_it(g_currentY++, 0, tmp); 1861 mr_free(tmp); 1862 1863 #ifdef __FreeBSD__ 1864 mr_asprintf(partcode, "%s", format); // was a5 1865 #else 1866 mr_asprintf(partcode, "%s", format); // was 83 1867 #endif 1868 } 1869 log_msg(1, "Setting %s's type to %s (%s)", partition, format, partcode); 1870 mr_free(partition); 1871 1872 if ((strcmp(partcode,"") != 0) && strcmp(partcode, "83")) { /* no need to set type if 83: 83 is default */ 1873 1874 if (pout_to_fdisk) { 1875 res = 0; 1876 fput_string_one_char_at_a_time(pout_to_fdisk, "t\n"); 1877 if (partno > 1 1878 || strstr(last_line_of_file(FDISK_LOG), " (1-4)")) { 1879 log_msg(5, "Specifying partno (%d) - yay", partno); 1880 mr_asprintf(tmp, "%d\n", partno); 1881 fput_string_one_char_at_a_time(pout_to_fdisk, tmp); 1882 log_msg(5, "A - last line = '%s'", last_line_of_file(FDISK_LOG)); 1883 mr_free(tmp); 1884 } 1885 1886 mr_asprintf(tmp, "%s\n", partcode); 1887 fput_string_one_char_at_a_time(pout_to_fdisk, tmp); 1888 mr_free(tmp); 1889 1890 log_msg(5, "B - last line = '%s'", 1891 last_line_of_file(FDISK_LOG)); 1892 fput_string_one_char_at_a_time(pout_to_fdisk, "\n"); 1893 log_msg(5, "C - last line = '%s'", 1894 last_line_of_file(FDISK_LOG)); 1895 1896 mr_asprintf(tmp, "%s", last_line_of_file(FDISK_LOG)); 1897 if (!strstr(tmp, " (m ")) { 1898 log_msg(1, "last line = '%s'; part type set failed", tmp); 1899 res++; 1900 fput_string_one_char_at_a_time(pout_to_fdisk, "\n"); 1901 } 1902 mr_free(tmp); 1903 1904 fput_string_one_char_at_a_time(pout_to_fdisk, "p\n"); 1905 } else { 1906 mr_asprintf(output, "t\n%d\n%s\nw\n", partno, partcode); 1907 mr_asprintf(command, "mr-parted2fdisk %s >> %s 2>> %s", drive, MONDO_LOGFILE, MONDO_LOGFILE); 1908 log_msg(5, "output = '%s'", output); 1909 log_msg(5, "partno=%d; partcode=%s", partno, partcode); 1910 log_msg(5, "command = '%s'", command); 1911 fout = popen(command, "w"); 1912 if (!fout) { 1913 log_OS_error(command); 1914 res = 1; 1915 } else { 1916 res = 0; 1917 fprintf(fout, "%s", output); 1918 paranoid_pclose(fout); 1919 } 1920 mr_free(command); 1921 paranoid_free(output); 1922 } 1923 } 1924 mr_free(partcode); 1925 1926 return (res); 1927 } 1928 1929 1930 int start_raid_device(char *raid_device) { 1931 1932 /** int *************************************************************/ 1933 int res; 1934 int retval = 0; 1935 1936 /** buffers *********************************************************/ 1937 char *program = NULL; 1938 1939 /** end *************************************************************/ 1940 1941 assert_string_is_neither_NULL_nor_zerolength(raid_device); 1942 1943 #ifdef __FreeBSD__ 1944 if (is_this_device_mounted(raid_device)) { 1945 log_it("Can't start %s when it's mounted!", raid_device); 1946 return 1; 1947 } 1948 mr_asprintf(program, "vinum start -f %s", raid_device); 1949 #else 1950 mr_asprintf(program, "raidstart %s", raid_device); 1951 #endif 1952 log_msg(1, "program = %s", program); 1953 res = run_program_and_log_output(program, 1); 1954 if (g_fprep) { 1955 fprintf(g_fprep, "%s\n", program); 1956 } 1957 mr_free(program); 1958 1959 if (res) { 1960 log_msg(1, "Warning - failed to start RAID device %s", raid_device); 1961 } 1962 retval += res; 1963 sleep(1); 1964 return (retval); 1965 } 1966 1967 1968 1969 /** 1970 * Stop @p raid_device using @p raidstop. 1971 * @param raid_device The software RAID device to stop. 1972 * @return 0 for success, nonzero for failure. 1973 */ 1974 int stop_raid_device(char *raid_device) { 1975 1976 /** int *************************************************************/ 1977 int res; 1978 int retval = 0; 1979 1980 /** buffers *********************************************************/ 1981 char *program = NULL; 1982 1983 /** end *************************************************************/ 1984 1985 assert_string_is_neither_NULL_nor_zerolength(raid_device); 1986 1987 #ifdef __FreeBSD__ 1988 if (is_this_device_mounted(raid_device)) { 1989 log_it("Can't stop %s when it's mounted!", raid_device); 1990 return 1; 1991 } 1992 mr_asprintf(program, "vinum stop -f %s", raid_device); 1993 #else 1994 // use raidstop if it exists, otherwise use mdadm 1995 if (run_program_and_log_output("which raidstop", FALSE)) { 1996 mr_asprintf(program, "mdadm -S %s", raid_device); 1997 } else { 1998 mr_asprintf(program, "raidstop %s", raid_device); 1999 } 2000 #endif 2001 log_msg(1, "program = %s", program); 2002 res = run_program_and_log_output(program, 1); 2003 if (g_fprep) { 2004 fprintf(g_fprep, "%s\n", program); 2005 } 2006 mr_free(program); 2007 2008 if (res) { 2009 log_msg(1, "Warning - failed to stop RAID device %s", raid_device); 2010 } 2011 retval += res; 2012 return (retval); 2013 } 2014 2015 2016 int start_all_raid_devices(struct mountlist_itself *mountlist) { 2017 2018 int i; 2019 int retval = 0; 2020 int res; 2021 2022 for (i = 0; i < mountlist->entries; i++) { 2023 if (!strncmp(mountlist->el[i].device, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) { 2024 log_msg(1, "Starting %s", mountlist->el[i].device); 2025 res = start_raid_device(mountlist->el[i].device); 2026 retval += res; 2027 } 2028 } 2029 if (retval) { 2030 log_msg(1, "Started all s/w raid devices OK"); 2031 } else { 2032 log_msg(1, "Failed to start some/all s/w raid devices"); 2033 } 2034 return (retval); 2035 } 2036 2037 /** 2038 * Stop all software RAID devices listed in @p mountlist. 2039 * @param mountlist The mountlist to stop the RAID devices in. 2040 * @return The number of errors encountered (0 for success). 2041 * @bug @p mountlist is not used. 2042 */ 2043 int stop_all_raid_devices(struct mountlist_itself *mountlist) { 2044 2045 /** int *************************************************************/ 2046 int retval = 0; 2047 2048 /** char ************************************************************/ 2049 char *incoming; 2050 #ifndef __FreeBSD__ 2051 char *dev; 2052 #endif 2053 /** pointers ********************************************************/ 2054 #ifndef __FreeBSD__ 2055 char *p; 2056 #endif 2057 FILE *fin; 2058 char *q; 2059 int i; 2060 2061 /** end ****************************************************************/ 2062 2063 malloc_string(incoming); 2180 void create_mountlist_for_drive(struct mountlist_itself *mountlist, char *drive_name, struct mountlist_reference *drivemntlist) { 2181 2182 int partno; 2183 char *tmp_drive_name, *c; 2184 2064 2185 assert(mountlist != NULL); 2065 2066 for (i = 0; i < 3; i++) { 2067 #ifdef __FreeBSD__ 2068 fin = popen("vinum list | grep '^[PVS]' | sed 's/S/1/;s/P/2/;s/V/3/' | sort | cut -d' ' -f2", "r"); 2069 if (!fin) { 2070 paranoid_free(incoming); 2071 return (1); 2072 } 2073 for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL); q = fgets(incoming, MAX_STR_LEN - 1, fin)) { 2074 retval += stop_raid_device(incoming); 2075 } 2076 #else 2077 fin = fopen("/proc/mdstat", "r"); 2078 if (!fin) { 2079 log_OS_error("/proc/mdstat"); 2080 paranoid_free(incoming); 2081 return (1); 2082 } 2083 for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL); q = fgets(incoming, MAX_STR_LEN - 1, fin)) { 2084 for (p = incoming; *p != '\0' && (*p != 'm' || *(p + 1) != 'd' || !isdigit(*(p + 2))); p++); 2085 if (*p != '\0') { 2086 malloc_string(dev); 2087 sprintf(dev, "/dev/%s", p); 2088 for (p = dev; *p > 32; p++); 2089 *p = '\0'; 2090 retval += stop_raid_device(dev); 2091 paranoid_free(dev); 2092 } 2093 } 2094 #endif 2095 } 2096 paranoid_fclose(fin); 2097 if (retval) { 2098 log_msg(1, "Warning - unable to stop some RAID devices"); 2099 } 2100 paranoid_free(incoming); 2101 paranoid_system("sync"); 2102 paranoid_system("sync"); 2103 paranoid_system("sync"); 2104 sleep(1); 2105 return (retval); 2106 } 2107 2108 2109 2110 /** 2111 * Decide which command we need to use to format a device of type @p format. 2112 * @param format The filesystem type we are about to format. 2113 * @param program Where to put the binary name for this format. 2114 * @return 0 for success, nonzero for failure. 2115 */ 2116 char *which_format_command_do_i_need(char *format) { 2117 2118 char *program = NULL; 2119 2120 assert_string_is_neither_NULL_nor_zerolength(format); 2121 2122 if (strcmp(format, "swap") == 0) { 2123 #ifdef __FreeBSD__ 2124 mr_asprintf(program, "true"); 2125 #else 2126 mr_asprintf(program, "mkswap -f"); 2127 #endif 2128 } else if (strcmp(format, "vfat") == 0) { 2129 #ifdef __FreeBSD__ 2130 mr_asprintf(program, "newfs_msdos -F 32"); 2131 #else 2132 #ifdef __IA64__ 2133 /* For EFI partitions on ia64 take fat16 2134 * as we want to make small ones */ 2135 mr_asprintf(program, "mkfs.vfat -F 16"); 2136 #else 2137 /* mkfs.vfat will make the best possible choice itself */ 2138 /* should avoid problems with mr-label later on when used */ 2139 mr_asprintf(program, "mkfs.vfat"); 2140 #endif 2141 #endif 2142 #ifndef __FreeBSD__ 2143 } else if (strcmp(format, "reiserfs") == 0) { 2144 mr_asprintf(program, "mkreiserfs -ff"); 2145 } else if (strcmp(format, "xfs") == 0) { 2146 /* Cf: https://bugzilla.redhat.com/show_bug.cgi?id=1309498 */ 2147 mr_asprintf(program, "mkfs.xfs -f -q -m crc=0 -n ftype=0"); 2148 } else if (strcmp(format, "jfs") == 0) { 2149 mr_asprintf(program, "mkfs.jfs"); 2150 } else if (strcmp(format, "ext3") == 0) { 2151 mr_asprintf(program, "mkfs -t ext3 -F -q"); 2152 } else if (strcmp(format, "ext4") == 0) { 2153 mr_asprintf(program, "mkfs -t ext4 -F -q"); 2154 } else if (strcmp(format, "btrfs") == 0) { 2155 mr_asprintf(program, "mkfs.btrfs -f"); 2156 } else if (strcmp(format, "minix") == 0) { 2157 mr_asprintf(program, "mkfs.minix"); 2158 } else if (strcmp(format, "vmfs") == 0) { 2159 mr_asprintf(program, "mkfs -t vmfs"); 2160 } else if (strcmp(format, "ntfs") == 0) { 2161 /* 2162 * mkfs.ntfs treats the '-c' switch as 'specify cluster size' 2163 * so the default "mkfs -t %s -c" command structure fails 2164 */ 2165 mr_asprintf(program, "mkfs -t ntfs"); 2166 } else if (strcmp(format, "ocfs2") == 0) { 2167 /* 2168 * For existing OCFS2 volumes, mkfs.ocfs2 ensures the volume is not mounted on any node in the cluster before formatting. For that to work, mkfs.ocfs2 expects the O2CB cluster service to be running. Specify this option to disable this check. 2169 * 2170 */ 2171 mr_asprintf(program, "mkfs -t ocfs2 -F"); 2172 #endif 2173 } else if (strcmp(format, "ext2") == 0) { 2174 mr_asprintf(program, "mke2fs -F -q"); 2175 } else { 2176 #ifdef __FreeBSD__ 2177 mr_asprintf(program, "newfs_%s", format); 2178 #else 2179 mr_asprintf(program, "mkfs -t %s -c", format); // -c checks for bad blocks 2180 #endif 2181 log_it("Unknown format (%s) - assuming '%s' will do", format, program); 2182 } 2183 return(program); 2186 assert(drive_name != NULL); 2187 assert(drivemntlist != NULL); 2188 2189 log_msg(1, "Creating list of partitions for drive %s", drive_name); 2190 2191 tmp_drive_name = strdup(drive_name); 2192 if (!tmp_drive_name) 2193 fatal_error("Out of memory"); 2194 2195 /* devfs devices? */ 2196 c = strrchr(tmp_drive_name, '/'); 2197 if (c && strncmp(c, "/disc", 5) == 0) { 2198 /* yup its devfs, change the "disc" to "part" so the existing code works */ 2199 strcpy(c + 1, "part"); 2200 } 2201 drivemntlist->entries = 0; 2202 for (partno = 0; partno < mountlist->entries; partno++) { 2203 if (strncmp(mountlist->el[partno].device, tmp_drive_name, strlen(tmp_drive_name)) == 0) { 2204 drivemntlist->el[drivemntlist->entries] = &mountlist->el[partno]; 2205 drivemntlist->entries++; 2206 } 2207 } 2208 if (tmp_drive_name) 2209 free(tmp_drive_name); 2184 2210 } 2185 2211 … … 2331 2357 paranoid_free(drivelist); 2332 2358 } 2333 2334 /**2335 * Create a mountlist_reference structure for @p drive_name in @p mountlist.2336 * @param mountlist The complete mountlist to get the drive references from.2337 * @param drive_name The drive to put in @p drivemntlist.2338 * @param drivemntlist The mountlist_reference structure to put the drive's entries in.2339 * @note @p drivemntlist and @p drivemntlist->el must be allocated by the caller.2340 * @author Ralph Grewe2341 */2342 void create_mountlist_for_drive(struct mountlist_itself *mountlist, char *drive_name, struct mountlist_reference *drivemntlist) {2343 2344 int partno;2345 char *tmp_drive_name, *c;2346 2347 assert(mountlist != NULL);2348 assert(drive_name != NULL);2349 assert(drivemntlist != NULL);2350 2351 log_msg(1, "Creating list of partitions for drive %s", drive_name);2352 2353 tmp_drive_name = strdup(drive_name);2354 if (!tmp_drive_name)2355 fatal_error("Out of memory");2356 2357 /* devfs devices? */2358 c = strrchr(tmp_drive_name, '/');2359 if (c && strncmp(c, "/disc", 5) == 0) {2360 /* yup its devfs, change the "disc" to "part" so the existing code works */2361 strcpy(c + 1, "part");2362 }2363 drivemntlist->entries = 0;2364 for (partno = 0; partno < mountlist->entries; partno++) {2365 if (strncmp(mountlist->el[partno].device, tmp_drive_name, strlen(tmp_drive_name)) == 0) {2366 drivemntlist->el[drivemntlist->entries] = &mountlist->el[partno];2367 drivemntlist->entries++;2368 }2369 }2370 if (tmp_drive_name)2371 free(tmp_drive_name);2372 }2373 2374 2359 /* @} - end of prepGroup */ -
branches/3.3/mondo/src/mondorestore/mondo-rstr-compare.c
r3875 r3879 7 7 #include "mr_mem.h" 8 8 #include "mr_file.h" 9 #include "../common/mondostructures.h" 10 #include "../common/libmondo.h" 11 //#include "../../config.h" 12 #include "mr-externs.h" 13 #include "mondo-rstr-compare.h" 14 #include "mondorestore-EXT.h" 9 #include "mr_sys.h" 10 #include "mondostructures.h" 15 11 #include "mondo-rstr-tools-EXT.h" 12 #include "libmondo-string-EXT.h" 13 #include "libmondo-verify-EXT.h" 14 #include "libmondo-files-EXT.h" 15 #include "libmondo-tools-EXT.h" 16 #include "libmondo-fork-EXT.h" 17 #include "libmondo-devices-EXT.h" 18 #include "libmondo-string-EXT.h" 19 #include "libmondo-mountlist-EXT.h" 20 #include "libmondo-raid-EXT.h" 21 #include "newt-specific-EXT.h" 16 22 17 23 extern char *MONDO_LOGFILE; … … 21 27 22 28 extern char *g_mountlist_fname; 29 extern int g_current_media_number; 30 extern bool g_text_mode; 31 extern int g_currentY; 32 extern long g_current_progress; 33 extern char *g_mondo_cfg_file; 34 35 // in mondo-rstr-newt.c 36 extern int edit_mountlist(char *, struct mountlist_itself *, struct raidlist_itself *); 23 37 24 38 //static char cvsid[] = "$Id$"; … … 63 77 64 78 if (!does_file_exist(slice_fname(bigfileno, 0, ARCHIVES_PATH, ""))) { 65 if (does_file_exist( MNT_CDROM "/archives/NOT-THE-LAST")) {79 if (does_file_exist(ARCHIVES_PATH "/NOT-THE-LAST")) { 66 80 insist_on_this_cd_number((++g_current_media_number)); 67 81 } else { … … 368 382 insist_on_this_cd_number(g_current_media_number); 369 383 update_progress_form(progress_str); 370 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%d.afio.bz2", current_tarball_number);384 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%d.afio.bz2", current_tarball_number); 371 385 372 386 if (!does_file_exist(tarball_fname)) { 373 387 mr_free(tarball_fname); 374 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%d.afio.lzo", current_tarball_number);388 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%d.afio.lzo", current_tarball_number); 375 389 } 376 390 if (!does_file_exist(tarball_fname)) { 377 391 mr_free(tarball_fname); 378 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%d.afio.lzma", current_tarball_number);392 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%d.afio.lzma", current_tarball_number); 379 393 } 380 394 if (!does_file_exist(tarball_fname)) { 381 395 mr_free(tarball_fname); 382 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%d.afio.gz", current_tarball_number);396 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%d.afio.gz", current_tarball_number); 383 397 } 384 398 if (!does_file_exist(tarball_fname)) { 385 399 mr_free(tarball_fname); 386 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%d.afio.", current_tarball_number);400 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%d.afio.", current_tarball_number); 387 401 } 388 402 if (!does_file_exist(tarball_fname)) { 389 403 mr_free(tarball_fname); 390 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%d.star.bz2", current_tarball_number);404 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%d.star.bz2", current_tarball_number); 391 405 } 392 406 if (!does_file_exist(tarball_fname)) { 393 407 mr_free(tarball_fname); 394 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%d.star.", current_tarball_number);408 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%d.star.", current_tarball_number); 395 409 } 396 410 if (!does_file_exist(tarball_fname)) { 397 if (!does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST") || 398 system("find " MNT_CDROM 399 "/archives/slice* > /dev/null 2> /dev/null") 411 if (!does_file_exist(ARCHIVES_PATH "/NOT-THE-LAST") || 412 system("find " ARCHIVES_PATH "/slice* > /dev/null 2> /dev/null") 400 413 == 0) { 401 414 log_msg(2, "OK, I think I'm done with tarballs..."); … … 492 505 **************************************************************************/ 493 506 507 /** 508 * Compare all data on a tape-based backup. 509 * @param bkpinfo The backup information structure. Field used: @c bkpinfo->restore_path. 510 * @return 0 for success, nonzero for failure. 511 */ 512 /************************************************************************** 513 * F@COMPARE_TO_TAPE() * 514 * compare_to_tape() - gots me?? * 515 * * 516 * returns: int * 517 **************************************************************************/ 518 int compare_to_tape() 519 { 520 int res; 521 char *dir; 522 char *command = NULL; 523 524 assert(bkpinfo != NULL); 525 malloc_string(dir); 526 527 if (getcwd(dir, MAX_STR_LEN)) { 528 // FIXME 529 } 530 if (chdir(bkpinfo->restore_path)) { 531 // FIXME 532 } 533 mr_asprintf(command, "cp -f /tmp/LAST-FILELIST-NUMBER %s/tmp", bkpinfo->restore_path); 534 run_program_and_log_output(command, FALSE); 535 mr_free(command); 536 537 mvaddstr_and_log_it(g_currentY, 0, "Verifying archives against filesystem"); 538 res = verify_tape_backups(); 539 if (chdir(dir)) { 540 // FIXME 541 } 542 if (res) { 543 mvaddstr_and_log_it(g_currentY++, 74, "Failed."); 544 } else { 545 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 546 } 547 paranoid_free(dir); 548 return (res); 549 } 550 551 /************************************************************************** 552 *END_COMPARE_TO_TAPE * 553 **************************************************************************/ 554 555 556 /** 557 * Compare all data on a cdstream-based backup. 558 * @param bkpinfo The backup information structure. Fields used: 559 * - @c bkpinfo->disaster_recovery 560 * - @c bkpinfo->media_device 561 * - @c bkpinfo->restore_path 562 * @return 0 for success, nonzero for failure. 563 */ 564 int compare_to_cdstream() 565 { 566 int res; 567 568 /** needs malloc **/ 569 char *dir; 570 char *command = NULL; 571 572 assert(bkpinfo != NULL); 573 malloc_string(dir); 574 if (getcwd(dir, MAX_STR_LEN)) { 575 // FIXME 576 } 577 if (chdir(bkpinfo->restore_path)) { 578 // FIXME 579 } 580 581 mr_asprintf(command, "cp -f /tmp/LAST-FILELIST-NUMBER %s/tmp", bkpinfo->restore_path); 582 run_program_and_log_output(command, FALSE); 583 mr_free(command); 584 mvaddstr_and_log_it(g_currentY, 0, "Verifying archives against filesystem"); 585 586 if (bkpinfo->disaster_recovery 587 && does_file_exist("/tmp/CDROM-LIVES-HERE")) { 588 mr_asprintf(bkpinfo->media_device, "%s", last_line_of_file("/tmp/CDROM-LIVES-HERE")); 589 } else { 590 bkpinfo->media_device = find_optical_device(); 591 } 592 res = verify_tape_backups(); 593 if (chdir(dir)) { 594 // FIXME 595 } 596 if (length_of_file(MONDO_CACHE"/changed.txt") > 2 597 && length_of_file(MONDO_CACHE"/changed.files") > 2) { 598 log_msg(0, 599 "Type 'less "MONDO_CACHE"/changed.files' to see which files don't match the archives"); 600 log_msg(2, "Calling popup_changelist_from_file()"); 601 popup_changelist_from_file(MONDO_CACHE"/changed.files"); 602 log_msg(2, "Returned from popup_changelist_from_file()"); 603 } 604 605 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 606 paranoid_free(dir); 607 return (res); 608 } 609 610 /************************************************************************** 611 *END_COMPARE_CD_STREAM * 612 **************************************************************************/ 494 613 495 614 … … 620 739 *END_COMPARE_MODE * 621 740 **************************************************************************/ 622 623 /**624 * Compare all data on a cdstream-based backup.625 * @param bkpinfo The backup information structure. Fields used:626 * - @c bkpinfo->disaster_recovery627 * - @c bkpinfo->media_device628 * - @c bkpinfo->restore_path629 * @return 0 for success, nonzero for failure.630 */631 int compare_to_cdstream()632 {633 int res;634 635 /** needs malloc **/636 char *dir;637 char *command = NULL;638 639 assert(bkpinfo != NULL);640 malloc_string(dir);641 if (getcwd(dir, MAX_STR_LEN)) {642 // FIXME643 }644 if (chdir(bkpinfo->restore_path)) {645 // FIXME646 }647 648 mr_asprintf(command, "cp -f /tmp/LAST-FILELIST-NUMBER %s/tmp", bkpinfo->restore_path);649 run_program_and_log_output(command, FALSE);650 mr_free(command);651 mvaddstr_and_log_it(g_currentY, 0, "Verifying archives against filesystem");652 653 if (bkpinfo->disaster_recovery654 && does_file_exist("/tmp/CDROM-LIVES-HERE")) {655 mr_asprintf(bkpinfo->media_device, "%s", last_line_of_file("/tmp/CDROM-LIVES-HERE"));656 } else {657 bkpinfo->media_device = find_optical_device();658 }659 res = verify_tape_backups();660 if (chdir(dir)) {661 // FIXME662 }663 if (length_of_file(MONDO_CACHE"/changed.txt") > 2664 && length_of_file(MONDO_CACHE"/changed.files") > 2) {665 log_msg(0,666 "Type 'less "MONDO_CACHE"/changed.files' to see which files don't match the archives");667 log_msg(2, "Calling popup_changelist_from_file()");668 popup_changelist_from_file(MONDO_CACHE"/changed.files");669 log_msg(2, "Returned from popup_changelist_from_file()");670 }671 672 mvaddstr_and_log_it(g_currentY++, 74, "Done.");673 paranoid_free(dir);674 return (res);675 }676 677 /**************************************************************************678 *END_COMPARE_CD_STREAM *679 **************************************************************************/680 681 682 /**683 * Compare all data on a tape-based backup.684 * @param bkpinfo The backup information structure. Field used: @c bkpinfo->restore_path.685 * @return 0 for success, nonzero for failure.686 */687 /**************************************************************************688 * F@COMPARE_TO_TAPE() *689 * compare_to_tape() - gots me?? *690 * *691 * returns: int *692 **************************************************************************/693 int compare_to_tape()694 {695 int res;696 char *dir;697 char *command = NULL;698 699 assert(bkpinfo != NULL);700 malloc_string(dir);701 702 if (getcwd(dir, MAX_STR_LEN)) {703 // FIXME704 }705 if (chdir(bkpinfo->restore_path)) {706 // FIXME707 }708 mr_asprintf(command, "cp -f /tmp/LAST-FILELIST-NUMBER %s/tmp", bkpinfo->restore_path);709 run_program_and_log_output(command, FALSE);710 mr_free(command);711 712 mvaddstr_and_log_it(g_currentY, 0, "Verifying archives against filesystem");713 res = verify_tape_backups();714 if (chdir(dir)) {715 // FIXME716 }717 if (res) {718 mvaddstr_and_log_it(g_currentY++, 74, "Failed.");719 } else {720 mvaddstr_and_log_it(g_currentY++, 74, "Done.");721 }722 paranoid_free(dir);723 return (res);724 }725 726 /**************************************************************************727 *END_COMPARE_TO_TAPE *728 **************************************************************************/729 730 741 /* @} - end compareGroup */ -
branches/3.3/mondo/src/mondorestore/mondo-rstr-mountlist.c
r3871 r3879 12 12 #include "mr_mem.h" 13 13 #include "mondostructures.h" 14 #include "libmondo-mountlist.h"15 16 14 #include "libmondo-raid-EXT.h" 17 15 #include "libmondo-devices-EXT.h" … … 535 533 536 534 /** 535 * Make a list of the drives mentioned in the mountlist. 536 * @param mountlist The mountlist to examine. 537 * @param drivelist Where to put the list of drives found. 538 * @return The number of physical (non-RAID non-LVM) drives found, or \<= 0 for error. 539 */ 540 int 541 make_list_of_drives_in_mountlist(struct mountlist_itself *mountlist, 542 struct list_of_disks *drivelist) 543 { 544 545 /*@ int ************************************************************* */ 546 int lino; 547 int noof_drives; 548 int j; 549 550 /*@ buffers ********************************************************* */ 551 char *drive = NULL; 552 char *truncdrive = NULL; 553 554 long long size; 555 556 assert(mountlist != NULL); 557 assert(drivelist != NULL); 558 log_it("Making list of drives"); 559 for (lino = 0, noof_drives = 0; lino < mountlist->entries; lino++) { 560 561 mr_asprintf(drive, "%s", mountlist->el[lino].device); 562 if (!strncmp(drive, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) { 563 log_msg(8, "Not putting %s in list of drives: it's a virtual drive", drive); 564 mr_free(drive); 565 continue; 566 } 567 568 size = mountlist->el[lino].size; 569 if (size == 0) { 570 log_msg(8, "Not putting %s in list of drives: it has zero size (maybe an LVM volume)", drive); 571 mr_free(drive); 572 continue; 573 } 574 575 log_msg(8, "Putting %s with size %lli in list of drives", drive, size); 576 577 /* memory allocation */ 578 truncdrive = truncate_to_drive_name(drive); 579 mr_free(drive); 580 581 log_msg(8, "drive truncated to %s", truncdrive); 582 583 for (j = 0; 584 j < noof_drives 585 && strcmp(drivelist->el[j].device, truncdrive) != 0; j++) { 586 continue; 587 } 588 if (j == noof_drives) { 589 strncpy(drivelist->el[noof_drives].device, truncdrive, 63); 590 drivelist->el[noof_drives].device[63] = '\0'; 591 log_msg(8,"Adding drive %s to list", drivelist->el[noof_drives].device); 592 noof_drives++; 593 } 594 paranoid_free(truncdrive); 595 if (noof_drives >= MAXIMUM_DISKS_PER_RAID_DEV) { 596 log_msg(0, "Unable to handle mountlist with more than %d lines", MAXIMUM_DISKS_PER_RAID_DEV); 597 log_to_screen("Unable to handle a so big mountlist"); 598 finish(1); 599 } 600 } 601 drivelist->entries = noof_drives; 602 log_msg(8, "Made list of %d drives",noof_drives); 603 604 return (noof_drives); 605 } 606 607 608 /** 537 609 * Evaluate a whole mountlist for flaws. Calls evaluate_drive_within_mountlist() 538 610 * for each drive, and then spreads the flaws across three lines. … … 642 714 return (i); 643 715 } 644 }645 646 647 /**648 * Make a list of the drives mentioned in the mountlist.649 * @param mountlist The mountlist to examine.650 * @param drivelist Where to put the list of drives found.651 * @return The number of physical (non-RAID non-LVM) drives found, or \<= 0 for error.652 */653 int654 make_list_of_drives_in_mountlist(struct mountlist_itself *mountlist,655 struct list_of_disks *drivelist)656 {657 658 /*@ int ************************************************************* */659 int lino;660 int noof_drives;661 int j;662 663 /*@ buffers ********************************************************* */664 char *drive = NULL;665 char *truncdrive = NULL;666 667 long long size;668 669 assert(mountlist != NULL);670 assert(drivelist != NULL);671 log_it("Making list of drives");672 for (lino = 0, noof_drives = 0; lino < mountlist->entries; lino++) {673 674 mr_asprintf(drive, "%s", mountlist->el[lino].device);675 if (!strncmp(drive, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) {676 log_msg(8, "Not putting %s in list of drives: it's a virtual drive", drive);677 mr_free(drive);678 continue;679 }680 681 size = mountlist->el[lino].size;682 if (size == 0) {683 log_msg(8, "Not putting %s in list of drives: it has zero size (maybe an LVM volume)", drive);684 mr_free(drive);685 continue;686 }687 688 log_msg(8, "Putting %s with size %lli in list of drives", drive, size);689 690 /* memory allocation */691 truncdrive = truncate_to_drive_name(drive);692 mr_free(drive);693 694 log_msg(8, "drive truncated to %s", truncdrive);695 696 for (j = 0;697 j < noof_drives698 && strcmp(drivelist->el[j].device, truncdrive) != 0; j++) {699 continue;700 }701 if (j == noof_drives) {702 strncpy(drivelist->el[noof_drives].device, truncdrive, 63);703 drivelist->el[noof_drives].device[63] = '\0';704 log_msg(8,"Adding drive %s to list", drivelist->el[noof_drives].device);705 noof_drives++;706 }707 paranoid_free(truncdrive);708 if (noof_drives >= MAXIMUM_DISKS_PER_RAID_DEV) {709 log_msg(0, "Unable to handle mountlist with more than %d lines", MAXIMUM_DISKS_PER_RAID_DEV);710 log_to_screen("Unable to handle a so big mountlist");711 finish(1);712 }713 }714 drivelist->entries = noof_drives;715 log_msg(8, "Made list of %d drives",noof_drives);716 717 return (noof_drives);718 716 } 719 717 … … 938 936 939 937 /** 938 * Swap two entries in the mountlist in-place. 939 * @param mountlist The mountlist to swap the entries in. 940 * @param a The index number of the first entry. 941 * @param b The index number of the second entry. 942 */ 943 void 944 swap_mountlist_entries(struct mountlist_itself *mountlist, int a, int b) 945 { 946 /*@ mallocs *** */ 947 char *device = NULL; 948 char *mountpoint = NULL; 949 char *format = NULL; 950 951 long long size; 952 953 assert(mountlist != NULL); 954 assert(a >= 0); 955 assert(b >= 0); 956 957 mr_asprintf(device, "%s", mountlist->el[a].device); 958 mr_asprintf(mountpoint, "%s", mountlist->el[a].mountpoint); 959 mr_asprintf(format, "%s", mountlist->el[a].format); 960 961 size = mountlist->el[a].size; 962 963 strcpy(mountlist->el[a].device, mountlist->el[b].device); 964 strcpy(mountlist->el[a].mountpoint, mountlist->el[b].mountpoint); 965 strcpy(mountlist->el[a].format, mountlist->el[b].format); 966 967 mountlist->el[a].size = mountlist->el[b].size; 968 969 strcpy(mountlist->el[b].device, device); 970 strcpy(mountlist->el[b].mountpoint, mountpoint); 971 strcpy(mountlist->el[b].format, format); 972 973 mountlist->el[b].size = size; 974 mr_free(device); 975 mr_free(mountpoint); 976 mr_free(format); 977 } 978 979 980 981 /** 940 982 * Sort the mountlist alphabetically by device. 941 983 * The sorting is done in-place. … … 991 1033 } 992 1034 993 994 /**995 * Swap two entries in the mountlist in-place.996 * @param mountlist The mountlist to swap the entries in.997 * @param a The index number of the first entry.998 * @param b The index number of the second entry.999 */1000 void1001 swap_mountlist_entries(struct mountlist_itself *mountlist, int a, int b)1002 {1003 /*@ mallocs *** */1004 char *device = NULL;1005 char *mountpoint = NULL;1006 char *format = NULL;1007 1008 long long size;1009 1010 assert(mountlist != NULL);1011 assert(a >= 0);1012 assert(b >= 0);1013 1014 mr_asprintf(device, "%s", mountlist->el[a].device);1015 mr_asprintf(mountpoint, "%s", mountlist->el[a].mountpoint);1016 mr_asprintf(format, "%s", mountlist->el[a].format);1017 1018 size = mountlist->el[a].size;1019 1020 strcpy(mountlist->el[a].device, mountlist->el[b].device);1021 strcpy(mountlist->el[a].mountpoint, mountlist->el[b].mountpoint);1022 strcpy(mountlist->el[a].format, mountlist->el[b].format);1023 1024 mountlist->el[a].size = mountlist->el[b].size;1025 1026 strcpy(mountlist->el[b].device, device);1027 strcpy(mountlist->el[b].mountpoint, mountpoint);1028 strcpy(mountlist->el[b].format, format);1029 1030 mountlist->el[b].size = size;1031 mr_free(device);1032 mr_free(mountpoint);1033 mr_free(format);1034 }1035 1036 1035 /* @} - end of mountlistGroup */ -
branches/3.3/mondo/src/mondorestore/mondo-rstr-newt.c
r3856 r3879 10 10 #endif 11 11 12 #include "mondo-rstr-newt.h" 12 #include "my-stuff.h" 13 #include "mondostructures.h" 13 14 #include "mr_mem.h" 14 15 #include "mr_str.h" 16 #include "libmondo-raid-EXT.h" 17 #include "libmondo-mountlist-EXT.h" 18 #include "libmondo-string-EXT.h" 19 #include "libmondo-tools-EXT.h" 20 #include "libmondo-files-EXT.h" 21 #include "libmondo-filelist-EXT.h" 22 #include "newt-specific-EXT.h" 15 23 16 24 //static char cvsid[] = "$Id$"; … … 18 26 extern bool popup_with_buttons(char *p, char *button1, char *button2); 19 27 extern char err_log_lines[NOOF_ERR_LINES][MAX_STR_LEN]; 28 29 static char g_strings_of_flist_window[ARBITRARY_MAXIMUM][MAX_STR_LEN]; 30 static bool g_is_path_selected[ARBITRARY_MAXIMUM]; 31 static bool g_is_path_expanded[ARBITRARY_MAXIMUM]; 32 static char tmpnopath[MAX_STR_LEN + 2]; 33 static char tmpprevpath[MAX_STR_LEN + 2]; 34 35 // from mondo-rstr-mountlist.c 36 extern void make_list_of_unallocated_raid_partitions(struct mountlist_itself *, struct mountlist_itself *, struct raidlist_itself *); 37 38 extern bool g_text_mode; 39 20 40 21 41 /** … … 36 56 37 57 /** 38 * @addtogroup restoreGuiGroup 39 * @{ 40 */ 58 * Redraw the list of unallocated RAID partitions. 59 * @param unallocated_raid_partitions The mountlist containing unallocated RAID partitions. 60 * @param keylist The list of keys for @p listbox. 61 * @param listbox The Newt listbox component to redraw. 62 * @ingroup restoreGuiDisklist 63 */ 64 void redraw_unallocpartnslist(struct mountlist_itself 65 *unallocated_raid_partitions, 66 void *keylist[ARBITRARY_MAXIMUM], 67 newtComponent listbox) 68 { 69 70 /** long *************************************************************/ 71 long i = 0; 72 73 /** buffers **********************************************************/ 74 char tmp[MAX_STR_LEN]; 75 76 assert(unallocated_raid_partitions != NULL); 77 assert(keylist != NULL); 78 assert(listbox != NULL); 79 80 newtListboxClear(listbox); 81 for (i = 0; i < ARBITRARY_MAXIMUM; i++) { 82 keylist[i] = (void *) i; 83 } 84 for (i = 0; i < unallocated_raid_partitions->entries; i++) { 85 sprintf(tmp, "%-22s %8lld", 86 unallocated_raid_partitions->el[i].device, 87 unallocated_raid_partitions->el[i].size / 1024L); 88 newtListboxAppendEntry(listbox, tmp, keylist[i]); 89 } 90 } 91 92 93 /** 94 * Find the next free location to place a disk in @p disklist. 95 * @param disklist The disklist to operate on. 96 * @return The next free location (starting from 0). 97 * @ingroup restoreGuiDisklist 98 */ 99 int find_next_free_index_in_disklist(struct list_of_disks *disklist) 100 { 101 102 /** int ***************************************************************/ 103 int index = -1; 104 int pos = 0; 105 106 /** bool **************************************************************/ 107 bool done; 108 109 assert(disklist != NULL); 110 111 for (done = FALSE; !done;) { 112 for (pos = 0; 113 pos < disklist->entries && disklist->el[pos].index <= index; 114 pos++); 115 if (pos >= disklist->entries) { 116 done = TRUE; 117 } else { 118 index = disklist->el[pos].index; 119 } 120 } 121 return (index + 1); 122 } 123 124 125 41 126 /** 42 127 * Add an entry in @p disklist from the list in @p unallocated_raid_partitions. … … 118 203 119 204 120 121 122 /** 123 * Add an entry to @p mountlist. 124 * @param mountlist The mountlist to add an entry to. 125 * @param raidlist The raidlist that accompanies @p mountlist. 126 * @param listbox The listbox component in the mountlist editor. 127 * @param currline The line selected in @p listbox. 205 /** 206 * Locate @p device in @p raidlist. 207 * @param raidlist The raidlist ot search in. 208 * @param device The RAID device to search for. 209 * @return The index of the device, or -1 if it could not be found. 210 * @ingroup restoreGuiMountlist 211 */ 212 int 213 find_raid_device_in_raidlist(struct raidlist_itself *raidlist, 214 char *device) 215 { 216 217 /** int ***************************************************************/ 218 int i = 0; 219 #ifdef __FreeBSD__ 220 char *vdev = NULL; 221 int res = 0; 222 #else 223 // Linux 224 #endif 225 226 assert(raidlist != NULL); 227 assert_string_is_neither_NULL_nor_zerolength(device); 228 229 #ifdef __FreeBSD__ 230 for (i = 0; i < raidlist->entries; i++) { 231 mr_asprintf(vdev, "/dev/vinum/%s", raidlist->el[i].volname); 232 res = strcmp(device, vdev); 233 mr_free(vdev); 234 235 if (!res) 236 break; 237 } 238 #else 239 240 for (i = 0; 241 strcmp(raidlist->el[i].raid_device, device) 242 && i < raidlist->entries; i++); 243 #endif 244 if (i == raidlist->entries) { 245 return (-1); 246 } else { 247 return (i); 248 } 249 } 250 251 252 /** 253 * Redraw the disklist. 254 * @param disklist The disklist to read from. 128 255 * @param keylist The list of keys for @p listbox. 256 * @param listbox The Newt listbox component to redraw. 257 * @ingroup restoreGuiDisklist 258 */ 259 void 260 redraw_disklist(struct list_of_disks *disklist, 261 void *keylist[ARBITRARY_MAXIMUM], newtComponent listbox) 262 { 263 264 /** long **************************************************************/ 265 long i = 0; 266 char *tmp = NULL; 267 268 assert(disklist != NULL); 269 assert(keylist != NULL); 270 assert(listbox != NULL); 271 272 newtListboxClear(listbox); 273 274 for (i = 0; i < ARBITRARY_MAXIMUM; i++) { 275 keylist[i] = (void *) i; 276 } 277 for (i = 0; i < disklist->entries; i++) { 278 tmp = disklist_entry_to_string(disklist, i); 279 newtListboxAppendEntry(listbox, tmp, keylist[i]); 280 mr_free(tmp); 281 } 282 } 283 284 285 286 /** 287 * Delete entry number @p currline from @p disklist. 288 * @param disklist The disklist to remove the entry from. 289 * @param raid_device The RAID device containing the partition we're removing. 290 * Used only in the popup "are you sure?" box. 291 * @param currline The line number (starting from 0) of the item to delete. 292 * @ingroup restoreGuiDisklist 293 */ 294 void 295 delete_disklist_entry(struct list_of_disks *disklist, char *raid_device, 296 int currline) 297 { 298 299 /** int ***************************************************************/ 300 int pos = 0; 301 int res = 0; 302 303 /** buffers ***********************************************************/ 304 char *tmp = NULL; 305 306 assert(disklist != NULL); 307 assert_string_is_neither_NULL_nor_zerolength(raid_device); 308 309 mr_asprintf(tmp, "Delete %s from RAID device %s - are you sure?", disklist->el[currline].device, raid_device); 310 res = ask_me_yes_or_no(tmp); 311 mr_free(tmp); 312 313 if (!res) { 314 return; 315 } 316 for (pos = currline; pos < disklist->entries - 1; pos++) { 317 strcpy(disklist->el[pos].device, disklist->el[pos + 1].device); 318 } 319 disklist->entries--; 320 } 321 322 323 324 /** 325 * Select the RAID disks to use in @p raidrec. 326 * @param mountlist_dontedit The mountlist (will not be edited). 327 * @param raidlist The raidlist to modify. 328 * @param raidrec The RAID device record in @p raidlist to work on. 329 * @param description_of_list The type of disks we're selecting (e.g. "data"). 330 * @param disklist The disklist to put the user-selected disks in. 129 331 * @ingroup restoreGuiMountlist 130 332 */ 131 333 void 132 add_mountlist_entry(struct mountlist_itself *mountlist, 133 struct raidlist_itself *raidlist, 134 newtComponent listbox, int currline, void *keylist[]) 334 select_raid_disks(struct mountlist_itself *mountlist_dontedit, 335 struct raidlist_itself *raidlist, 336 struct raid_device_record *raidrec, 337 char *description_of_list, 338 struct list_of_disks *disklist) 339 { 340 void *curr_choice; 341 342 /** ??? ***************************************************************/ 343 344 /** structures ********************************************************/ 345 struct raidlist_itself *bkp_raidlist; 346 struct raid_device_record *bkp_raidrec; 347 struct list_of_disks *bkp_disklist; 348 struct mountlist_itself *unallocated_raid_partitions; 349 350 /** newt **************************************************************/ 351 newtComponent myForm = NULL; 352 newtComponent bAdd = NULL; 353 newtComponent bDelete = NULL; 354 newtComponent bOK = NULL; 355 newtComponent bCancel = NULL; 356 newtComponent b_res = NULL; 357 newtComponent partitionsListbox = NULL; 358 newtComponent headerMsg = NULL; 359 360 /** buffers **********************************************************/ 361 void *keylist[ARBITRARY_MAXIMUM]; 362 char *tmp = NULL; 363 char *help_text = NULL; 364 char *title_of_window = NULL; 365 char sz_res[MAX_STR_LEN]; 366 char *header_text = NULL; 367 368 /** int **************************************************************/ 369 int i = 0; 370 int currline = 0; 371 372 assert(mountlist_dontedit != NULL); 373 assert(raidlist != NULL); 374 assert(raidrec != NULL); 375 assert(description_of_list != NULL); 376 assert(disklist != NULL); 377 378 log_it("malloc'ing"); 379 bkp_raidrec = mr_malloc(sizeof(struct raid_device_record)); 380 bkp_disklist = mr_malloc(sizeof(struct list_of_disks)); 381 bkp_raidlist = mr_malloc(sizeof(struct raidlist_itself)); 382 unallocated_raid_partitions = mr_malloc(sizeof(struct mountlist_itself)); 383 384 memcpy((void *) bkp_raidlist, (void *) raidlist, sizeof(struct raidlist_itself)); 385 memcpy((void *) bkp_raidrec, (void *) raidrec, sizeof(struct raid_device_record)); 386 memcpy((void *) bkp_disklist, (void *) disklist, sizeof(struct list_of_disks)); 387 388 log_it("Post-malloc"); 389 mr_asprintf(help_text, " Edit this RAID device's list of partitions. Choose OK or Cancel when done."); 390 mr_asprintf(header_text, "%-24s %s", "Device", "Index"); 391 mr_asprintf(title_of_window, "%s contains...", raidrec->raid_device); 392 newtPushHelpLine(help_text); 393 for (b_res = (newtComponent) 12345; b_res != bOK && b_res != bCancel;) { 394 headerMsg = newtLabel(1, 1, header_text); 395 partitionsListbox = 396 newtListbox(1, 2, 6, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); 397 redraw_disklist(disklist, keylist, partitionsListbox); 398 i = 1; 399 bAdd = newtCompactButton(i, 9, " Add "); 400 bDelete = newtCompactButton(i += 8, 9, "Delete"); 401 bOK = newtCompactButton(i += 9, 9, " OK "); 402 bCancel = newtCompactButton(i += 9, 9, "Cancel"); 403 newtOpenWindow(21, 7, 38, 10, title_of_window); 404 myForm = newtForm(NULL, NULL, 0); 405 if (disklist->entries == 0) { 406 newtFormAddComponents(myForm, headerMsg, bAdd, bDelete, bOK, 407 bCancel, NULL); 408 } else { 409 newtFormAddComponents(myForm, headerMsg, partitionsListbox, 410 bAdd, bDelete, bOK, bCancel, NULL); 411 } 412 b_res = newtRunForm(myForm); 413 if (b_res == bOK || b_res == bCancel) { /* do nothing */ 414 // That's OK. At the end of this subroutine (after this do/while loop), 415 // we'll throw away the changes if Cancel was pushed. 416 } else { 417 curr_choice = newtListboxGetCurrent(partitionsListbox); 418 for (i = 0; i < disklist->entries && keylist[i] != curr_choice; 419 i++); 420 if (i == disklist->entries && disklist->entries > 0) { 421 log_to_screen("I don't know what that button does!"); 422 } else { 423 currline = i; 424 if (b_res == bAdd) { 425 log_it("Making list of unallocated RAID slices"); 426 make_list_of_unallocated_raid_partitions 427 (unallocated_raid_partitions, mountlist_dontedit, 428 raidlist); 429 if (unallocated_raid_partitions->entries <= 0) { 430 popup_and_OK 431 ("There are no unallocated partitions marked for RAID."); 432 } else { 433 log_it 434 ("Done. The user may add one or more of the above to RAID device"); 435 add_disklist_entry(disklist, raidrec->raid_device, 436 unallocated_raid_partitions); 437 log_it("I have finished adding a disklist entry."); 438 redraw_disklist(disklist, keylist, 439 partitionsListbox); 440 } 441 } else if (b_res == bDelete) { 442 delete_disklist_entry(disklist, raidrec->raid_device, 443 currline); 444 redraw_disklist(disklist, keylist, partitionsListbox); 445 } else { 446 mr_asprintf(tmp, "%s's index is %d. What should it be?", raidrec->raid_device, disklist->el[currline].index); 447 sprintf(sz_res, "%d", disklist->el[currline].index); 448 if (popup_and_get_string("Set index", tmp, sz_res, 10)) { 449 disklist->el[currline].index = atoi(sz_res); 450 } 451 mr_free(tmp); 452 453 redraw_disklist(disklist, keylist, partitionsListbox); 454 } 455 } 456 } 457 newtFormDestroy(myForm); 458 newtPopWindow(); 459 } 460 newtPopHelpLine(); 461 mr_free(help_text); 462 mr_free(header_text); 463 mr_free(title_of_window); 464 465 if (b_res == bCancel) { 466 memcpy((void *) raidlist, (void *) bkp_raidlist, sizeof(struct raidlist_itself)); 467 memcpy((void *) raidrec, (void *) bkp_raidrec, sizeof(struct raid_device_record)); 468 memcpy((void *) disklist, (void *) bkp_disklist, sizeof(struct list_of_disks)); 469 } 470 mr_free(bkp_raidrec); 471 mr_free(bkp_disklist); 472 mr_free(bkp_raidlist); 473 mr_free(unallocated_raid_partitions); 474 } 475 476 477 #ifndef __FreeBSD__ 478 /** 479 * Insert the RAID variables not stored in the "additional RAID variables" list there too. 480 * @param raidrec The RAID device record to operate on. 481 * @ingroup restoreGuiVarslist 482 */ 483 void insert_essential_additionalvars(struct raid_device_record *raidrec) 135 484 { 136 485 137 486 /** int **************************************************************/ 487 int items = 0; 488 489 assert(raidrec != NULL); 490 491 items = raidrec->additional_vars.entries; 492 write_variableINT_to_raid_var_line(raidrec, items++, 493 "persistent-superblock", 494 raidrec->persistent_superblock); 495 write_variableINT_to_raid_var_line(raidrec, items++, "chunk-size", 496 raidrec->chunk_size); 497 raidrec->additional_vars.entries = items; 498 } 499 500 #endif 501 502 503 #ifndef __FreeBSD__ 504 /** 505 * Redraw the list of additional RAID variables. 506 * @param additional_vars The list of additional RAID varibals. 507 * @param keylist The list of keys for @p listbox. 508 * @param listbox The Newt listbox component to redraw. 509 * @ingroup restoreGuiVarslist 510 */ 511 void 512 redraw_varslist(struct additional_raid_variables *additional_vars, 513 void *keylist[], newtComponent listbox) 514 { 515 /** long ************************************************************/ 516 long i = 0; 517 518 /** buffers *********************************************************/ 519 char tmp[MAX_STR_LEN]; 520 521 assert(additional_vars != NULL); 522 assert(keylist != NULL); 523 assert(listbox != NULL); 524 525 newtListboxClear(listbox); 526 527 for (i = 0; i < ARBITRARY_MAXIMUM; i++) { 528 keylist[i] = (void *) i; 529 } 530 for (i = 0; i < additional_vars->entries; i++) { 531 sprintf(tmp, "%-32s %-8s", additional_vars->el[i].label, 532 additional_vars->el[i].value); 533 newtListboxAppendEntry(listbox, tmp, keylist[i]); 534 } 535 } 536 537 #endif 538 539 540 #ifndef __FreeBSD__ 541 /** 542 * Remove variable @p label from the RAID variables list in @p raidrec. 543 * @param raidrec The RAID device record to remove the variable from. 544 * @param label The variable name to remove. 545 * @return The value of the variable removed. 546 * @ingroup restoreUtilityGroup 547 */ 548 int 549 read_variableINT_and_remove_from_raidvars(struct 550 OSSWAP (raid_device_record, 551 vinum_volume) * raidrec, 552 char *label) 553 { 554 /** int ***************************************************************/ 138 555 int i = 0; 139 140 /** newt *************************************************************/ 141 newtComponent myForm; 556 int res = 0; 557 558 559 assert(raidrec != NULL); 560 assert(label != NULL); 561 562 for (i = 0; 563 i < raidrec->additional_vars.entries 564 && strcmp(raidrec->additional_vars.el[i].label, label); i++); 565 if (i == raidrec->additional_vars.entries) { 566 res = -1; 567 } else { 568 res = atoi(raidrec->additional_vars.el[i].value); 569 for (i++; i < raidrec->additional_vars.entries; i++) { 570 memcpy((void *) &raidrec->additional_vars.el[i - 1], 571 (void *) &raidrec->additional_vars.el[i], 572 sizeof(struct raid_var_line)); 573 } 574 raidrec->additional_vars.entries--; 575 } 576 return (res); 577 } 578 #endif 579 580 #ifndef __FreeBSD__ 581 /** 582 * Remove the essential RAID variables from the "additional variables" section. 583 * If they have been changed, set them in their normal locations too. 584 * @param raidrec The RAID device record to operate on. 585 * @ingroup restoreUtilityVarslist 586 */ 587 void remove_essential_additionalvars(struct raid_device_record *raidrec) 588 { 589 590 /** int **************************************************************/ 591 int res = 0; 592 593 assert(raidrec != NULL); 594 595 res = 596 read_variableINT_and_remove_from_raidvars(raidrec, 597 "persistent-superblock"); 598 if (res > 0) { 599 raidrec->persistent_superblock = res; 600 } 601 res = read_variableINT_and_remove_from_raidvars(raidrec, "chunk-size"); 602 if (res > 0) { 603 raidrec->chunk_size = res; 604 } 605 res = read_variableINT_and_remove_from_raidvars(raidrec, "block-size"); 606 } 607 608 #endif 609 610 611 612 /** 613 * Choose the RAID level for the RAID device record in @p raidrec. 614 * @param raidrec The RAID device record to set the RAID level of. 615 * @ingroup restoreGuiMountlist 616 */ 617 void 618 choose_raid_level(struct OSSWAP (raid_device_record, vinum_plex) * raidrec) 619 { 620 621 #ifdef __FreeBSD__ 622 623 /** int ***************************************************************/ 624 int res = 0; 625 int out = 0; 626 627 /** buffers ***********************************************************/ 628 char tmp[MAX_STR_LEN]; 629 char *prompt = NULL; 630 char sz[MAX_STR_LEN]; 631 632 mr_asprintf(prompt, "Please enter the RAID level you want. (concat, striped, raid5)"); 633 if (raidrec->raidlevel == -1) { 634 strcpy(tmp, "concat"); 635 } else if (raidrec->raidlevel == 0) { 636 strcpy(tmp, "striped"); 637 } else { 638 sprintf(tmp, "raid%i", raidrec->raidlevel); 639 } 640 for (out = 999; out == 999;) { 641 res = popup_and_get_string("Specify RAID level", prompt, tmp, 10); 642 if (!res) { 643 mr_free(prompt); 644 return; 645 } 646 strip_spaces(tmp); 647 if (tmp[0] == '[' && tmp[strlen(tmp) - 1] == ']') { 648 strcpy(sz, tmp); 649 strncpy(tmp, sz + 1, strlen(sz) - 2); 650 tmp[strlen(sz) - 2] = '\0'; 651 } 652 if (!strcmp(tmp, "concat")) { 653 out = -1; 654 } else if (!strcmp(tmp, "striped")) { 655 out = 0; 656 } else if (!strcmp(tmp, "raid5")) { 657 out = 5; 658 } 659 log_it(tmp); 660 if (is_this_raid_personality_registered(out)) { 661 log_it("Groovy. You've picked a RAID personality which is registered."); 662 } else { 663 if (ask_me_yes_or_no("You have chosen a RAID personality which is not registered with the kernel. Make another selection?")) 664 { 665 out = 999; 666 } 667 } 668 } 669 mr_free(prompt); 670 671 raidrec->raidlevel = out; 672 #else 673 /** buffers ***********************************************************/ 674 char tmp[MAX_STR_LEN]; 675 char *personalities = NULL; 676 char *prompt = NULL; 677 char sz[MAX_STR_LEN]; 678 int out = 0; 679 int res = 0; 680 681 682 assert(raidrec != NULL); 683 paranoid_system("grep Pers /proc/mdstat > /tmp/raid-personalities.txt 2> /dev/null"); 684 mr_asprintf(personalities, "%s", last_line_of_file("/tmp/raid-personalities.txt")); 685 mr_asprintf(prompt, "Please enter the RAID level you want. %s", personalities); 686 mr_free(personalities); 687 688 if (raidrec->raid_level == -1) { 689 strcpy(tmp, "linear"); 690 } else { 691 sprintf(tmp, "%d", raidrec->raid_level); 692 } 693 for (out = 999; 694 out != -1 && out != 0 && out != 1 && out != 4 && out != 5 695 && out != 10;) { 696 res = popup_and_get_string("Specify RAID level", prompt, tmp, 10); 697 if (!res) { 698 return; 699 } 700 strip_spaces(tmp); 701 if (tmp[0] == '[' && tmp[strlen(tmp) - 1] == ']') { 702 strcpy(sz, tmp); 703 strncpy(tmp, sz + 1, strlen(sz) - 2); 704 tmp[strlen(sz) - 2] = '\0'; 705 } 706 if (!strcmp(tmp, "linear")) { 707 out = -1; 708 } else if (!strncmp(tmp, "raid", 4)) { 709 out = atoi(tmp + 4); 710 } else { 711 out = atoi(tmp); 712 } 713 log_it(tmp); 714 if (is_this_raid_personality_registered(out)) { 715 log_it("Groovy. You've picked a RAID personality which is registered."); 716 } else { 717 if (ask_me_yes_or_no("You have chosen a RAID personality which is not registered with the kernel. Make another selection?")) { 718 out = 999; 719 } 720 } 721 } 722 mr_free(prompt); 723 724 raidrec->raid_level = out; 725 #endif 726 } 727 728 729 #ifdef __FreeBSD__ 730 731 /** 732 * Edit the plex @p raidrec in @p raidlist. 733 * @param mountlist The mountlist to get some of the information from. 734 * @param raidlist The raidlist containing information about RAID devices. 735 * @param raidrec The plex to edit. 736 * @param currline The line number (starting from 0) of the RAID device in @p mountlist. 737 * @param currline2 The line number (starting from 0) of the plex within the RAID device. 738 * @author Joshua Oreman 739 * @ingroup restoreGuiMountlist 740 */ 741 void 742 edit_raidlist_plex(struct mountlist_itself *mountlist, 743 struct raidlist_itself *raidlist, 744 struct vinum_plex *raidrec, int currline, int currline2) 745 { 746 747 /** structures ********************************************************/ 748 struct vinum_plex bkp_raidrec; 749 750 751 /** buffers ***********************************************************/ 752 char *title_of_editraidForm_window = NULL; 753 754 /** newt **************************************************************/ 755 newtComponent editraidForm; 142 756 newtComponent bOK; 143 757 newtComponent bCancel; 758 newtComponent bEdit; 759 newtComponent bAdd; 760 newtComponent bDelete; 144 761 newtComponent b_res; 145 newtComponent mountpointComp; 146 newtComponent label0; 147 newtComponent label1; 148 newtComponent label2; 149 newtComponent label3; 150 newtComponent sizeComp; 151 newtComponent deviceComp; 152 newtComponent formatComp; 153 154 /** buffers **********************************************************/ 155 char *drive_to_add = NULL; 156 char *mountpoint_str = NULL; 157 char *size_str = NULL; 158 char *device_str = NULL; 159 char *format_str = NULL; 160 161 /** pointers *********************************************************/ 162 char *mountpoint_here; 163 char *size_here; 164 char *device_here; 165 char *format_here; 166 167 assert(mountlist != NULL); 168 assert(raidlist != NULL); 169 assert(listbox != NULL); 170 assert(keylist != NULL); 171 172 mr_asprintf(device_str, "/dev/"); 173 mr_asprintf(mountpoint_str, "/"); 174 mr_asprintf(size_str, ""); 175 #ifdef __FreeBSD__ 176 mr_asprintf(format_str, "ufs"); 762 newtComponent unallocListbox, allocListbox; 763 newtComponent bLevel, sLevel; 764 newtComponent bStripeSize, sStripeSize; 765 newtComponent bAlloc, bUnalloc; 766 767 void *keylist[ARBITRARY_MAXIMUM]; 768 void *curr_choice_a, *curr_choice_u; 769 int currline_a, currline_u; 770 771 char *p = NULL; 772 char *tmp = NULL; 773 char *entry = NULL; 774 775 struct mountlist_itself *unallocparts; 776 777 unallocparts = malloc(sizeof(struct mountlist_itself)); 778 779 log_it("Started edit_raidlist_entry"); 780 memcpy((void *) &bkp_raidrec, (void *) raidrec, 781 sizeof(struct vinum_plex)); 782 mr_asprintf(title_of_editraidForm_window, "%s.p%i", raidlist->el[currline].volname, currline2); 783 newtPushHelpLine 784 (" Please select a subdisk to edit, or edit this plex's parameters"); 785 newtOpenWindow(13, 3, 54, 18, title_of_editraidForm_window); 786 mr_free(title_of_editraidForm_window); 787 788 for (;;) { 789 int i; 790 791 switch (raidrec->raidlevel) { 792 case -1: 793 mr_asprintf(tmp, "concat"); 794 break; 795 case 0: 796 mr_asprintf(tmp, "striped"); 797 break; 798 case 5: 799 mr_asprintf(tmp, "raid5"); 800 break; 801 default: 802 mr_asprintf(tmp, "unknown (%i)", raidrec->raidlevel); 803 break; 804 } 805 bLevel = newtCompactButton(2, 2, " RAID level "); 806 sLevel = newtLabel(19, 2, tmp); 807 mr_free(tmp); 808 809 if (raidrec->raidlevel >= 0) { 810 mr_asprintf(tmp, "%ik", raidrec->stripesize); 811 bStripeSize = newtCompactButton(2, 4, " Stripe size "); 812 } else { 813 mr_asprintf(tmp, "N/A"); 814 bStripeSize = newtLabel(2, 4, "Stripe size:"); 815 } 816 sStripeSize = newtLabel(19, 4, tmp); 817 mr_free(tmp); 818 819 bOK = newtCompactButton(2, 16, " OK "); 820 bCancel = newtCompactButton(12, 16, "Cancel"); 821 bAdd = newtCompactButton(22, 16, " Add "); 822 bEdit = newtCompactButton(32, 16, " Edit "); 823 bDelete = newtCompactButton(42, 16, "Delete"); 824 825 826 unallocListbox = 827 newtListbox(2, 7, 7, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); 828 allocListbox = 829 newtListbox(33, 7, 7, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); 830 bAlloc = newtButton(23, 7, " -> "); 831 bUnalloc = newtButton(23, 11, " <- "); 832 833 editraidForm = newtForm(NULL, NULL, 0); 834 835 newtListboxClear(allocListbox); 836 newtListboxClear(unallocListbox); 837 bzero(unallocparts, sizeof(struct mountlist_itself)); 838 make_list_of_unallocated_raid_partitions(unallocparts, mountlist, 839 raidlist); 840 for (i = 0; i < ARBITRARY_MAXIMUM; ++i) { 841 keylist[i] = (void *) i; 842 if (i < raidrec->subdisks) { 843 mr_asprintf(entry, "%-17s", find_dev_entry_for_raid_device_name(raidlist, raidrec->sd[i].which_device)); 844 newtListboxAppendEntry(allocListbox, entry, keylist[i]); 845 mr_free(entry); 846 } 847 if (i < unallocparts->entries) { 848 mr_asprintf(entry, "%-17s", unallocparts->el[i].device); 849 newtListboxAppendEntry(unallocListbox, entry, keylist[i]); 850 mr_free(entry); 851 } 852 } 853 854 #define COMP(x) newtFormAddComponent (editraidForm, x) 855 #define UCOMP(x) if (unallocparts->entries > 0) COMP(x) 856 #define ACOMP(x) if (raidrec->subdisks > 0) COMP(x) 857 editraidForm = newtForm(NULL, NULL, 0); 858 UCOMP(unallocListbox); 859 UCOMP(bAlloc); 860 ACOMP(allocListbox); 861 ACOMP(bUnalloc); 862 COMP(bOK); 863 COMP(bCancel); 864 COMP(bLevel); 865 COMP(sLevel); 866 if (raidrec->raidlevel != -1) { 867 COMP(bStripeSize); 868 COMP(sStripeSize); 869 } 870 #undef COMP 871 #undef UCOMP 872 #undef ACOMP 873 874 newtDrawForm(editraidForm); 875 newtRefresh(); 876 b_res = newtRunForm(editraidForm); 877 if (b_res == bOK || b_res == bCancel) { 878 break; 879 } 880 881 curr_choice_a = (raidrec->subdisks > 0) ? 882 newtListboxGetCurrent(allocListbox) : (void *) 1234; 883 curr_choice_u = (unallocparts->entries > 0) ? 884 newtListboxGetCurrent(unallocListbox) : (void *) 1234; 885 for (currline_a = 0; currline_a < raidrec->subdisks; ++currline_a) { 886 if (currline_a > ARBITRARY_MAXIMUM) 887 break; 888 if (keylist[currline_a] == curr_choice_a) 889 break; 890 } 891 for (currline_u = 0; currline_u < unallocparts->entries; 892 ++currline_u) { 893 if (currline_u > ARBITRARY_MAXIMUM) 894 break; 895 if (keylist[currline_u] == curr_choice_u) 896 break; 897 } 898 if (b_res == bLevel) { 899 choose_raid_level(raidrec); 900 } else if (b_res == bStripeSize) { 901 char tmp1[64]; 902 sprintf(tmp1, "%i", raidrec->stripesize); 903 if (popup_and_get_string 904 ("Stripe size", 905 "Please enter the stripe size in kilobytes.", tmp1, 20)) { 906 raidrec->stripesize = atoi(tmp1); 907 } 908 } else if ((b_res == bAlloc) || (b_res == unallocListbox)) { 909 if (currline_u <= unallocparts->entries) 910 add_raid_subdisk(raidlist, raidrec, 911 unallocparts->el[currline_u].device); 912 } else if ((b_res == bUnalloc) || (b_res == allocListbox)) { 913 if (currline_a <= raidrec->subdisks) { 914 memcpy((void *) &raidrec->sd[currline_a], 915 (void *) &raidrec->sd[raidrec->subdisks - 1], 916 sizeof(struct vinum_subdisk)); 917 raidrec->subdisks--; 918 } 919 } 920 newtFormDestroy(editraidForm); 921 newtRefresh(); 922 } 923 924 if (b_res == bCancel) { 925 memcpy((void *) raidrec, (void *) &bkp_raidrec, sizeof(struct vinum_plex)); 926 } 927 newtPopWindow(); 928 newtPopHelpLine(); 929 } 177 930 #else 178 mr_asprintf(format_str, "ext3"); 931 /** 932 * Edit additional RAID variable number @p lino. 933 * @param raidrec The RAID device record to edit the variable in. 934 * @param lino The line number (starting from 0) of the variable to edit. 935 * @ingroup restoreGuiVarslist 936 */ 937 void edit_varslist_entry(struct raid_device_record *raidrec, int lino) 938 { 939 940 /** buffers ***********************************************************/ 941 char *header = NULL; 942 char *comment = NULL; 943 char sz_out[MAX_STR_LEN]; 944 945 assert(raidrec != 0); 946 assert(lino >= 0); 947 948 strcpy(sz_out, raidrec->additional_vars.el[lino].value); 949 mr_asprintf(header, "Edit %s", raidrec->additional_vars.el[lino].label); 950 mr_asprintf(comment, "Please set %s's value (currently '%s')", raidrec->additional_vars.el[lino].label, sz_out); 951 if (popup_and_get_string(header, comment, sz_out, MAX_STR_LEN)) { 952 strip_spaces(sz_out); 953 strcpy(raidrec->additional_vars.el[lino].value, sz_out); 954 } 955 mr_free(header); 956 mr_free(comment); 957 } 179 958 #endif 180 newtOpenWindow(20, 5, 48, 10, "Add entry");181 label0 = newtLabel(2, 1, "Device: ");182 label1 = newtLabel(2, 2, "Mountpoint:");183 label2 = newtLabel(2, 3, "Size (MB): ");184 label3 = newtLabel(2, 4, "Format: ");185 deviceComp = newtEntry(14, 1, device_str, 30, (void *) &device_here, 0);186 mountpointComp = newtEntry(14, 2, mountpoint_str, 30, (void *) &mountpoint_here, 0);187 formatComp = newtEntry(14, 4, format_str, 15, (void *) &format_here, 0);188 sizeComp = newtEntry(14, 3, size_str, 10, (void *) &size_here, 0);189 bOK = newtButton(5, 6, " OK ");190 bCancel = newtButton(17, 6, "Cancel");191 newtPushHelpLine192 ("To add an entry to the mountlist, please fill in these fields and then hit 'OK'");193 myForm = newtForm(NULL, NULL, 0);194 newtFormAddComponents(myForm, deviceComp, mountpointComp, sizeComp,195 formatComp, label0, label1, label2, label3, bOK,196 bCancel, NULL);197 for (b_res = NULL; b_res != bOK && b_res != bCancel;) {198 b_res = newtRunForm(myForm);199 mr_free(device_str);200 device_str = mr_strip_spaces(device_here);201 202 mr_free(mountpoint_str);203 mountpoint_str = mr_strip_spaces(mountpoint_here);204 205 mr_free(format_str);206 format_str = mr_strip_spaces(format_here);207 208 mr_free(size_str);209 size_str = mr_strip_spaces(size_here);210 211 if (b_res == bOK) {212 if (device_str[strlen(device_str) - 1] == '/') {213 popup_and_OK("You left the device nearly blank!");214 b_res = NULL;215 }216 if (size_of_specific_device_in_mountlist(mountlist, device_str) >= 0) {217 popup_and_OK("Can't add this - you've got one already!");218 b_res = NULL;219 }220 }221 }222 newtFormDestroy(myForm);223 newtPopHelpLine();224 newtPopWindow();225 if (b_res == bCancel) {226 return;227 }228 mr_asprintf(drive_to_add, "%s", device_str);229 for (i = strlen(drive_to_add); isdigit(drive_to_add[i - 1]); i--);230 mr_free(drive_to_add);231 232 currline = mountlist->entries;233 strcpy(mountlist->el[currline].device, device_str);234 strcpy(mountlist->el[currline].mountpoint, mountpoint_str);235 mr_free(mountpoint_str);236 237 strcpy(mountlist->el[currline].format, format_str);238 mr_free(format_str);239 240 mountlist->el[currline].size = atol(size_str) * 1024L;241 mr_free(size_str);242 243 mountlist->entries++;244 if (strstr(mountlist->el[currline].device, RAID_DEVICE_STUB)) {245 initiate_new_raidlist_entry(raidlist, mountlist, currline, device_str);246 }247 mr_free(device_str);248 249 redraw_mountlist(mountlist, keylist, listbox);250 }251 959 252 960 … … 289 997 } 290 998 #endif 999 1000 1001 #ifndef __FreeBSD__ 1002 /** 1003 * Delete entry number @p lino in the additional RAID variables section of @p raidrec. 1004 * @param raidrec The RAID device record containing the RAID variable to delete. 1005 * @param lino The line number (starting from 0) of the variable to delete. 1006 * @ingroup restoreGuiVarslist 1007 */ 1008 void delete_varslist_entry(struct raid_device_record *raidrec, int lino) 1009 { 1010 1011 /** buffers ************************************************************/ 1012 char *tmp = NULL; 1013 int res = 0; 1014 1015 /** structures *********************************************************/ 1016 struct additional_raid_variables *av; 1017 1018 assert(raidrec != NULL); 1019 1020 av = &raidrec->additional_vars; 1021 mr_asprintf(tmp, "Delete %s - are you sure?", av->el[lino].label); 1022 res = ask_me_yes_or_no(tmp); 1023 mr_free(tmp); 1024 1025 if (res) { 1026 if (!strcmp(av->el[lino].label, "persistent-superblock") 1027 || !strcmp(av->el[lino].label, "chunk-size")) { 1028 mr_asprintf(tmp, "%s must not be deleted. It would be bad.", av->el[lino].label); 1029 popup_and_OK(tmp); 1030 mr_free(tmp); 1031 } else { 1032 memcpy((void *) &av->el[lino], (void *) &av->el[av->entries--], 1033 sizeof(struct raid_var_line)); 1034 } 1035 } 1036 } 1037 #endif 1038 1039 1040 1041 #ifndef __FreeBSD__ 1042 /** 1043 * Edit the additional RAID variables in @p raidrec. 1044 * @param raidrec The RAID device record to edit the RAID variables in. 1045 * @ingroup restoreGuiVarslist 1046 */ 1047 void edit_raidrec_additional_vars(struct raid_device_record *raidrec) 1048 { 1049 1050 /** structure *********************************************************/ 1051 struct raid_device_record bkp_raidrec; 1052 1053 /** newt **************************************************************/ 1054 newtComponent myForm; 1055 newtComponent bAdd; 1056 newtComponent bEdit; 1057 newtComponent bDelete; 1058 newtComponent bOK; 1059 newtComponent bCancel; 1060 newtComponent b_res; 1061 newtComponent varsListbox; 1062 newtComponent headerMsg; 1063 1064 /** ?? ***************************************************************/ 1065 void *keylist[ARBITRARY_MAXIMUM], *curr_choice; 1066 1067 /** buffers **********************************************************/ 1068 char title_of_window[MAX_STR_LEN]; 1069 1070 /** int **************************************************************/ 1071 int i = 0; 1072 int currline = 0; 1073 1074 1075 assert(raidrec != NULL); 1076 1077 memcpy((void *) &bkp_raidrec, (void *) raidrec, 1078 sizeof(struct raid_device_record)); 1079 sprintf(title_of_window, "Additional variables"); 1080 newtPushHelpLine 1081 (" Edit the additional fields to your heart's content, then click OK or Cancel."); 1082 headerMsg = newtLabel(1, 1, "Label Value"); 1083 varsListbox = 1084 newtListbox(1, 2, 6, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); 1085 i = 1; 1086 bAdd = newtCompactButton(i, 9, " Add "); 1087 bEdit = newtCompactButton(i += 8, 9, " Edit "); 1088 bDelete = newtCompactButton(i += 9, 9, "Delete"); 1089 bOK = newtCompactButton(i += 9, 9, " OK "); 1090 bCancel = newtCompactButton(i += 9, 9, "Cancel"); 1091 newtOpenWindow(17, 7, 46, 10, title_of_window); 1092 myForm = newtForm(NULL, NULL, 0); 1093 newtFormAddComponents(myForm, headerMsg, varsListbox, bAdd, bEdit, 1094 bDelete, bOK, bCancel, NULL); 1095 insert_essential_additionalvars(raidrec); 1096 redraw_varslist(&raidrec->additional_vars, keylist, varsListbox); 1097 for (b_res = NULL; b_res != bOK && b_res != bCancel;) { 1098 b_res = newtRunForm(myForm); 1099 curr_choice = newtListboxGetCurrent(varsListbox); 1100 for (currline = 0; 1101 currline < raidrec->additional_vars.entries 1102 && keylist[currline] != curr_choice; currline++); 1103 if (currline == raidrec->additional_vars.entries 1104 && raidrec->additional_vars.entries > 0) { 1105 log_it("Warning - I don't know what this button does"); 1106 } 1107 if (b_res == bOK) { /* do nothing */ 1108 } else if (b_res == bCancel) { /* do nothing */ 1109 } else if (b_res == bAdd) { 1110 add_varslist_entry(raidrec); 1111 } else if (b_res == bDelete) { 1112 delete_varslist_entry(raidrec, currline); 1113 } else { 1114 edit_varslist_entry(raidrec, currline); 1115 } 1116 redraw_varslist(&raidrec->additional_vars, keylist, varsListbox); 1117 } 1118 remove_essential_additionalvars(raidrec); 1119 newtFormDestroy(myForm); 1120 newtPopWindow(); 1121 newtPopHelpLine(); 1122 if (b_res == bCancel) { 1123 memcpy((void *) raidrec, (void *) &bkp_raidrec, 1124 sizeof(struct raid_device_record)); 1125 } 1126 return; 1127 } 1128 #endif 1129 291 1130 292 1131 /** … … 445 1284 446 1285 /** 447 * Choose the RAID level for the RAID device record in @p raidrec. 448 * @param raidrec The RAID device record to set the RAID level of. 1286 * Edit the entry for @p raidrec in @p raidlist. 1287 * @param mountlist The mountlist to get some information from. 1288 * @param raidlist The raidlist containing information about RAID devices. 1289 * @param raidrec The RAID device record for this partition. 1290 * @param currline The line number (starting from 0) in the mountlist of the RAID device. 449 1291 * @ingroup restoreGuiMountlist 450 1292 */ 1293 void edit_raidlist_entry(struct mountlist_itself *mountlist, 1294 struct raidlist_itself *raidlist, 1295 struct OSSWAP (raid_device_record, 1296 vinum_volume) * raidrec, int currline) 1297 { 1298 1299 #ifdef __FreeBSD__ 1300 /** structures ********************************************************/ 1301 struct vinum_volume bkp_raidrec; 1302 1303 1304 /** buffers ***********************************************************/ 1305 char title_of_editraidForm_window[MAX_STR_LEN]; 1306 1307 /** newt **************************************************************/ 1308 newtComponent editraidForm; 1309 newtComponent bOK; 1310 newtComponent bCancel; 1311 newtComponent bEdit; 1312 newtComponent bAdd; 1313 newtComponent bDelete; 1314 newtComponent b_res; 1315 newtComponent plexesListbox; 1316 newtComponent plexesHeader; 1317 1318 void *keylist[10]; 1319 void *curr_choice; 1320 char *raidlevel = NULL; 1321 char *chunksize = NULL; 1322 char *msg = NULL; 1323 1324 int currline2 = 0; 1325 int res = 0; 1326 1327 log_it("Started edit_raidlist_entry"); 1328 memcpy((void *) &bkp_raidrec, (void *) raidrec, 1329 sizeof(struct vinum_volume)); 1330 sprintf(title_of_editraidForm_window, "Plexes on %s", 1331 raidrec->volname); 1332 newtPushHelpLine(" Please select a plex to edit"); 1333 newtOpenWindow(13, 5, 54, 15, title_of_editraidForm_window); 1334 for (;;) { 1335 int i; 1336 char *headerstr = NULL; 1337 mr_asprintf(headerstr, "%-14s %-8s %11s %8s", "Plex", "Level", "Stripe Size", "Subdisks"); 1338 1339 bOK = newtCompactButton(2, 13, " OK "); 1340 bCancel = newtCompactButton(12, 13, "Cancel"); 1341 bAdd = newtCompactButton(22, 13, " Add "); 1342 bEdit = newtCompactButton(32, 13, " Edit "); 1343 bDelete = newtCompactButton(42, 13, "Delete"); 1344 1345 plexesListbox = 1346 newtListbox(2, 3, 9, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); 1347 plexesHeader = newtLabel(2, 2, headerstr); 1348 mr_free(headerstr); 1349 editraidForm = newtForm(NULL, NULL, 0); 1350 1351 newtListboxClear(plexesListbox); 1352 for (i = 0; i < 10; ++i) { 1353 keylist[i] = (void *) i; 1354 if (i < raidrec->plexes) { 1355 char *pname; 1356 char *entry; 1357 switch (raidrec->plex[i].raidlevel) { 1358 case -1: 1359 mr_asprintf(raidlevel, "concat"); 1360 break; 1361 case 0: 1362 mr_asprintf(raidlevel, "striped"); 1363 break; 1364 case 5: 1365 mr_asprintf(raidlevel, "raid5"); 1366 break; 1367 default: 1368 mr_asprintf(raidlevel, "raid%i", raidrec->plex[i].raidlevel); 1369 break; 1370 } 1371 1372 if (raidrec->plex[i].raidlevel == -1) { 1373 mr_asprintf(chunksize, "N/A"); 1374 } else { 1375 mr_asprintf(chunksize, "%dk", raidrec->plex[i].stripesize); 1376 } 1377 mr_asprintf(pname, "%s.p%i", raidrec->volname, i); 1378 mr_asprintf(entry, "%-14s %-8s %11s %8d", pname, raidlevel, chunksize, raidrec->plex[i].subdisks); 1379 mr_free(pname); 1380 mr_free(raidlevel); 1381 mr_free(chunksize); 1382 1383 newtListboxAppendEntry(plexesListbox, entry, keylist[i]); 1384 mr_free(entry); 1385 } 1386 } 1387 1388 newtFormAddComponents(editraidForm, bOK, bCancel, bAdd, bEdit, 1389 bDelete, plexesListbox, plexesHeader, NULL); 1390 1391 b_res = newtRunForm(editraidForm); 1392 if (b_res == bOK || b_res == bCancel) { 1393 break; 1394 } 1395 1396 curr_choice = newtListboxGetCurrent(plexesListbox); 1397 for (currline2 = 0; currline2 < raidrec->plexes; ++currline2) { 1398 if (currline2 > 9) 1399 break; 1400 if (keylist[currline2] == curr_choice) 1401 break; 1402 } 1403 1404 if (b_res == bDelete) { 1405 mr_asprintf(msg, "Are you sure you want to delete %s.p%i?", raidrec->volname, currline2); 1406 res = ask_me_yes_or_no(msg); 1407 mr_free(msg); 1408 1409 if (res) { 1410 log_it("Deleting RAID plex"); 1411 memcpy((void *) &raidrec->plex[currline2], 1412 (void *) &raidrec->plex[raidrec->plexes - 1], 1413 sizeof(struct vinum_plex)); 1414 raidrec->plexes--; 1415 } 1416 continue; 1417 } 1418 if (b_res == bAdd) { 1419 raidrec->plex[raidrec->plexes].raidlevel = 0; 1420 raidrec->plex[raidrec->plexes].stripesize = 279; 1421 raidrec->plex[raidrec->plexes].subdisks = 0; 1422 currline2 = raidrec->plexes++; 1423 } 1424 edit_raidlist_plex(mountlist, raidlist, &raidrec->plex[currline2], 1425 currline, currline2); 1426 newtFormDestroy(editraidForm); 1427 } 1428 if (b_res == bCancel) { 1429 memcpy((void *) raidrec, (void *) &bkp_raidrec, 1430 sizeof(struct vinum_volume)); 1431 } 1432 newtPopHelpLine(); 1433 newtPopWindow(); 1434 mountlist->el[currline].size = 1435 calculate_raid_device_size(mountlist, raidlist, raidrec->volname); 1436 #else 1437 /** structures ********************************************************/ 1438 struct raid_device_record *bkp_raidrec; 1439 1440 1441 /** buffers ***********************************************************/ 1442 char *title_of_editraidForm_window; 1443 char *sz_raid_level = NULL; 1444 char *sz_data_disks = NULL; 1445 char *sz_spare_disks = NULL; 1446 char *sz_parity_disks = NULL; 1447 char *sz_failed_disks = NULL; 1448 1449 /** newt **************************************************************/ 1450 newtComponent editraidForm; 1451 newtComponent bOK; 1452 newtComponent bCancel; 1453 newtComponent bAdditional; 1454 newtComponent bChangeRaid; 1455 newtComponent bSelectData; 1456 newtComponent bSelectSpare; 1457 newtComponent bSelectParity; 1458 newtComponent bSelectFailed; 1459 newtComponent b_res; 1460 1461 assert(mountlist != NULL); 1462 assert(raidlist != NULL); 1463 assert(raidrec != NULL); 1464 1465 bkp_raidrec = mr_malloc(sizeof(struct raid_device_record)); 1466 log_it("Started edit_raidlist_entry"); 1467 1468 memcpy((void *) bkp_raidrec, (void *) raidrec, sizeof(struct raid_device_record)); 1469 mr_asprintf(title_of_editraidForm_window, "%s", raidrec->raid_device); 1470 log_msg(2, "Opening newt window"); 1471 newtOpenWindow(20, 5, 40, 14, title_of_editraidForm_window); 1472 for (;;) { 1473 log_msg(2, "Main loop"); 1474 mr_free(title_of_editraidForm_window); 1475 mr_asprintf(title_of_editraidForm_window, "Edit %s", raidrec->raid_device); 1476 sz_raid_level = turn_raid_level_number_to_string(raidrec->raid_level); 1477 sz_data_disks = number_of_disks_as_string(raidrec->data_disks.entries, "data"); 1478 sz_spare_disks = number_of_disks_as_string(raidrec->spare_disks.entries, "spare"); 1479 sz_parity_disks = number_of_disks_as_string(raidrec->parity_disks.entries, "parity"); 1480 sz_failed_disks = number_of_disks_as_string(raidrec->failed_disks.entries, "failed"); 1481 bSelectData = newtButton(1, 1, sz_data_disks); 1482 bSelectSpare = newtButton(20, 1, sz_spare_disks); 1483 bSelectParity = newtButton(1, 5, sz_parity_disks); 1484 bSelectFailed = newtButton(20, 5, sz_failed_disks); 1485 bChangeRaid = newtButton(1, 9, sz_raid_level); 1486 bOK = newtButton(16 + (raidrec->raid_level == -1), 9, " OK "); 1487 bCancel = newtButton(28, 9, "Cancel"); 1488 bAdditional = 1489 newtCompactButton(1, 13, 1490 "Additional settings and information"); 1491 newtPushHelpLine 1492 (" Edit the RAID device's settings to your heart's content, then hit OK/Cancel."); 1493 editraidForm = newtForm(NULL, NULL, 0); 1494 newtFormAddComponents(editraidForm, bSelectData, bSelectParity, 1495 bChangeRaid, bSelectSpare, bSelectFailed, 1496 bOK, bCancel, bAdditional); 1497 b_res = newtRunForm(editraidForm); 1498 if (b_res == bChangeRaid) { 1499 choose_raid_level(raidrec); 1500 } else if (b_res == bSelectData) { 1501 select_raid_disks(mountlist, raidlist, raidrec, "data", &raidrec->data_disks); 1502 } else if (b_res == bSelectSpare) { 1503 select_raid_disks(mountlist, raidlist, raidrec, "spare", &raidrec->spare_disks); 1504 } else if (b_res == bSelectParity) { 1505 select_raid_disks(mountlist, raidlist, raidrec, "parity", &raidrec->parity_disks); 1506 } else if (b_res == bSelectFailed) { 1507 select_raid_disks(mountlist, raidlist, raidrec, "failed", &raidrec->failed_disks); 1508 } else if (b_res == bAdditional) { 1509 edit_raidrec_additional_vars(raidrec); 1510 } 1511 newtFormDestroy(editraidForm); 1512 if (b_res == bOK || b_res == bCancel) { 1513 break; 1514 } 1515 mr_free(sz_data_disks); 1516 mr_free(sz_spare_disks); 1517 mr_free(sz_parity_disks); 1518 mr_free(sz_failed_disks); 1519 } 1520 if (b_res == bCancel) { 1521 memcpy((void *) raidrec, (void *) bkp_raidrec, sizeof(struct raid_device_record)); 1522 } 1523 newtPopHelpLine(); 1524 newtPopWindow(); 1525 mountlist->el[currline].size = calculate_raid_device_size(mountlist, raidlist, raidrec->raid_device); 1526 mr_free(title_of_editraidForm_window); 1527 mr_free(sz_raid_level); 1528 paranoid_free(bkp_raidrec); 1529 #endif 1530 } 1531 1532 1533 /** 1534 * Create a new raidtab entry for @p device in @p raidlist. 1535 * @param raidlist The raidlist to add the device to. 1536 * @param mountlist The mountlist containing information about the user's partitions. 1537 * @param currline The selected line in the mountlist. 1538 * @param device The RAID device (e.g. /dev/md0) to use. 1539 * @ingroup restoreGuiMountlist 1540 */ 451 1541 void 452 choose_raid_level(struct OSSWAP (raid_device_record, vinum_plex) * raidrec) 453 { 454 1542 initiate_new_raidlist_entry(struct raidlist_itself *raidlist, 1543 struct mountlist_itself *mountlist, 1544 int currline, char *device) 1545 { 1546 1547 /** structure *********************************************************/ 1548 struct OSSWAP (raid_device_record, vinum_volume) * raidrec; 1549 1550 /** int ***************************************************************/ 1551 int pos_in_raidlist = 0; 1552 1553 assert(raidlist != NULL); 1554 assert(mountlist != NULL); 1555 assert_string_is_neither_NULL_nor_zerolength(device); 1556 1557 pos_in_raidlist = 1558 find_raid_device_in_raidlist(raidlist, 1559 mountlist->el[currline].device); 1560 if (pos_in_raidlist >= 0) { 1561 fatal_error("Sorry, that RAID device already exists. Weird."); 1562 } 1563 pos_in_raidlist = raidlist->entries++; 1564 raidrec = &raidlist->el[pos_in_raidlist]; 1565 initialize_raidrec(raidrec); 1566 strcpy(raidrec->OSSWAP(raid_device, volname), OSSWAP(device, basename(device))); 1567 #ifndef __FreeBSD__ 1568 choose_raid_level(raidrec); 1569 select_raid_disks(mountlist, raidlist, raidrec, "data", 1570 &raidrec->data_disks); 1571 #endif 1572 edit_raidlist_entry(mountlist, raidlist, raidrec, currline); 1573 } 1574 1575 1576 /** 1577 * Redraw the mountlist. 1578 * @param mountlist The mountlist to read from. 1579 * @param keylist The list of keys for @p listbox. 1580 * @param listbox The Newt listbox component to redraw. 1581 * @ingroup restoreGuiMountlist 1582 */ 1583 void 1584 redraw_mountlist(struct mountlist_itself *mountlist, 1585 void *keylist[ARBITRARY_MAXIMUM], newtComponent listbox) 1586 { 1587 1588 /** long **************************************************************/ 1589 long i = 0; 1590 char * tmp = NULL; 1591 1592 assert(mountlist != NULL); 1593 assert(keylist != NULL); 1594 assert(listbox != NULL); 1595 1596 newtListboxClear(listbox); 1597 // sort_mountlist_by_device (mountlist); 1598 for (i = 0; i < ARBITRARY_MAXIMUM; i++) { 1599 keylist[i] = (void *) i; 1600 } 1601 for (i = 0; i < mountlist->entries; i++) { 1602 tmp = mountlist_entry_to_string(mountlist, i); 1603 newtListboxAppendEntry(listbox, tmp, keylist[i]); 1604 mr_free(tmp); 1605 } 1606 } 1607 1608 1609 1610 1611 /** 1612 * Add an entry to @p mountlist. 1613 * @param mountlist The mountlist to add an entry to. 1614 * @param raidlist The raidlist that accompanies @p mountlist. 1615 * @param listbox The listbox component in the mountlist editor. 1616 * @param currline The line selected in @p listbox. 1617 * @param keylist The list of keys for @p listbox. 1618 * @ingroup restoreGuiMountlist 1619 */ 1620 void 1621 add_mountlist_entry(struct mountlist_itself *mountlist, 1622 struct raidlist_itself *raidlist, 1623 newtComponent listbox, int currline, void *keylist[]) 1624 { 1625 1626 /** int **************************************************************/ 1627 int i = 0; 1628 1629 /** newt *************************************************************/ 1630 newtComponent myForm; 1631 newtComponent bOK; 1632 newtComponent bCancel; 1633 newtComponent b_res; 1634 newtComponent mountpointComp; 1635 newtComponent label0; 1636 newtComponent label1; 1637 newtComponent label2; 1638 newtComponent label3; 1639 newtComponent sizeComp; 1640 newtComponent deviceComp; 1641 newtComponent formatComp; 1642 1643 /** buffers **********************************************************/ 1644 char *drive_to_add = NULL; 1645 char *mountpoint_str = NULL; 1646 char *size_str = NULL; 1647 char *device_str = NULL; 1648 char *format_str = NULL; 1649 1650 /** pointers *********************************************************/ 1651 char *mountpoint_here; 1652 char *size_here; 1653 char *device_here; 1654 char *format_here; 1655 1656 assert(mountlist != NULL); 1657 assert(raidlist != NULL); 1658 assert(listbox != NULL); 1659 assert(keylist != NULL); 1660 1661 mr_asprintf(device_str, "/dev/"); 1662 mr_asprintf(mountpoint_str, "/"); 1663 mr_asprintf(size_str, ""); 455 1664 #ifdef __FreeBSD__ 456 457 /** int ***************************************************************/ 458 int res = 0; 459 int out = 0; 460 461 /** buffers ***********************************************************/ 462 char tmp[MAX_STR_LEN]; 463 char *prompt = NULL; 464 char sz[MAX_STR_LEN]; 465 466 mr_asprintf(prompt, "Please enter the RAID level you want. (concat, striped, raid5)"); 467 if (raidrec->raidlevel == -1) { 468 strcpy(tmp, "concat"); 469 } else if (raidrec->raidlevel == 0) { 470 strcpy(tmp, "striped"); 471 } else { 472 sprintf(tmp, "raid%i", raidrec->raidlevel); 473 } 474 for (out = 999; out == 999;) { 475 res = popup_and_get_string("Specify RAID level", prompt, tmp, 10); 476 if (!res) { 477 mr_free(prompt); 478 return; 479 } 480 strip_spaces(tmp); 481 if (tmp[0] == '[' && tmp[strlen(tmp) - 1] == ']') { 482 strcpy(sz, tmp); 483 strncpy(tmp, sz + 1, strlen(sz) - 2); 484 tmp[strlen(sz) - 2] = '\0'; 485 } 486 if (!strcmp(tmp, "concat")) { 487 out = -1; 488 } else if (!strcmp(tmp, "striped")) { 489 out = 0; 490 } else if (!strcmp(tmp, "raid5")) { 491 out = 5; 492 } 493 log_it(tmp); 494 if (is_this_raid_personality_registered(out)) { 495 log_it("Groovy. You've picked a RAID personality which is registered."); 496 } else { 497 if (ask_me_yes_or_no("You have chosen a RAID personality which is not registered with the kernel. Make another selection?")) 498 { 499 out = 999; 1665 mr_asprintf(format_str, "ufs"); 1666 #else 1667 mr_asprintf(format_str, "ext3"); 1668 #endif 1669 newtOpenWindow(20, 5, 48, 10, "Add entry"); 1670 label0 = newtLabel(2, 1, "Device: "); 1671 label1 = newtLabel(2, 2, "Mountpoint:"); 1672 label2 = newtLabel(2, 3, "Size (MB): "); 1673 label3 = newtLabel(2, 4, "Format: "); 1674 deviceComp = newtEntry(14, 1, device_str, 30, (void *) &device_here, 0); 1675 mountpointComp = newtEntry(14, 2, mountpoint_str, 30, (void *) &mountpoint_here, 0); 1676 formatComp = newtEntry(14, 4, format_str, 15, (void *) &format_here, 0); 1677 sizeComp = newtEntry(14, 3, size_str, 10, (void *) &size_here, 0); 1678 bOK = newtButton(5, 6, " OK "); 1679 bCancel = newtButton(17, 6, "Cancel"); 1680 newtPushHelpLine 1681 ("To add an entry to the mountlist, please fill in these fields and then hit 'OK'"); 1682 myForm = newtForm(NULL, NULL, 0); 1683 newtFormAddComponents(myForm, deviceComp, mountpointComp, sizeComp, 1684 formatComp, label0, label1, label2, label3, bOK, 1685 bCancel, NULL); 1686 for (b_res = NULL; b_res != bOK && b_res != bCancel;) { 1687 b_res = newtRunForm(myForm); 1688 mr_free(device_str); 1689 device_str = mr_strip_spaces(device_here); 1690 1691 mr_free(mountpoint_str); 1692 mountpoint_str = mr_strip_spaces(mountpoint_here); 1693 1694 mr_free(format_str); 1695 format_str = mr_strip_spaces(format_here); 1696 1697 mr_free(size_str); 1698 size_str = mr_strip_spaces(size_here); 1699 1700 if (b_res == bOK) { 1701 if (device_str[strlen(device_str) - 1] == '/') { 1702 popup_and_OK("You left the device nearly blank!"); 1703 b_res = NULL; 500 1704 } 501 } 502 } 503 mr_free(prompt); 504 505 raidrec->raidlevel = out; 506 #else 507 /** buffers ***********************************************************/ 508 char tmp[MAX_STR_LEN]; 509 char *personalities = NULL; 510 char *prompt = NULL; 511 char sz[MAX_STR_LEN]; 512 int out = 0; 513 int res = 0; 514 515 516 assert(raidrec != NULL); 517 paranoid_system("grep Pers /proc/mdstat > /tmp/raid-personalities.txt 2> /dev/null"); 518 mr_asprintf(personalities, "%s", last_line_of_file("/tmp/raid-personalities.txt")); 519 mr_asprintf(prompt, "Please enter the RAID level you want. %s", personalities); 520 mr_free(personalities); 521 522 if (raidrec->raid_level == -1) { 523 strcpy(tmp, "linear"); 524 } else { 525 sprintf(tmp, "%d", raidrec->raid_level); 526 } 527 for (out = 999; 528 out != -1 && out != 0 && out != 1 && out != 4 && out != 5 529 && out != 10;) { 530 res = popup_and_get_string("Specify RAID level", prompt, tmp, 10); 531 if (!res) { 532 return; 533 } 534 strip_spaces(tmp); 535 if (tmp[0] == '[' && tmp[strlen(tmp) - 1] == ']') { 536 strcpy(sz, tmp); 537 strncpy(tmp, sz + 1, strlen(sz) - 2); 538 tmp[strlen(sz) - 2] = '\0'; 539 } 540 if (!strcmp(tmp, "linear")) { 541 out = -1; 542 } else if (!strncmp(tmp, "raid", 4)) { 543 out = atoi(tmp + 4); 544 } else { 545 out = atoi(tmp); 546 } 547 log_it(tmp); 548 if (is_this_raid_personality_registered(out)) { 549 log_it("Groovy. You've picked a RAID personality which is registered."); 550 } else { 551 if (ask_me_yes_or_no("You have chosen a RAID personality which is not registered with the kernel. Make another selection?")) { 552 out = 999; 1705 if (size_of_specific_device_in_mountlist(mountlist, device_str) >= 0) { 1706 popup_and_OK("Can't add this - you've got one already!"); 1707 b_res = NULL; 553 1708 } 554 1709 } 555 1710 } 556 mr_free(prompt); 557 558 raidrec->raid_level = out; 559 #endif 1711 newtFormDestroy(myForm); 1712 newtPopHelpLine(); 1713 newtPopWindow(); 1714 if (b_res == bCancel) { 1715 return; 1716 } 1717 mr_asprintf(drive_to_add, "%s", device_str); 1718 for (i = strlen(drive_to_add); isdigit(drive_to_add[i - 1]); i--); 1719 mr_free(drive_to_add); 1720 1721 currline = mountlist->entries; 1722 strcpy(mountlist->el[currline].device, device_str); 1723 strcpy(mountlist->el[currline].mountpoint, mountpoint_str); 1724 mr_free(mountpoint_str); 1725 1726 strcpy(mountlist->el[currline].format, format_str); 1727 mr_free(format_str); 1728 1729 mountlist->el[currline].size = atol(size_str) * 1024L; 1730 mr_free(size_str); 1731 1732 mountlist->entries++; 1733 if (strstr(mountlist->el[currline].device, RAID_DEVICE_STUB)) { 1734 initiate_new_raidlist_entry(raidlist, mountlist, currline, device_str); 1735 } 1736 mr_free(device_str); 1737 1738 redraw_mountlist(mountlist, keylist, listbox); 560 1739 } 561 1740 … … 601 1780 602 1781 603 604 /**605 * Delete entry number @p currline from @p disklist.606 * @param disklist The disklist to remove the entry from.607 * @param raid_device The RAID device containing the partition we're removing.608 * Used only in the popup "are you sure?" box.609 * @param currline The line number (starting from 0) of the item to delete.610 * @ingroup restoreGuiDisklist611 */612 void613 delete_disklist_entry(struct list_of_disks *disklist, char *raid_device,614 int currline)615 {616 617 /** int ***************************************************************/618 int pos = 0;619 int res = 0;620 621 /** buffers ***********************************************************/622 char *tmp = NULL;623 624 assert(disklist != NULL);625 assert_string_is_neither_NULL_nor_zerolength(raid_device);626 627 mr_asprintf(tmp, "Delete %s from RAID device %s - are you sure?", disklist->el[currline].device, raid_device);628 res = ask_me_yes_or_no(tmp);629 mr_free(tmp);630 631 if (!res) {632 return;633 }634 for (pos = currline; pos < disklist->entries - 1; pos++) {635 strcpy(disklist->el[pos].device, disklist->el[pos + 1].device);636 }637 disklist->entries--;638 }639 640 641 642 /**643 * Delete entry number @p currline from @p mountlist.644 * @param mountlist The mountlist to delete the entry from.645 * @param raidlist The raidlist that goes with @p mountlist.646 * @param listbox The Newt listbox component in the mountlist editor.647 * @param currline The line number (starting from 0) of the item to delete.648 * @param keylist The list of keys for @p listbox.649 * @ingroup restoreGuiMountlist650 */651 void652 delete_mountlist_entry(struct mountlist_itself *mountlist,653 struct raidlist_itself *raidlist,654 newtComponent listbox, int currline,655 void *keylist[])656 {657 658 /** int ***************************************************************/659 int pos = 0;660 int res = 0;661 662 /** buffers ***********************************************************/663 char *tmp = NULL;664 char *device = NULL;665 666 667 assert(mountlist != NULL);668 assert(raidlist != NULL);669 assert(listbox != NULL);670 assert(keylist != NULL);671 672 pos = which_raid_device_is_using_this_partition(raidlist, mountlist->el[currline].device);673 if (pos >= 0) {674 mr_asprintf(tmp, "Cannot delete %s: it is in use by RAID device %s", mountlist->el[currline].device, raidlist->el[pos].OSSWAP(raid_device, volname));675 popup_and_OK(tmp);676 mr_free(tmp);677 return;678 }679 mr_asprintf(tmp, "Delete %s - are you sure?", mountlist->el[currline].device);680 res = ask_me_yes_or_no(tmp);681 mr_free(tmp);682 683 if (!res) {684 return;685 }686 if (strstr(mountlist->el[currline].device, RAID_DEVICE_STUB)) {687 mr_asprintf(device, "%s", mountlist->el[currline].device);688 delete_raidlist_entry(mountlist, raidlist, device);689 for (currline = 0;690 currline < mountlist->entries691 && strcmp(mountlist->el[currline].device, device);692 currline++);693 mr_free(device);694 695 if (currline == mountlist->entries) {696 log_it("Dev is gone. I can't delete it. Ho-hum");697 return;698 }699 }700 memcpy((void *) &mountlist->el[currline],701 (void *) &mountlist->el[mountlist->entries - 1],702 sizeof(struct mountlist_line));703 mountlist->entries--;704 redraw_mountlist(mountlist, keylist, listbox);705 }706 707 708 1782 /** 709 1783 * Delete @p device from @p raidlist. … … 713 1787 * @ingroup restoreGuiMountlist 714 1788 */ 715 void 716 delete_raidlist_entry(struct mountlist_itself *mountlist, 1789 void delete_raidlist_entry(struct mountlist_itself *mountlist, 717 1790 struct raidlist_itself *raidlist, char *device) 718 1791 { … … 783 1856 784 1857 785 #ifndef __FreeBSD__ 786 /** 787 * Delete entry number @p lino in the additional RAID variables section of @p raidrec. 788 * @param raidrec The RAID device record containing the RAID variable to delete. 789 * @param lino The line number (starting from 0) of the variable to delete. 790 * @ingroup restoreGuiVarslist 791 */ 792 void delete_varslist_entry(struct raid_device_record *raidrec, int lino) 793 { 794 795 /** buffers ************************************************************/ 1858 1859 /** 1860 * Delete entry number @p currline from @p mountlist. 1861 * @param mountlist The mountlist to delete the entry from. 1862 * @param raidlist The raidlist that goes with @p mountlist. 1863 * @param listbox The Newt listbox component in the mountlist editor. 1864 * @param currline The line number (starting from 0) of the item to delete. 1865 * @param keylist The list of keys for @p listbox. 1866 * @ingroup restoreGuiMountlist 1867 */ 1868 void 1869 delete_mountlist_entry(struct mountlist_itself *mountlist, 1870 struct raidlist_itself *raidlist, 1871 newtComponent listbox, int currline, 1872 void *keylist[]) 1873 { 1874 1875 /** int ***************************************************************/ 1876 int pos = 0; 1877 int res = 0; 1878 1879 /** buffers ***********************************************************/ 796 1880 char *tmp = NULL; 797 int res = 0; 798 799 /** structures *********************************************************/ 800 struct additional_raid_variables *av; 801 802 assert(raidrec != NULL); 803 804 av = &raidrec->additional_vars; 805 mr_asprintf(tmp, "Delete %s - are you sure?", av->el[lino].label); 1881 char *device = NULL; 1882 1883 1884 assert(mountlist != NULL); 1885 assert(raidlist != NULL); 1886 assert(listbox != NULL); 1887 assert(keylist != NULL); 1888 1889 pos = which_raid_device_is_using_this_partition(raidlist, mountlist->el[currline].device); 1890 if (pos >= 0) { 1891 mr_asprintf(tmp, "Cannot delete %s: it is in use by RAID device %s", mountlist->el[currline].device, raidlist->el[pos].OSSWAP(raid_device, volname)); 1892 popup_and_OK(tmp); 1893 mr_free(tmp); 1894 return; 1895 } 1896 mr_asprintf(tmp, "Delete %s - are you sure?", mountlist->el[currline].device); 806 1897 res = ask_me_yes_or_no(tmp); 807 1898 mr_free(tmp); 808 1899 809 if (res) { 810 if (!strcmp(av->el[lino].label, "persistent-superblock") 811 || !strcmp(av->el[lino].label, "chunk-size")) { 812 mr_asprintf(tmp, "%s must not be deleted. It would be bad.", av->el[lino].label); 813 popup_and_OK(tmp); 814 mr_free(tmp); 1900 if (!res) { 1901 return; 1902 } 1903 if (strstr(mountlist->el[currline].device, RAID_DEVICE_STUB)) { 1904 mr_asprintf(device, "%s", mountlist->el[currline].device); 1905 delete_raidlist_entry(mountlist, raidlist, device); 1906 for (currline = 0; 1907 currline < mountlist->entries 1908 && strcmp(mountlist->el[currline].device, device); 1909 currline++); 1910 mr_free(device); 1911 1912 if (currline == mountlist->entries) { 1913 log_it("Dev is gone. I can't delete it. Ho-hum"); 1914 return; 1915 } 1916 } 1917 memcpy((void *) &mountlist->el[currline], 1918 (void *) &mountlist->el[mountlist->entries - 1], 1919 sizeof(struct mountlist_line)); 1920 mountlist->entries--; 1921 redraw_mountlist(mountlist, keylist, listbox); 1922 } 1923 1924 1925 /** 1926 * Strip a path to the bare minimum (^ pointing to the directory above, plus filename). 1927 * @param tmp The path to strip. 1928 * @return The stripped path. 1929 * @author Conor Daly 1930 * @ingroup restoreUtilityGroup 1931 */ 1932 char *strip_path(char *tmp) 1933 { 1934 1935 int i = 0, j = 0, slashcount = 0; 1936 int slashloc = 0, lastslashloc = 0; 1937 1938 while (tmp[i] != '\0') { /* Count the slashes in tmp 1939 1 slash per dir */ 1940 if (tmp[i] == '/') { 1941 slashcount++; 1942 lastslashloc = slashloc; 1943 slashloc = i; 1944 if (tmp[i + 1] == '\0') { /* if this slash is last char, back off */ 1945 slashcount--; 1946 slashloc = lastslashloc; 1947 } 1948 } 1949 i++; 1950 } 1951 if (slashcount > 0) 1952 slashcount--; /* Keep one slash 'cos Hugh does... */ 1953 1954 for (i = 0; i < slashcount; i++) { /* Replace each dir with a space char */ 1955 tmpnopath[i] = ' '; 1956 } 1957 1958 i = slashloc; 1959 j = slashcount; 1960 while (tmp[i] != '\0') { /* Now add what's left of tmp */ 1961 if ((tmpprevpath[j] == ' ' || tmpprevpath[j] == '^') 1962 && tmp[i] == '/' && tmpnopath[j - 1] != '^' && j != 0) { /* Add a pointer upwards if this is not in the same dir as line above */ 1963 tmpnopath[j - 1] = '^'; 815 1964 } else { 816 memcpy((void *) &av->el[lino], (void *) &av->el[av->entries--], 817 sizeof(struct raid_var_line)); 818 } 819 } 820 } 821 #endif 1965 tmpnopath[j++] = tmp[i++]; 1966 } 1967 } 1968 tmpnopath[j] = '\0'; 1969 1970 strcpy(tmpprevpath, tmpnopath); /* Make a copy for next iteration */ 1971 1972 return (tmpnopath); 1973 } 1974 822 1975 823 1976 … … 924 2077 return (0); 925 2078 } 926 }927 928 929 /**930 * Strip a path to the bare minimum (^ pointing to the directory above, plus filename).931 * @param tmp The path to strip.932 * @return The stripped path.933 * @author Conor Daly934 * @ingroup restoreUtilityGroup935 */936 char *strip_path(char *tmp)937 {938 939 int i = 0, j = 0, slashcount = 0;940 int slashloc = 0, lastslashloc = 0;941 942 while (tmp[i] != '\0') { /* Count the slashes in tmp943 1 slash per dir */944 if (tmp[i] == '/') {945 slashcount++;946 lastslashloc = slashloc;947 slashloc = i;948 if (tmp[i + 1] == '\0') { /* if this slash is last char, back off */949 slashcount--;950 slashloc = lastslashloc;951 }952 }953 i++;954 }955 if (slashcount > 0)956 slashcount--; /* Keep one slash 'cos Hugh does... */957 958 for (i = 0; i < slashcount; i++) { /* Replace each dir with a space char */959 tmpnopath[i] = ' ';960 }961 962 i = slashloc;963 j = slashcount;964 while (tmp[i] != '\0') { /* Now add what's left of tmp */965 if ((tmpprevpath[j] == ' ' || tmpprevpath[j] == '^')966 && tmp[i] == '/' && tmpnopath[j - 1] != '^' && j != 0) { /* Add a pointer upwards if this is not in the same dir as line above */967 tmpnopath[j - 1] = '^';968 } else {969 tmpnopath[j++] = tmp[i++];970 }971 }972 tmpnopath[j] = '\0';973 974 strcpy(tmpprevpath, tmpnopath); /* Make a copy for next iteration */975 976 return (tmpnopath);977 2079 } 978 2080 … … 1113 2215 1114 2216 /** 2217 * Change all RAID devices to use @p new_dev instead of @p old_dev. 2218 * @param raidlist The raidlist to make the changes in. 2219 * @param old_dev The old name of the device (what it used to be). 2220 * @param new_dev The new name of the device (what it is now). 2221 * @ingroup restoreGuiMountlist 2222 */ 2223 void rejig_partition_name_in_raidlist_if_necessary(struct raidlist_itself 2224 *raidlist, 2225 char *old_dev, 2226 char *new_dev) 2227 { 2228 /** int ************************************************************/ 2229 int pos = 0; 2230 int j = 0; 2231 2232 assert(raidlist != NULL); 2233 assert_string_is_neither_NULL_nor_zerolength(old_dev); 2234 assert_string_is_neither_NULL_nor_zerolength(new_dev); 2235 2236 pos = which_raid_device_is_using_this_partition(raidlist, old_dev); 2237 if (pos < 0) { 2238 log_it("No need to rejig %s in raidlist: it's not listed.", old_dev); 2239 } else { 2240 if ((j = 2241 where_in_drivelist_is_drive(&raidlist-> 2242 OSSWAP(el[pos].data_disks, disks), 2243 old_dev)) >= 0) { 2244 strcpy(raidlist->OSSWAP(el[pos].data_disks, disks).el[j].device, new_dev); 2245 } else 2246 if ((j = 2247 where_in_drivelist_is_drive(&raidlist-> 2248 OSSWAP(el[pos].spare_disks, 2249 spares), 2250 old_dev)) >= 0) { 2251 strcpy(raidlist->OSSWAP(el[pos].spare_disks, spares).el[j].device, new_dev); 2252 } 2253 #ifndef __FreeBSD__ 2254 else if ((j = 2255 where_in_drivelist_is_drive(&raidlist->el[pos]. 2256 parity_disks, 2257 old_dev)) >= 0) { 2258 strcpy(raidlist->el[pos].parity_disks.el[j].device, new_dev); 2259 } else 2260 if ((j = 2261 where_in_drivelist_is_drive(&raidlist->el[pos]. 2262 failed_disks, 2263 old_dev)) >= 0) { 2264 strcpy(raidlist->el[pos].failed_disks.el[j].device, new_dev); 2265 } 2266 #endif 2267 else { 2268 log_it("%s is supposed to be listed in this raid dev but it's not...", old_dev); 2269 } 2270 } 2271 } 2272 2273 2274 /** 1115 2275 * Edit an entry in @p mountlist. 1116 2276 * @param mountlist The mountlist containing information about the user's partitions. … … 1380 2540 struct vinum_plex *raidrec, int currline, 1381 2541 int currline2); 1382 1383 #endif1384 1385 1386 /**1387 * Edit the entry for @p raidrec in @p raidlist.1388 * @param mountlist The mountlist to get some information from.1389 * @param raidlist The raidlist containing information about RAID devices.1390 * @param raidrec The RAID device record for this partition.1391 * @param currline The line number (starting from 0) in the mountlist of the RAID device.1392 * @ingroup restoreGuiMountlist1393 */1394 void1395 edit_raidlist_entry(struct mountlist_itself *mountlist,1396 struct raidlist_itself *raidlist,1397 struct OSSWAP (raid_device_record,1398 vinum_volume) * raidrec, int currline)1399 {1400 1401 #ifdef __FreeBSD__1402 /** structures ********************************************************/1403 struct vinum_volume bkp_raidrec;1404 1405 1406 /** buffers ***********************************************************/1407 char title_of_editraidForm_window[MAX_STR_LEN];1408 1409 /** newt **************************************************************/1410 newtComponent editraidForm;1411 newtComponent bOK;1412 newtComponent bCancel;1413 newtComponent bEdit;1414 newtComponent bAdd;1415 newtComponent bDelete;1416 newtComponent b_res;1417 newtComponent plexesListbox;1418 newtComponent plexesHeader;1419 1420 void *keylist[10];1421 void *curr_choice;1422 char *raidlevel = NULL;1423 char *chunksize = NULL;1424 char *msg = NULL;1425 1426 int currline2 = 0;1427 int res = 0;1428 1429 log_it("Started edit_raidlist_entry");1430 memcpy((void *) &bkp_raidrec, (void *) raidrec,1431 sizeof(struct vinum_volume));1432 sprintf(title_of_editraidForm_window, "Plexes on %s",1433 raidrec->volname);1434 newtPushHelpLine(" Please select a plex to edit");1435 newtOpenWindow(13, 5, 54, 15, title_of_editraidForm_window);1436 for (;;) {1437 int i;1438 char *headerstr = NULL;1439 mr_asprintf(headerstr, "%-14s %-8s %11s %8s", "Plex", "Level", "Stripe Size", "Subdisks");1440 1441 bOK = newtCompactButton(2, 13, " OK ");1442 bCancel = newtCompactButton(12, 13, "Cancel");1443 bAdd = newtCompactButton(22, 13, " Add ");1444 bEdit = newtCompactButton(32, 13, " Edit ");1445 bDelete = newtCompactButton(42, 13, "Delete");1446 1447 plexesListbox =1448 newtListbox(2, 3, 9, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);1449 plexesHeader = newtLabel(2, 2, headerstr);1450 mr_free(headerstr);1451 editraidForm = newtForm(NULL, NULL, 0);1452 1453 newtListboxClear(plexesListbox);1454 for (i = 0; i < 10; ++i) {1455 keylist[i] = (void *) i;1456 if (i < raidrec->plexes) {1457 char *pname;1458 char *entry;1459 switch (raidrec->plex[i].raidlevel) {1460 case -1:1461 mr_asprintf(raidlevel, "concat");1462 break;1463 case 0:1464 mr_asprintf(raidlevel, "striped");1465 break;1466 case 5:1467 mr_asprintf(raidlevel, "raid5");1468 break;1469 default:1470 mr_asprintf(raidlevel, "raid%i", raidrec->plex[i].raidlevel);1471 break;1472 }1473 1474 if (raidrec->plex[i].raidlevel == -1) {1475 mr_asprintf(chunksize, "N/A");1476 } else {1477 mr_asprintf(chunksize, "%dk", raidrec->plex[i].stripesize);1478 }1479 mr_asprintf(pname, "%s.p%i", raidrec->volname, i);1480 mr_asprintf(entry, "%-14s %-8s %11s %8d", pname, raidlevel, chunksize, raidrec->plex[i].subdisks);1481 mr_free(pname);1482 mr_free(raidlevel);1483 mr_free(chunksize);1484 1485 newtListboxAppendEntry(plexesListbox, entry, keylist[i]);1486 mr_free(entry);1487 }1488 }1489 1490 newtFormAddComponents(editraidForm, bOK, bCancel, bAdd, bEdit,1491 bDelete, plexesListbox, plexesHeader, NULL);1492 1493 b_res = newtRunForm(editraidForm);1494 if (b_res == bOK || b_res == bCancel) {1495 break;1496 }1497 1498 curr_choice = newtListboxGetCurrent(plexesListbox);1499 for (currline2 = 0; currline2 < raidrec->plexes; ++currline2) {1500 if (currline2 > 9)1501 break;1502 if (keylist[currline2] == curr_choice)1503 break;1504 }1505 1506 if (b_res == bDelete) {1507 mr_asprintf(msg, "Are you sure you want to delete %s.p%i?", raidrec->volname, currline2);1508 res = ask_me_yes_or_no(msg);1509 mr_free(msg);1510 1511 if (res) {1512 log_it("Deleting RAID plex");1513 memcpy((void *) &raidrec->plex[currline2],1514 (void *) &raidrec->plex[raidrec->plexes - 1],1515 sizeof(struct vinum_plex));1516 raidrec->plexes--;1517 }1518 continue;1519 }1520 if (b_res == bAdd) {1521 raidrec->plex[raidrec->plexes].raidlevel = 0;1522 raidrec->plex[raidrec->plexes].stripesize = 279;1523 raidrec->plex[raidrec->plexes].subdisks = 0;1524 currline2 = raidrec->plexes++;1525 }1526 edit_raidlist_plex(mountlist, raidlist, &raidrec->plex[currline2],1527 currline, currline2);1528 newtFormDestroy(editraidForm);1529 }1530 if (b_res == bCancel) {1531 memcpy((void *) raidrec, (void *) &bkp_raidrec,1532 sizeof(struct vinum_volume));1533 }1534 newtPopHelpLine();1535 newtPopWindow();1536 mountlist->el[currline].size =1537 calculate_raid_device_size(mountlist, raidlist, raidrec->volname);1538 #else1539 /** structures ********************************************************/1540 struct raid_device_record *bkp_raidrec;1541 1542 1543 /** buffers ***********************************************************/1544 char *title_of_editraidForm_window;1545 char *sz_raid_level = NULL;1546 char *sz_data_disks = NULL;1547 char *sz_spare_disks = NULL;1548 char *sz_parity_disks = NULL;1549 char *sz_failed_disks = NULL;1550 1551 /** newt **************************************************************/1552 newtComponent editraidForm;1553 newtComponent bOK;1554 newtComponent bCancel;1555 newtComponent bAdditional;1556 newtComponent bChangeRaid;1557 newtComponent bSelectData;1558 newtComponent bSelectSpare;1559 newtComponent bSelectParity;1560 newtComponent bSelectFailed;1561 newtComponent b_res;1562 1563 assert(mountlist != NULL);1564 assert(raidlist != NULL);1565 assert(raidrec != NULL);1566 1567 bkp_raidrec = mr_malloc(sizeof(struct raid_device_record));1568 log_it("Started edit_raidlist_entry");1569 1570 memcpy((void *) bkp_raidrec, (void *) raidrec, sizeof(struct raid_device_record));1571 mr_asprintf(title_of_editraidForm_window, "%s", raidrec->raid_device);1572 log_msg(2, "Opening newt window");1573 newtOpenWindow(20, 5, 40, 14, title_of_editraidForm_window);1574 for (;;) {1575 log_msg(2, "Main loop");1576 mr_free(title_of_editraidForm_window);1577 mr_asprintf(title_of_editraidForm_window, "Edit %s", raidrec->raid_device);1578 sz_raid_level = turn_raid_level_number_to_string(raidrec->raid_level);1579 sz_data_disks = number_of_disks_as_string(raidrec->data_disks.entries, "data");1580 sz_spare_disks = number_of_disks_as_string(raidrec->spare_disks.entries, "spare");1581 sz_parity_disks = number_of_disks_as_string(raidrec->parity_disks.entries, "parity");1582 sz_failed_disks = number_of_disks_as_string(raidrec->failed_disks.entries, "failed");1583 bSelectData = newtButton(1, 1, sz_data_disks);1584 bSelectSpare = newtButton(20, 1, sz_spare_disks);1585 bSelectParity = newtButton(1, 5, sz_parity_disks);1586 bSelectFailed = newtButton(20, 5, sz_failed_disks);1587 bChangeRaid = newtButton(1, 9, sz_raid_level);1588 bOK = newtButton(16 + (raidrec->raid_level == -1), 9, " OK ");1589 bCancel = newtButton(28, 9, "Cancel");1590 bAdditional =1591 newtCompactButton(1, 13,1592 "Additional settings and information");1593 newtPushHelpLine1594 (" Edit the RAID device's settings to your heart's content, then hit OK/Cancel.");1595 editraidForm = newtForm(NULL, NULL, 0);1596 newtFormAddComponents(editraidForm, bSelectData, bSelectParity,1597 bChangeRaid, bSelectSpare, bSelectFailed,1598 bOK, bCancel, bAdditional);1599 b_res = newtRunForm(editraidForm);1600 if (b_res == bChangeRaid) {1601 choose_raid_level(raidrec);1602 } else if (b_res == bSelectData) {1603 select_raid_disks(mountlist, raidlist, raidrec, "data", &raidrec->data_disks);1604 } else if (b_res == bSelectSpare) {1605 select_raid_disks(mountlist, raidlist, raidrec, "spare", &raidrec->spare_disks);1606 } else if (b_res == bSelectParity) {1607 select_raid_disks(mountlist, raidlist, raidrec, "parity", &raidrec->parity_disks);1608 } else if (b_res == bSelectFailed) {1609 select_raid_disks(mountlist, raidlist, raidrec, "failed", &raidrec->failed_disks);1610 } else if (b_res == bAdditional) {1611 edit_raidrec_additional_vars(raidrec);1612 }1613 newtFormDestroy(editraidForm);1614 if (b_res == bOK || b_res == bCancel) {1615 break;1616 }1617 mr_free(sz_data_disks);1618 mr_free(sz_spare_disks);1619 mr_free(sz_parity_disks);1620 mr_free(sz_failed_disks);1621 }1622 if (b_res == bCancel) {1623 memcpy((void *) raidrec, (void *) bkp_raidrec, sizeof(struct raid_device_record));1624 }1625 newtPopHelpLine();1626 newtPopWindow();1627 mountlist->el[currline].size = calculate_raid_device_size(mountlist, raidlist, raidrec->raid_device);1628 mr_free(title_of_editraidForm_window);1629 mr_free(sz_raid_level);1630 paranoid_free(bkp_raidrec);1631 #endif1632 }1633 1634 #ifdef __FreeBSD__1635 1636 /**1637 * Edit the plex @p raidrec in @p raidlist.1638 * @param mountlist The mountlist to get some of the information from.1639 * @param raidlist The raidlist containing information about RAID devices.1640 * @param raidrec The plex to edit.1641 * @param currline The line number (starting from 0) of the RAID device in @p mountlist.1642 * @param currline2 The line number (starting from 0) of the plex within the RAID device.1643 * @author Joshua Oreman1644 * @ingroup restoreGuiMountlist1645 */1646 void1647 edit_raidlist_plex(struct mountlist_itself *mountlist,1648 struct raidlist_itself *raidlist,1649 struct vinum_plex *raidrec, int currline, int currline2)1650 {1651 1652 /** structures ********************************************************/1653 struct vinum_plex bkp_raidrec;1654 1655 1656 /** buffers ***********************************************************/1657 char *title_of_editraidForm_window = NULL;1658 1659 /** newt **************************************************************/1660 newtComponent editraidForm;1661 newtComponent bOK;1662 newtComponent bCancel;1663 newtComponent bEdit;1664 newtComponent bAdd;1665 newtComponent bDelete;1666 newtComponent b_res;1667 newtComponent unallocListbox, allocListbox;1668 newtComponent bLevel, sLevel;1669 newtComponent bStripeSize, sStripeSize;1670 newtComponent bAlloc, bUnalloc;1671 1672 void *keylist[ARBITRARY_MAXIMUM];1673 void *curr_choice_a, *curr_choice_u;1674 int currline_a, currline_u;1675 1676 char *p = NULL;1677 char *tmp = NULL;1678 char *entry = NULL;1679 1680 struct mountlist_itself *unallocparts;1681 1682 unallocparts = malloc(sizeof(struct mountlist_itself));1683 1684 log_it("Started edit_raidlist_entry");1685 memcpy((void *) &bkp_raidrec, (void *) raidrec,1686 sizeof(struct vinum_plex));1687 mr_asprintf(title_of_editraidForm_window, "%s.p%i", raidlist->el[currline].volname, currline2);1688 newtPushHelpLine1689 (" Please select a subdisk to edit, or edit this plex's parameters");1690 newtOpenWindow(13, 3, 54, 18, title_of_editraidForm_window);1691 mr_free(title_of_editraidForm_window);1692 1693 for (;;) {1694 int i;1695 1696 switch (raidrec->raidlevel) {1697 case -1:1698 mr_asprintf(tmp, "concat");1699 break;1700 case 0:1701 mr_asprintf(tmp, "striped");1702 break;1703 case 5:1704 mr_asprintf(tmp, "raid5");1705 break;1706 default:1707 mr_asprintf(tmp, "unknown (%i)", raidrec->raidlevel);1708 break;1709 }1710 bLevel = newtCompactButton(2, 2, " RAID level ");1711 sLevel = newtLabel(19, 2, tmp);1712 mr_free(tmp);1713 1714 if (raidrec->raidlevel >= 0) {1715 mr_asprintf(tmp, "%ik", raidrec->stripesize);1716 bStripeSize = newtCompactButton(2, 4, " Stripe size ");1717 } else {1718 mr_asprintf(tmp, "N/A");1719 bStripeSize = newtLabel(2, 4, "Stripe size:");1720 }1721 sStripeSize = newtLabel(19, 4, tmp);1722 mr_free(tmp);1723 1724 bOK = newtCompactButton(2, 16, " OK ");1725 bCancel = newtCompactButton(12, 16, "Cancel");1726 bAdd = newtCompactButton(22, 16, " Add ");1727 bEdit = newtCompactButton(32, 16, " Edit ");1728 bDelete = newtCompactButton(42, 16, "Delete");1729 1730 1731 unallocListbox =1732 newtListbox(2, 7, 7, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);1733 allocListbox =1734 newtListbox(33, 7, 7, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);1735 bAlloc = newtButton(23, 7, " -> ");1736 bUnalloc = newtButton(23, 11, " <- ");1737 1738 editraidForm = newtForm(NULL, NULL, 0);1739 1740 newtListboxClear(allocListbox);1741 newtListboxClear(unallocListbox);1742 bzero(unallocparts, sizeof(struct mountlist_itself));1743 make_list_of_unallocated_raid_partitions(unallocparts, mountlist,1744 raidlist);1745 for (i = 0; i < ARBITRARY_MAXIMUM; ++i) {1746 keylist[i] = (void *) i;1747 if (i < raidrec->subdisks) {1748 mr_asprintf(entry, "%-17s", find_dev_entry_for_raid_device_name(raidlist, raidrec->sd[i].which_device));1749 newtListboxAppendEntry(allocListbox, entry, keylist[i]);1750 mr_free(entry);1751 }1752 if (i < unallocparts->entries) {1753 mr_asprintf(entry, "%-17s", unallocparts->el[i].device);1754 newtListboxAppendEntry(unallocListbox, entry, keylist[i]);1755 mr_free(entry);1756 }1757 }1758 1759 #define COMP(x) newtFormAddComponent (editraidForm, x)1760 #define UCOMP(x) if (unallocparts->entries > 0) COMP(x)1761 #define ACOMP(x) if (raidrec->subdisks > 0) COMP(x)1762 editraidForm = newtForm(NULL, NULL, 0);1763 UCOMP(unallocListbox);1764 UCOMP(bAlloc);1765 ACOMP(allocListbox);1766 ACOMP(bUnalloc);1767 COMP(bOK);1768 COMP(bCancel);1769 COMP(bLevel);1770 COMP(sLevel);1771 if (raidrec->raidlevel != -1) {1772 COMP(bStripeSize);1773 COMP(sStripeSize);1774 }1775 #undef COMP1776 #undef UCOMP1777 #undef ACOMP1778 1779 newtDrawForm(editraidForm);1780 newtRefresh();1781 b_res = newtRunForm(editraidForm);1782 if (b_res == bOK || b_res == bCancel) {1783 break;1784 }1785 1786 curr_choice_a = (raidrec->subdisks > 0) ?1787 newtListboxGetCurrent(allocListbox) : (void *) 1234;1788 curr_choice_u = (unallocparts->entries > 0) ?1789 newtListboxGetCurrent(unallocListbox) : (void *) 1234;1790 for (currline_a = 0; currline_a < raidrec->subdisks; ++currline_a) {1791 if (currline_a > ARBITRARY_MAXIMUM)1792 break;1793 if (keylist[currline_a] == curr_choice_a)1794 break;1795 }1796 for (currline_u = 0; currline_u < unallocparts->entries;1797 ++currline_u) {1798 if (currline_u > ARBITRARY_MAXIMUM)1799 break;1800 if (keylist[currline_u] == curr_choice_u)1801 break;1802 }1803 if (b_res == bLevel) {1804 choose_raid_level(raidrec);1805 } else if (b_res == bStripeSize) {1806 char tmp1[64];1807 sprintf(tmp1, "%i", raidrec->stripesize);1808 if (popup_and_get_string1809 ("Stripe size",1810 "Please enter the stripe size in kilobytes.", tmp1, 20)) {1811 raidrec->stripesize = atoi(tmp1);1812 }1813 } else if ((b_res == bAlloc) || (b_res == unallocListbox)) {1814 if (currline_u <= unallocparts->entries)1815 add_raid_subdisk(raidlist, raidrec,1816 unallocparts->el[currline_u].device);1817 } else if ((b_res == bUnalloc) || (b_res == allocListbox)) {1818 if (currline_a <= raidrec->subdisks) {1819 memcpy((void *) &raidrec->sd[currline_a],1820 (void *) &raidrec->sd[raidrec->subdisks - 1],1821 sizeof(struct vinum_subdisk));1822 raidrec->subdisks--;1823 }1824 }1825 newtFormDestroy(editraidForm);1826 newtRefresh();1827 }1828 1829 if (b_res == bCancel) {1830 memcpy((void *) raidrec, (void *) &bkp_raidrec, sizeof(struct vinum_plex));1831 }1832 newtPopWindow();1833 newtPopHelpLine();1834 }1835 #else1836 /**1837 * Edit additional RAID variable number @p lino.1838 * @param raidrec The RAID device record to edit the variable in.1839 * @param lino The line number (starting from 0) of the variable to edit.1840 * @ingroup restoreGuiVarslist1841 */1842 void edit_varslist_entry(struct raid_device_record *raidrec, int lino)1843 {1844 1845 /** buffers ***********************************************************/1846 char *header = NULL;1847 char *comment = NULL;1848 char sz_out[MAX_STR_LEN];1849 1850 assert(raidrec != 0);1851 assert(lino >= 0);1852 1853 strcpy(sz_out, raidrec->additional_vars.el[lino].value);1854 mr_asprintf(header, "Edit %s", raidrec->additional_vars.el[lino].label);1855 mr_asprintf(comment, "Please set %s's value (currently '%s')", raidrec->additional_vars.el[lino].label, sz_out);1856 if (popup_and_get_string(header, comment, sz_out, MAX_STR_LEN)) {1857 strip_spaces(sz_out);1858 strcpy(raidrec->additional_vars.el[lino].value, sz_out);1859 }1860 mr_free(header);1861 mr_free(comment);1862 }1863 2542 1864 2543 #endif … … 2048 2727 } 2049 2728 2050 2051 2052 2053 #ifndef __FreeBSD__2054 /**2055 * Edit the additional RAID variables in @p raidrec.2056 * @param raidrec The RAID device record to edit the RAID variables in.2057 * @ingroup restoreGuiVarslist2058 */2059 void edit_raidrec_additional_vars(struct raid_device_record *raidrec)2060 {2061 2062 /** structure *********************************************************/2063 struct raid_device_record bkp_raidrec;2064 2065 /** newt **************************************************************/2066 newtComponent myForm;2067 newtComponent bAdd;2068 newtComponent bEdit;2069 newtComponent bDelete;2070 newtComponent bOK;2071 newtComponent bCancel;2072 newtComponent b_res;2073 newtComponent varsListbox;2074 newtComponent headerMsg;2075 2076 /** ?? ***************************************************************/2077 void *keylist[ARBITRARY_MAXIMUM], *curr_choice;2078 2079 /** buffers **********************************************************/2080 char title_of_window[MAX_STR_LEN];2081 2082 /** int **************************************************************/2083 int i = 0;2084 int currline = 0;2085 2086 2087 assert(raidrec != NULL);2088 2089 memcpy((void *) &bkp_raidrec, (void *) raidrec,2090 sizeof(struct raid_device_record));2091 sprintf(title_of_window, "Additional variables");2092 newtPushHelpLine2093 (" Edit the additional fields to your heart's content, then click OK or Cancel.");2094 headerMsg = newtLabel(1, 1, "Label Value");2095 varsListbox =2096 newtListbox(1, 2, 6, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);2097 i = 1;2098 bAdd = newtCompactButton(i, 9, " Add ");2099 bEdit = newtCompactButton(i += 8, 9, " Edit ");2100 bDelete = newtCompactButton(i += 9, 9, "Delete");2101 bOK = newtCompactButton(i += 9, 9, " OK ");2102 bCancel = newtCompactButton(i += 9, 9, "Cancel");2103 newtOpenWindow(17, 7, 46, 10, title_of_window);2104 myForm = newtForm(NULL, NULL, 0);2105 newtFormAddComponents(myForm, headerMsg, varsListbox, bAdd, bEdit,2106 bDelete, bOK, bCancel, NULL);2107 insert_essential_additionalvars(raidrec);2108 redraw_varslist(&raidrec->additional_vars, keylist, varsListbox);2109 for (b_res = NULL; b_res != bOK && b_res != bCancel;) {2110 b_res = newtRunForm(myForm);2111 curr_choice = newtListboxGetCurrent(varsListbox);2112 for (currline = 0;2113 currline < raidrec->additional_vars.entries2114 && keylist[currline] != curr_choice; currline++);2115 if (currline == raidrec->additional_vars.entries2116 && raidrec->additional_vars.entries > 0) {2117 log_it("Warning - I don't know what this button does");2118 }2119 if (b_res == bOK) { /* do nothing */2120 } else if (b_res == bCancel) { /* do nothing */2121 } else if (b_res == bAdd) {2122 add_varslist_entry(raidrec);2123 } else if (b_res == bDelete) {2124 delete_varslist_entry(raidrec, currline);2125 } else {2126 edit_varslist_entry(raidrec, currline);2127 }2128 redraw_varslist(&raidrec->additional_vars, keylist, varsListbox);2129 }2130 remove_essential_additionalvars(raidrec);2131 newtFormDestroy(myForm);2132 newtPopWindow();2133 newtPopHelpLine();2134 if (b_res == bCancel) {2135 memcpy((void *) raidrec, (void *) &bkp_raidrec,2136 sizeof(struct raid_device_record));2137 }2138 return;2139 }2140 #endif2141 2142 2143 /**2144 * Find the next free location to place a disk in @p disklist.2145 * @param disklist The disklist to operate on.2146 * @return The next free location (starting from 0).2147 * @ingroup restoreGuiDisklist2148 */2149 int find_next_free_index_in_disklist(struct list_of_disks *disklist)2150 {2151 2152 /** int ***************************************************************/2153 int index = -1;2154 int pos = 0;2155 2156 /** bool **************************************************************/2157 bool done;2158 2159 assert(disklist != NULL);2160 2161 for (done = FALSE; !done;) {2162 for (pos = 0;2163 pos < disklist->entries && disklist->el[pos].index <= index;2164 pos++);2165 if (pos >= disklist->entries) {2166 done = TRUE;2167 } else {2168 index = disklist->el[pos].index;2169 }2170 }2171 return (index + 1);2172 }2173 2174 2175 2176 /**2177 * Locate @p device in @p raidlist.2178 * @param raidlist The raidlist ot search in.2179 * @param device The RAID device to search for.2180 * @return The index of the device, or -1 if it could not be found.2181 * @ingroup restoreGuiMountlist2182 */2183 int2184 find_raid_device_in_raidlist(struct raidlist_itself *raidlist,2185 char *device)2186 {2187 2188 /** int ***************************************************************/2189 int i = 0;2190 #ifdef __FreeBSD__2191 char *vdev = NULL;2192 int res = 0;2193 #else2194 // Linux2195 #endif2196 2197 assert(raidlist != NULL);2198 assert_string_is_neither_NULL_nor_zerolength(device);2199 2200 #ifdef __FreeBSD__2201 for (i = 0; i < raidlist->entries; i++) {2202 mr_asprintf(vdev, "/dev/vinum/%s", raidlist->el[i].volname);2203 res = strcmp(device, vdev);2204 mr_free(vdev);2205 2206 if (!res)2207 break;2208 }2209 #else2210 2211 for (i = 0;2212 strcmp(raidlist->el[i].raid_device, device)2213 && i < raidlist->entries; i++);2214 #endif2215 if (i == raidlist->entries) {2216 return (-1);2217 } else {2218 return (i);2219 }2220 }2221 2222 2223 /**2224 * Create a new raidtab entry for @p device in @p raidlist.2225 * @param raidlist The raidlist to add the device to.2226 * @param mountlist The mountlist containing information about the user's partitions.2227 * @param currline The selected line in the mountlist.2228 * @param device The RAID device (e.g. /dev/md0) to use.2229 * @ingroup restoreGuiMountlist2230 */2231 void2232 initiate_new_raidlist_entry(struct raidlist_itself *raidlist,2233 struct mountlist_itself *mountlist,2234 int currline, char *device)2235 {2236 2237 /** structure *********************************************************/2238 struct OSSWAP (raid_device_record, vinum_volume) * raidrec;2239 2240 /** int ***************************************************************/2241 int pos_in_raidlist = 0;2242 2243 assert(raidlist != NULL);2244 assert(mountlist != NULL);2245 assert_string_is_neither_NULL_nor_zerolength(device);2246 2247 pos_in_raidlist =2248 find_raid_device_in_raidlist(raidlist,2249 mountlist->el[currline].device);2250 if (pos_in_raidlist >= 0) {2251 fatal_error("Sorry, that RAID device already exists. Weird.");2252 }2253 pos_in_raidlist = raidlist->entries++;2254 raidrec = &raidlist->el[pos_in_raidlist];2255 initialize_raidrec(raidrec);2256 strcpy(raidrec->OSSWAP(raid_device, volname), OSSWAP(device, basename(device)));2257 #ifndef __FreeBSD__2258 choose_raid_level(raidrec);2259 select_raid_disks(mountlist, raidlist, raidrec, "data",2260 &raidrec->data_disks);2261 #endif2262 edit_raidlist_entry(mountlist, raidlist, raidrec, currline);2263 }2264 2265 2266 #ifndef __FreeBSD__2267 /**2268 * Insert the RAID variables not stored in the "additional RAID variables" list there too.2269 * @param raidrec The RAID device record to operate on.2270 * @ingroup restoreGuiVarslist2271 */2272 void insert_essential_additionalvars(struct raid_device_record *raidrec)2273 {2274 2275 /** int **************************************************************/2276 int items = 0;2277 2278 assert(raidrec != NULL);2279 2280 items = raidrec->additional_vars.entries;2281 write_variableINT_to_raid_var_line(raidrec, items++,2282 "persistent-superblock",2283 raidrec->persistent_superblock);2284 write_variableINT_to_raid_var_line(raidrec, items++, "chunk-size",2285 raidrec->chunk_size);2286 raidrec->additional_vars.entries = items;2287 }2288 2289 #endif2290 2291 2729 /** 2292 2730 * Dummy function that proves that we can get to the point where Mondo is run. … … 2314 2752 newtPopHelpLine(); 2315 2753 } 2316 2317 2318 2319 /**2320 * Redraw the disklist.2321 * @param disklist The disklist to read from.2322 * @param keylist The list of keys for @p listbox.2323 * @param listbox The Newt listbox component to redraw.2324 * @ingroup restoreGuiDisklist2325 */2326 void2327 redraw_disklist(struct list_of_disks *disklist,2328 void *keylist[ARBITRARY_MAXIMUM], newtComponent listbox)2329 {2330 2331 /** long **************************************************************/2332 long i = 0;2333 char *tmp = NULL;2334 2335 assert(disklist != NULL);2336 assert(keylist != NULL);2337 assert(listbox != NULL);2338 2339 newtListboxClear(listbox);2340 2341 for (i = 0; i < ARBITRARY_MAXIMUM; i++) {2342 keylist[i] = (void *) i;2343 }2344 for (i = 0; i < disklist->entries; i++) {2345 tmp = disklist_entry_to_string(disklist, i);2346 newtListboxAppendEntry(listbox, tmp, keylist[i]);2347 mr_free(tmp);2348 }2349 }2350 2351 2352 /**2353 * Redraw the mountlist.2354 * @param mountlist The mountlist to read from.2355 * @param keylist The list of keys for @p listbox.2356 * @param listbox The Newt listbox component to redraw.2357 * @ingroup restoreGuiMountlist2358 */2359 void2360 redraw_mountlist(struct mountlist_itself *mountlist,2361 void *keylist[ARBITRARY_MAXIMUM], newtComponent listbox)2362 {2363 2364 /** long **************************************************************/2365 long i = 0;2366 char * tmp = NULL;2367 2368 assert(mountlist != NULL);2369 assert(keylist != NULL);2370 assert(listbox != NULL);2371 2372 newtListboxClear(listbox);2373 // sort_mountlist_by_device (mountlist);2374 for (i = 0; i < ARBITRARY_MAXIMUM; i++) {2375 keylist[i] = (void *) i;2376 }2377 for (i = 0; i < mountlist->entries; i++) {2378 tmp = mountlist_entry_to_string(mountlist, i);2379 newtListboxAppendEntry(listbox, tmp, keylist[i]);2380 mr_free(tmp);2381 }2382 }2383 2384 2385 2386 2387 /**2388 * Redraw the list of unallocated RAID partitions.2389 * @param unallocated_raid_partitions The mountlist containing unallocated RAID partitions.2390 * @param keylist The list of keys for @p listbox.2391 * @param listbox The Newt listbox component to redraw.2392 * @ingroup restoreGuiDisklist2393 */2394 void redraw_unallocpartnslist(struct mountlist_itself2395 *unallocated_raid_partitions,2396 void *keylist[ARBITRARY_MAXIMUM],2397 newtComponent listbox)2398 {2399 2400 /** long *************************************************************/2401 long i = 0;2402 2403 /** buffers **********************************************************/2404 char tmp[MAX_STR_LEN];2405 2406 assert(unallocated_raid_partitions != NULL);2407 assert(keylist != NULL);2408 assert(listbox != NULL);2409 2410 newtListboxClear(listbox);2411 for (i = 0; i < ARBITRARY_MAXIMUM; i++) {2412 keylist[i] = (void *) i;2413 }2414 for (i = 0; i < unallocated_raid_partitions->entries; i++) {2415 sprintf(tmp, "%-22s %8lld",2416 unallocated_raid_partitions->el[i].device,2417 unallocated_raid_partitions->el[i].size / 1024L);2418 newtListboxAppendEntry(listbox, tmp, keylist[i]);2419 }2420 }2421 2422 #ifndef __FreeBSD__2423 /**2424 * Redraw the list of additional RAID variables.2425 * @param additional_vars The list of additional RAID varibals.2426 * @param keylist The list of keys for @p listbox.2427 * @param listbox The Newt listbox component to redraw.2428 * @ingroup restoreGuiVarslist2429 */2430 void2431 redraw_varslist(struct additional_raid_variables *additional_vars,2432 void *keylist[], newtComponent listbox)2433 {2434 /** long ************************************************************/2435 long i = 0;2436 2437 /** buffers *********************************************************/2438 char tmp[MAX_STR_LEN];2439 2440 assert(additional_vars != NULL);2441 assert(keylist != NULL);2442 assert(listbox != NULL);2443 2444 newtListboxClear(listbox);2445 2446 for (i = 0; i < ARBITRARY_MAXIMUM; i++) {2447 keylist[i] = (void *) i;2448 }2449 for (i = 0; i < additional_vars->entries; i++) {2450 sprintf(tmp, "%-32s %-8s", additional_vars->el[i].label,2451 additional_vars->el[i].value);2452 newtListboxAppendEntry(listbox, tmp, keylist[i]);2453 }2454 }2455 2456 2457 /**2458 * Remove variable @p label from the RAID variables list in @p raidrec.2459 * @param raidrec The RAID device record to remove the variable from.2460 * @param label The variable name to remove.2461 * @return The value of the variable removed.2462 * @ingroup restoreUtilityGroup2463 */2464 int2465 read_variableINT_and_remove_from_raidvars(struct2466 OSSWAP (raid_device_record,2467 vinum_volume) * raidrec,2468 char *label)2469 {2470 /** int ***************************************************************/2471 int i = 0;2472 int res = 0;2473 2474 2475 assert(raidrec != NULL);2476 assert(label != NULL);2477 2478 for (i = 0;2479 i < raidrec->additional_vars.entries2480 && strcmp(raidrec->additional_vars.el[i].label, label); i++);2481 if (i == raidrec->additional_vars.entries) {2482 res = -1;2483 } else {2484 res = atoi(raidrec->additional_vars.el[i].value);2485 for (i++; i < raidrec->additional_vars.entries; i++) {2486 memcpy((void *) &raidrec->additional_vars.el[i - 1],2487 (void *) &raidrec->additional_vars.el[i],2488 sizeof(struct raid_var_line));2489 }2490 raidrec->additional_vars.entries--;2491 }2492 return (res);2493 }2494 #endif2495 2496 /**2497 * Change all RAID devices to use @p new_dev instead of @p old_dev.2498 * @param raidlist The raidlist to make the changes in.2499 * @param old_dev The old name of the device (what it used to be).2500 * @param new_dev The new name of the device (what it is now).2501 * @ingroup restoreGuiMountlist2502 */2503 void rejig_partition_name_in_raidlist_if_necessary(struct raidlist_itself2504 *raidlist,2505 char *old_dev,2506 char *new_dev)2507 {2508 /** int ************************************************************/2509 int pos = 0;2510 int j = 0;2511 2512 assert(raidlist != NULL);2513 assert_string_is_neither_NULL_nor_zerolength(old_dev);2514 assert_string_is_neither_NULL_nor_zerolength(new_dev);2515 2516 pos = which_raid_device_is_using_this_partition(raidlist, old_dev);2517 if (pos < 0) {2518 log_it("No need to rejig %s in raidlist: it's not listed.", old_dev);2519 } else {2520 if ((j =2521 where_in_drivelist_is_drive(&raidlist->2522 OSSWAP(el[pos].data_disks, disks),2523 old_dev)) >= 0) {2524 strcpy(raidlist->OSSWAP(el[pos].data_disks, disks).el[j].device, new_dev);2525 } else2526 if ((j =2527 where_in_drivelist_is_drive(&raidlist->2528 OSSWAP(el[pos].spare_disks,2529 spares),2530 old_dev)) >= 0) {2531 strcpy(raidlist->OSSWAP(el[pos].spare_disks, spares).el[j].device, new_dev);2532 }2533 #ifndef __FreeBSD__2534 else if ((j =2535 where_in_drivelist_is_drive(&raidlist->el[pos].2536 parity_disks,2537 old_dev)) >= 0) {2538 strcpy(raidlist->el[pos].parity_disks.el[j].device, new_dev);2539 } else2540 if ((j =2541 where_in_drivelist_is_drive(&raidlist->el[pos].2542 failed_disks,2543 old_dev)) >= 0) {2544 strcpy(raidlist->el[pos].failed_disks.el[j].device, new_dev);2545 }2546 #endif2547 else {2548 log_it("%s is supposed to be listed in this raid dev but it's not...", old_dev);2549 }2550 }2551 }2552 2553 2554 #ifndef __FreeBSD__2555 /**2556 * Remove the essential RAID variables from the "additional variables" section.2557 * If they have been changed, set them in their normal locations too.2558 * @param raidrec The RAID device record to operate on.2559 * @ingroup restoreUtilityVarslist2560 */2561 void remove_essential_additionalvars(struct raid_device_record *raidrec)2562 {2563 2564 /** int **************************************************************/2565 int res = 0;2566 2567 assert(raidrec != NULL);2568 2569 res =2570 read_variableINT_and_remove_from_raidvars(raidrec,2571 "persistent-superblock");2572 if (res > 0) {2573 raidrec->persistent_superblock = res;2574 }2575 res = read_variableINT_and_remove_from_raidvars(raidrec, "chunk-size");2576 if (res > 0) {2577 raidrec->chunk_size = res;2578 }2579 res = read_variableINT_and_remove_from_raidvars(raidrec, "block-size");2580 }2581 2582 /**2583 * Select the RAID disks to use in @p raidrec.2584 * @param mountlist_dontedit The mountlist (will not be edited).2585 * @param raidlist The raidlist to modify.2586 * @param raidrec The RAID device record in @p raidlist to work on.2587 * @param description_of_list The type of disks we're selecting (e.g. "data").2588 * @param disklist The disklist to put the user-selected disks in.2589 * @ingroup restoreGuiMountlist2590 */2591 void2592 select_raid_disks(struct mountlist_itself *mountlist_dontedit,2593 struct raidlist_itself *raidlist,2594 struct raid_device_record *raidrec,2595 char *description_of_list,2596 struct list_of_disks *disklist)2597 {2598 void *curr_choice;2599 2600 /** ??? ***************************************************************/2601 2602 /** structures ********************************************************/2603 struct raidlist_itself *bkp_raidlist;2604 struct raid_device_record *bkp_raidrec;2605 struct list_of_disks *bkp_disklist;2606 struct mountlist_itself *unallocated_raid_partitions;2607 2608 /** newt **************************************************************/2609 newtComponent myForm = NULL;2610 newtComponent bAdd = NULL;2611 newtComponent bDelete = NULL;2612 newtComponent bOK = NULL;2613 newtComponent bCancel = NULL;2614 newtComponent b_res = NULL;2615 newtComponent partitionsListbox = NULL;2616 newtComponent headerMsg = NULL;2617 2618 /** buffers **********************************************************/2619 void *keylist[ARBITRARY_MAXIMUM];2620 char *tmp = NULL;2621 char *help_text = NULL;2622 char *title_of_window = NULL;2623 char sz_res[MAX_STR_LEN];2624 char *header_text = NULL;2625 2626 /** int **************************************************************/2627 int i = 0;2628 int currline = 0;2629 2630 assert(mountlist_dontedit != NULL);2631 assert(raidlist != NULL);2632 assert(raidrec != NULL);2633 assert(description_of_list != NULL);2634 assert(disklist != NULL);2635 2636 log_it("malloc'ing");2637 bkp_raidrec = mr_malloc(sizeof(struct raid_device_record));2638 bkp_disklist = mr_malloc(sizeof(struct list_of_disks));2639 bkp_raidlist = mr_malloc(sizeof(struct raidlist_itself));2640 unallocated_raid_partitions = mr_malloc(sizeof(struct mountlist_itself));2641 2642 memcpy((void *) bkp_raidlist, (void *) raidlist, sizeof(struct raidlist_itself));2643 memcpy((void *) bkp_raidrec, (void *) raidrec, sizeof(struct raid_device_record));2644 memcpy((void *) bkp_disklist, (void *) disklist, sizeof(struct list_of_disks));2645 2646 log_it("Post-malloc");2647 mr_asprintf(help_text, " Edit this RAID device's list of partitions. Choose OK or Cancel when done.");2648 mr_asprintf(header_text, "%-24s %s", "Device", "Index");2649 mr_asprintf(title_of_window, "%s contains...", raidrec->raid_device);2650 newtPushHelpLine(help_text);2651 for (b_res = (newtComponent) 12345; b_res != bOK && b_res != bCancel;) {2652 headerMsg = newtLabel(1, 1, header_text);2653 partitionsListbox =2654 newtListbox(1, 2, 6, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);2655 redraw_disklist(disklist, keylist, partitionsListbox);2656 i = 1;2657 bAdd = newtCompactButton(i, 9, " Add ");2658 bDelete = newtCompactButton(i += 8, 9, "Delete");2659 bOK = newtCompactButton(i += 9, 9, " OK ");2660 bCancel = newtCompactButton(i += 9, 9, "Cancel");2661 newtOpenWindow(21, 7, 38, 10, title_of_window);2662 myForm = newtForm(NULL, NULL, 0);2663 if (disklist->entries == 0) {2664 newtFormAddComponents(myForm, headerMsg, bAdd, bDelete, bOK,2665 bCancel, NULL);2666 } else {2667 newtFormAddComponents(myForm, headerMsg, partitionsListbox,2668 bAdd, bDelete, bOK, bCancel, NULL);2669 }2670 b_res = newtRunForm(myForm);2671 if (b_res == bOK || b_res == bCancel) { /* do nothing */2672 // That's OK. At the end of this subroutine (after this do/while loop),2673 // we'll throw away the changes if Cancel was pushed.2674 } else {2675 curr_choice = newtListboxGetCurrent(partitionsListbox);2676 for (i = 0; i < disklist->entries && keylist[i] != curr_choice;2677 i++);2678 if (i == disklist->entries && disklist->entries > 0) {2679 log_to_screen("I don't know what that button does!");2680 } else {2681 currline = i;2682 if (b_res == bAdd) {2683 log_it("Making list of unallocated RAID slices");2684 make_list_of_unallocated_raid_partitions2685 (unallocated_raid_partitions, mountlist_dontedit,2686 raidlist);2687 if (unallocated_raid_partitions->entries <= 0) {2688 popup_and_OK2689 ("There are no unallocated partitions marked for RAID.");2690 } else {2691 log_it2692 ("Done. The user may add one or more of the above to RAID device");2693 add_disklist_entry(disklist, raidrec->raid_device,2694 unallocated_raid_partitions);2695 log_it("I have finished adding a disklist entry.");2696 redraw_disklist(disklist, keylist,2697 partitionsListbox);2698 }2699 } else if (b_res == bDelete) {2700 delete_disklist_entry(disklist, raidrec->raid_device,2701 currline);2702 redraw_disklist(disklist, keylist, partitionsListbox);2703 } else {2704 mr_asprintf(tmp, "%s's index is %d. What should it be?", raidrec->raid_device, disklist->el[currline].index);2705 sprintf(sz_res, "%d", disklist->el[currline].index);2706 if (popup_and_get_string("Set index", tmp, sz_res, 10)) {2707 disklist->el[currline].index = atoi(sz_res);2708 }2709 mr_free(tmp);2710 2711 redraw_disklist(disklist, keylist, partitionsListbox);2712 }2713 }2714 }2715 newtFormDestroy(myForm);2716 newtPopWindow();2717 }2718 newtPopHelpLine();2719 mr_free(help_text);2720 mr_free(header_text);2721 mr_free(title_of_window);2722 2723 if (b_res == bCancel) {2724 memcpy((void *) raidlist, (void *) bkp_raidlist, sizeof(struct raidlist_itself));2725 memcpy((void *) raidrec, (void *) bkp_raidrec, sizeof(struct raid_device_record));2726 memcpy((void *) disklist, (void *) bkp_disklist, sizeof(struct list_of_disks));2727 }2728 mr_free(bkp_raidrec);2729 mr_free(bkp_disklist);2730 mr_free(bkp_raidlist);2731 mr_free(unallocated_raid_partitions);2732 }2733 #endif2734 2735 2736 2754 2737 2755 /** -
branches/3.3/mondo/src/mondorestore/mondo-rstr-tools.c
r3876 r3879 10 10 #include "mr_file.h" 11 11 #include "mr_sys.h" 12 #include "../common/mondostructures.h" 13 #include "../common/libmondo.h" 14 #include "mr-externs.h" 15 #include "mondo-rstr-tools.h" 12 #include "mondostructures.h" 16 13 #include "libmondo-mountlist-EXT.h" 14 #include "libmondo-tools-EXT.h" 15 #include "libmondo-filelist-EXT.h" 16 #include "libmondo-files-EXT.h" 17 #include "libmondo-devices-EXT.h" 18 #include "libmondo-string-EXT.h" 19 #include "libmondo-raid-EXT.h" 20 #include "libmondo-fork-EXT.h" 17 21 #include "newt-specific-EXT.h" 22 // no include for now in mondo-rstr-newt.c 23 extern int edit_filelist(struct s_node *); 18 24 19 25 /** … … 74 80 extern char *g_mountlist_fname; // where mountlist.txt (the mountlist file) is stored 75 81 extern char *g_mondo_home; // homedir of Mondo; usually /usr/local/share/mondo 82 extern int g_currentY; 83 extern bool g_restoring_live_from_cd; 84 extern bool g_text_mode; 85 extern int g_current_media_number; 76 86 77 87 extern t_bkptype g_backup_media_type; … … 169 179 170 180 171 181 /** 182 * Extract mondorestore.cfg and the mountlist from the tape inserted 183 * to the ./tmp/ directory. 184 * @param dev The tape device to read from. 185 * @return 0 for success, nonzero for failure. 186 */ 187 int extract_cfg_file_and_mountlist_from_tape_dev(char *dev) 188 { 189 char *command = NULL; 190 int res = 0; 191 192 if (bkpinfo->use_obdr) { 193 skip_obdr(); 194 } else { 195 // TODO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.0 196 set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size); 197 } 198 199 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); 200 log_msg(2, "command = '%s'", command); 201 res = run_program_and_log_output(command, -1); 202 mr_free(command); 203 204 if (res != 0) { 205 if (does_file_exist(MONDO_CFG_FILE_STUB)) { 206 res = 0; 207 } else { 208 /* Doing that allow us to remain compatible with pre-2.2.5 versions */ 209 log_msg(2, "pre-2.2.4 compatible mode on"); 210 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); 211 log_msg(2, "command = '%s'", command); 212 res = run_program_and_log_output(command, -1); 213 mr_free(command); 214 if ((res != 0) && (does_file_exist(MONDO_CFG_FILE_STUB))) { 215 res = 0; 216 } 217 } 218 } 219 paranoid_free(command); 220 return (res); 221 } 222 223 224 225 226 227 /** 228 * Get the configuration file from the tape, or CD. 229 * @param bkpinfo The backup information structure. Fields used: 230 * - @c bkpinfo->backup_media_type 231 * - @c bkpinfo->media_device 232 * - @c bkpinfo->tmpdir 233 * @return 0 for success, nonzero for failure. 234 */ 235 int get_cfg_file_from_archive() 236 { 237 int retval = 0; 238 239 /** malloc *****/ 240 char *command = NULL; 241 char *cfg_file = NULL; 242 char *tmp = NULL; 243 char *tmp1 = NULL; 244 char *mountpt = NULL; 245 char *mountlist_file = NULL; 246 bool extract_mountlist_stub = FALSE; 247 bool extract_i_want_my_lvm = FALSE; 248 249 bool try_plan_B; 250 251 assert(bkpinfo != NULL); 252 log_msg(2, "gcffa --- starting"); 253 log_to_screen("I'm thinking..."); 254 mr_asprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir); 255 if (chdir(bkpinfo->tmpdir)) { 256 // FIXME 257 } 258 mr_asprintf(cfg_file, "%s", MONDO_CFG_FILE_STUB); 259 unlink(cfg_file); // cfg_file[] is missing the '/' at the start, FYI, by intent 260 mr_free(cfg_file); 261 262 unlink(FILELIST_FULL_STUB); 263 unlink(BIGGIELIST_TXT_STUB); 264 mr_asprintf(command, "mkdir -p %s", mountpt); 265 run_program_and_log_output(command, FALSE); 266 mr_free(command); 267 268 mr_asprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB); 269 mr_asprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB); 270 log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file); 271 mr_free(mountpt); 272 273 if (!does_file_exist(cfg_file)) { 274 log_msg(2, "gcffa --- we don't have cfg file yet."); 275 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 276 try_plan_B = TRUE; 277 } else { 278 log_msg(2, "gcffa --- calling mount_media now :)"); 279 if (!mount_media(MNT_CDROM)) { 280 log_msg(2, "gcffa --- managed to mount CD; so, no need for Plan B"); 281 try_plan_B = FALSE; 282 } else { 283 try_plan_B = TRUE; 284 } 285 if (what_number_cd_is_this() > 1) { 286 insist_on_this_cd_number((g_current_media_number = 1)); 287 } 288 } 289 if (try_plan_B) { 290 log_msg(2, "gcffa --- OK, switching to Plan B"); 291 if (chdir(bkpinfo->tmpdir)) { 292 // FIXME 293 } 294 run_program_and_log_output("mkdir -p tmp", FALSE); 295 296 if (bkpinfo->media_device == NULL) { 297 mr_asprintf(bkpinfo->media_device, "%s", "/dev/st0"); 298 log_msg(2, "media_device is blank; assuming %s", bkpinfo->media_device); 299 } 300 mr_asprintf(tmp, "%s", bkpinfo->media_device); 301 if (extract_cfg_file_and_mountlist_from_tape_dev(bkpinfo->media_device)) { 302 mr_free(bkpinfo->media_device); 303 mr_asprintf(bkpinfo->media_device, "%s", "/dev/st0"); 304 if (extract_cfg_file_and_mountlist_from_tape_dev(bkpinfo->media_device)) { 305 mr_free(bkpinfo->media_device); 306 mr_asprintf(bkpinfo->media_device, "%s", "/dev/osst0"); 307 if (extract_cfg_file_and_mountlist_from_tape_dev(bkpinfo->media_device)) { 308 mr_free(bkpinfo->media_device); 309 mr_asprintf(bkpinfo->media_device, "%s", "/dev/ht0"); 310 if (extract_cfg_file_and_mountlist_from_tape_dev(bkpinfo->media_device)) { 311 log_msg(3, "I tried lots of devices but none worked."); 312 mr_free(bkpinfo->media_device); 313 } 314 } 315 } 316 } 317 if (bkpinfo->media_device == NULL) { 318 bkpinfo->media_device = tmp; 319 } else { 320 mr_free(tmp); 321 } 322 323 if (!does_file_exist("tmp/mondorestore.cfg")) { 324 log_to_screen("Cannot find config info on media"); 325 return (1); 326 } 327 } else { 328 if (does_file_exist("/"MOUNTLIST_FNAME_STUB)) { 329 extract_mountlist_stub = FALSE; 330 } else { 331 extract_mountlist_stub = TRUE; 332 } 333 if (does_file_exist("/"IWANTMYLVM_STUB)) { 334 extract_i_want_my_lvm = FALSE; 335 } else { 336 extract_i_want_my_lvm = TRUE; 337 } 338 339 log_msg(2, "gcffa --- Plan B, a.k.a. untarring some file from all.tar.gz"); 340 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 341 run_program_and_log_output(command, TRUE); 342 mr_free(command); 343 344 if (!does_file_exist(MONDO_CFG_FILE_STUB)) { 345 /* Doing that allow us to remain compatible with pre-2.2.5 versions */ 346 log_msg(2, "pre-2.2.4 compatible mode on"); 347 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 348 run_program_and_log_output(command, TRUE); 349 mr_free(command); 350 if (!does_file_exist(MONDO_CFG_FILE_STUB)) { 351 fatal_error 352 ("Please reinsert the disk/CD and try again."); 353 } 354 } 355 } 356 } 357 if (does_file_exist(MONDO_CFG_FILE_STUB)) { 358 log_msg(1, "gcffa --- great! We've got the config file"); 359 tmp1 = call_program_and_get_last_line_of_output("pwd"); 360 mr_asprintf(tmp, "%s/%s", tmp1, MONDO_CFG_FILE_STUB); 361 mr_asprintf(command, "cp -f %s %s", tmp, cfg_file); 362 log_it("%s",command); 363 if (strcmp(tmp, cfg_file) && run_program_and_log_output(command, 1)) { 364 log_msg(1, 365 "... but an error occurred when I tried to move it to %s", 366 cfg_file); 367 } else { 368 log_msg(1, "... and I moved it successfully to %s", cfg_file); 369 } 370 mr_free(command); 371 372 mr_asprintf(command, "cp -f %s/%s %s", tmp1, MOUNTLIST_FNAME_STUB, mountlist_file); 373 mr_free(tmp1); 374 log_it("%s",command); 375 if (extract_mountlist_stub) { 376 if (strcmp(tmp, cfg_file) && run_program_and_log_output(command, 1)) { 377 log_msg(1, "Failed to get mountlist"); 378 } else { 379 log_msg(1, "Got mountlist too"); 380 mr_free(command); 381 mr_asprintf(command, "cp -f %s %s", mountlist_file, g_mountlist_fname); 382 if (run_program_and_log_output(command, 1)) { 383 log_msg(1, "Failed to copy mountlist to /tmp"); 384 } else { 385 log_msg(1, "Copied mountlist to /tmp as well OK"); 386 mr_free(command); 387 mr_asprintf(command, "cp -f %s /tmp/",IWANTMYLVM_STUB); 388 run_program_and_log_output(command, 1); 389 } 390 } 391 } 392 mr_free(command); 393 mr_free(tmp); 394 } 395 396 run_program_and_log_output("umount -d " MNT_CDROM, FALSE); 397 if (!does_file_exist(cfg_file)) { 398 log_it("%s",cfg_file); 399 log_msg(1, "%s not found", cfg_file); 400 log_to_screen("Oh dear. Unable to recover configuration file from boot disk"); 401 return (1); 402 } 403 404 log_to_screen("Recovered mondorestore.cfg"); 405 if (!does_file_exist(MOUNTLIST_FNAME_STUB)) { 406 log_to_screen("...but not mountlist.txt - a pity, really..."); 407 } else { 408 /* Is this code really useful ??? */ 409 if (extract_mountlist_stub) { 410 mr_asprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB); 411 run_program_and_log_output(command, FALSE); 412 mr_free(command); 413 } 414 } 415 416 mr_asprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB); 417 mr_free(cfg_file); 418 419 run_program_and_log_output(command, FALSE); 420 mr_free(command); 421 422 if (extract_mountlist_stub) { 423 mr_asprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB); 424 run_program_and_log_output(command, FALSE); 425 mr_free(command); 426 } 427 mr_free(mountlist_file); 428 429 mr_asprintf(command, "cp -f etc/raidtab /etc/"); 430 run_program_and_log_output(command, FALSE); 431 mr_free(command); 432 433 if (extract_i_want_my_lvm) { 434 mr_asprintf(command, "cp -f %s /tmp/",IWANTMYLVM_STUB); 435 run_program_and_log_output(command, FALSE); 436 mr_free(command); 437 } 438 g_backup_media_type = bkpinfo->backup_media_type; 439 return (retval); 440 } 441 442 /************************************************************************** 443 *END_GET_CFG_FILE_FROM_ARCHIVE * 444 **************************************************************************/ 172 445 173 446 … … 642 915 /** add mallocs **/ 643 916 char value[MAX_STR_LEN]; 917 char *tmp = NULL; 644 918 char *tmp1 = NULL; 645 919 char *envtmp1 = NULL; … … 683 957 run_program_and_log_output("mount /dev/cdrom "MNT_CDROM, 1); 684 958 } 685 if (does_file_exist( MNT_CDROM"/archives/filelist.0")) {959 if (does_file_exist(ARCHIVES_PATH "/filelist.0")) { 686 960 bkpinfo->backup_media_type = cdr; 687 961 run_program_and_log_output("umount -d "MNT_CDROM, 1); … … 1284 1558 1285 1559 /** 1286 * Install the user's boot loader in the MBR.1287 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported.1288 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them.1289 * @return 0 for success, nonzero for failure.1290 */1291 int run_boot_loader(bool offer_to_hack_scripts)1292 {1293 int res;1294 int retval = 0;1295 1296 /** malloc *******/1297 char *device = NULL;1298 char *disk = NULL;1299 char *name = NULL;1300 char *type = NULL;1301 char *cmd = NULL;1302 1303 malloc_string(device);1304 malloc_string(name);1305 malloc_string(type);1306 1307 /* In order to have a working bootloader, we need to have all devices1308 * ready in the chroot. If they are not there (udev) then copy them from1309 * the current /dev location1310 */1311 mr_asprintf(cmd,"tar cf - /dev | ( cd %s ; tar xf - )",MNT_RESTORING);1312 run_program_and_log_output(cmd, 3);1313 mr_free(cmd);1314 1315 backup_crucial_file(MNT_RESTORING, "/etc/fstab");1316 backup_crucial_file(MNT_RESTORING, "/boot/grub/menu.lst");1317 backup_crucial_file(MNT_RESTORING, "/boot/grub/grub.cfg");1318 backup_crucial_file(MNT_RESTORING, "/boot/grub2/grub.cfg");1319 backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf");1320 backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf");1321 backup_crucial_file(MNT_RESTORING, "/boot/grub/device.map");1322 backup_crucial_file(MNT_RESTORING, "/boot/grub2/device.map");1323 backup_crucial_file(MNT_RESTORING, "/etc/mtab");1324 read_cfg_var(g_mondo_cfg_file, "bootloader.device", device);1325 read_cfg_var(g_mondo_cfg_file, "bootloader.name", name);1326 read_cfg_var(g_mondo_cfg_file, "boot-type", type);1327 log_msg(2, "run_boot_loader: device='%s', name='%s', type='%s'", device, name, type);1328 sync();1329 1330 offer_to_make_initrd();1331 1332 disk = truncate_to_drive_name(device);1333 if (strcmp(type,"BIOS") == 0) {1334 // Force installation of a MBR bootloader brought by mindi on the disk1335 // in case none was available and we then start from a partition1336 log_msg(2, "Reinstalling mbr.bin on %s", disk);1337 mr_system("dd bs=440 count=1 conv=notrunc if=/tmp/mbr.bin of=%s &> /dev/null",disk);1338 } else {1339 // Same for GPT1340 log_msg(2, "Reinstalling gptmbr.bin on %s", disk);1341 mr_system("dd bs=440 count=1 conv=notrunc if=/tmp/gptmbr.bin of=%s &> /dev/null",disk);1342 }1343 1344 // Now reinstall bootloader1345 if (!strcmp(name, "LILO")) {1346 res = run_lilo(offer_to_hack_scripts);1347 } else if (!strcmp(name, "ELILO")) {1348 res = run_elilo(offer_to_hack_scripts);1349 } else if (!strcmp(name, "GRUB")) {1350 res = run_grub(offer_to_hack_scripts, device);1351 } else if (!strcmp(name, "RAW")) {1352 res = run_raw_mbr(offer_to_hack_scripts, device);1353 }1354 #ifdef __FreeBSD__1355 else if (!strcmp(name, "BOOT0")) {1356 mr_asprintf(tmp, "boot0cfg -B %s", device);1357 res = run_program_and_log_output(tmp, FALSE);1358 paranoid_free(tmp);1359 } else {1360 mr_asprintf(tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device);1361 if (!system(tmp)) {1362 mr_free(tmp);1363 mr_asprintf(tmp, MNT_RESTORING "/sbin/fdisk -B %s", device);1364 res = run_program_and_log_output(tmp, 3);1365 } else {1366 log_msg(1, "I'm not running any boot loader. You have a DD boot drive. It's already loaded up.");1367 }1368 mr_free(tmp);1369 }1370 #else1371 else {1372 log_to_screen1373 ("Unable to determine type of boot loader. Defaulting to LILO.");1374 res = run_lilo(offer_to_hack_scripts);1375 }1376 #endif1377 retval += res;1378 if (res) {1379 log_to_screen("Your boot loader returned an error");1380 } else {1381 log_to_screen("Your boot loader ran OK");1382 }1383 paranoid_free(device);1384 paranoid_free(name);1385 return (retval);1386 }1387 1388 /**************************************************************************1389 *END_ RUN_BOOT_LOADER *1390 **************************************************************************/1391 1392 1393 1394 /**1395 1560 * Attempt to find the user's editor. 1396 1561 * @return The editor found ("vi" if none could be found). … … 1417 1582 return (output); 1418 1583 } 1584 1585 1586 1587 1588 /** 1589 * Install LILO on the user's boot drive (determined by /etc/lilo.conf). 1590 * @param offer_to_run_stablilo If TRUE, then offer to hack the user's fstab for them. 1591 * @return 0 for success, nonzero for failure. 1592 */ 1593 int run_lilo(bool offer_to_run_stablilo) 1594 { 1595 /** malloc **/ 1596 char *command = NULL; 1597 char *tmp = NULL; 1598 char *editor = NULL; 1599 1600 int res; 1601 int done; 1602 bool run_lilo_M = FALSE; 1603 1604 if (!run_program_and_log_output 1605 ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) { 1606 run_lilo_M = TRUE; 1607 } 1608 1609 if (offer_to_run_stablilo 1610 && ask_me_yes_or_no("Did you change the mountlist or cloned the system ?")) 1611 1612 /* interactive mode */ 1613 { 1614 mvaddstr_and_log_it(g_currentY, 1615 0, 1616 "Modifying fstab and lilo.conf, and running LILO... "); 1617 mr_asprintf(command, "mr-stablilo-me"); 1618 res = run_program_and_log_output(command, 3); 1619 mr_free(command); 1620 1621 if (res) { 1622 popup_and_OK 1623 ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist."); 1624 for (done = FALSE; !done;) { 1625 editor = find_my_editor(); 1626 if (editor == NULL) { 1627 popup_and_OK("No editor found. You won't be able to edit conf files"); 1628 } else { 1629 if (!g_text_mode) { 1630 newtSuspend(); 1631 } 1632 mr_asprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor); 1633 paranoid_system(tmp); 1634 mr_free(tmp); 1635 1636 mr_asprintf(tmp, "%s " MNT_RESTORING "/etc/lilo.conf", editor); 1637 paranoid_system(tmp); 1638 mr_free(tmp); 1639 mr_free(editor); 1640 1641 if (!g_text_mode) { 1642 newtResume(); 1643 } 1644 // newtCls(); 1645 if (ask_me_yes_or_no("Edit them again?")) { 1646 continue; 1647 } 1648 } 1649 mr_free(editor); 1650 1651 res = run_program_and_log_output("chroot " MNT_RESTORING " lilo -L", 3); 1652 if (res) { 1653 res = run_program_and_log_output("chroot " MNT_RESTORING " lilo", 3); 1654 } 1655 if (res) { 1656 done = ask_me_yes_or_no("LILO failed. Re-edit system files?"); 1657 } else { 1658 done = TRUE; 1659 } 1660 } 1661 } else { 1662 log_to_screen("lilo.conf and fstab were modified OK"); 1663 } 1664 } else 1665 /* nuke mode */ 1666 { 1667 mvaddstr_and_log_it(g_currentY, 1668 0, 1669 "Running LILO... "); 1670 res = 1671 run_program_and_log_output("chroot " MNT_RESTORING " lilo -L", 1672 3); 1673 if (res) { 1674 res = 1675 run_program_and_log_output("chroot " MNT_RESTORING " lilo", 1676 3); 1677 } 1678 if (res) { 1679 mvaddstr_and_log_it(g_currentY++, 74, "Failed."); 1680 log_to_screen 1681 ("Failed to re-jig fstab and/or lilo. Edit/run manually, please."); 1682 } else { 1683 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 1684 } 1685 } 1686 if (run_lilo_M) { 1687 run_program_and_log_output("chroot " MNT_RESTORING 1688 " lilo -M /dev/hda", 3); 1689 run_program_and_log_output("chroot " MNT_RESTORING 1690 " lilo -M /dev/sda", 3); 1691 } 1692 return (res); 1693 } 1694 1695 /************************************************************************** 1696 *END_RUN_LILO * 1697 **************************************************************************/ 1698 1699 1700 /** 1701 * Install a raw MBR onto @p bd. 1702 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them. 1703 * @param bd The device to copy the stored MBR to. 1704 * @return 0 for success, nonzero for failure. 1705 */ 1706 int run_raw_mbr(bool offer_to_hack_scripts, char *bd) 1707 { 1708 /** malloc **/ 1709 char *command = NULL; 1710 char *boot_device = NULL; 1711 char *tmp = NULL; 1712 char *editor; 1713 int res; 1714 int done; 1715 1716 malloc_string(boot_device); 1717 assert_string_is_neither_NULL_nor_zerolength(bd); 1718 1719 strcpy(boot_device, bd); 1720 1721 if (offer_to_hack_scripts 1722 && ask_me_yes_or_no("Did you change the mountlist or cloned the system ?")) { 1723 /* interactive mode */ 1724 mvaddstr_and_log_it(g_currentY, 0, "Modifying fstab and restoring MBR... "); 1725 for (done = FALSE; !done;) { 1726 popup_and_OK("You will now edit fstab"); 1727 editor = find_my_editor(); 1728 if (editor == NULL) { 1729 popup_and_OK("No editor found. You won't be able to edit conf files"); 1730 } else { 1731 if (!g_text_mode) { 1732 newtSuspend(); 1733 } 1734 mr_asprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor); 1735 1736 paranoid_system(tmp); 1737 mr_free(tmp); 1738 if (!g_text_mode) { 1739 newtResume(); 1740 } 1741 } 1742 mr_free(editor); 1743 1744 popup_and_get_string("Boot device", "Please confirm/enter the boot device. If in doubt, try /dev/hda", boot_device, MAX_STR_LEN / 4); 1745 mr_asprintf(command, "mr-stabraw-me %s", boot_device); 1746 res = run_program_and_log_output(command, 3); 1747 mr_free(command); 1748 1749 if (res) { 1750 done = ask_me_yes_or_no("Modifications failed. Re-try?"); 1751 } else { 1752 done = TRUE; 1753 } 1754 } 1755 } else { 1756 /* nuke mode */ 1757 mr_asprintf(command, "mr-raw %s /"MOUNTLIST_FNAME_STUB, boot_device); 1758 log_msg(2, "run_raw_mbr() --- command='%s'", command); 1759 1760 mvaddstr_and_log_it(g_currentY, 0, "Restoring MBR... "); 1761 res = run_program_and_log_output(command, 3); 1762 mr_free(command); 1763 } 1764 if (res) { 1765 mvaddstr_and_log_it(g_currentY++, 74, "Failed."); 1766 log_to_screen("MBR+fstab processed w/error(s). See %s for more info.", MONDO_LOGFILE); 1767 } else { 1768 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 1769 } 1770 paranoid_free(boot_device); 1771 return (res); 1772 } 1773 1774 /************************************************************************** 1775 *END_RUN_RAW_MBR * 1776 **************************************************************************/ 1419 1777 1420 1778 … … 1465 1823 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"); 1466 1824 } 1467 editor = find_my_editor() );1825 editor = find_my_editor(); 1468 1826 if (editor == NULL) { 1469 1827 popup_and_OK("No editor found. You won't be able to edit conf files"); … … 1644 2002 1645 2003 1646 /** 1647 * Install LILO on the user's boot drive (determined by /etc/lilo.conf). 1648 * @param offer_to_run_stablilo If TRUE, then offer to hack the user's fstab for them. 2004 2005 /** 2006 * Install the user's boot loader in the MBR. 2007 * Currently LILO, ELILO, GRUB, RAW (dd of MBR), and the FreeBSD bootloader are supported. 2008 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them. 1649 2009 * @return 0 for success, nonzero for failure. 1650 2010 */ 1651 int run_ lilo(bool offer_to_run_stablilo)2011 int run_boot_loader(bool offer_to_hack_scripts) 1652 2012 { 1653 /** malloc **/1654 char *command = NULL;1655 char *tmp = NULL;1656 char *editor = NULL;1657 1658 2013 int res; 1659 int done; 1660 bool run_lilo_M = FALSE; 1661 1662 if (!run_program_and_log_output 1663 ("grep \"boot.*=.*/dev/md\" " MNT_RESTORING "/etc/lilo.conf", 1)) { 1664 run_lilo_M = TRUE; 1665 } 1666 1667 if (offer_to_run_stablilo 1668 && ask_me_yes_or_no("Did you change the mountlist or cloned the system ?")) 1669 1670 /* interactive mode */ 1671 { 1672 mvaddstr_and_log_it(g_currentY, 1673 0, 1674 "Modifying fstab and lilo.conf, and running LILO... "); 1675 mr_asprintf(command, "mr-stablilo-me"); 1676 res = run_program_and_log_output(command, 3); 1677 mr_free(command); 1678 1679 if (res) { 1680 popup_and_OK 1681 ("You will now edit fstab and lilo.conf, to make sure they match your new mountlist."); 1682 for (done = FALSE; !done;) { 1683 editor = find_my_editor(); 1684 if (editor == NULL) { 1685 popup_and_OK("No editor found. You won't be able to edit conf files"); 1686 } else { 1687 if (!g_text_mode) { 1688 newtSuspend(); 1689 } 1690 mr_asprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor); 1691 paranoid_system(tmp); 1692 mr_free(tmp); 1693 1694 mr_asprintf(tmp, "%s " MNT_RESTORING "/etc/lilo.conf", editor); 1695 paranoid_system(tmp); 1696 mr_free(tmp); 1697 mr_free(editor); 1698 1699 if (!g_text_mode) { 1700 newtResume(); 1701 } 1702 // newtCls(); 1703 if (ask_me_yes_or_no("Edit them again?")) { 1704 continue; 1705 } 1706 } 1707 mr_free(editor); 1708 1709 res = run_program_and_log_output("chroot " MNT_RESTORING " lilo -L", 3); 1710 if (res) { 1711 res = run_program_and_log_output("chroot " MNT_RESTORING " lilo", 3); 1712 } 1713 if (res) { 1714 done = ask_me_yes_or_no("LILO failed. Re-edit system files?"); 1715 } else { 1716 done = TRUE; 1717 } 1718 } 2014 int retval = 0; 2015 2016 /** malloc *******/ 2017 char *device = NULL; 2018 char *disk = NULL; 2019 char *name = NULL; 2020 char *type = NULL; 2021 char *cmd = NULL; 2022 2023 malloc_string(device); 2024 malloc_string(name); 2025 malloc_string(type); 2026 2027 /* In order to have a working bootloader, we need to have all devices 2028 * ready in the chroot. If they are not there (udev) then copy them from 2029 * the current /dev location 2030 */ 2031 mr_asprintf(cmd,"tar cf - /dev | ( cd %s ; tar xf - )",MNT_RESTORING); 2032 run_program_and_log_output(cmd, 3); 2033 mr_free(cmd); 2034 2035 backup_crucial_file(MNT_RESTORING, "/etc/fstab"); 2036 backup_crucial_file(MNT_RESTORING, "/boot/grub/menu.lst"); 2037 backup_crucial_file(MNT_RESTORING, "/boot/grub/grub.cfg"); 2038 backup_crucial_file(MNT_RESTORING, "/boot/grub2/grub.cfg"); 2039 backup_crucial_file(MNT_RESTORING, "/etc/lilo.conf"); 2040 backup_crucial_file(MNT_RESTORING, "/etc/elilo.conf"); 2041 backup_crucial_file(MNT_RESTORING, "/boot/grub/device.map"); 2042 backup_crucial_file(MNT_RESTORING, "/boot/grub2/device.map"); 2043 backup_crucial_file(MNT_RESTORING, "/etc/mtab"); 2044 read_cfg_var(g_mondo_cfg_file, "bootloader.device", device); 2045 read_cfg_var(g_mondo_cfg_file, "bootloader.name", name); 2046 read_cfg_var(g_mondo_cfg_file, "boot-type", type); 2047 log_msg(2, "run_boot_loader: device='%s', name='%s', type='%s'", device, name, type); 2048 sync(); 2049 2050 offer_to_make_initrd(); 2051 2052 disk = truncate_to_drive_name(device); 2053 if (strcmp(type,"BIOS") == 0) { 2054 // Force installation of a MBR bootloader brought by mindi on the disk 2055 // in case none was available and we then start from a partition 2056 log_msg(2, "Reinstalling mbr.bin on %s", disk); 2057 mr_system("dd bs=440 count=1 conv=notrunc if=/tmp/mbr.bin of=%s &> /dev/null",disk); 2058 } else { 2059 // Same for GPT 2060 log_msg(2, "Reinstalling gptmbr.bin on %s", disk); 2061 mr_system("dd bs=440 count=1 conv=notrunc if=/tmp/gptmbr.bin of=%s &> /dev/null",disk); 2062 } 2063 2064 // Now reinstall bootloader 2065 if (!strcmp(name, "LILO")) { 2066 res = run_lilo(offer_to_hack_scripts); 2067 } else if (!strcmp(name, "ELILO")) { 2068 res = run_elilo(offer_to_hack_scripts); 2069 } else if (!strcmp(name, "GRUB")) { 2070 res = run_grub(offer_to_hack_scripts, device); 2071 } else if (!strcmp(name, "RAW")) { 2072 res = run_raw_mbr(offer_to_hack_scripts, device); 2073 } 2074 #ifdef __FreeBSD__ 2075 else if (!strcmp(name, "BOOT0")) { 2076 mr_asprintf(tmp, "boot0cfg -B %s", device); 2077 res = run_program_and_log_output(tmp, FALSE); 2078 paranoid_free(tmp); 2079 } else { 2080 mr_asprintf(tmp, "ls /dev | grep -Eq '^%ss[1-4].*'", device); 2081 if (!system(tmp)) { 2082 mr_free(tmp); 2083 mr_asprintf(tmp, MNT_RESTORING "/sbin/fdisk -B %s", device); 2084 res = run_program_and_log_output(tmp, 3); 1719 2085 } else { 1720 log_to_screen("lilo.conf and fstab were modified OK"); 1721 } 1722 } else 1723 /* nuke mode */ 1724 { 1725 mvaddstr_and_log_it(g_currentY, 1726 0, 1727 "Running LILO... "); 1728 res = 1729 run_program_and_log_output("chroot " MNT_RESTORING " lilo -L", 1730 3); 1731 if (res) { 1732 res = 1733 run_program_and_log_output("chroot " MNT_RESTORING " lilo", 1734 3); 1735 } 1736 if (res) { 1737 mvaddstr_and_log_it(g_currentY++, 74, "Failed."); 1738 log_to_screen 1739 ("Failed to re-jig fstab and/or lilo. Edit/run manually, please."); 1740 } else { 1741 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 1742 } 1743 } 1744 if (run_lilo_M) { 1745 run_program_and_log_output("chroot " MNT_RESTORING 1746 " lilo -M /dev/hda", 3); 1747 run_program_and_log_output("chroot " MNT_RESTORING 1748 " lilo -M /dev/sda", 3); 1749 } 1750 return (res); 2086 log_msg(1, "I'm not running any boot loader. You have a DD boot drive. It's already loaded up."); 2087 } 2088 mr_free(tmp); 2089 } 2090 #else 2091 else { 2092 log_to_screen 2093 ("Unable to determine type of boot loader. Defaulting to LILO."); 2094 res = run_lilo(offer_to_hack_scripts); 2095 } 2096 #endif 2097 retval += res; 2098 if (res) { 2099 log_to_screen("Your boot loader returned an error"); 2100 } else { 2101 log_to_screen("Your boot loader ran OK"); 2102 } 2103 paranoid_free(device); 2104 paranoid_free(name); 2105 return (retval); 1751 2106 } 1752 2107 1753 2108 /************************************************************************** 1754 *END_RUN_LILO * 1755 **************************************************************************/ 1756 1757 1758 /** 1759 * Install a raw MBR onto @p bd. 1760 * @param offer_to_hack_scripts If TRUE, then offer to hack the user's fstab for them. 1761 * @param bd The device to copy the stored MBR to. 1762 * @return 0 for success, nonzero for failure. 1763 */ 1764 int run_raw_mbr(bool offer_to_hack_scripts, char *bd) 1765 { 1766 /** malloc **/ 1767 char *command = NULL; 1768 char *boot_device = NULL; 1769 char *tmp = NULL; 1770 char *editor; 1771 int res; 1772 int done; 1773 1774 malloc_string(boot_device); 1775 assert_string_is_neither_NULL_nor_zerolength(bd); 1776 1777 strcpy(boot_device, bd); 1778 1779 if (offer_to_hack_scripts 1780 && ask_me_yes_or_no("Did you change the mountlist or cloned the system ?")) { 1781 /* interactive mode */ 1782 mvaddstr_and_log_it(g_currentY, 0, "Modifying fstab and restoring MBR... "); 1783 for (done = FALSE; !done;) { 1784 popup_and_OK("You will now edit fstab"); 1785 editor = find_my_editor()); 1786 if (editor == NULL) { 1787 popup_and_OK("No editor found. You won't be able to edit conf files"); 1788 } else { 1789 if (!g_text_mode) { 1790 newtSuspend(); 1791 } 1792 mr_asprintf(tmp, "%s " MNT_RESTORING "/etc/fstab", editor); 1793 1794 paranoid_system(tmp); 1795 mr_free(tmp); 1796 if (!g_text_mode) { 1797 newtResume(); 1798 } 1799 } 1800 mr_free(editor); 1801 1802 popup_and_get_string("Boot device", "Please confirm/enter the boot device. If in doubt, try /dev/hda", boot_device, MAX_STR_LEN / 4); 1803 mr_asprintf(command, "mr-stabraw-me %s", boot_device); 1804 res = run_program_and_log_output(command, 3); 1805 mr_free(command); 1806 1807 if (res) { 1808 done = ask_me_yes_or_no("Modifications failed. Re-try?"); 1809 } else { 1810 done = TRUE; 1811 } 1812 } 1813 } else { 1814 /* nuke mode */ 1815 mr_asprintf(command, "mr-raw %s /"MOUNTLIST_FNAME_STUB, boot_device); 1816 log_msg(2, "run_raw_mbr() --- command='%s'", command); 1817 1818 mvaddstr_and_log_it(g_currentY, 0, "Restoring MBR... "); 1819 res = run_program_and_log_output(command, 3); 1820 mr_free(command); 1821 } 1822 if (res) { 1823 mvaddstr_and_log_it(g_currentY++, 74, "Failed."); 1824 log_to_screen("MBR+fstab processed w/error(s). See %s for more info.", MONDO_LOGFILE); 1825 } else { 1826 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 1827 } 1828 paranoid_free(boot_device); 1829 return (res); 1830 } 1831 1832 /************************************************************************** 1833 *END_RUN_RAW_MBR * 2109 *END_ RUN_BOOT_LOADER * 1834 2110 **************************************************************************/ 1835 2111 … … 2068 2344 *END_UNMOUNT_ALL_DEVICES * 2069 2345 **************************************************************************/ 2070 2071 /**2072 * Extract mondorestore.cfg and the mountlist from the tape inserted2073 * to the ./tmp/ directory.2074 * @param dev The tape device to read from.2075 * @return 0 for success, nonzero for failure.2076 */2077 int extract_cfg_file_and_mountlist_from_tape_dev(char *dev)2078 {2079 char *command = NULL;2080 int res = 0;2081 2082 if (bkpinfo->use_obdr) {2083 skip_obdr();2084 } else {2085 // TODO: below 32KB seems to block at least on RHAS 2.1 and MDK 10.02086 set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size);2087 }2088 2089 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);2090 log_msg(2, "command = '%s'", command);2091 res = run_program_and_log_output(command, -1);2092 mr_free(command);2093 2094 if (res != 0) {2095 if (does_file_exist(MONDO_CFG_FILE_STUB)) {2096 res = 0;2097 } else {2098 /* Doing that allow us to remain compatible with pre-2.2.5 versions */2099 log_msg(2, "pre-2.2.4 compatible mode on");2100 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);2101 log_msg(2, "command = '%s'", command);2102 res = run_program_and_log_output(command, -1);2103 mr_free(command);2104 if ((res != 0) && (does_file_exist(MONDO_CFG_FILE_STUB))) {2105 res = 0;2106 }2107 }2108 }2109 paranoid_free(command);2110 return (res);2111 }2112 2113 2114 /**2115 * Get the configuration file from the tape, or CD.2116 * @param bkpinfo The backup information structure. Fields used:2117 * - @c bkpinfo->backup_media_type2118 * - @c bkpinfo->media_device2119 * - @c bkpinfo->tmpdir2120 * @return 0 for success, nonzero for failure.2121 */2122 int get_cfg_file_from_archive()2123 {2124 int retval = 0;2125 2126 /** malloc *****/2127 char *command = NULL;2128 char *cfg_file = NULL;2129 char *tmp = NULL;2130 char *tmp1 = NULL;2131 char *mountpt = NULL;2132 char *mountlist_file = NULL;2133 bool extract_mountlist_stub = FALSE;2134 bool extract_i_want_my_lvm = FALSE;2135 2136 bool try_plan_B;2137 2138 assert(bkpinfo != NULL);2139 log_msg(2, "gcffa --- starting");2140 log_to_screen("I'm thinking...");2141 mr_asprintf(mountpt, "%s/mount.bootdisk", bkpinfo->tmpdir);2142 if (chdir(bkpinfo->tmpdir)) {2143 // FIXME2144 }2145 mr_asprintf(cfg_file, "%s", MONDO_CFG_FILE_STUB);2146 unlink(cfg_file); // cfg_file[] is missing the '/' at the start, FYI, by intent2147 mr_free(cfg_file);2148 2149 unlink(FILELIST_FULL_STUB);2150 unlink(BIGGIELIST_TXT_STUB);2151 mr_asprintf(command, "mkdir -p %s", mountpt);2152 run_program_and_log_output(command, FALSE);2153 mr_free(command);2154 2155 mr_asprintf(cfg_file, "%s/%s", bkpinfo->tmpdir, MONDO_CFG_FILE_STUB);2156 mr_asprintf(mountlist_file, "%s/%s", bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);2157 log_msg(2, "mountpt = %s; cfg_file=%s", mountpt, cfg_file);2158 mr_free(mountpt);2159 2160 if (!does_file_exist(cfg_file)) {2161 log_msg(2, "gcffa --- we don't have cfg file yet.");2162 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {2163 try_plan_B = TRUE;2164 } else {2165 log_msg(2, "gcffa --- calling mount_media now :)");2166 if (!mount_media(MNT_CDROM)) {2167 log_msg(2, "gcffa --- managed to mount CD; so, no need for Plan B");2168 try_plan_B = FALSE;2169 } else {2170 try_plan_B = TRUE;2171 }2172 if (what_number_cd_is_this() > 1) {2173 insist_on_this_cd_number((g_current_media_number = 1));2174 }2175 }2176 if (try_plan_B) {2177 log_msg(2, "gcffa --- OK, switching to Plan B");2178 if (chdir(bkpinfo->tmpdir)) {2179 // FIXME2180 }2181 run_program_and_log_output("mkdir -p tmp", FALSE);2182 2183 if (bkpinfo->media_device == NULL) {2184 mr_asprintf(bkpinfo->media_device, "%s", "/dev/st0");2185 log_msg(2, "media_device is blank; assuming %s", bkpinfo->media_device);2186 }2187 mr_asprintf(tmp, "%s", bkpinfo->media_device);2188 if (extract_cfg_file_and_mountlist_from_tape_dev(bkpinfo->media_device)) {2189 mr_free(bkpinfo->media_device);2190 mr_asprintf(bkpinfo->media_device, "%s", "/dev/st0");2191 if (extract_cfg_file_and_mountlist_from_tape_dev(bkpinfo->media_device)) {2192 mr_free(bkpinfo->media_device);2193 mr_asprintf(bkpinfo->media_device, "%s", "/dev/osst0");2194 if (extract_cfg_file_and_mountlist_from_tape_dev(bkpinfo->media_device)) {2195 mr_free(bkpinfo->media_device);2196 mr_asprintf(bkpinfo->media_device, "%s", "/dev/ht0");2197 if (extract_cfg_file_and_mountlist_from_tape_dev(bkpinfo->media_device)) {2198 log_msg(3, "I tried lots of devices but none worked.");2199 mr_free(bkpinfo->media_device);2200 }2201 }2202 }2203 }2204 if (bkpinfo->media_device == NULL) {2205 bkpinfo->media_device = tmp;2206 } else {2207 mr_free(tmp);2208 }2209 2210 if (!does_file_exist("tmp/mondorestore.cfg")) {2211 log_to_screen("Cannot find config info on media");2212 return (1);2213 }2214 } else {2215 if (does_file_exist("/"MOUNTLIST_FNAME_STUB)) {2216 extract_mountlist_stub = FALSE;2217 } else {2218 extract_mountlist_stub = TRUE;2219 }2220 if (does_file_exist("/"IWANTMYLVM_STUB)) {2221 extract_i_want_my_lvm = FALSE;2222 } else {2223 extract_i_want_my_lvm = TRUE;2224 }2225 2226 log_msg(2, "gcffa --- Plan B, a.k.a. untarring some file from all.tar.gz");2227 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 necessary2228 run_program_and_log_output(command, TRUE);2229 mr_free(command);2230 2231 if (!does_file_exist(MONDO_CFG_FILE_STUB)) {2232 /* Doing that allow us to remain compatible with pre-2.2.5 versions */2233 log_msg(2, "pre-2.2.4 compatible mode on");2234 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 necessary2235 run_program_and_log_output(command, TRUE);2236 mr_free(command);2237 if (!does_file_exist(MONDO_CFG_FILE_STUB)) {2238 fatal_error2239 ("Please reinsert the disk/CD and try again.");2240 }2241 }2242 }2243 }2244 if (does_file_exist(MONDO_CFG_FILE_STUB)) {2245 log_msg(1, "gcffa --- great! We've got the config file");2246 tmp1 = call_program_and_get_last_line_of_output("pwd");2247 mr_asprintf(tmp, "%s/%s", tmp1, MONDO_CFG_FILE_STUB);2248 mr_asprintf(command, "cp -f %s %s", tmp, cfg_file);2249 log_it("%s",command);2250 if (strcmp(tmp, cfg_file) && run_program_and_log_output(command, 1)) {2251 log_msg(1,2252 "... but an error occurred when I tried to move it to %s",2253 cfg_file);2254 } else {2255 log_msg(1, "... and I moved it successfully to %s", cfg_file);2256 }2257 mr_free(command);2258 2259 mr_asprintf(command, "cp -f %s/%s %s", tmp1, MOUNTLIST_FNAME_STUB, mountlist_file);2260 mr_free(tmp1);2261 log_it("%s",command);2262 if (extract_mountlist_stub) {2263 if (strcmp(tmp, cfg_file) && run_program_and_log_output(command, 1)) {2264 log_msg(1, "Failed to get mountlist");2265 } else {2266 log_msg(1, "Got mountlist too");2267 mr_free(command);2268 mr_asprintf(command, "cp -f %s %s", mountlist_file, g_mountlist_fname);2269 if (run_program_and_log_output(command, 1)) {2270 log_msg(1, "Failed to copy mountlist to /tmp");2271 } else {2272 log_msg(1, "Copied mountlist to /tmp as well OK");2273 mr_free(command);2274 mr_asprintf(command, "cp -f %s /tmp/",IWANTMYLVM_STUB);2275 run_program_and_log_output(command, 1);2276 }2277 }2278 }2279 mr_free(command);2280 mr_free(tmp);2281 }2282 2283 run_program_and_log_output("umount -d " MNT_CDROM, FALSE);2284 if (!does_file_exist(cfg_file)) {2285 log_it("%s",cfg_file);2286 log_msg(1, "%s not found", cfg_file);2287 log_to_screen("Oh dear. Unable to recover configuration file from boot disk");2288 return (1);2289 }2290 2291 log_to_screen("Recovered mondorestore.cfg");2292 if (!does_file_exist(MOUNTLIST_FNAME_STUB)) {2293 log_to_screen("...but not mountlist.txt - a pity, really...");2294 } else {2295 /* Is this code really useful ??? */2296 if (extract_mountlist_stub) {2297 mr_asprintf(command, "cp -f %s %s/%s", MOUNTLIST_FNAME_STUB, bkpinfo->tmpdir, MOUNTLIST_FNAME_STUB);2298 run_program_and_log_output(command, FALSE);2299 mr_free(command);2300 }2301 }2302 2303 mr_asprintf(command, "cp -f %s /%s", cfg_file, MONDO_CFG_FILE_STUB);2304 mr_free(cfg_file);2305 2306 run_program_and_log_output(command, FALSE);2307 mr_free(command);2308 2309 if (extract_mountlist_stub) {2310 mr_asprintf(command, "cp -f %s /%s", mountlist_file, MOUNTLIST_FNAME_STUB);2311 run_program_and_log_output(command, FALSE);2312 mr_free(command);2313 }2314 mr_free(mountlist_file);2315 2316 mr_asprintf(command, "cp -f etc/raidtab /etc/");2317 run_program_and_log_output(command, FALSE);2318 mr_free(command);2319 2320 if (extract_i_want_my_lvm) {2321 mr_asprintf(command, "cp -f %s /tmp/",IWANTMYLVM_STUB);2322 run_program_and_log_output(command, FALSE);2323 mr_free(command);2324 }2325 g_backup_media_type = bkpinfo->backup_media_type;2326 return (retval);2327 }2328 2329 /**************************************************************************2330 *END_GET_CFG_FILE_FROM_ARCHIVE *2331 **************************************************************************/2332 2333 2346 /* @} - end restoreUtilityGroup */ 2334 2347 -
branches/3.3/mondo/src/mondorestore/mondorestore.c
r3876 r3879 13 13 #include "mr_mem.h" 14 14 #include "mr_file.h" 15 #include "../common/mondostructures.h" 16 #include "../common/libmondo.h" 17 #include "mr-externs.h" 15 #include "mondostructures.h" 18 16 #include "mondorestore.h" 19 17 #include "mr_msg.h" … … 21 19 #include "mondo-rstr-tools-EXT.h" 22 20 #include "libmondo-mountlist-EXT.h" 21 #include "libmondo-tools-EXT.h" 22 #include "libmondo-gui-EXT.h" 23 #include "libmondo-devices-EXT.h" 24 #include "libmondo-fork-EXT.h" 25 #include "libmondo-string-EXT.h" 26 #include "libmondo-archive-EXT.h" 27 #include "libmondo-raid-EXT.h" 28 #include "libmondo-filelist-EXT.h" 29 #include "libmondo-files-EXT.h" 30 #include "libmondo-stream-EXT.h" 31 #include "libmondo-cli-EXT.h" 23 32 #include "newt-specific-EXT.h" 24 33 25 34 extern void wait_until_software_raids_are_prepped(char *, int); 26 35 extern void twenty_seconds_til_yikes(void); 36 // in mondo-prep.c 37 extern void resize_mountlist_proportionately_to_suit_new_drives(struct mountlist_itself *); 38 extern int format_everything(struct mountlist_itself *, bool , struct raidlist_itself *); 39 extern int partition_everything(struct mountlist_itself *); 40 extern int fput_string_one_char_at_a_time(FILE *, char *); 41 extern int do_my_funky_lvm_stuff(bool, bool ); 42 extern int stop_all_raid_devices(struct mountlist_itself *); 43 44 // in mondo-rstr-newt.c 45 extern int edit_mountlist(char *, struct mountlist_itself *, struct raidlist_itself *); 46 47 // from libmondo-devices.c 48 extern bool g_restoring_live_from_cd; 49 extern bool g_restoring_live_from_netfs; 50 51 extern int g_currentY; 27 52 28 53 /* We don't have a cleanup function yet */ … … 53 78 extern int g_partition_table_locked_up; 54 79 extern int g_noof_rows; 55 56 extern int partition_everything(struct mountlist_itself *mountlist); 57 extern int handle_incoming_parameters(int argc, char *argv[]); 80 extern int g_current_media_number; 58 81 59 82 /** … … 121 144 char *g_getfattr; 122 145 146 extern long g_current_progress; 147 extern int g_currentY; 148 extern int g_current_media_number; 149 150 123 151 /* @} - end of "Restore-Time Globals" in globalGroup */ 124 152 125 126 127 extern int copy_from_src_to_dest(FILE * f_orig, FILE * f_archived,128 char direction);129 153 130 154 … … 580 604 just_changed_cds = FALSE; 581 605 log_msg(3, "I'll continue to scan this CD for bigfiles to be restored."); 582 } else if (does_file_exist( MNT_CDROM "/archives/NOT-THE-LAST")) {606 } else if (does_file_exist(ARCHIVES_PATH "/NOT-THE-LAST")) { 583 607 insist_on_this_cd_number(++g_current_media_number); 584 608 log_to_screen("Restoring from %s #%d", mds, g_current_media_number); … … 691 715 paranoid_free(command); 692 716 693 mr_asprintf(filelist_name, MNT_CDROM "/archives/filelist.%ld", current_tarball_number);717 mr_asprintf(filelist_name, ARCHIVES_PATH "/filelist.%ld", current_tarball_number); 694 718 if (length_of_file(filelist_name) <= 2) { 695 719 log_msg(2, "There are _zero_ files in filelist '%s'", filelist_name); … … 726 750 if (filelist == NULL || matches > 0) { 727 751 if (g_getfattr) { 728 mr_asprintf(xattr_fname, XATTR_LIST_FNAME_RAW_SZ, MNT_CDROM "/archives", current_tarball_number);752 mr_asprintf(xattr_fname, XATTR_LIST_FNAME_RAW_SZ, ARCHIVES_PATH, current_tarball_number); 729 753 } 730 754 if (g_getfacl) { 731 mr_asprintf(acl_fname, ACL_LIST_FNAME_RAW_SZ, MNT_CDROM "/archives", current_tarball_number);755 mr_asprintf(acl_fname, ACL_LIST_FNAME_RAW_SZ, ARCHIVES_PATH, current_tarball_number); 732 756 } 733 757 if (strstr(tarball_fname, ".bz2")) { … … 922 946 mr_free(progress_str); 923 947 924 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.bz2", current_tarball_number);948 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%ld.afio.bz2", current_tarball_number); 925 949 if (!does_file_exist(tarball_fname)) { 926 950 mr_free(tarball_fname); 927 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.gz", current_tarball_number);951 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%ld.afio.gz", current_tarball_number); 928 952 } 929 953 if (!does_file_exist(tarball_fname)) { 930 954 mr_free(tarball_fname); 931 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.lzma", current_tarball_number);955 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%ld.afio.lzma", current_tarball_number); 932 956 } 933 957 if (!does_file_exist(tarball_fname)) { 934 958 mr_free(tarball_fname); 935 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.lzo", current_tarball_number);959 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%ld.afio.lzo", current_tarball_number); 936 960 } 937 961 if (!does_file_exist(tarball_fname)) { 938 962 mr_free(tarball_fname); 939 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.", current_tarball_number);963 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%ld.afio.", current_tarball_number); 940 964 } 941 965 if (!does_file_exist(tarball_fname)) { 942 966 mr_free(tarball_fname); 943 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.star.bz2", current_tarball_number);967 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%ld.star.bz2", current_tarball_number); 944 968 } 945 969 if (!does_file_exist(tarball_fname)) { 946 970 mr_free(tarball_fname); 947 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.star.", current_tarball_number);971 mr_asprintf(tarball_fname, ARCHIVES_PATH "/%ld.star.", current_tarball_number); 948 972 } 949 973 if (!does_file_exist(tarball_fname)) { … … 954 978 return (0); 955 979 } 956 if (!does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST") 957 || system("find " MNT_CDROM 958 "/archives/slice* > /dev/null 2> /dev/null") == 980 if (!does_file_exist(ARCHIVES_PATH "/NOT-THE-LAST") 981 || system("find " ARCHIVES_PATH "/slice* > /dev/null 2> /dev/null") == 959 982 0) { 960 983 break;
Note:
See TracChangeset
for help on using the changeset viewer.
