Changeset 3287 in MondoRescue
- Timestamp:
- May 3, 2014, 10:13:14 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mondo/src/mondorestore/mondo-prep.c
r3286 r3287 182 182 183 183 #ifdef __FreeBSD__ 184 184 return (0); 185 185 #endif 186 186 … … 419 419 420 420 #ifdef __FreeBSD__ 421 422 421 log_to_screen("I don't know how to extrapolate the mountlist on FreeBSD. Sorry."); 422 return (1); 423 423 #endif 424 424 … … 439 439 q = fgets(incoming, MAX_STR_LEN - 1, fin)); 440 440 if (!feof(fin)) { 441 log_it(tmp, "Investigating %s", old_mountlist->el[lino].device); 442 for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL) 443 && !strstr(incoming, "raiddev"); 444 q = fgets(incoming, MAX_STR_LEN - 1, fin)) { 445 if (strstr(incoming, OSSWAP("device", "drive")) 446 && !strchr(incoming, '#')) { 441 log_it("Investigating %s", old_mountlist->el[lino].device); 442 for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL) && !strstr(incoming, "raiddev"); q = fgets(incoming, MAX_STR_LEN - 1, fin)) { 443 if (strstr(incoming, OSSWAP("device", "drive")) && !strchr(incoming, '#')) { 447 444 for (p = incoming + strlen(incoming); 448 445 *(p - 1) <= 32; p--); 449 446 *p = '\0'; 450 447 for (p--; p > incoming && *(p - 1) > 32; p--); 451 log_it(tmp, "Extrapolating %s", p); 452 for (j = 0; 453 j < new_mountlist->entries 454 && strcmp(new_mountlist->el[j].device, p); 455 j++); 448 log_it("Extrapolating %s", p); 449 for (j = 0; j < new_mountlist->entries && strcmp(new_mountlist->el[j].device, p); j++); 456 450 if (j >= new_mountlist->entries) { 457 451 strcpy(new_mountlist-> el[new_mountlist->entries].device, p); … … 461 455 new_mountlist->entries++; 462 456 } else { 463 log_it( tmp,"Not adding %s to mountlist: it's already there", p);457 log_it("Not adding %s to mountlist: it's already there", p); 464 458 } 465 459 } … … 639 633 /** int **************************************************************/ 640 634 #ifdef __FreeBSD__ 641 635 static bool vinum_started_yet = FALSE; 642 636 #endif 643 637 … … 658 652 } 659 653 #ifdef __FreeBSD__ 660 661 662 663 654 if (strcmp(format, "swap") == 0) { 655 log_it("Not formatting %s - it's swap", device); 656 return (0); 657 } 664 658 #endif 665 659 if (strlen(format) <= 2) { … … 675 669 newtSuspend(); 676 670 #ifdef __FreeBSD__ 677 if (!vinum_started_yet) { 678 if (!does_file_exist("/tmp/raidconf.txt")) { 679 log_to_screen("/tmp/raidconf.txt does not exist. I therefore cannot start Vinum."); 680 } else { 681 int res; 682 res = run_program_and_log_output("vinum create /tmp/raidconf.txt", TRUE); 683 if (res) { 684 log_to_screen("`vinum create /tmp/raidconf.txt' returned errors. Please fix them and re-run mondorestore."); 685 finish(1); 671 if (!vinum_started_yet) { 672 if (!does_file_exist("/tmp/raidconf.txt")) { 673 log_to_screen("/tmp/raidconf.txt does not exist. I therefore cannot start Vinum."); 674 } else { 675 int res; 676 res = run_program_and_log_output("vinum create /tmp/raidconf.txt", TRUE); 677 if (res) { 678 log_to_screen("`vinum create /tmp/raidconf.txt' returned errors. Please fix them and re-run mondorestore."); 679 finish(1); 680 } 681 vinum_started_yet = TRUE; 682 } 683 } 684 685 if (vinum_started_yet) { 686 FILE *fin; 687 char line[MAX_STR_LEN]; 688 689 log_to_screen(tmp, "Initializing Vinum device %s (this may take a *long* time)", device); 690 691 /* format raid partition */ 692 mr_asprintf(program, "for plex in `vinum lv -r %s | grep '^P' | tr '\t' ' ' | tr -s ' ' | cut -d' ' -f2`; do echo $plex; done > /tmp/plexes", basename(device)); 693 paranoid_system(program); 694 if (g_fprep) { 695 fprintf(g_fprep, "%s\n", program); 696 } 697 fin = fopen("/tmp/plexes", "r"); 698 while (fgets(line, MAX_STR_LEN - 1, fin)) { 699 if (strchr(line, '\n')) 700 *(strchr(line, '\n')) = '\0'; // get rid of the \n on the end 701 702 mr_asprintf(tmp, "Initializing plex: %s", line); 703 open_evalcall_form(tmp); 704 mr_free(tmp); 705 706 mr_asprintf(tmp, "vinum init %s", line); 707 paranoid_system(tmp); 708 mr_free(tmp); 709 710 while (1) { 711 mr_asprintf(tmp, "vinum lp -r %s | grep '^S' | head -1 | tr -s ' ' | cut -d: -f2 | cut -f1 | sed 's/^ //' | sed 's/I //' | sed 's/%%//'", line); 712 FILE *pin = popen(tmp, "r"); 713 mr_free(tmp); 714 715 char status[MAX_STR_LEN / 4]; 716 if (fgets(status, MAX_STR_LEN / 4 - 1, pin)) { 717 // FIXME 686 718 } 687 vinum_started_yet = TRUE; 688 } 689 } 690 691 if (vinum_started_yet) { 692 FILE *fin; 693 char line[MAX_STR_LEN]; 694 695 log_to_screen(tmp, "Initializing Vinum device %s (this may take a *long* time)", device); 696 697 /* format raid partition */ 698 mr_asprintf(program, "for plex in `vinum lv -r %s | grep '^P' | tr '\t' ' ' | tr -s ' ' | cut -d' ' -f2`; do echo $plex; done > /tmp/plexes", basename(device)); 699 paranoid_system(program); 700 if (g_fprep) { 701 fprintf(g_fprep, "%s\n", program); 702 } 703 fin = fopen("/tmp/plexes", "r"); 704 while (fgets(line, MAX_STR_LEN - 1, fin)) { 705 if (strchr(line, '\n')) 706 *(strchr(line, '\n')) = '\0'; // get rid of the \n on the end 707 708 mr_asprintf(tmp, "Initializing plex: %s", line); 709 open_evalcall_form(tmp); 710 mr_free(tmp); 711 712 mr_asprintf(tmp, "vinum init %s", line); 713 paranoid_system(tmp); 714 mr_free(tmp); 715 716 while (1) { 717 mr_asprintf(tmp, "vinum lp -r %s | grep '^S' | head -1 | tr -s ' ' | cut -d: -f2 | cut -f1 | sed 's/^ //' | sed 's/I //' | sed 's/%%//'", line); 718 FILE *pin = popen(tmp, "r"); 719 mr_free(tmp); 720 721 char status[MAX_STR_LEN / 4]; 722 if (fgets(status, MAX_STR_LEN / 4 - 1, pin)) { 723 // FIXME 724 } 725 pclose(pin); 726 727 if (!strcmp(status, "up")) { 728 break; /* it's done */ 729 } 730 update_evalcall_form(atoi(status)); 731 usleep(250000); 719 pclose(pin); 720 721 if (!strcmp(status, "up")) { 722 break; /* it's done */ 732 723 } 733 close_evalcall_form(); 734 } 735 fclose(fin); 736 unlink("/tmp/plexes"); 737 } 724 update_evalcall_form(atoi(status)); 725 usleep(250000); 726 } 727 close_evalcall_form(); 728 } 729 fclose(fin); 730 unlink("/tmp/plexes"); 731 } 738 732 #else 739 log_to_screen("Initializing RAID device %s", device); 740 741 // Shouldn't be necessary. 742 log_to_screen("Stopping %s", device); 743 stop_raid_device(device); 733 log_to_screen("Initializing RAID device %s", device); 734 735 // Shouldn't be necessary. 736 log_to_screen("Stopping %s", device); 737 stop_raid_device(device); 738 paranoid_system("sync"); 739 sleep(1); 740 741 log_msg(1, "Making %s", device); 742 // use mkraid if it exists, otherwise use mdadm 743 if (run_program_and_log_output("which mkraid", FALSE)) { 744 res = create_raid_device_via_mdadm(raidlist, device, TRUE); 745 log_msg(1, "Creating RAID device %s via mdadm returned %d", device, res); 746 } else { 747 mr_asprintf(program, "mkraid --really-force %s", device); 748 res = run_program_and_log_output(program, 1); 749 log_msg(1, "%s returned %d", program, res); 744 750 paranoid_system("sync"); 745 sleep(1); 746 747 log_msg(1, "Making %s", device); 748 // use mkraid if it exists, otherwise use mdadm 749 if (run_program_and_log_output("which mkraid", FALSE)) { 750 res = create_raid_device_via_mdadm(raidlist, device, TRUE); 751 log_msg(1, "Creating RAID device %s via mdadm returned %d", device, res); 752 } else { 753 mr_asprintf(program, "mkraid --really-force %s", device); 754 res = run_program_and_log_output(program, 1); 755 log_msg(1, "%s returned %d", program, res); 756 paranoid_system("sync"); 757 sleep(3); 758 start_raid_device(device); 759 if (g_fprep) { 760 fprintf(g_fprep, "%s\n", program); 761 } 762 } 763 paranoid_system("sync"); 764 sleep(2); 765 #endif 766 paranoid_system("sync"); 767 sleep(1); 768 newtResume(); 751 sleep(3); 752 start_raid_device(device); 753 if (g_fprep) { 754 fprintf(g_fprep, "%s\n", program); 755 } 756 } 757 paranoid_system("sync"); 758 sleep(2); 759 #endif 760 paranoid_system("sync"); 761 sleep(1); 762 newtResume(); 769 763 } 770 764 … … 800 794 mr_free(program); 801 795 #ifdef __FreeBSD__ 802 796 mr_asprintf(program, "newfs_msdos -F 32 %s", device); 803 797 #else 804 798 #ifdef __IA64__ 805 806 807 799 /* For EFI partitions take fat16 800 * as we want to make small ones */ 801 mr_asprintf(program, "mkfs -t %s -F 16 %s", format, device); 808 802 #else 809 803 mr_asprintf(program, "mkfs -t %s -F 32 %s", format, device); 810 804 #endif 811 805 #endif … … 1007 1001 */ 1008 1002 int make_dummy_partitions(FILE * pout_to_fdisk, char *drivename, int devno_we_must_allow_for) { 1009 /** int **************************************************************/ 1010 int current_devno; 1011 int previous_devno; 1012 int retval = 0; 1013 int res; 1014 1015 /** buffers **********************************************************/ 1016 char *tmp; 1017 1018 /** end **************************************************************/ 1019 1020 malloc_string(tmp); 1021 assert_string_is_neither_NULL_nor_zerolength(drivename); 1022 1023 if (devno_we_must_allow_for >= 5) { 1024 sprintf(tmp, "Making dummy primary 1 on %s", drivename); 1025 log_it(tmp); 1026 g_maximum_progress++; 1027 res = 1028 partition_device(pout_to_fdisk, drivename, 1, 0, "ext2", 1029 32000); 1030 retval += res; 1031 previous_devno = 1; 1032 current_devno = 5; 1033 } else { 1034 previous_devno = 0; 1035 current_devno = 1; 1036 } 1037 for (; current_devno < devno_we_must_allow_for; current_devno++) { 1038 sprintf(tmp, "Creating dummy partition %d on %s", current_devno, drivename); 1039 log_it(tmp); 1040 g_maximum_progress++; 1041 res = 1042 partition_device(pout_to_fdisk, drivename, current_devno, 1043 previous_devno, OSSWAP("ext2", "ufs"), 32000); 1044 retval += res; 1045 previous_devno = current_devno; 1046 } 1047 paranoid_free(tmp); 1048 return (previous_devno); 1003 1004 /** int **************************************************************/ 1005 int current_devno; 1006 int previous_devno; 1007 int retval = 0; 1008 int res; 1009 1010 assert_string_is_neither_NULL_nor_zerolength(drivename); 1011 1012 if (devno_we_must_allow_for >= 5) { 1013 log_it("Making dummy primary 1 on %s", drivename); 1014 g_maximum_progress++; 1015 res = partition_device(pout_to_fdisk, drivename, 1, 0, "ext2", 32000); 1016 retval += res; 1017 previous_devno = 1; 1018 current_devno = 5; 1019 } else { 1020 previous_devno = 0; 1021 current_devno = 1; 1022 } 1023 for (; current_devno < devno_we_must_allow_for; current_devno++) { 1024 log_it("Creating dummy partition %d on %s", current_devno, drivename); 1025 g_maximum_progress++; 1026 res = partition_device(pout_to_fdisk, drivename, current_devno, previous_devno, OSSWAP("ext2", "ufs"), 32000); 1027 retval += res; 1028 previous_devno = current_devno; 1029 } 1030 return (previous_devno); 1049 1031 } 1050 1032 … … 1055 1037 * @return TRUE if it does, FALSE if it doesn't. 1056 1038 */ 1057 bool mountlist_contains_raid_devices(struct mountlist_itself * mountlist) 1058 { 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1039 bool mountlist_contains_raid_devices(struct mountlist_itself * mountlist) { 1040 1041 /** int *************************************************************/ 1042 int i; 1043 int matching = 0; 1044 1045 /** end **************************************************************/ 1046 1047 assert(mountlist != NULL); 1048 1049 for (i = 0; i < mountlist->entries; i++) { 1050 if (strstr(mountlist->el[i].device, RAID_DEVICE_STUB)) { 1051 matching++; 1052 } 1053 } 1054 if (matching) { 1055 return (TRUE); 1056 } else { 1057 return (FALSE); 1058 } 1077 1059 } 1078 1060 1079 1061 /* The following 2 functions are stolen from /usr/src/sbin/disklabel/disklabel.c */ 1080 1062 #ifdef __FreeBSD__ 1081 static void display_disklabel(FILE * f, const struct disklabel *lp) 1082 { 1083 int i, j; 1084 const struct partition *pp; 1085 1086 fprintf(f, "# %s\n", "Generated by Mondo Rescue"); 1087 if (lp->d_type < DKMAXTYPES) 1088 fprintf(f, "type: %s\n", dktypenames[lp->d_type]); 1089 else 1090 fprintf(f, "type: %u\n", lp->d_type); 1091 fprintf(f, "disk: %.*s\n", (int) sizeof(lp->d_typename), 1092 lp->d_typename); 1093 fprintf(f, "label: %.*s\n", (int) sizeof(lp->d_packname), 1094 lp->d_packname); 1095 fprintf(f, "flags:"); 1096 if (lp->d_flags & D_REMOVABLE) 1097 fprintf(f, " removeable"); 1098 if (lp->d_flags & D_ECC) 1099 fprintf(f, " ecc"); 1100 if (lp->d_flags & D_BADSECT) 1101 fprintf(f, " badsect"); 1102 fprintf(f, "\n"); 1103 fprintf(f, "bytes/sector: %lu\n", (u_long) lp->d_secsize); 1104 fprintf(f, "sectors/track: %lu\n", (u_long) lp->d_nsectors); 1105 fprintf(f, "tracks/cylinder: %lu\n", (u_long) lp->d_ntracks); 1106 fprintf(f, "sectors/cylinder: %lu\n", (u_long) lp->d_secpercyl); 1107 fprintf(f, "cylinders: %lu\n", (u_long) lp->d_ncylinders); 1108 fprintf(f, "sectors/unit: %lu\n", (u_long) lp->d_secperunit); 1109 fprintf(f, "rpm: %u\n", lp->d_rpm); 1110 fprintf(f, "interleave: %u\n", lp->d_interleave); 1111 fprintf(f, "trackskew: %u\n", lp->d_trackskew); 1112 fprintf(f, "cylinderskew: %u\n", lp->d_cylskew); 1113 fprintf(f, "headswitch: %lu\t\t# milliseconds\n", 1114 (u_long) lp->d_headswitch); 1115 fprintf(f, "track-to-track seek: %ld\t# milliseconds\n", 1116 (u_long) lp->d_trkseek); 1117 fprintf(f, "drivedata: "); 1118 for (i = NDDATA - 1; i >= 0; i--) 1119 if (lp->d_drivedata[i]) 1063 static void display_disklabel(FILE * f, const struct disklabel *lp) { 1064 1065 int i, j; 1066 const struct partition *pp; 1067 1068 fprintf(f, "# %s\n", "Generated by Mondo Rescue"); 1069 if (lp->d_type < DKMAXTYPES) 1070 fprintf(f, "type: %s\n", dktypenames[lp->d_type]); 1071 else 1072 fprintf(f, "type: %u\n", lp->d_type); 1073 fprintf(f, "disk: %.*s\n", (int) sizeof(lp->d_typename), lp->d_typename); 1074 fprintf(f, "label: %.*s\n", (int) sizeof(lp->d_packname), lp->d_packname); 1075 fprintf(f, "flags:"); 1076 if (lp->d_flags & D_REMOVABLE) 1077 fprintf(f, " removeable"); 1078 if (lp->d_flags & D_ECC) 1079 fprintf(f, " ecc"); 1080 if (lp->d_flags & D_BADSECT) 1081 fprintf(f, " badsect"); 1082 fprintf(f, "\n"); 1083 fprintf(f, "bytes/sector: %lu\n", (u_long) lp->d_secsize); 1084 fprintf(f, "sectors/track: %lu\n", (u_long) lp->d_nsectors); 1085 fprintf(f, "tracks/cylinder: %lu\n", (u_long) lp->d_ntracks); 1086 fprintf(f, "sectors/cylinder: %lu\n", (u_long) lp->d_secpercyl); 1087 fprintf(f, "cylinders: %lu\n", (u_long) lp->d_ncylinders); 1088 fprintf(f, "sectors/unit: %lu\n", (u_long) lp->d_secperunit); 1089 fprintf(f, "rpm: %u\n", lp->d_rpm); 1090 fprintf(f, "interleave: %u\n", lp->d_interleave); 1091 fprintf(f, "trackskew: %u\n", lp->d_trackskew); 1092 fprintf(f, "cylinderskew: %u\n", lp->d_cylskew); 1093 fprintf(f, "headswitch: %lu\t\t# milliseconds\n", (u_long) lp->d_headswitch); 1094 fprintf(f, "track-to-track seek: %ld\t# milliseconds\n", (u_long) lp->d_trkseek); 1095 fprintf(f, "drivedata: "); 1096 for (i = NDDATA - 1; i >= 0; i--) 1097 if (lp->d_drivedata[i]) 1098 break; 1099 if (i < 0) 1100 i = 0; 1101 for (j = 0; j <= i; j++) 1102 fprintf(f, "%lu ", (u_long) lp->d_drivedata[j]); 1103 fprintf(f, "\n\n%u partitions:\n", lp->d_npartitions); 1104 fprintf(f, "# size offset fstype [fsize bsize bps/cpg]\n"); 1105 pp = lp->d_partitions; 1106 for (i = 0; i < lp->d_npartitions; i++, pp++) { 1107 if (pp->p_size) { 1108 fprintf(f, " %c: %8lu %8lu ", 'a' + i, (u_long) pp->p_size, (u_long) pp->p_offset); 1109 if (pp->p_fstype < FSMAXTYPES) 1110 fprintf(f, "%8.8s", fstypenames[pp->p_fstype]); 1111 else 1112 fprintf(f, "%8d", pp->p_fstype); 1113 switch (pp->p_fstype) { 1114 1115 case FS_UNUSED: /* XXX */ 1116 fprintf(f, " %5lu %5lu %5.5s ", (u_long) pp->p_fsize, (u_long) (pp->p_fsize * pp->p_frag), ""); 1120 1117 break; 1121 if (i < 0) 1122 i = 0; 1123 for (j = 0; j <= i; j++) 1124 fprintf(f, "%lu ", (u_long) lp->d_drivedata[j]); 1125 fprintf(f, "\n\n%u partitions:\n", lp->d_npartitions); 1126 fprintf(f, 1127 "# size offset fstype [fsize bsize bps/cpg]\n"); 1128 pp = lp->d_partitions; 1129 for (i = 0; i < lp->d_npartitions; i++, pp++) { 1130 if (pp->p_size) { 1131 fprintf(f, " %c: %8lu %8lu ", 'a' + i, (u_long) pp->p_size, 1132 (u_long) pp->p_offset); 1133 if (pp->p_fstype < FSMAXTYPES) 1134 fprintf(f, "%8.8s", fstypenames[pp->p_fstype]); 1135 else 1136 fprintf(f, "%8d", pp->p_fstype); 1137 switch (pp->p_fstype) { 1138 1139 case FS_UNUSED: /* XXX */ 1140 fprintf(f, " %5lu %5lu %5.5s ", (u_long) pp->p_fsize, 1141 (u_long) (pp->p_fsize * pp->p_frag), ""); 1142 break; 1143 1144 case FS_BSDFFS: 1145 fprintf(f, " %5lu %5lu %5u ", (u_long) pp->p_fsize, 1146 (u_long) (pp->p_fsize * pp->p_frag), pp->p_cpg); 1147 break; 1148 1149 case FS_BSDLFS: 1150 fprintf(f, " %5lu %5lu %5d", (u_long) pp->p_fsize, 1151 (u_long) (pp->p_fsize * pp->p_frag), pp->p_cpg); 1152 break; 1153 1154 default: 1155 fprintf(f, "%20.20s", ""); 1156 break; 1157 } 1158 fprintf(f, "\t# (Cyl. %4lu", 1159 (u_long) (pp->p_offset / lp->d_secpercyl)); 1160 if (pp->p_offset % lp->d_secpercyl) 1161 putc('*', f); 1162 else 1163 putc(' ', f); 1164 fprintf(f, "- %lu", 1165 (u_long) ((pp->p_offset + pp->p_size + 1166 lp->d_secpercyl - 1) / lp->d_secpercyl - 1167 1)); 1168 if (pp->p_size % lp->d_secpercyl) 1169 putc('*', f); 1170 fprintf(f, ")\n"); 1171 } 1172 } 1173 fflush(f); 1174 } 1175 1176 static struct disklabel *get_virgin_disklabel(char *dkname) 1177 { 1178 static struct disklabel loclab; 1179 struct partition *dp; 1180 char lnamebuf[BBSIZE]; 1181 int f; 1182 u_int secsize, u; 1183 off_t mediasize; 1184 1185 (void) snprintf(lnamebuf, BBSIZE, "%s", dkname); 1186 if ((f = open(lnamebuf, O_RDONLY)) == -1) { 1187 warn("cannot open %s", lnamebuf); 1188 return (NULL); 1189 } 1190 1191 /* New world order */ 1192 if ((ioctl(f, DIOCGMEDIASIZE, &mediasize) != 0) 1193 || (ioctl(f, DIOCGSECTORSIZE, &secsize) != 0)) { 1194 close(f); 1195 return (NULL); 1196 } 1197 memset(&loclab, 0, sizeof loclab); 1198 loclab.d_magic = DISKMAGIC; 1199 loclab.d_magic2 = DISKMAGIC; 1200 loclab.d_secsize = secsize; 1201 loclab.d_secperunit = mediasize / secsize; 1202 1203 /* 1204 * Nobody in these enligthened days uses the CHS geometry for 1205 * anything, but nontheless try to get it right. If we fail 1206 * to get any good ideas from the device, construct something 1207 * which is IBM-PC friendly. 1208 */ 1209 if (ioctl(f, DIOCGFWSECTORS, &u) == 0) 1210 loclab.d_nsectors = u; 1211 else 1212 loclab.d_nsectors = 63; 1213 if (ioctl(f, DIOCGFWHEADS, &u) == 0) 1214 loclab.d_ntracks = u; 1215 else if (loclab.d_secperunit <= 63 * 1 * 1024) 1216 loclab.d_ntracks = 1; 1217 else if (loclab.d_secperunit <= 63 * 16 * 1024) 1218 loclab.d_ntracks = 16; 1219 else 1220 loclab.d_ntracks = 255; 1221 loclab.d_secpercyl = loclab.d_ntracks * loclab.d_nsectors; 1222 loclab.d_ncylinders = loclab.d_secperunit / loclab.d_secpercyl; 1223 loclab.d_npartitions = MAXPARTITIONS; 1224 1225 /* Various (unneeded) compat stuff */ 1226 loclab.d_rpm = 3600; 1227 loclab.d_bbsize = BBSIZE; 1228 loclab.d_interleave = 1;; 1229 strncpy(loclab.d_typename, "amnesiac", sizeof(loclab.d_typename)); 1118 1119 case FS_BSDFFS: 1120 fprintf(f, " %5lu %5lu %5u ", (u_long) pp->p_fsize, (u_long) (pp->p_fsize * pp->p_frag), pp->p_cpg); 1121 break; 1122 1123 case FS_BSDLFS: 1124 fprintf(f, " %5lu %5lu %5d", (u_long) pp->p_fsize, (u_long) (pp->p_fsize * pp->p_frag), pp->p_cpg); 1125 break; 1126 1127 default: 1128 fprintf(f, "%20.20s", ""); 1129 break; 1130 } 1131 fprintf(f, "\t# (Cyl. %4lu", (u_long) (pp->p_offset / lp->d_secpercyl)); 1132 if (pp->p_offset % lp->d_secpercyl) 1133 putc('*', f); 1134 else 1135 putc(' ', f); 1136 fprintf(f, "- %lu", (u_long) ((pp->p_offset + pp->p_size + lp->d_secpercyl - 1) / lp->d_secpercyl - 1)); 1137 if (pp->p_size % lp->d_secpercyl) 1138 putc('*', f); 1139 fprintf(f, ")\n"); 1140 } 1141 } 1142 fflush(f); 1143 } 1144 1145 static struct disklabel *get_virgin_disklabel(char *dkname) { 1146 1147 static struct disklabel loclab; 1148 struct partition *dp; 1149 char *lnamebuf = NULL; 1150 int f; 1151 u_int secsize, u; 1152 off_t mediasize; 1153 1154 mr_asprintf(lnamebuf, "%s", dkname); 1155 if ((f = open(lnamebuf, O_RDONLY)) == -1) { 1156 warn("cannot open %s", lnamebuf); 1157 mr_free(lnamebuf); 1158 return (NULL); 1159 } 1160 mr_free(lnamebuf); 1161 1162 /* New world order */ 1163 if ((ioctl(f, DIOCGMEDIASIZE, &mediasize) != 0) 1164 || (ioctl(f, DIOCGSECTORSIZE, &secsize) != 0)) { 1165 close(f); 1166 return (NULL); 1167 } 1168 memset(&loclab, 0, sizeof loclab); 1169 loclab.d_magic = DISKMAGIC; 1170 loclab.d_magic2 = DISKMAGIC; 1171 loclab.d_secsize = secsize; 1172 loclab.d_secperunit = mediasize / secsize; 1173 1174 /* 1175 * Nobody in these enligthened days uses the CHS geometry for 1176 * anything, but nontheless try to get it right. If we fail 1177 * to get any good ideas from the device, construct something 1178 * which is IBM-PC friendly. 1179 */ 1180 if (ioctl(f, DIOCGFWSECTORS, &u) == 0) 1181 loclab.d_nsectors = u; 1182 else 1183 loclab.d_nsectors = 63; 1184 1185 if (ioctl(f, DIOCGFWHEADS, &u) == 0) 1186 loclab.d_ntracks = u; 1187 else if (loclab.d_secperunit <= 63 * 1 * 1024) 1188 loclab.d_ntracks = 1; 1189 else if (loclab.d_secperunit <= 63 * 16 * 1024) 1190 loclab.d_ntracks = 16; 1191 else 1192 loclab.d_ntracks = 255; 1193 loclab.d_secpercyl = loclab.d_ntracks * loclab.d_nsectors; 1194 loclab.d_ncylinders = loclab.d_secperunit / loclab.d_secpercyl; 1195 loclab.d_npartitions = MAXPARTITIONS; 1196 1197 /* Various (unneeded) compat stuff */ 1198 loclab.d_rpm = 3600; 1199 loclab.d_bbsize = BBSIZE; 1200 loclab.d_interleave = 1;; 1201 strncpy(loclab.d_typename, "amnesiac", sizeof(loclab.d_typename)); 1230 1202 1231 1203 dp = &loclab.d_partitions[RAW_PART]; 1232 1233 1234 1235 1204 dp->p_size = loclab.d_secperunit; 1205 loclab.d_checksum = dkcksum(&loclab); 1206 close(f); 1207 return (&loclab); 1236 1208 } 1237 1209 1238 1210 /* End stolen from /usr/src/sbin/disklabel/disklabel.c. */ 1239 1211 1240 char *canonical_name(char *drivename) 1241 { 1242 1243 1244 1245 1246 1247 1212 char *canonical_name(char *drivename) { 1213 1214 if (drivename) { 1215 if (strncmp(drivename, "/dev/", 5) == 0) { 1216 return drivename + 5; 1217 } 1218 } 1219 return drivename; 1248 1220 } 1249 1221 … … 1255 1227 * @return The number of errors encountered (0 for success). 1256 1228 */ 1257 int label_drive_or_slice(struct mountlist_itself *mountlist, 1258 char *drivename, struct disklabel *ret) 1259 { 1260 char subdev_str[MAX_STR_LEN]; 1261 char command[MAX_STR_LEN]; 1262 struct disklabel *lp; 1263 int i, lo = 0; 1264 int retval = 0; 1265 char c; 1266 FILE *ftmp; 1267 1268 lp = get_virgin_disklabel(drivename); 1269 for (c = 'a'; c <= 'z'; ++c) { 1270 int idx; 1271 sprintf(subdev_str, "%s%c", drivename, c); 1272 if ((idx = find_device_in_mountlist(mountlist, subdev_str)) < 0) { 1273 lp->d_partitions[c - 'a'].p_size = 0; 1274 lp->d_partitions[c - 'a'].p_fstype = FS_UNUSED; 1275 } else { 1276 lo = c - 'a'; 1277 lp->d_partitions[c - 'a'].p_size = mountlist->el[idx].size * 2; 1278 lp->d_partitions[c - 'a'].p_fsize = 0; 1279 lp->d_partitions[c - 'a'].p_frag = 0; 1280 lp->d_partitions[c - 'a'].p_cpg = 0; 1281 if (!strcmp(mountlist->el[idx].format, "ufs") 1282 || !strcmp(mountlist->el[idx].format, "ffs") 1283 || !strcmp(mountlist->el[idx].format, "4.2BSD")) { 1284 lp->d_partitions[c - 'a'].p_fstype = FS_BSDFFS; 1285 lp->d_partitions[c - 'a'].p_fsize = 2048; 1286 lp->d_partitions[c - 'a'].p_frag = 8; 1287 lp->d_partitions[c - 'a'].p_cpg = 64; 1288 } else if (!strcasecmp(mountlist->el[idx].format, "raid") 1289 || !strcasecmp(mountlist->el[idx].format, "vinum")) { 1290 lp->d_partitions[c - 'a'].p_fstype = FS_VINUM; 1291 } else if (!strcmp(mountlist->el[idx].format, "swap")) { 1292 lp->d_partitions[c - 'a'].p_fstype = FS_SWAP; 1293 } else 1294 lp->d_partitions[c - 'a'].p_fstype = FS_OTHER; 1295 } 1296 } 1297 1298 // fix up the offsets 1299 lp->d_partitions[0].p_offset = 0; 1300 lp->d_partitions[RAW_PART].p_offset = 0; 1301 lp->d_partitions[RAW_PART].p_size = lp->d_secperunit; 1302 lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED; 1303 1304 for (i = 1; i < lp->d_npartitions; ++i) { 1305 int lastone; 1306 if ((i == RAW_PART) || (lp->d_partitions[i].p_size == 0)) 1307 continue; 1308 for (lastone = i - 1; lastone >= 0; lastone--) { 1309 if ((lp->d_partitions[lastone].p_size) 1310 && (lastone != RAW_PART)) 1311 break; 1312 } 1313 lp->d_partitions[i].p_offset = 1314 lp->d_partitions[lastone].p_offset + 1315 lp->d_partitions[lastone].p_size; 1316 } 1317 if (lp->d_partitions[lo].p_offset + lp->d_partitions[lo].p_size > 1318 lp->d_secperunit) { 1319 lp->d_partitions[lo].p_size = 1320 lp->d_secperunit - lp->d_partitions[lo].p_offset; 1321 } 1322 1323 ftmp = fopen("/tmp/disklabel", "w"); 1324 display_disklabel(ftmp, lp); 1325 fclose(ftmp); 1326 sprintf(command, "disklabel -wr %s auto", canonical_name(drivename)); 1327 retval += run_program_and_log_output(command, TRUE); 1328 sprintf(command, "disklabel -R %s /tmp/disklabel", 1329 canonical_name(drivename)); 1330 retval += run_program_and_log_output(command, TRUE); 1331 if (ret) 1332 *ret = *lp; 1333 return retval; 1229 int label_drive_or_slice(struct mountlist_itself *mountlist, char *drivename, struct disklabel *ret) { 1230 1231 char *subdev_str = NULL; 1232 char *command = NULL; 1233 struct disklabel *lp; 1234 int i, lo = 0; 1235 int retval = 0; 1236 char c; 1237 FILE *ftmp; 1238 1239 lp = get_virgin_disklabel(drivename); 1240 for (c = 'a'; c <= 'z'; ++c) { 1241 int idx; 1242 mr_asprintf(subdev_str, "%s%c", drivename, c); 1243 if ((idx = find_device_in_mountlist(mountlist, subdev_str)) < 0) { 1244 lp->d_partitions[c - 'a'].p_size = 0; 1245 lp->d_partitions[c - 'a'].p_fstype = FS_UNUSED; 1246 } else { 1247 lo = c - 'a'; 1248 lp->d_partitions[c - 'a'].p_size = mountlist->el[idx].size * 2; 1249 lp->d_partitions[c - 'a'].p_fsize = 0; 1250 lp->d_partitions[c - 'a'].p_frag = 0; 1251 lp->d_partitions[c - 'a'].p_cpg = 0; 1252 if (!strcmp(mountlist->el[idx].format, "ufs") || !strcmp(mountlist->el[idx].format, "ffs") || !strcmp(mountlist->el[idx].format, "4.2BSD")) { 1253 lp->d_partitions[c - 'a'].p_fstype = FS_BSDFFS; 1254 lp->d_partitions[c - 'a'].p_fsize = 2048; 1255 lp->d_partitions[c - 'a'].p_frag = 8; 1256 lp->d_partitions[c - 'a'].p_cpg = 64; 1257 } else if (!strcasecmp(mountlist->el[idx].format, "raid") || !strcasecmp(mountlist->el[idx].format, "vinum")) { 1258 lp->d_partitions[c - 'a'].p_fstype = FS_VINUM; 1259 } else if (!strcmp(mountlist->el[idx].format, "swap")) { 1260 lp->d_partitions[c - 'a'].p_fstype = FS_SWAP; 1261 } else 1262 lp->d_partitions[c - 'a'].p_fstype = FS_OTHER; 1263 } 1264 mr_free(subdev_str); 1265 } 1266 1267 // fix up the offsets 1268 lp->d_partitions[0].p_offset = 0; 1269 lp->d_partitions[RAW_PART].p_offset = 0; 1270 lp->d_partitions[RAW_PART].p_size = lp->d_secperunit; 1271 lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED; 1272 1273 for (i = 1; i < lp->d_npartitions; ++i) { 1274 int lastone; 1275 if ((i == RAW_PART) || (lp->d_partitions[i].p_size == 0)) 1276 continue; 1277 for (lastone = i - 1; lastone >= 0; lastone--) { 1278 if ((lp->d_partitions[lastone].p_size) && (lastone != RAW_PART)) 1279 break; 1280 } 1281 lp->d_partitions[i].p_offset = lp->d_partitions[lastone].p_offset + lp->d_partitions[lastone].p_size; 1282 } 1283 if (lp->d_partitions[lo].p_offset + lp->d_partitions[lo].p_size > lp->d_secperunit) { 1284 lp->d_partitions[lo].p_size = lp->d_secperunit - lp->d_partitions[lo].p_offset; 1285 } 1286 1287 ftmp = fopen("/tmp/disklabel", "w"); 1288 display_disklabel(ftmp, lp); 1289 fclose(ftmp); 1290 mr_asprintf(command, "disklabel -wr %s auto", canonical_name(drivename)); 1291 retval += run_program_and_log_output(command, TRUE); 1292 mr_free(command); 1293 1294 mr_asprintf(command, "disklabel -R %s /tmp/disklabel", canonical_name(drivename)); 1295 retval += run_program_and_log_output(command, TRUE); 1296 mr_free(command); 1297 1298 if (ret) 1299 *ret = *lp; 1300 return retval; 1334 1301 } 1335 1302 #endif … … 1342 1309 * @return 0 for success, nonzero for failure. 1343 1310 */ 1344 int partition_drive(struct mountlist_itself *mountlist, char *drivename) 1345 { 1346 1347 1348 1349 1350 1351 1352 1311 int partition_drive(struct mountlist_itself *mountlist, char *drivename) { 1312 1313 /** int *************************************************************/ 1314 int current_devno; 1315 int previous_devno = 0; 1316 int lino; 1317 int retval = 0; 1318 int i; 1319 FILE *pout_to_fdisk = NULL; 1353 1320 1354 1321 #ifdef __FreeBSD__ 1355 bool fbsd_part = FALSE; 1356 char subdev_str[MAX_STR_LEN]; 1357 #endif 1358 1359 /** long long *******************************************************/ 1360 long long partsize; 1361 1362 /** buffers *********************************************************/ 1363 char *device_str; 1364 char *format; 1365 char *tmp; 1366 char *tmp1 = NULL; 1367 1368 /** end *************************************************************/ 1369 1370 assert(mountlist != NULL); 1371 assert_string_is_neither_NULL_nor_zerolength(drivename); 1372 1373 malloc_string(device_str); 1374 malloc_string(format); 1375 malloc_string(tmp); 1376 1377 sprintf(tmp, "Partitioning drive %s", drivename); 1378 log_it(tmp); 1322 bool fbsd_part = FALSE; 1323 char *subdev_str = NULL; 1324 #endif 1325 1326 /** long long *******************************************************/ 1327 long long partsize; 1328 1329 /** buffers *********************************************************/ 1330 char *device_str; 1331 char *format = NULL; 1332 char *tmp = NULL; 1333 char *tmp1 = NULL; 1334 1335 /** end *************************************************************/ 1336 1337 assert(mountlist != NULL); 1338 assert_string_is_neither_NULL_nor_zerolength(drivename); 1339 1340 1341 log_it("Partitioning drive %s", drivename); 1379 1342 1380 1343 #if __FreeBSD__ … … 1382 1345 pout_to_fdisk = NULL; 1383 1346 #else 1384 make_hole_for_file(FDISK_LOG); 1385 sprintf(tmp, "parted2fdisk %s >> %s 2>> %s", drivename, FDISK_LOG, FDISK_LOG); 1386 pout_to_fdisk = popen(tmp, "w"); 1387 if (!pout_to_fdisk) { 1388 log_to_screen("Cannot call parted2fdisk to configure %s", drivename); 1389 paranoid_free(device_str); 1390 paranoid_free(format); 1391 paranoid_free(tmp); 1392 return (1); 1393 } 1394 #endif 1395 for (current_devno = 1; current_devno < 99; current_devno++) { 1396 build_partition_name(device_str, drivename, current_devno); 1397 lino = find_device_in_mountlist(mountlist, device_str); 1398 1399 if (lino < 0) { 1400 // device not found in mountlist 1347 make_hole_for_file(FDISK_LOG); 1348 mr_asprintf(tmp, "parted2fdisk %s >> %s 2>> %s", drivename, FDISK_LOG, FDISK_LOG); 1349 pout_to_fdisk = popen(tmp, "w"); 1350 if (!pout_to_fdisk) { 1351 log_to_screen("Cannot call parted2fdisk to configure %s", drivename); 1352 mr_free(tmp); 1353 return (1); 1354 } 1355 mr_free(tmp); 1356 #endif 1357 1358 malloc_string(device_str); 1359 1360 for (current_devno = 1; current_devno < 99; current_devno++) { 1361 build_partition_name(device_str, drivename, current_devno); 1362 lino = find_device_in_mountlist(mountlist, device_str); 1363 1364 if (lino < 0) { 1365 // device not found in mountlist 1401 1366 #if __FreeBSD__ 1402 1367 // If this is the first partition (just as a sentinel value), … … 1407 1372 // try DangerouslyDedicated mode 1408 1373 for (c = 'a'; c <= 'z'; c++) { 1409 sprintf(subdev_str, "%s%c", drivename, c); 1410 if (find_device_in_mountlist(mountlist, subdev_str) > 1411 0) { 1374 mr_asprintf(subdev_str, "%s%c", drivename, c); 1375 if (find_device_in_mountlist(mountlist, subdev_str) > 0) { 1412 1376 fbsd_part = TRUE; 1413 1377 } 1378 mr_free(subdev_str); 1414 1379 } 1415 1380 if (fbsd_part) { … … 1425 1390 } 1426 1391 paranoid_free(device_str); 1427 paranoid_free(format);1428 paranoid_free(tmp);1429 1392 return r; 1430 1393 } 1431 1394 } 1432 1395 for (c = 'a'; c <= 'z'; c++) { 1433 sprintf(subdev_str, "%s%c", device_str, c);1396 mr_assprintf(subdev_str, "%s%c", device_str, c); 1434 1397 if (find_device_in_mountlist(mountlist, subdev_str) > 0) { 1435 1398 fbsd_part = TRUE; 1436 1399 } 1400 mr_free(subdev_str); 1437 1401 } 1438 1402 // Now we check the subpartitions of the current partition. … … 1440 1404 int i, line; 1441 1405 1442 strcpy(format, "ufs");1406 mr_asprintf(format, "ufs"); 1443 1407 partsize = 0; 1444 1408 for (i = 'a'; i < 'z'; ++i) { 1445 sprintf(subdev_str, "%s%c", device_str, i);1409 mr_asprintf(subdev_str, "%s%c", device_str, i); 1446 1410 line = find_device_in_mountlist(mountlist, subdev_str); 1411 mr_free(subdev_str); 1412 1447 1413 if (line > 0) { 1448 1414 // We found one! Add its size to the total size. … … 1456 1422 continue; 1457 1423 #endif 1458 1459 1460 1461 1462 1463 1464 1465 1466 1424 } 1425 1426 /* OK, we've found partition /dev/hdxN in mountlist; let's prep it */ 1427 /* For FreeBSD, that is /dev/adXsY */ 1428 1429 log_it("Found partition %s in mountlist", device_str); 1430 if (!previous_devno) { 1431 1432 log_it("Wiping %s's partition table", drivename); 1467 1433 #if __FreeBSD__ 1468 1434 // FreeBSD doesn't let you write to blk devices in <512byte chunks. 1469 // sprintf(tmp, "dd if=/dev/zero of=%s count=1 bs=512", drivename);1470 // if (run_program_and_log_output(tmp, TRUE)) {1471 1435 file = open(drivename, O_WRONLY); 1472 1436 if (file != -1) { 1473 sprintf(tmp, 1474 "Warning - unable to open %s for wiping it's partition table", 1475 drivename); 1476 log_to_screen(tmp); 1437 log_to_screnn("Warning - unable to open %s for wiping it's partition table", drivename); 1477 1438 } 1478 1439 1479 1440 for (i = 0; i < 512; i++) { 1480 1441 if (!write(file, "\0", 1)) { 1481 sprintf(tmp, "Warning - unable to write to %s", 1482 drivename); 1483 log_to_screen(tmp); 1442 log_to_screen("Warning - unable to write to %s", drivename); 1484 1443 } 1485 1444 } … … 1491 1450 fflush(pout_to_fdisk); 1492 1451 } 1493 // sprintf(tmp, "dd if=/dev/zero of=%s count=1 bs=512", drivename); 1494 // run_program_and_log_output(tmp, 1); 1495 #endif 1496 if (current_devno > 1) { 1497 previous_devno = 1498 make_dummy_partitions(pout_to_fdisk, drivename, 1499 current_devno); 1500 } 1501 } 1452 #endif 1453 if (current_devno > 1) { 1454 previous_devno = make_dummy_partitions(pout_to_fdisk, drivename, current_devno); 1455 } 1456 } 1502 1457 #ifdef __FreeBSD__ 1503 if (!fbsd_part) { 1504 #endif 1505 1506 strcpy(format, mountlist->el[lino].format); 1507 partsize = mountlist->el[lino].size; 1458 if (!fbsd_part) { 1459 mr_free(format); 1460 #endif 1461 1462 mr_asprintf(format, "%s", mountlist->el[lino].format); 1463 partsize = mountlist->el[lino].size; 1508 1464 1509 1465 #ifdef __FreeBSD__ 1510 1466 } 1511 1467 #endif 1512 1468 1513 1469 #ifndef __IA64__ 1514 if (current_devno == 5 && previous_devno == 4) { 1515 log_to_screen 1516 ("You must leave at least one partition spare as the Extended partition."); 1517 paranoid_free(device_str); 1518 paranoid_free(format); 1519 paranoid_free(tmp); 1520 return (1); 1521 } 1522 #endif 1523 1524 retval += 1525 partition_device(pout_to_fdisk, drivename, current_devno, 1526 previous_devno, format, partsize); 1470 if (current_devno == 5 && previous_devno == 4) { 1471 log_to_screen("You must leave at least one partition spare as the Extended partition."); 1472 paranoid_free(device_str); 1473 mr_free(format); 1474 return (1); 1475 } 1476 #endif 1477 1478 retval += partition_device(pout_to_fdisk, drivename, current_devno, previous_devno, format, partsize); 1479 mr_free(format); 1527 1480 1528 1481 #ifdef __FreeBSD__ 1529 if ((current_devno <= 4) && fbsd_part) { 1530 sprintf(tmp, "disklabel -B %s", basename(device_str)); 1531 retval += label_drive_or_slice(mountlist, device_str, 0); 1532 if (system(tmp)) { 1533 log_to_screen 1534 ("Warning! Unable to make the slice bootable."); 1535 } 1536 } 1537 #endif 1538 1539 previous_devno = current_devno; 1540 } 1541 1542 if (pout_to_fdisk) { 1543 // close fdisk 1544 fput_string_one_char_at_a_time(pout_to_fdisk, "p\n"); 1545 fput_string_one_char_at_a_time(pout_to_fdisk, "w\n"); 1546 paranoid_pclose(pout_to_fdisk); 1547 paranoid_system("sync"); 1548 log_msg(0,"------------------- fdisk.log looks like this ------------------"); 1549 sprintf(tmp, "cat %s >> %s", FDISK_LOG, MONDO_LOGFILE); 1550 paranoid_system(tmp); 1551 // mark relevant partition as bootable 1552 mr_asprintf(tmp1,"make-me-bootable /tmp/mountlist.txt %s",drivename); 1553 call_program_and_get_last_line_of_output(tmp1); 1554 mr_free(tmp1); 1555 log_msg(0,"------------------- end of fdisk.log... ------------------"); 1556 paranoid_system("sync"); 1557 sprintf(tmp, "tail -n6 %s | grep -F \"16: \"", FDISK_LOG); 1558 if (!run_program_and_log_output(tmp, 5)) { 1559 g_partition_table_locked_up++; 1560 } 1561 sprintf(tmp, "partprobe %s", drivename); 1562 if (!run_program_and_log_output(tmp, 5)) { 1563 g_partition_table_locked_up--; 1564 } 1565 if (g_partition_table_locked_up > 0) { 1566 log_to_screen 1567 ("A flaw in the Linux kernel has locked the partition table. Even calling partprobe did not suceed :-("); 1568 } 1569 } 1570 paranoid_free(device_str); 1571 paranoid_free(format); 1572 paranoid_free(tmp); 1573 return (retval); 1482 if ((current_devno <= 4) && fbsd_part) { 1483 mr_asprintf(tmp, "disklabel -B %s", basename(device_str)); 1484 retval += label_drive_or_slice(mountlist, device_str, 0); 1485 if (system(tmp)) { 1486 log_to_screen("Warning! Unable to make the slice bootable."); 1487 } 1488 mr_free(tmp); 1489 } 1490 #endif 1491 1492 previous_devno = current_devno; 1493 } 1494 1495 if (pout_to_fdisk) { 1496 // close fdisk 1497 fput_string_one_char_at_a_time(pout_to_fdisk, "p\n"); 1498 fput_string_one_char_at_a_time(pout_to_fdisk, "w\n"); 1499 paranoid_pclose(pout_to_fdisk); 1500 paranoid_system("sync"); 1501 log_msg(0,"------------------- fdisk.log looks like this ------------------"); 1502 mr_asprintf(tmp, "cat %s >> %s", FDISK_LOG, MONDO_LOGFILE); 1503 paranoid_system(tmp); 1504 mr_free(tmp); 1505 1506 // mark relevant partition as bootable 1507 mr_asprintf(tmp1,"make-me-bootable /tmp/mountlist.txt %s",drivename); 1508 call_program_and_get_last_line_of_output(tmp1); 1509 mr_free(tmp1); 1510 1511 log_msg(0,"------------------- end of fdisk.log... ------------------"); 1512 paranoid_system("sync"); 1513 mr_asprintf(tmp, "tail -n6 %s | grep -F \"16: \"", FDISK_LOG); 1514 if (!run_program_and_log_output(tmp, 5)) { 1515 g_partition_table_locked_up++; 1516 } 1517 mr_free(tmp); 1518 1519 mr_asprintf(tmp, "partprobe %s", drivename); 1520 if (!run_program_and_log_output(tmp, 5)) { 1521 g_partition_table_locked_up--; 1522 } 1523 mr_free(tmp); 1524 1525 if (g_partition_table_locked_up > 0) { 1526 log_to_screen("A flaw in the Linux kernel has locked the partition table. Even calling partprobe did not suceed :-("); 1527 } 1528 } 1529 paranoid_free(device_str); 1530 return (retval); 1574 1531 } 1575 1532 … … 1583 1540 * @return 0 for success, nonzero for failure. 1584 1541 */ 1585 int partition_device(FILE * pout_to_fdisk, const char *drive, int partno, 1586 int prev_partno, const char *format, 1587 long long partsize) 1588 { 1589 /** int **************************************************************/ 1590 int retval = 0; 1591 int res = 0; 1592 1593 /** buffers **********************************************************/ 1594 char *program; 1595 char *partition_name; 1596 char *tmp; 1597 char *logfile; 1598 char *output = NULL; 1599 1600 /** pointers **********************************************************/ 1601 char *p; 1602 char *part_table_fmt = NULL; 1603 FILE *fout; 1604 1605 /** end ***************************************************************/ 1606 1607 malloc_string(program); 1608 malloc_string(partition_name); 1609 malloc_string(tmp); 1610 malloc_string(logfile); 1611 1612 assert_string_is_neither_NULL_nor_zerolength(drive); 1613 assert(format != NULL); 1614 1615 log_it("partition_device('%s', %d, %d, '%s', %lld) --- starting", 1616 drive, partno, prev_partno, format, partsize); 1617 1618 if (!strncmp(drive, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) { 1619 sprintf(tmp, "Not partitioning %s - it is a virtual drive", drive); 1620 log_it(tmp); 1621 paranoid_free(program); 1622 paranoid_free(partition_name); 1623 paranoid_free(tmp); 1624 paranoid_free(logfile); 1625 return (0); 1626 } 1627 build_partition_name(partition_name, drive, partno); 1628 if (partsize <= 0) { 1629 sprintf(tmp, "Partitioning device %s (max size)", partition_name); 1542 int partition_device(FILE * pout_to_fdisk, const char *drive, int partno, int prev_partno, const char *format, long long partsize) { 1543 1544 /** int **************************************************************/ 1545 int retval = 0; 1546 int res = 0; 1547 1548 /** buffers **********************************************************/ 1549 char *program = NULL; 1550 char *partition_name; 1551 char *tmp = NULL; 1552 char *output = NULL; 1553 1554 /** pointers **********************************************************/ 1555 char *part_table_fmt = NULL; 1556 FILE *fout; 1557 1558 /** end ***************************************************************/ 1559 1560 assert_string_is_neither_NULL_nor_zerolength(drive); 1561 assert(format != NULL); 1562 1563 log_it("partition_device('%s', %d, %d, '%s', %lld) --- starting", drive, partno, prev_partno, format, partsize); 1564 1565 if (!strncmp(drive, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) { 1566 log_it("Not partitioning %s - it is a virtual drive", drive); 1567 return (0); 1568 } 1569 1570 malloc_string(partition_name); 1571 build_partition_name(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 paranoid_free(partition_name); 1584 return (1); 1585 } 1586 1587 1588 mr_asprintf(program, "parted2fdisk %s >> %s 2>> %s", drive, MONDO_LOGFILE, MONDO_LOGFILE); 1589 1590 /* BERLIOS: 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 paranoid_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"); 1630 1611 } else { 1631 sprintf(tmp, "Partitioning device %s (%lld MB)", partition_name, 1632 (long long) partsize / 1024); 1633 } 1634 update_progress_form(tmp); 1635 log_it(tmp); 1636 1637 if (is_this_device_mounted(partition_name)) { 1638 sprintf(tmp, "%s is mounted, and should not be partitioned", 1639 partition_name); 1640 log_to_screen(tmp); 1641 paranoid_free(program); 1642 paranoid_free(partition_name); 1643 paranoid_free(tmp); 1644 paranoid_free(logfile); 1645 return (1); 1646 /* 1647 } else if (does_partition_exist(drive, partno)) { 1648 sprintf(tmp, "%s already has a partition", partition_name); 1649 log_to_screen(tmp); 1650 return (1); 1651 */ 1652 } 1653 1654 1655 /* sprintf(tmp,"Partitioning %s ",partition_name); */ 1656 /* mvaddstr_and_log_it(g_currentY+1,30,tmp); */ 1657 p = (char *) strrchr(partition_name, '/'); 1658 sprintf(logfile, "/tmp/fdisk.log.%s", ++p); 1659 sprintf(program, "parted2fdisk %s >> %s 2>> %s", drive, MONDO_LOGFILE, 1660 MONDO_LOGFILE); 1661 1662 /* BERLIOS: should not be called each time */ 1663 part_table_fmt = which_partition_format(drive); 1664 mr_asprintf(output, ""); 1665 /* make it a primary/extended/logical */ 1666 if (partno <= 4) { 1612 /* GPT allows more than 4 primary partitions */ 1667 1613 mr_strcat(output, "n\np\n%d\n", partno); 1668 } else { 1669 /* MBR needs an extended partition if more than 4 partitions */ 1670 if (strcmp(part_table_fmt, "MBR") == 0) { 1671 if (partno == 5) { 1672 if (prev_partno >= 4) { 1673 log_to_screen 1674 ("You need to leave at least one partition free, for 'extended/logical'"); 1675 paranoid_free(program); 1676 paranoid_free(partition_name); 1677 paranoid_free(tmp); 1678 paranoid_free(logfile); 1679 paranoid_free(output); 1680 return (1); 1681 } else { 1682 mr_strcat(output, "n\ne\n%d\n\n\n", prev_partno + 1); 1683 } 1684 } 1685 mr_strcat(output, "n\nl\n"); 1686 } else { 1687 /* GPT allows more than 4 primary partitions */ 1688 mr_strcat(output, "n\np\n%d\n", partno); 1689 } 1690 } 1691 mr_free(part_table_fmt); 1692 1693 mr_strcat(output, "\n"); /*start block (ENTER for next free blk */ 1694 if (partsize > 0) { 1695 if (!strcmp(format, "7")) { 1696 log_msg(1, "Adding 512K, just in case"); 1697 partsize += 512; 1698 } 1699 mr_strcat(output, "+%lldK", (long long) (partsize)); 1700 } 1701 mr_strcat(output, "\n"); 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"); 1702 1627 #if 0 1703 1628 /* 1704 1629 #endif 1705 sprintf(tmp,"PARTSIZE = +%ld",(long)partsize); 1706 log_it(tmp); 1707 log_it("---fdisk command---"); 1708 log_it(output); 1709 log_it("---end of fdisk---"); 1630 log_it("PARTSIZE = +%ld",(long)partsize); 1631 log_it("---fdisk command---"); 1632 log_it(output); 1633 log_it("---end of fdisk---"); 1710 1634 #if 0 1711 1635 */ … … 1713 1637 1714 1638 1715 if (pout_to_fdisk) { 1716 log_msg(1, "Doing the new all-in-one fdisk thing"); 1717 log_msg(1, "output = '%s'", output); 1718 fput_string_one_char_at_a_time(pout_to_fdisk, output); 1719 fput_string_one_char_at_a_time(pout_to_fdisk, "\n\np\n"); 1720 strcpy(tmp, last_line_of_file(FDISK_LOG)); 1721 if (strstr(tmp, " (m ")) { 1722 log_msg(1, "Successfully created partition %d on %s", partno, drive); 1639 if (pout_to_fdisk) { 1640 log_msg(1, "Doing the new all-in-one fdisk thing"); 1641 log_msg(1, "output = '%s'", output); 1642 fput_string_one_char_at_a_time(pout_to_fdisk, output); 1643 fput_string_one_char_at_a_time(pout_to_fdisk, "\n\np\n"); 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++; 1723 1684 } else { 1724 log_msg(1, "last line = %s", tmp); 1725 log_msg(1, "Failed to create partition %d on %s; sending 'Enter'...", partno, drive); 1726 } 1727 if (!retval) { 1728 log_msg(1, "Trying to set partition %d type now on %s", partno, drive); 1729 retval = 1730 set_partition_type(pout_to_fdisk, drive, partno, format, 1731 partsize); 1732 if (retval) { 1733 log_msg(1, "Failed. Trying again..."); 1734 retval = 1735 set_partition_type(pout_to_fdisk, drive, partno, 1736 format, partsize); 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"); 1737 1697 } 1738 1698 } 1739 if (retval) {1740 log_msg(1, "...but failed to set type");1741 }1742 1699 } else { 1743 mr_strcat(output, "w\n\n"); 1744 if (g_fprep) { 1745 fprintf(g_fprep, "echo \"%s\" | %s\n", output, program); 1746 } 1747 /* write to disk; close fdisk's stream */ 1748 if (!(fout = popen(program, "w"))) { 1749 log_OS_error("can't popen-out to program"); 1700 mr_asprintf(tmp, "Failed to partition %s", partition_name); 1701 if (partsize > 0) { 1702 log_to_screen(tmp); 1750 1703 } else { 1751 fputs(output, fout); 1752 paranoid_pclose(fout); 1753 } 1754 if (!does_partition_exist(drive, partno) && partsize > 0) { 1755 log_it("Vaccum-packing"); 1756 g_current_progress--; 1757 res = 1758 partition_device(pout_to_fdisk, drive, partno, prev_partno, 1759 format, -1); 1760 if (res) { 1761 sprintf(tmp, "Failed to vacuum-pack %s", partition_name); 1762 log_it(tmp); 1763 retval++; 1764 } else { 1765 retval = 0; 1766 } 1767 } 1768 if (does_partition_exist(drive, partno)) { 1769 retval = 1770 set_partition_type(pout_to_fdisk, drive, partno, format, 1771 partsize); 1772 if (retval) { 1773 sprintf(tmp, "Partitioned %s but failed to set its type", 1774 partition_name); 1775 log_it(tmp); 1776 } else { 1777 if (partsize > 0) { 1778 sprintf(tmp, "Partition %s created+configured OK", 1779 partition_name); 1780 log_to_screen(tmp); 1781 } else { 1782 log_it("Returning from a successful vacuum-pack"); 1783 } 1784 } 1785 } else { 1786 sprintf(tmp, "Failed to partition %s", partition_name); 1787 if (partsize > 0) { 1788 log_to_screen(tmp); 1789 } else { 1790 log_it(tmp); 1791 } 1792 retval++; 1793 } 1794 } 1795 paranoid_free(output); 1796 1797 g_current_progress++; 1798 log_it("partition_device() --- leaving"); 1799 paranoid_free(program); 1800 paranoid_free(partition_name); 1801 paranoid_free(tmp); 1802 paranoid_free(logfile); 1803 return (retval); 1704 log_it(tmp); 1705 } 1706 mr_free(tmp); 1707 retval++; 1708 } 1709 } 1710 mr_free(program); 1711 paranoid_free(output); 1712 1713 g_current_progress++; 1714 log_it("partition_device() --- leaving"); 1715 paranoid_free(partition_name); 1716 return (retval); 1804 1717 } 1805 1718 … … 1813 1726 * Use format_everything() for that. 1814 1727 */ 1815 int partition_everything(struct mountlist_itself *mountlist) 1816 { 1817 /** int ************************************************************/ 1818 int lino; 1819 int retval = 0; 1820 int i; 1821 int res; 1822 1823 /** buffer *********************************************************/ 1824 struct list_of_disks *drivelist; 1825 /* struct mountlist_itself new_mtlist, *mountlist; */ 1826 1827 /** end ************************************************************/ 1828 1829 drivelist = malloc(sizeof(struct list_of_disks)); 1830 assert(mountlist != NULL); 1831 1832 log_it("partition_everything() --- starting"); 1833 mvaddstr_and_log_it(g_currentY, 0, "Partitioning hard drives "); 1834 /* mountlist=orig_mtlist; */ 1835 if (mountlist_contains_raid_devices(mountlist)) { 1836 /* mountlist=&new_mtlist; */ 1837 /* extrapolate_mountlist_to_include_raid_partitions(mountlist,orig_mtlist); */ 1838 log_msg(0, 1839 "Mountlist, including the partitions incorporated in RAID devices:-"); 1840 for (i = 0; i < mountlist->entries; i++) { 1841 log_it(mountlist->el[i].device); 1842 } 1843 log_msg(0, "End of mountlist."); 1844 } 1845 log_msg(0, "Stopping all LVMs, just in case"); 1846 if (!g_text_mode) { 1847 newtSuspend(); 1848 } 1849 do_my_funky_lvm_stuff(TRUE, FALSE); // just remove old partitions 1850 if (!g_text_mode) { 1851 newtResume(); 1852 } 1853 log_msg(0, "Stopping all software RAID devices, just in case"); 1854 stop_all_raid_devices(mountlist); 1855 log_msg(0, "Done."); 1856 1857 /* 1858 if (does_file_exist("/tmp/i-want-my-lvm")) 1859 { 1860 wipe_MBRs_and_reboot_if_necessary(mountlist); // i.e. if it wasn't done recently 1861 } 1862 */ 1863 1864 open_progress_form("Partitioning devices", 1865 "I am now going to partition all your drives.", 1866 "This should not take more than five minutes.", "", 1867 mountlist->entries); 1868 1869 make_list_of_drives_in_mountlist(mountlist, drivelist); 1870 1871 /* partition each drive */ 1872 for (lino = 0; lino < drivelist->entries; lino++) { 1873 res = partition_drive(mountlist, drivelist->el[lino].device); 1874 retval += res; 1875 } 1876 close_progress_form(); 1877 if (retval) { 1878 mvaddstr_and_log_it(g_currentY++, 74, "Failed."); 1879 log_to_screen 1880 ("Errors occurred during the partitioning of your hard drives."); 1881 } else { 1882 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 1883 paranoid_system("rm -f /tmp/fdisk*.log 2> /dev/null"); 1884 } 1728 int partition_everything(struct mountlist_itself *mountlist) { 1729 1730 /** int ************************************************************/ 1731 int lino; 1732 int retval = 0; 1733 int i; 1734 int res; 1735 1736 /** buffer *********************************************************/ 1737 struct list_of_disks *drivelist; 1738 1739 /** end ************************************************************/ 1740 1741 drivelist = malloc(sizeof(struct list_of_disks)); 1742 assert(mountlist != NULL); 1743 1744 log_it("partition_everything() --- starting"); 1745 mvaddstr_and_log_it(g_currentY, 0, "Partitioning hard drives "); 1746 1747 if (mountlist_contains_raid_devices(mountlist)) { 1748 log_msg(0, "Mountlist, including the partitions incorporated in RAID devices:-"); 1749 for (i = 0; i < mountlist->entries; i++) { 1750 log_it(mountlist->el[i].device); 1751 } 1752 log_msg(0, "End of mountlist."); 1753 } 1754 log_msg(0, "Stopping all LVMs, just in case"); 1755 if (!g_text_mode) { 1885 1756 newtSuspend(); 1886 paranoid_system("clear"); 1757 } 1758 do_my_funky_lvm_stuff(TRUE, FALSE); // just remove old partitions 1759 if (!g_text_mode) { 1887 1760 newtResume(); 1888 paranoid_free(drivelist); 1889 return (retval); 1890 } 1891 1892 1893 1761 } 1762 log_msg(0, "Stopping all software RAID devices, just in case"); 1763 stop_all_raid_devices(mountlist); 1764 log_msg(0, "Done."); 1765 1766 open_progress_form("Partitioning devices", "I am now going to partition all your drives.", "This should not take more than five minutes.", "", mountlist->entries); 1767 1768 make_list_of_drives_in_mountlist(mountlist, drivelist); 1769 1770 /* partition each drive */ 1771 for (lino = 0; lino < drivelist->entries; lino++) { 1772 res = partition_drive(mountlist, drivelist->el[lino].device); 1773 retval += res; 1774 } 1775 close_progress_form(); 1776 if (retval) { 1777 mvaddstr_and_log_it(g_currentY++, 74, "Failed."); 1778 log_to_screen("Errors occurred during the partitioning of your hard drives."); 1779 } else { 1780 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 1781 paranoid_system("rm -f /tmp/fdisk*.log 2> /dev/null"); 1782 } 1783 newtSuspend(); 1784 paranoid_system("clear"); 1785 newtResume(); 1786 paranoid_free(drivelist); 1787 return (retval); 1788 } 1894 1789 1895 1790 … … 1904 1799 * @return 0 for success, nonzero for failure. 1905 1800 */ 1906 int set_partition_type(FILE * pout_to_fdisk, const char *drive, int partno, 1907 const char *format, long long partsize) 1908 { 1909 /** buffers *********************************************************/ 1910 char *partition; 1911 char *command; 1912 char *output = NULL; 1913 char *tmp; 1914 char *partcode; 1915 char *logfile; 1916 1917 /** pointers *********************************************************/ 1918 char *p; 1919 FILE *fout; 1920 1921 /** int **************************************************************/ 1922 int res = 0; 1923 1924 /** end **************************************************************/ 1925 1926 assert_string_is_neither_NULL_nor_zerolength(drive); 1927 assert(format != NULL); 1928 1929 malloc_string(partition); 1930 malloc_string(command); 1931 malloc_string(tmp); 1932 malloc_string(partcode); 1933 malloc_string(logfile); 1934 1935 build_partition_name(partition, drive, partno); 1936 p = (char *) strrchr(partition, '/'); 1937 sprintf(logfile, "/tmp/fdisk-set-type.%s.log", ++p); 1938 if (strcmp(format, "swap") == 0) { 1939 strcpy(partcode, "82"); 1940 } else if (strcmp(format, "vfat") == 0) { 1941 if (partsize / 1024 > 8192) { 1942 strcpy(partcode, "c"); 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; 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 malloc_string(partition); 1822 1823 build_partition_name(partition, drive, partno); 1824 if (strcmp(format, "swap") == 0) { 1825 mr_asprintf(partcode, "82"); 1826 } else if (strcmp(format, "vfat") == 0) { 1827 if (partsize / 1024 > 8192) { 1828 mr_asprintf(partcode, "c"); 1829 } else { 1830 mr_asprintf(partcode, "b"); 1831 } 1832 } else if (strcmp(format, "ext2") == 0 1833 || strcmp(format, "reiserfs") == 0 1834 || strcmp(format, "ext3") == 0 1835 || strcmp(format, "ext4") == 0 1836 || strcmp(format, "xfs") == 0 1837 || strcmp(format, "jfs") == 0 1838 || strcmp(format, "btrfs") == 0) { 1839 mr_asprintf(partcode, "83"); 1840 } else if (strcmp(format, "minix") == 0) { 1841 mr_asprintf(partcode, "81"); 1842 } else if (strcmp(format, "vmfs3") == 0) { 1843 mr_asprintf(partcode, "fb"); 1844 } else if (strcmp(format, "vmkcore") == 0) { 1845 mr_asprintf(partcode, "fc"); 1846 } else if (strcmp(format, "raid") == 0) { 1847 mr_asprintf(partcode, "fd"); 1848 } else if (strcmp(format, "ntfs") == 0) { 1849 mr_asprintf(partcode, "7"); 1850 } else if ((strcmp(format, "ufs") == 0) 1851 || (strcmp(format, "ffs") == 0)) { /* raid autodetect */ 1852 mr_asprintf(partcode, "a5"); 1853 } else if (strcmp(format, "lvm") == 0) { 1854 mr_asprintf(partcode, "8e"); 1855 } else if (format[0] == '\0') { /* LVM physical partition */ 1856 mr_asprintf(partcode, ""); 1857 } else if (strlen(format) >= 1 && strlen(format) <= 2) { 1858 mr_asprintf(partcode, format); 1859 } else { 1860 /* probably an image */ 1861 mr_asprintf(tmp, "Unknown format ('%s') - using supplied string anyway", format); 1862 mvaddstr_and_log_it(g_currentY++, 0, tmp); 1863 mr_free(tmp); 1864 1865 #ifdef __FreeBSD__ 1866 mr_asprintf(partcode, format); // was a5 1867 #else 1868 mr_asprintf(partcode, format); // was 83 1869 #endif 1870 } 1871 log_msg(1, "Setting %s's type to %s (%s)", partition, format, partcode); 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, "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; 1943 1915 } else { 1944 strcpy(partcode, "b"); 1945 } 1946 } else if (strcmp(format, "ext2") == 0 1947 || strcmp(format, "reiserfs") == 0 1948 || strcmp(format, "ext3") == 0 1949 || strcmp(format, "ext4") == 0 1950 || strcmp(format, "xfs") == 0 1951 || strcmp(format, "jfs") == 0 1952 || strcmp(format, "btrfs") == 0) { 1953 strcpy(partcode, "83"); 1954 } else if (strcmp(format, "minix") == 0) { 1955 strcpy(partcode, "81"); 1956 } else if (strcmp(format, "vmfs3") == 0) { 1957 strcpy(partcode, "fb"); 1958 } else if (strcmp(format, "vmkcore") == 0) { 1959 strcpy(partcode, "fc"); 1960 } else if (strcmp(format, "raid") == 0) { 1961 strcpy(partcode, "fd"); 1962 } else if (strcmp(format, "ntfs") == 0) { 1963 strcpy(partcode, "7"); 1964 } else if ((strcmp(format, "ufs") == 0) 1965 || (strcmp(format, "ffs") == 0)) { /* raid autodetect */ 1966 strcpy(partcode, "a5"); 1967 } else if (strcmp(format, "lvm") == 0) { 1968 strcpy(partcode, "8e"); 1969 } else if (format[0] == '\0') { /* LVM physical partition */ 1970 partcode[0] = '\0'; 1971 } else if (strlen(format) >= 1 && strlen(format) <= 2) { 1972 strcpy(partcode, format); 1973 } else { 1974 /* probably an image */ 1975 sprintf(tmp, 1976 "Unknown format ('%s') - using supplied string anyway", 1977 format); 1978 mvaddstr_and_log_it(g_currentY++, 0, tmp); 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 paranoid_free(partition); 1927 1928 return (res); 1929 } 1930 1931 1932 int start_raid_device(char *raid_device) { 1933 1934 /** int *************************************************************/ 1935 int res; 1936 int retval = 0; 1937 1938 /** buffers *********************************************************/ 1939 char *program = NULL; 1940 1941 /** end *************************************************************/ 1942 1943 assert_string_is_neither_NULL_nor_zerolength(raid_device); 1944 1979 1945 #ifdef __FreeBSD__ 1980 strcpy(partcode, format); // was a5 1946 if (is_this_device_mounted(raid_device)) { 1947 log_it("Can't start %s when it's mounted!", raid_device); 1948 return 1; 1949 } 1950 mr_asprintf(program, "vinum start -f %s", raid_device); 1981 1951 #else 1982 strcpy(partcode, format); // was 83 1983 #endif 1984 } 1985 sprintf(tmp, "Setting %s's type to %s (%s)", partition, format, 1986 partcode); 1987 log_msg(1, tmp); 1988 if (partcode[0] != '\0' && strcmp(partcode, "83")) { /* no need to set type if 83: 83 is default */ 1989 1990 if (pout_to_fdisk) { 1991 res = 0; 1992 fput_string_one_char_at_a_time(pout_to_fdisk, "t\n"); 1993 if (partno > 1 1994 || strstr(last_line_of_file(FDISK_LOG), " (1-4)")) { 1995 log_msg(5, "Specifying partno (%d) - yay", partno); 1996 sprintf(tmp, "%d\n", partno); 1997 fput_string_one_char_at_a_time(pout_to_fdisk, tmp); 1998 log_msg(5, "A - last line = '%s'", 1999 last_line_of_file(FDISK_LOG)); 2000 } 2001 2002 sprintf(tmp, "%s\n", partcode); 2003 fput_string_one_char_at_a_time(pout_to_fdisk, tmp); 2004 log_msg(5, "B - last line = '%s'", 2005 last_line_of_file(FDISK_LOG)); 2006 fput_string_one_char_at_a_time(pout_to_fdisk, "\n"); 2007 log_msg(5, "C - last line = '%s'", 2008 last_line_of_file(FDISK_LOG)); 2009 2010 strcpy(tmp, last_line_of_file(FDISK_LOG)); 2011 if (!strstr(tmp, " (m ")) { 2012 log_msg(1, "last line = '%s'; part type set failed", tmp); 2013 res++; 2014 fput_string_one_char_at_a_time(pout_to_fdisk, "\n"); 2015 } 2016 fput_string_one_char_at_a_time(pout_to_fdisk, "p\n"); 2017 } else { 2018 mr_asprintf(output, "t\n%d\n%s\nw\n", partno, partcode); 2019 sprintf(command, "parted2fdisk %s >> %s 2>> %s", drive, 2020 MONDO_LOGFILE, MONDO_LOGFILE); 2021 log_msg(5, "output = '%s'", output); 2022 log_msg(5, "partno=%d; partcode=%s", partno, partcode); 2023 log_msg(5, "command = '%s'", command); 2024 fout = popen(command, "w"); 2025 if (!fout) { 2026 log_OS_error(command); 2027 res = 1; 2028 } else { 2029 res = 0; 2030 fprintf(fout, "%s", output); 2031 paranoid_pclose(fout); 2032 } 2033 paranoid_free(output); 2034 } 2035 if (res) { 2036 log_OS_error(command); 2037 } 2038 } 2039 2040 paranoid_free(partition); 2041 paranoid_free(command); 2042 paranoid_free(tmp); 2043 paranoid_free(partcode); 2044 paranoid_free(logfile); 2045 2046 return (res); 2047 } 2048 2049 2050 int start_raid_device(char *raid_device) 2051 { 2052 /** int *************************************************************/ 2053 int res; 2054 int retval = 0; 2055 2056 /** buffers *********************************************************/ 2057 char *program; 2058 2059 /** end *************************************************************/ 2060 2061 assert_string_is_neither_NULL_nor_zerolength(raid_device); 2062 malloc_string(program); 2063 2064 #ifdef __FreeBSD__ 2065 if (is_this_device_mounted(raid_device)) { 2066 log_it("Can't start %s when it's mounted!", raid_device); 2067 return 1; 2068 } 2069 sprintf(program, "vinum start -f %s", raid_device); 2070 #else 2071 sprintf(program, "raidstart %s", raid_device); 2072 #endif 2073 log_msg(1, "program = %s", program); 2074 res = run_program_and_log_output(program, 1); 2075 if (g_fprep) { 2076 fprintf(g_fprep, "%s\n", program); 2077 } 2078 if (res) { 2079 log_msg(1, "Warning - failed to start RAID device %s", 2080 raid_device); 2081 } 2082 retval += res; 2083 sleep(1); 2084 return (retval); 1952 mr_asprintf(program, "raidstart %s", raid_device); 1953 #endif 1954 log_msg(1, "program = %s", program); 1955 res = run_program_and_log_output(program, 1); 1956 if (g_fprep) { 1957 fprintf(g_fprep, "%s\n", program); 1958 } 1959 mr_free(program); 1960 1961 if (res) { 1962 log_msg(1, "Warning - failed to start RAID device %s", raid_device); 1963 } 1964 retval += res; 1965 sleep(1); 1966 return (retval); 2085 1967 } 2086 1968 … … 2092 1974 * @return 0 for success, nonzero for failure. 2093 1975 */ 2094 int stop_raid_device(char *raid_device) 2095 { 2096 /** int *************************************************************/ 2097 int res; 2098 int retval = 0; 2099 2100 /** buffers *********************************************************/ 2101 char *program; 2102 2103 /** end *************************************************************/ 2104 2105 assert_string_is_neither_NULL_nor_zerolength(raid_device); 2106 malloc_string(program); 1976 int stop_raid_device(char *raid_device) { 1977 1978 /** int *************************************************************/ 1979 int res; 1980 int retval = 0; 1981 1982 /** buffers *********************************************************/ 1983 char *program = NULL; 1984 1985 /** end *************************************************************/ 1986 1987 assert_string_is_neither_NULL_nor_zerolength(raid_device); 2107 1988 2108 1989 #ifdef __FreeBSD__ 2109 2110 2111 2112 2113 1990 if (is_this_device_mounted(raid_device)) { 1991 log_it("Can't stop %s when it's mounted!", raid_device); 1992 return 1; 1993 } 1994 mr_asprintf(program, "vinum stop -f %s", raid_device); 2114 1995 #else 2115 2116 2117 2118 2119 2120 2121 #endif 2122 2123 2124 2125 2126 2127 if (res) { 2128 log_msg(1, "Warning - failed to stop RAID device %s", raid_device); 2129 } 2130 retval += res;2131 return (retval); 2132 } 2133 2134 2135 int start_all_raid_devices(struct mountlist_itself *mountlist) 2136 { 2137 int i; 2138 int retval = 0; 2139 int res;2140 2141 for (i = 0; i < mountlist->entries; i++) { 2142 if (!strncmp 2143 (mountlist->el[i].device, RAID_DEVICE_STUB, 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 1996 // use raidstop if it exists, otherwise use mdadm 1997 if (run_program_and_log_output("which raidstop", FALSE)) { 1998 mr_asprintf(program, "mdadm -S %s", raid_device); 1999 } else { 2000 mr_asprintf(program, "raidstop %s", raid_device); 2001 } 2002 #endif 2003 log_msg(1, "program = %s", program); 2004 res = run_program_and_log_output(program, 1); 2005 if (g_fprep) { 2006 fprintf(g_fprep, "%s\n", program); 2007 } 2008 mr_free(program); 2009 2010 if (res) { 2011 log_msg(1, "Warning - failed to stop RAID device %s", raid_device); 2012 } 2013 retval += res; 2014 return (retval); 2015 } 2016 2017 2018 int start_all_raid_devices(struct mountlist_itself *mountlist) { 2019 2020 int i; 2021 int retval = 0; 2022 int res; 2023 2024 for (i = 0; i < mountlist->entries; i++) { 2025 if (!strncmp(mountlist->el[i].device, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) { 2026 log_msg(1, "Starting %s", mountlist->el[i].device); 2027 res = start_raid_device(mountlist->el[i].device); 2028 retval += res; 2029 } 2030 } 2031 if (retval) { 2032 log_msg(1, "Started all s/w raid devices OK"); 2033 } else { 2034 log_msg(1, "Failed to start some/all s/w raid devices"); 2035 } 2036 return (retval); 2156 2037 } 2157 2038 … … 2162 2043 * @bug @p mountlist is not used. 2163 2044 */ 2164 int stop_all_raid_devices(struct mountlist_itself *mountlist) 2165 { 2166 2167 2168 2169 2170 2045 int stop_all_raid_devices(struct mountlist_itself *mountlist) { 2046 2047 /** int *************************************************************/ 2048 int retval = 0; 2049 2050 /** char ************************************************************/ 2051 char *incoming; 2171 2052 #ifndef __FreeBSD__ 2172 2173 #endif 2174 2053 char *dev; 2054 #endif 2055 /** pointers ********************************************************/ 2175 2056 #ifndef __FreeBSD__ 2176 char *p; 2177 #endif 2178 FILE *fin; 2179 char *q; 2180 int i; 2181 2182 /** end ****************************************************************/ 2183 2184 malloc_string(dev); 2185 malloc_string(incoming); 2186 assert(mountlist != NULL); 2187 2188 for (i = 0; i < 3; i++) { 2057 char *p; 2058 #endif 2059 FILE *fin; 2060 char *q; 2061 int i; 2062 2063 /** end ****************************************************************/ 2064 2065 malloc_string(incoming); 2066 assert(mountlist != NULL); 2067 2068 for (i = 0; i < 3; i++) { 2189 2069 #ifdef __FreeBSD__ 2190 fin = 2191 popen 2192 ("vinum list | grep '^[PVS]' | sed 's/S/1/;s/P/2/;s/V/3/' | sort | cut -d' ' -f2", 2193 "r"); 2194 if (!fin) { 2070 fin = popen("vinum list | grep '^[PVS]' | sed 's/S/1/;s/P/2/;s/V/3/' | sort | cut -d' ' -f2", "r"); 2071 if (!fin) { 2072 paranoid_free(incoming); 2073 return (1); 2074 } 2075 for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL); q = fgets(incoming, MAX_STR_LEN - 1, fin)) { 2076 retval += stop_raid_device(incoming); 2077 } 2078 #else 2079 fin = fopen("/proc/mdstat", "r"); 2080 if (!fin) { 2081 log_OS_error("/proc/mdstat"); 2082 paranoid_free(incoming); 2083 return (1); 2084 } 2085 for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL); q = fgets(incoming, MAX_STR_LEN - 1, fin)) { 2086 for (p = incoming; *p != '\0' && (*p != 'm' || *(p + 1) != 'd' || !isdigit(*(p + 2))); p++); 2087 if (*p != '\0') { 2088 malloc_string(dev); 2089 sprintf(dev, "/dev/%s", p); 2090 for (p = dev; *p > 32; p++); 2091 *p = '\0'; 2092 retval += stop_raid_device(dev); 2195 2093 paranoid_free(dev); 2196 paranoid_free(incoming); 2197 return (1); 2198 } 2199 for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL); 2200 q = fgets(incoming, MAX_STR_LEN - 1, fin)) { 2201 retval += stop_raid_device(incoming); 2202 } 2203 #else 2204 fin = fopen("/proc/mdstat", "r"); 2205 if (!fin) { 2206 log_OS_error("/proc/mdstat"); 2207 paranoid_free(dev); 2208 paranoid_free(incoming); 2209 return (1); 2210 } 2211 for (q = fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin) && (q != NULL); 2212 q = fgets(incoming, MAX_STR_LEN - 1, fin)) { 2213 for (p = incoming; 2214 *p != '\0' && (*p != 'm' || *(p + 1) != 'd' 2215 || !isdigit(*(p + 2))); p++); 2216 if (*p != '\0') { 2217 sprintf(dev, "/dev/%s", p); 2218 for (p = dev; *p > 32; p++); 2219 *p = '\0'; 2220 retval += stop_raid_device(dev); 2221 } 2222 } 2223 #endif 2224 } 2225 paranoid_fclose(fin); 2226 if (retval) { 2227 log_msg(1, "Warning - unable to stop some RAID devices"); 2228 } 2229 paranoid_free(dev); 2230 paranoid_free(incoming); 2231 paranoid_system("sync"); 2232 paranoid_system("sync"); 2233 paranoid_system("sync"); 2234 sleep(1); 2235 return (retval); 2094 } 2095 } 2096 #endif 2097 } 2098 paranoid_fclose(fin); 2099 if (retval) { 2100 log_msg(1, "Warning - unable to stop some RAID devices"); 2101 } 2102 paranoid_free(incoming); 2103 paranoid_system("sync"); 2104 paranoid_system("sync"); 2105 paranoid_system("sync"); 2106 sleep(1); 2107 return (retval); 2236 2108 } 2237 2109 … … 2244 2116 * @return 0 for success, nonzero for failure. 2245 2117 */ 2246 int which_format_command_do_i_need(char *format, char *program) 2247 { 2248 /** int *************************************************************/ 2249 int res = 0; 2250 2251 /** buffers *********************************************************/ 2252 char *tmp; 2253 2254 /** end ***************************************************************/ 2255 2256 malloc_string(tmp); 2257 assert_string_is_neither_NULL_nor_zerolength(format); 2258 assert(program != NULL); 2259 2260 if (strcmp(format, "swap") == 0) { 2118 int which_format_command_do_i_need(char *format, char *program) { 2119 2120 /** int *************************************************************/ 2121 int res = 0; 2122 2123 /** buffers *********************************************************/ 2124 2125 /** end ***************************************************************/ 2126 2127 assert_string_is_neither_NULL_nor_zerolength(format); 2128 assert(program != NULL); 2129 2130 if (strcmp(format, "swap") == 0) { 2261 2131 #ifdef __FreeBSD__ 2262 2132 strcpy(program, "true"); 2263 2133 #else 2264 2265 #endif 2266 2267 2134 strcpy(program, "mkswap"); 2135 #endif 2136 } else if (strcmp(format, "vfat") == 0) { 2137 strcpy(program, "format-and-kludge-vfat"); 2268 2138 #ifndef __FreeBSD__ 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 #endif 2298 2299 2300 2139 } else if (strcmp(format, "reiserfs") == 0) { 2140 strcpy(program, "mkreiserfs -ff"); 2141 } else if (strcmp(format, "xfs") == 0) { 2142 strcpy(program, "mkfs.xfs -f -q"); 2143 } else if (strcmp(format, "jfs") == 0) { 2144 strcpy(program, "mkfs.jfs"); 2145 } else if (strcmp(format, "ext3") == 0) { 2146 strcpy(program, "mkfs -t ext3 -F -q"); 2147 } else if (strcmp(format, "ext4") == 0) { 2148 strcpy(program, "mkfs -t ext4 -F -q"); 2149 } else if (strcmp(format, "btrfs") == 0) { 2150 strcpy(program, "mkfs.btrfs"); 2151 } else if (strcmp(format, "minix") == 0) { 2152 strcpy(program, "mkfs.minix"); 2153 } else if (strcmp(format, "vmfs") == 0) { 2154 strcpy(program, "mkfs -t vmfs"); 2155 } else if (strcmp(format, "ntfs") == 0) { 2156 /* 2157 * mkfs.ntfs treats the '-c' switch as 'specify cluster size' 2158 * so the default "mkfs -t %s -c" command structure fails 2159 */ 2160 strcpy(program, "mkfs -t ntfs"); 2161 } else if (strcmp(format, "ocfs2") == 0) { 2162 /* 2163 * 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. 2164 * 2165 */ 2166 strcpy(program, "mkfs -t ocfs2 -F"); 2167 #endif 2168 } else if (strcmp(format, "ext2") == 0) { 2169 strcpy(program, "mke2fs -F -q"); 2170 } else { 2301 2171 #ifdef __FreeBSD__ 2302 2172 sprintf(program, "newfs_%s", format); 2303 2173 #else 2304 sprintf(program, "mkfs -t %s -c", format); // -c checks for bad blocks 2305 #endif 2306 sprintf(tmp, "Unknown format (%s) - assuming '%s' will do", format, 2307 program); 2308 log_it(tmp); 2309 res = 0; 2310 } 2311 paranoid_free(tmp); 2312 return (res); 2174 sprintf(program, "mkfs -t %s -c", format); // -c checks for bad blocks 2175 #endif 2176 log_it("Unknown format (%s) - assuming '%s' will do", format, program); 2177 res = 0; 2178 } 2179 return (res); 2313 2180 } 2314 2181 … … 2325 2192 * @param drive_name The drive to resize. 2326 2193 */ 2327 void resize_drive_proportionately_to_suit_new_drives(struct mountlist_itself 2328 *mountlist, 2329 char *drive_name) 2330 { 2331 /**buffers **********************************************************/ 2332 char *tmp; 2333 2334 /** int *************************************************************/ 2335 int partno, lastpart; 2336 2337 /** float ***********************************************************/ 2338 float factor; 2339 long long new_size; 2340 2341 /** long *************************************************************/ 2342 long long newsizL = 0LL; 2343 long long totalsizL = 0LL; 2344 long long current_size_of_drive = 0LL; /* use KB interally for precision */ 2345 long long original_size_of_drive = 0LL; /* use KB interally for precision */ 2346 struct mountlist_reference *drivemntlist; 2347 2348 /** structures *******************************************************/ 2349 2350 /** end **************************************************************/ 2351 2352 assert(mountlist != NULL); 2353 assert_string_is_neither_NULL_nor_zerolength(drive_name); 2354 2355 if (strlen(drive_name) >= strlen(RAID_DEVICE_STUB)) { 2356 if (strncmp(drive_name, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB)) 2357 == 0) { 2358 return; 2359 } 2360 } 2361 2362 current_size_of_drive = (long long) get_phys_size_of_drive(drive_name) * 1024LL; 2363 2364 if (current_size_of_drive <= 0LL) { 2365 log_it("Not resizing to match %s - can't find drive", drive_name); 2194 void resize_drive_proportionately_to_suit_new_drives(struct mountlist_itself *mountlist, char *drive_name) { 2195 2196 /**buffers **********************************************************/ 2197 char *tmp = NULL; 2198 2199 /** int *************************************************************/ 2200 int partno, lastpart; 2201 2202 /** float ***********************************************************/ 2203 float factor; 2204 long long new_size; 2205 2206 /** long *************************************************************/ 2207 long long newsizL = 0LL; 2208 long long totalsizL = 0LL; 2209 long long current_size_of_drive = 0LL; /* use KB interally for precision */ 2210 long long original_size_of_drive = 0LL; /* use KB interally for precision */ 2211 struct mountlist_reference *drivemntlist; 2212 2213 /** structures *******************************************************/ 2214 2215 /** end **************************************************************/ 2216 2217 assert(mountlist != NULL); 2218 assert_string_is_neither_NULL_nor_zerolength(drive_name); 2219 2220 if (strlen(drive_name) >= strlen(RAID_DEVICE_STUB)) { 2221 if (strncmp(drive_name, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB)) 2222 == 0) { 2366 2223 return; 2367 2224 } 2368 mr_asprintf(tmp, "Expanding entries to suit drive %s (%lld MB)", drive_name, current_size_of_drive / 1024); 2369 log_to_screen(tmp); 2370 mr_free(tmp); 2371 2372 drivemntlist = malloc(sizeof(struct mountlist_reference)); 2373 drivemntlist->el = malloc(sizeof(struct mountlist_line *) * MAX_MOUNTLIST_ENTRIES); 2374 2375 if (!drivemntlist) { 2376 fatal_error("Cannot malloc temporary mountlist\n"); 2377 } 2378 create_mountlist_for_drive(mountlist, drive_name, drivemntlist); 2379 2380 for (partno = 0; partno < drivemntlist->entries; partno++) { 2381 if (drivemntlist->el[partno]->size > 0LL) { 2382 /* Keep KB here */ 2383 original_size_of_drive += drivemntlist->el[partno]->size; 2384 } 2385 } 2386 2387 if (original_size_of_drive <= 0LL) { 2388 mr_asprintf(tmp, "Cannot resize %s's entries. Drive not found.", drive_name); 2389 log_to_screen(tmp); 2390 mr_free(tmp); 2391 return; 2392 } 2393 factor = ((float)current_size_of_drive/(float)original_size_of_drive); 2394 mr_asprintf(tmp, "Disk %s was %lld MB; is now %lld MB; Proportionally resizing partitions (factor ~= %.5f)", 2395 drive_name, original_size_of_drive/1024, current_size_of_drive/1024, factor); 2396 log_to_screen(tmp); 2397 mr_free(tmp); 2398 2399 lastpart = drivemntlist->entries - 1; 2400 for (partno = 0; partno < drivemntlist->entries; partno++) { 2401 /* the 'atoi' thing is to make sure we don't try to resize _images_, whose formats will be numeric */ 2402 if (!atoi(drivemntlist->el[partno]->format)) { 2403 new_size = (long long)((drivemntlist->el[partno]->size) * factor); 2404 } else { 2405 new_size = drivemntlist->el[partno]->size; 2406 } 2407 2408 if (!strcmp(drivemntlist->el[partno]->mountpoint, "image")) { 2409 log_msg(1, "Skipping %s (%s) because it's an image", 2410 drivemntlist->el[partno]->device, 2411 drivemntlist->el[partno]->mountpoint); 2412 } 2413 newsizL = new_size; 2414 2415 /* Do not apply the factor if partition was of negative size */ 2416 if (newsizL < 0LL) { 2417 newsizL = drivemntlist->el[partno]->size; 2418 } 2419 totalsizL += newsizL; 2420 2421 mr_asprintf(tmp, "Changing %s from %lld KB to %lld KB", drivemntlist->el[partno]->device, drivemntlist->el[partno]->size, newsizL); 2422 log_to_screen(tmp); 2423 mr_free(tmp); 2424 drivemntlist->el[partno]->size = newsizL; 2425 } 2426 // Ensures over-allocation alert and prompt for interactive mode does not happen 2427 if (totalsizL > current_size_of_drive) { 2428 mr_asprintf(tmp, "Last partition size calculated would be over-allocated, reducing %s from %lld KB to %lld KB.", drivemntlist->el[lastpart]->device, drivemntlist->el[lastpart]->size, drivemntlist->el[lastpart]->size - (totalsizL - current_size_of_drive)); 2429 drivemntlist->el[drivemntlist->entries-1]->size -= (totalsizL - current_size_of_drive); 2430 } else if (totalsizL < current_size_of_drive) { 2431 mr_asprintf(tmp, "Last partition size calculated would be under-allocated, increasing %s from %lld KB to %lld KB.",drivemntlist->el[lastpart]->device, drivemntlist->el[lastpart]->size, drivemntlist->el[lastpart]->size + (current_size_of_drive - totalsizL)); 2432 drivemntlist->el[drivemntlist->entries-1]->size += (current_size_of_drive - totalsizL); 2433 } 2434 log_to_screen(tmp); 2435 mr_free(tmp); 2436 mr_asprintf(tmp, "final_size = %lld MB", current_size_of_drive / 1024); 2437 log_to_screen(tmp); 2438 mr_free(tmp); 2225 } 2226 2227 current_size_of_drive = (long long) get_phys_size_of_drive(drive_name) * 1024LL; 2228 2229 if (current_size_of_drive <= 0LL) { 2230 log_it("Not resizing to match %s - can't find drive", drive_name); 2231 return; 2232 } 2233 log_to_screen("Expanding entries to suit drive %s (%lld MB)", drive_name, current_size_of_drive / 1024); 2234 2235 drivemntlist = malloc(sizeof(struct mountlist_reference)); 2236 drivemntlist->el = malloc(sizeof(struct mountlist_line *) * MAX_MOUNTLIST_ENTRIES); 2237 2238 if (!drivemntlist) { 2239 fatal_error("Cannot malloc temporary mountlist\n"); 2240 } 2241 create_mountlist_for_drive(mountlist, drive_name, drivemntlist); 2242 2243 for (partno = 0; partno < drivemntlist->entries; partno++) { 2244 if (drivemntlist->el[partno]->size > 0LL) { 2245 /* Keep KB here */ 2246 original_size_of_drive += drivemntlist->el[partno]->size; 2247 } 2248 } 2249 2250 if (original_size_of_drive <= 0LL) { 2251 log_to_screen("Cannot resize %s's entries. Drive not found.", drive_name); 2252 return; 2253 } 2254 factor = ((float)current_size_of_drive/(float)original_size_of_drive); 2255 log_to_screen("Disk %s was %lld MB; is now %lld MB; Proportionally resizing partitions (factor ~= %.5f)", drive_name, original_size_of_drive/1024, current_size_of_drive/1024, factor); 2256 2257 lastpart = drivemntlist->entries - 1; 2258 for (partno = 0; partno < drivemntlist->entries; partno++) { 2259 /* the 'atoi' thing is to make sure we don't try to resize _images_, whose formats will be numeric */ 2260 if (!atoi(drivemntlist->el[partno]->format)) { 2261 new_size = (long long)((drivemntlist->el[partno]->size) * factor); 2262 } else { 2263 new_size = drivemntlist->el[partno]->size; 2264 } 2265 2266 if (!strcmp(drivemntlist->el[partno]->mountpoint, "image")) { 2267 log_msg(1, "Skipping %s (%s) because it's an image", 2268 drivemntlist->el[partno]->device, 2269 drivemntlist->el[partno]->mountpoint); 2270 } 2271 newsizL = new_size; 2272 2273 /* Do not apply the factor if partition was of negative size */ 2274 if (newsizL < 0LL) { 2275 newsizL = drivemntlist->el[partno]->size; 2276 } 2277 totalsizL += newsizL; 2278 2279 log_to_screen("Changing %s from %lld KB to %lld KB", drivemntlist->el[partno]->device, drivemntlist->el[partno]->size, newsizL); 2280 drivemntlist->el[partno]->size = newsizL; 2281 } 2282 // Ensures over-allocation alert and prompt for interactive mode does not happen 2283 if (totalsizL > current_size_of_drive) { 2284 mr_asprintf(tmp, "Last partition size calculated would be over-allocated, reducing %s from %lld KB to %lld KB.", drivemntlist->el[lastpart]->device, drivemntlist->el[lastpart]->size, drivemntlist->el[lastpart]->size - (totalsizL - current_size_of_drive)); 2285 drivemntlist->el[drivemntlist->entries-1]->size -= (totalsizL - current_size_of_drive); 2286 } else if (totalsizL < current_size_of_drive) { 2287 mr_asprintf(tmp, "Last partition size calculated would be under-allocated, increasing %s from %lld KB to %lld KB.",drivemntlist->el[lastpart]->device, drivemntlist->el[lastpart]->size, drivemntlist->el[lastpart]->size + (current_size_of_drive - totalsizL)); 2288 drivemntlist->el[drivemntlist->entries-1]->size += (current_size_of_drive - totalsizL); 2289 } 2290 log_to_screen(tmp); 2291 mr_free(tmp); 2292 log_to_screen("final_size = %lld MB", current_size_of_drive / 1024); 2439 2293 } 2440 2294 … … 2446 2300 * @param mountlist The mountlist to resize the drives in. 2447 2301 */ 2448 void resize_mountlist_proportionately_to_suit_new_drives(struct mountlist_itself 2449 *mountlist) 2450 { 2451 /** buffers *********************************************************/ 2452 struct list_of_disks *drivelist; 2453 2454 /** int *************************************************************/ 2455 int driveno; 2456 2457 /** end *************************************************************/ 2458 2459 drivelist = malloc(sizeof(struct list_of_disks)); 2460 assert(mountlist != NULL); 2461 2462 if (g_mountlist_fname[0] == '\0') { 2463 log_it("resize_mountlist_prop...() - warning - mountlist fname is blank"); 2464 log_it("That does NOT affect the functioning of this subroutine."); 2465 log_it("--- Hugo, 2002/11/20"); 2466 } 2467 log_it("Resizing mountlist"); 2468 make_list_of_drives_in_mountlist(mountlist, drivelist); 2469 log_it("Back from MLoDiM"); 2470 for (driveno = 0; driveno < drivelist->entries; driveno++) { 2471 resize_drive_proportionately_to_suit_new_drives(mountlist, drivelist->el[driveno].device); 2472 } 2473 log_to_screen("Mountlist adjusted to suit current hard drive(s)"); 2474 paranoid_free(drivelist); 2302 void resize_mountlist_proportionately_to_suit_new_drives(struct mountlist_itself *mountlist) { 2303 2304 /** buffers *********************************************************/ 2305 struct list_of_disks *drivelist; 2306 2307 /** int *************************************************************/ 2308 int driveno; 2309 2310 /** end *************************************************************/ 2311 2312 drivelist = malloc(sizeof(struct list_of_disks)); 2313 assert(mountlist != NULL); 2314 2315 if (g_mountlist_fname[0] == '\0') { 2316 log_it("resize_mountlist_prop...() - warning - mountlist fname is blank"); 2317 log_it("That does NOT affect the functioning of this subroutine."); 2318 log_it("--- Hugo, 2002/11/20"); 2319 } 2320 log_it("Resizing mountlist"); 2321 make_list_of_drives_in_mountlist(mountlist, drivelist); 2322 log_it("Back from MLoDiM"); 2323 for (driveno = 0; driveno < drivelist->entries; driveno++) { 2324 resize_drive_proportionately_to_suit_new_drives(mountlist, drivelist->el[driveno].device); 2325 } 2326 log_to_screen("Mountlist adjusted to suit current hard drive(s)"); 2327 paranoid_free(drivelist); 2475 2328 } 2476 2329 … … 2483 2336 * @author Ralph Grewe 2484 2337 */ 2485 void create_mountlist_for_drive(struct mountlist_itself *mountlist, 2486 char *drive_name, 2487 struct mountlist_reference *drivemntlist) 2488 { 2489 int partno; 2490 char *tmp_drive_name, *c; 2491 2492 assert(mountlist != NULL); 2493 assert(drive_name != NULL); 2494 assert(drivemntlist != NULL); 2495 2496 log_msg(1, "Creating list of partitions for drive %s", drive_name); 2497 2498 tmp_drive_name = strdup(drive_name); 2499 if (!tmp_drive_name) 2500 fatal_error("Out of memory"); 2501 2502 /* devfs devices? */ 2503 c = strrchr(tmp_drive_name, '/'); 2504 if (c && strncmp(c, "/disc", 5) == 0) { 2505 /* yup its devfs, change the "disc" to "part" so the existing code works */ 2506 strcpy(c + 1, "part"); 2507 } 2508 drivemntlist->entries = 0; 2509 for (partno = 0; partno < mountlist->entries; partno++) { 2510 if (strncmp 2511 (mountlist->el[partno].device, tmp_drive_name, 2512 strlen(tmp_drive_name)) == 0) { 2513 drivemntlist->el[drivemntlist->entries] = 2514 &mountlist->el[partno]; 2515 drivemntlist->entries++; 2516 } 2517 } 2518 if (tmp_drive_name) 2519 free(tmp_drive_name); 2338 void create_mountlist_for_drive(struct mountlist_itself *mountlist, char *drive_name, struct mountlist_reference *drivemntlist) { 2339 2340 int partno; 2341 char *tmp_drive_name, *c; 2342 2343 assert(mountlist != NULL); 2344 assert(drive_name != NULL); 2345 assert(drivemntlist != NULL); 2346 2347 log_msg(1, "Creating list of partitions for drive %s", drive_name); 2348 2349 tmp_drive_name = strdup(drive_name); 2350 if (!tmp_drive_name) 2351 fatal_error("Out of memory"); 2352 2353 /* devfs devices? */ 2354 c = strrchr(tmp_drive_name, '/'); 2355 if (c && strncmp(c, "/disc", 5) == 0) { 2356 /* yup its devfs, change the "disc" to "part" so the existing code works */ 2357 strcpy(c + 1, "part"); 2358 } 2359 drivemntlist->entries = 0; 2360 for (partno = 0; partno < mountlist->entries; partno++) { 2361 if (strncmp(mountlist->el[partno].device, tmp_drive_name, strlen(tmp_drive_name)) == 0) { 2362 drivemntlist->el[drivemntlist->entries] = &mountlist->el[partno]; 2363 drivemntlist->entries++; 2364 } 2365 } 2366 if (tmp_drive_name) 2367 free(tmp_drive_name); 2520 2368 } 2521 2369
Note:
See TracChangeset
for help on using the changeset viewer.