Changeset 558 in MondoRescue
- Timestamp:
- May 20, 2006, 4:54:20 PM (19 years ago)
- Location:
- branches/stable/mondo/mondo
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mondo/mondo/common/libmondo-raid-EXT.h
r128 r558 53 53 #endif 54 54 55 extern int create_raidtab_from_mdstat(char *, char *); 56 extern int read_mdstat(struct s_mdstat *mdstat, char *mdstat_file); 57 58 extern int create_raidtab_from_mdstat(char *raidtab_fname, 59 char *mdstat_fname); 55 extern int parse_mdstat(struct raidlist_itself *raidlist, char *device_prefix); 56 extern int create_raidtab_from_mdstat(char *raidtab_fname); -
branches/stable/mondo/mondo/common/libmondo-raid.c
r541 r558 395 395 396 396 fprintf(fout, "raiddev %s\n", raidrec->raid_device); 397 if (raidrec->raid_level == -1) { 397 if (raidrec->raid_level == -2) { 398 fprintf(fout, " raid-level multipath\n"); 399 } else if (raidrec->raid_level == -1) { 398 400 fprintf(fout, " raid-level linear\n"); 399 401 } else { … … 401 403 raidrec->raid_level); 402 404 } 403 fprintf(fout, " chunk-size %d\n", raidrec->chunk_size);404 405 fprintf(fout, " nr-raid-disks %d\n", 405 406 raidrec->data_disks.entries); 406 fprintf(fout, " nr-spare-disks %d\n", 407 raidrec->spare_disks.entries); 407 if (raidrec->spare_disks.entries > 0) { 408 fprintf(fout, " nr-spare-disks %d\n", 409 raidrec->spare_disks.entries); 410 } 408 411 if (raidrec->parity_disks.entries > 0) { 409 412 fprintf(fout, " nr-parity-disks %d\n", 410 413 raidrec->parity_disks.entries); 411 414 } 412 413 415 fprintf(fout, " persistent-superblock %d\n", 414 416 raidrec->persistent_superblock); 417 if (raidrec->chunk_size > -1) { 418 fprintf(fout, " chunk-size %d\n", raidrec->chunk_size); 419 } 420 if (raidrec->parity > -1) { 421 switch(raidrec->parity) { 422 case 0: 423 fprintf(fout, " parity-algorithm left-asymmetric\n"); 424 break; 425 case 1: 426 fprintf(fout, " parity-algorithm right-asymmetric\n"); 427 break; 428 case 2: 429 fprintf(fout, " parity-algorithm left-symmetric\n"); 430 break; 431 case 3: 432 fprintf(fout, " parity-algorithm right-symmetric\n"); 433 break; 434 default: 435 fatal_error("Unknown RAID parity algorithm."); 436 break; 437 } 438 } 415 439 save_additional_vars_to_file(&raidrec->additional_vars, fout); 416 440 fprintf(fout, "\n"); … … 713 737 714 738 if (!strcmp(label, "raid-level")) { 715 if (!strcmp(value, "linear")) { 739 if (!strcmp(value, "multipath")) { 740 raidrec->raid_level = -2; 741 } else if (!strcmp(value, "linear")) { 716 742 raidrec->raid_level = -1; 717 743 } else { … … 726 752 } else if (!strcmp(label, "chunk-size")) { 727 753 raidrec->chunk_size = atoi(value); 754 } else if (!strcmp(label, "parity-algorithm")) { 755 if (!strcmp(value, "left-asymmetric")) { 756 raidrec->parity = 0; 757 } else if (!strcmp(value, "right-asymmetric")) { 758 raidrec->parity = 1; 759 } else if (!strcmp(value, "left-symmetric")) { 760 raidrec->parity = 2; 761 } else if (!strcmp(value, "right-symmetric")) { 762 raidrec->parity = 3; 763 } else { 764 log_msg(1, "Unknown RAID parity algorithm '%s'\n.", value); 765 } 728 766 } else if (!strcmp(label, "device")) { 729 767 get_next_raidtab_line(fin, labelB, valueB); … … 972 1010 973 1011 974 int read_mdstat(struct s_mdstat *mdstat, char *mdstat_file) 975 { 976 FILE *fin; 977 char *tmp; 978 char *stub; 979 char *incoming; 980 char *raid_devname; 981 char *p, *q, *r; 982 int diskno; 983 984 malloc_string(tmp); 985 malloc_string(stub); 986 malloc_string(incoming); 987 malloc_string(raid_devname); 988 if (!(fin = fopen(mdstat_file, "r"))) { 989 log_msg(1, "%s not found", mdstat_file); 1012 int parse_mdstat(struct raidlist_itself *raidlist, char *device_prefix) { 1013 1014 const char delims[] = " "; 1015 1016 FILE *fin; 1017 int res = 0, row, i, index_min; 1018 size_t len = 0; 1019 char *token, *string = NULL, *pos, type, *strtmp; 1020 1021 // open file 1022 if (!(fin = fopen(MDSTAT_FILE, "r"))) { 1023 log_msg(1, "Could not open %s.\n", MDSTAT_FILE); 1024 return 1; 1025 } 1026 // initialise record, build progress and row counters 1027 raidlist->entries = 0; 1028 raidlist->el[raidlist->entries].progress = 999; 1029 row = 1; 1030 // skip first output row - contains registered RAID levels 1031 res = getline(&string, &len, fin); 1032 // parse the rest 1033 while ( !feof_unlocked(fin) ) { 1034 res = getline(&string, &len, fin); 1035 if (res <= 0) break; 1036 // trim leading spaces 1037 pos = string; 1038 while (*pos == ' ') *pos++; 1039 memmove(string, pos, strlen(string)); 1040 // if we have newline after only spaces, this is a blank line, update 1041 // counters, otherwise do normal parsing 1042 if (*string == '\n') { 1043 row = 1; 1044 raidlist->entries++; 1045 raidlist->el[raidlist->entries].progress = 999; 1046 } else { 1047 switch (row) { 1048 case 1: // device information 1049 // check whether last line of record and if so skip 1050 pos = strcasestr(string, "unused devices: "); 1051 if (pos == string) { 1052 //raidlist->entries--; 1053 break; 1054 } 1055 // tokenise string 1056 token = strtok (string, delims); 1057 // get RAID device name 1058 asprintf(&strtmp,"%s%s", device_prefix, token); 1059 strcpy(raidlist->el[raidlist->entries].raid_device, strtmp); 1060 paranoid_free(strtmp); 1061 // skip ':' and status 1062 token = strtok (NULL, delims); 1063 token = strtok (NULL, delims); 1064 if (!strcmp(token, "inactive")) { 1065 log_msg(1, "RAID device '%s' inactive.\n", 1066 raidlist->el[raidlist->entries].raid_device); 1067 paranoid_free(string); 1068 return 1; 1069 } 1070 // get RAID level 1071 token = strtok (NULL, delims); 1072 if (!strcmp(token, "multipath")) { 1073 raidlist->el[raidlist->entries].raid_level = -2; 1074 } else if (!strcmp(token, "linear")) { 1075 raidlist->el[raidlist->entries].raid_level = -1; 1076 } else if (!strcmp(token, "raid0")) { 1077 raidlist->el[raidlist->entries].raid_level = 0; 1078 } else if (!strcmp(token, "raid1")) { 1079 raidlist->el[raidlist->entries].raid_level = 1; 1080 } else if (!strcmp(token, "raid4")) { 1081 raidlist->el[raidlist->entries].raid_level = 4; 1082 } else if (!strcmp(token, "raid5")) { 1083 raidlist->el[raidlist->entries].raid_level = 5; 1084 } else if (!strcmp(token, "raid6")) { 1085 raidlist->el[raidlist->entries].raid_level = 6; 1086 } else if (!strcmp(token, "raid10")) { 1087 raidlist->el[raidlist->entries].raid_level = 10; 1088 } else { 1089 log_msg(1, "Unknown RAID level '%s'.\n", token); 1090 paranoid_free(string); 1091 return 1; 1092 } 1093 // get RAID devices (type, index, device) 1094 // Note: parity disk for RAID4 is last normal disk, there is no '(P)' 1095 raidlist->el[raidlist->entries].data_disks.entries = 0; 1096 raidlist->el[raidlist->entries].spare_disks.entries = 0; 1097 raidlist->el[raidlist->entries].failed_disks.entries = 0; 1098 while((token = strtok (NULL, delims))) { 1099 if ((pos = strstr(token, "("))) { 1100 type = *(pos+1); 1101 } else { 1102 type = ' '; 1103 } 1104 pos = strstr(token, "["); 1105 *pos = '\0'; 1106 switch(type) { 1107 case ' ': // normal data disks 1108 raidlist->el[raidlist->entries].data_disks.el[raidlist->el[raidlist->entries].data_disks.entries].index = atoi(pos + 1); 1109 asprintf(&strtmp,"%s%s", device_prefix, token); 1110 strcpy(raidlist->el[raidlist->entries].data_disks.el[raidlist->el[raidlist->entries].data_disks.entries].device, strtmp); 1111 paranoid_free(strtmp); 1112 raidlist->el[raidlist->entries].data_disks.entries++; 1113 break; 1114 case 'S': // spare disks 1115 raidlist->el[raidlist->entries].spare_disks.el[raidlist->el[raidlist->entries].spare_disks.entries].index = atoi(pos + 1); 1116 asprintf(&strtmp,"%s%s", device_prefix, token); 1117 strcpy(raidlist->el[raidlist->entries].spare_disks.el[raidlist->el[raidlist->entries].spare_disks.entries].device, strtmp); 1118 paranoid_free(strtmp); 1119 raidlist->el[raidlist->entries].spare_disks.entries++; 1120 break; 1121 case 'F': // failed disks 1122 raidlist->el[raidlist->entries].failed_disks.el[raidlist->el[raidlist->entries].failed_disks.entries].index = atoi(pos + 1); 1123 asprintf(&strtmp,"%s%s", device_prefix, token); 1124 strcpy(raidlist->el[raidlist->entries].failed_disks.el[raidlist->el[raidlist->entries].failed_disks.entries].device, strtmp); 1125 paranoid_free(strtmp); 1126 raidlist->el[raidlist->entries].failed_disks.entries++; 1127 log_it("At least one failed disk found in RAID array.\n"); 1128 break; 1129 default: // error 1130 log_msg(1, "Unknown device type '%c'\n", type); 1131 paranoid_free(string); 1132 return 1; 1133 break; 1134 } 1135 } 1136 // adjust index for each device so that it starts with 0 for every type 1137 index_min = 99; 1138 for (i=0; i<raidlist->el[raidlist->entries].data_disks.entries;i++) { 1139 if (raidlist->el[raidlist->entries].data_disks.el[i].index < index_min) { 1140 index_min = raidlist->el[raidlist->entries].data_disks.el[i].index; 1141 } 1142 } 1143 if (index_min > 0) { 1144 for (i=0; i<raidlist->el[raidlist->entries].data_disks.entries;i++) { 1145 raidlist->el[raidlist->entries].data_disks.el[i].index = raidlist->el[raidlist->entries].data_disks.el[i].index - index_min; 1146 } 1147 } 1148 index_min = 99; 1149 for (i=0; i<raidlist->el[raidlist->entries].spare_disks.entries;i++) { 1150 if (raidlist->el[raidlist->entries].spare_disks.el[i].index < index_min) { 1151 index_min = raidlist->el[raidlist->entries].spare_disks.el[i].index; 1152 } 1153 } 1154 if (index_min > 0) { 1155 for (i=0; i<raidlist->el[raidlist->entries].spare_disks.entries;i++) { 1156 raidlist->el[raidlist->entries].spare_disks.el[i].index = raidlist->el[raidlist->entries].spare_disks.el[i].index - index_min; 1157 } 1158 } 1159 index_min = 99; 1160 for (i=0; i<raidlist->el[raidlist->entries].failed_disks.entries;i++) { 1161 if (raidlist->el[raidlist->entries].failed_disks.el[i].index < index_min) { 1162 index_min = raidlist->el[raidlist->entries].failed_disks.el[i].index; 1163 } 1164 } 1165 if (index_min > 0) { 1166 for (i=0; i<raidlist->el[raidlist->entries].failed_disks.entries;i++) { 1167 raidlist->el[raidlist->entries].failed_disks.el[i].index = raidlist->el[raidlist->entries].failed_disks.el[i].index - index_min; 1168 } 1169 } 1170 break; 1171 case 2: // config information 1172 // check for persistent super block 1173 if (strcasestr(string, "super non-persistent")) { 1174 raidlist->el[raidlist->entries].persistent_superblock = 0; 1175 } else { 1176 raidlist->el[raidlist->entries].persistent_superblock = 1; 1177 } 1178 // extract chunk size 1179 if (!(pos = strcasestr(string, "k chunk"))) { 1180 raidlist->el[raidlist->entries].chunk_size = -1; 1181 } else { 1182 while (*pos != ' ') { 1183 *pos--; 1184 if (pos < string) { 1185 log_it("String underflow!\n"); 1186 paranoid_free(string); 1187 return 1; 1188 } 1189 } 1190 raidlist->el[raidlist->entries].chunk_size = atoi(pos + 1); 1191 } 1192 // extract parity if present 1193 if ((pos = strcasestr(string, "algorithm"))) { 1194 raidlist->el[raidlist->entries].parity = atoi(pos + 9); 1195 } else { 1196 raidlist->el[raidlist->entries].parity = -1; 1197 } 1198 break; 1199 case 3: // optional build status information 1200 if (!(pos = strchr(string, '\%'))) { 1201 if (strcasestr(string, "delayed")) { 1202 raidlist->el[raidlist->entries].progress = -1; // delayed (therefore, stuck at 0%) 1203 } else { 1204 raidlist->el[raidlist->entries].progress = 999; // not found 1205 } 1206 } else { 1207 while (*pos != ' ') { 1208 *pos--; 1209 if (pos < string) { 1210 printf("ERROR: String underflow!\n"); 1211 paranoid_free(string); 1212 return 1; 1213 } 1214 } 1215 raidlist->el[raidlist->entries].progress = atoi(pos); 1216 } 1217 break; 1218 default: // error 1219 log_msg(1, "Row %d should not occur in record!\n", row); 1220 break; 1221 } 1222 row++; 1223 } 1224 } 1225 // close file 1226 fclose(fin); 1227 // free string 1228 paranoid_free(string); 1229 // return success 1230 return 0; 1231 1232 } 1233 1234 1235 1236 1237 int create_raidtab_from_mdstat(char *raidtab_fname) 1238 { 1239 struct raidlist_itself *raidlist; 1240 int retval = 0; 1241 1242 raidlist = malloc(sizeof(struct raidlist_itself)); 1243 1244 // FIXME: Prefix '/dev/' should really be dynamic! 1245 if (parse_mdstat(raidlist, "/dev/")) { 1246 log_to_screen("Sorry, cannot read %s", MDSTAT_FILE); 990 1247 return (1); 991 1248 } 992 mdstat->entries = 0; 993 for (fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin); 994 fgets(incoming, MAX_STR_LEN - 1, fin)) { 995 p = incoming; 996 if (*p != 'm' && *(p + 1) == 'm') { 997 p++; 998 } 999 if (strncmp(p, "md", 2)) { 1000 continue; 1001 } 1002 // read first line --- mdN : active raidX ............ 1003 mdstat->el[mdstat->entries].md = atoi(p + 2); 1004 log_msg(8, "Storing /dev/md%d's info", atoi(p + 2)); 1005 while (*p != ':' && *p) { 1006 p++; 1007 } 1008 while ((*p != 'r' || *(p + 1) != 'a') && *p) { 1009 p++; 1010 } 1011 if (!strncmp(p, "raid", 4)) { 1012 mdstat->el[mdstat->entries].raidlevel = *(p + 4) - '0'; 1013 } 1014 p += 4; 1015 while (*p != ' ' && *p) { 1016 p++; 1017 } 1018 while (*p == ' ' && *p) { 1019 p++; 1020 } 1021 for (diskno = 0; *p; diskno++) { 1022 strcpy(stub, p); 1023 // log_msg(1, "diskno=%d; tmp=%s", diskno, tmp); 1024 q = strchr(stub, '['); 1025 if (q) { 1026 *q = '\0'; 1027 q++; 1028 r = strchr(q, ']'); 1029 if (r) { 1030 *r = '\0'; 1031 } 1032 mdstat->el[mdstat->entries].disks.el[diskno].index = 1033 atoi(q); 1034 } else { 1035 mdstat->el[mdstat->entries].disks.el[diskno].index = -1; 1036 q = strchr(stub, ' '); 1037 if (q) { 1038 *q = '\0'; 1039 } 1040 } 1041 sprintf(tmp, "/dev/%s", stub); 1042 log_msg(8, "/dev/md%d : disk#%d : %s (%d)", 1043 mdstat->el[mdstat->entries].md, diskno, tmp, 1044 mdstat->el[mdstat->entries].disks.el[diskno].index); 1045 strcpy(mdstat->el[mdstat->entries].disks.el[diskno].device, 1046 tmp); 1047 while (*p != ' ' && *p) { 1048 p++; 1049 } 1050 while (*p == ' ' && *p) { 1051 p++; 1052 } 1053 } 1054 mdstat->el[mdstat->entries].disks.entries = diskno; 1055 // next line --- skip it 1056 if (!feof(fin)) { 1057 fgets(incoming, MAX_STR_LEN - 1, fin); 1058 } else { 1059 continue; 1060 } 1061 // next line --- the 'progress' line 1062 if (!feof(fin)) { 1063 fgets(incoming, MAX_STR_LEN - 1, fin); 1064 } else { 1065 continue; 1066 } 1067 // log_msg(1, "Percentage line = '%s'", incoming); 1068 if (!(p = strchr(incoming, '\%'))) { 1069 mdstat->el[mdstat->entries].progress = 999; // not found 1070 } else if (strstr(incoming, "DELAYED")) { 1071 mdstat->el[mdstat->entries].progress = -1; // delayed (therefore, stuck at 0%) 1072 } else { 1073 for (*p = '\0'; *p != ' '; p--); 1074 mdstat->el[mdstat->entries].progress = atoi(p); 1075 } 1076 log_msg(8, "progress =%d", mdstat->el[mdstat->entries].progress); 1077 mdstat->entries++; 1078 } 1079 fclose(fin); 1080 paranoid_free(tmp); 1081 paranoid_free(stub); 1082 paranoid_free(incoming); 1083 paranoid_free(raid_devname); 1084 return (0); 1085 } 1086 1087 1088 1089 int create_raidtab_from_mdstat(char *raidtab_fname, char *mdstat_fname) 1090 { 1091 struct raidlist_itself *raidlist; 1092 struct s_mdstat *mdstat; 1093 int retval = 0; 1094 int i; 1095 1096 raidlist = malloc(sizeof(struct raidlist_itself)); 1097 mdstat = malloc(sizeof(struct s_mdstat)); 1098 1099 if (read_mdstat(mdstat, mdstat_fname)) { 1100 log_to_screen("Sorry, cannot read %s", mdstat_fname); 1101 return (1); 1102 } 1103 1104 for (i = 0; i < mdstat->entries; i++) { 1105 sprintf(raidlist->el[i].raid_device, "/dev/md%d", 1106 mdstat->el[i].md); 1107 raidlist->el[i].raid_level = mdstat->el[i].raidlevel; 1108 raidlist->el[i].persistent_superblock = 1; 1109 raidlist->el[i].chunk_size = 4; 1110 memcpy((void *) &raidlist->el[i].data_disks, 1111 (void *) &mdstat->el[i].disks, 1112 sizeof(struct list_of_disks)); 1113 // FIXME --- the above line does not allow for spare disks 1114 log_to_screen 1115 ("FIXME - create_raidtab_from_mdstat does not allow for spare disks"); 1116 } 1117 raidlist->entries = i; 1249 1118 1250 retval += save_raidlist_to_raidtab(raidlist, raidtab_fname); 1119 1251 return (retval); -
branches/stable/mondo/mondo/common/libmondo-raid.h
r128 r558 43 43 #endif 44 44 45 46 int create_raidtab_from_mdstat(char *, char *); 47 int read_mdstat(struct s_mdstat *mdstat, char *mdstat_file); 48 49 int create_raidtab_from_mdstat(char *raidtab_fname, char *mdstat_fname); 45 int create_raidtab_from_mdstat(char *raidtab_fname); 46 int parse_mdstat(struct raidlist_itself *raidlist, char *device_prefix); -
branches/stable/mondo/mondo/common/libmondo-string.c
r557 r558 1159 1159 1160 1160 /* New functions safe from a memory manageemnt point of view */ 1161 /* Developped by Andree Leidenfrost */ 1161 1162 1162 1163 char *mr_strtok(char *instr, const char *delims, int *lastpos) { -
branches/stable/mondo/mondo/common/libmondo-tools.c
r541 r558 442 442 assert(raidrec != NULL); 443 443 raidrec->raid_device[0] = '\0'; 444 raidrec->raid_level = 0; 445 raidrec->chunk_size = 4; 444 raidrec->raid_level = -9; 446 445 raidrec->persistent_superblock = 1; 446 raidrec->chunk_size = 64; 447 raidrec->parity = -1; 447 448 raidrec->data_disks.entries = 0; 448 449 raidrec->spare_disks.entries = 0; … … 1224 1225 log_to_screen 1225 1226 ("You have RAID partitions but no /etc/raidtab - creating one from /proc/mdstat"); 1226 create_raidtab_from_mdstat("/etc/raidtab" , "/proc/mdstat");1227 create_raidtab_from_mdstat("/etc/raidtab"); 1227 1228 } 1228 1229 -
branches/stable/mondo/mondo/common/mondostructures.h
r543 r558 150 150 */ 151 151 int index; 152 153 /** 154 * Type of disk. 155 */ 156 char type; // ' ' = data (default), S = spare, F = faulty 157 152 158 }; 153 159 … … 241 247 */ 242 248 int chunk_size; 249 250 /** 251 * The parity algorithm of this RAID device. (RAID5 only) 252 */ 253 int parity; // 0=left-asymmetric, 1=right-asymmetric, 2=left-symmetric, 3=right-symmetric 243 254 244 255 /** … … 266 277 */ 267 278 struct additional_raid_variables additional_vars; 279 280 /** 281 * Resync progress for this device. 282 */ 283 int progress; 268 284 }; 269 285 … … 787 803 struct s_tapecat_entry el[MAX_TAPECATALOG_ENTRIES]; 788 804 }; 789 790 791 792 struct s_mdrec {793 int md; // /dev/mdN794 int raidlevel; // 0, 1, 5795 struct list_of_disks disks;796 int progress;797 };798 799 struct s_mdstat {800 int entries;801 struct s_mdrec el[MAXIMUM_RAID_DEVS];802 }; -
branches/stable/mondo/mondo/common/my-stuff.h
r542 r558 231 231 */ 232 232 #define MONDO_CFG_FILE_STUB "tmp/mondo-restore.cfg" 233 234 /** 235 * The RAID kernel proc file 236 */ 237 #define MDSTAT_FILE "/proc/mdstat" 233 238 234 239 /** -
branches/stable/mondo/mondo/mondorestore/mondo-prep.c
r541 r558 695 695 696 696 /** 697 * Create @p RAID device using information from @p structure. 698 * This will create the specified RAID devive using information provided in 699 * raidlist by means of the mdadm tool. 700 * @param raidlist The structure containing all RAID information 701 * @param device The RAID device to create. 702 * @return 0 for success, nonzero for failure. 703 */ 704 int create_raid_device_via_mdadm(struct raidlist_itself *raidlist, char *device) 705 { 706 /** int **************************************************************/ 707 int i = 0; 708 int j = 0; 709 int res = 0; 710 711 /** buffers ***********************************************************/ 712 char *devices = NULL; 713 char *strtmp = NULL; 714 char *level = NULL; 715 char *program = NULL; 716 717 // leave straight away if raidlist is initial or has no entries 718 if (!raidlist || raidlist->entries == 0) { 719 log_msg(1, "No RAID arrays found."); 720 return 1; 721 } else { 722 log_msg(1, "%d RAID arrays found.", raidlist->entries); 723 } 724 // find raidlist entry for requested device 725 for (i = 0; i < raidlist->entries; i++) { 726 if (!strcmp(raidlist->el[i].raid_device, device)) break; 727 } 728 // check whether RAID device was found in raidlist 729 if (i == raidlist->entries) { 730 log_msg(1, "RAID device %s not found in list.", device); 731 return 1; 732 } 733 // create device list from normal disks followed by spare ones 734 asprintf(&devices, raidlist->el[i].data_disks.el[0].device); 735 for (j = 1; j < raidlist->el[i].data_disks.entries; j++) { 736 asprintf(&strtmp, "%s", devices); 737 paranoid_free(devices); 738 asprintf(&devices, "%s %s", strtmp, 739 raidlist->el[i].data_disks.el[j].device); 740 paranoid_free(strtmp); 741 } 742 for (j = 0; j < raidlist->el[i].spare_disks.entries; j++) { 743 asprintf(&strtmp, "%s", devices); 744 paranoid_free(devices); 745 asprintf(&devices, "%s %s", strtmp, 746 raidlist->el[i].spare_disks.el[j].device); 747 paranoid_free(strtmp); 748 } 749 // translate RAID level 750 if (raidlist->el[i].raid_level == -2) { 751 asprintf(&level, "multipath"); 752 } else if (raidlist->el[i].raid_level == -1) { 753 asprintf(&level, "linear"); 754 } else { 755 asprintf(&level, "raid%d", raidlist->el[i].raid_level); 756 } 757 // create RAID device: 758 // - RAID device, number of devices and devices mandatory 759 // - parity algorithm, chunk size and spare devices optional 760 // - faulty devices ignored 761 // - persistent superblock always used as this is recommended 762 asprintf(&program, 763 "mdadm --create --force --run --auto=yes %s --level=%s --raid-devices=%d", 764 raidlist->el[i].raid_device, level, 765 raidlist->el[i].data_disks.entries); 766 if (raidlist->el[i].parity != -1) { 767 asprintf(&strtmp, "%s", program); 768 paranoid_free(program); 769 switch(raidlist->el[i].parity) { 770 case 0: 771 asprintf(&program, "%s --parity=%s", strtmp, "la"); 772 break; 773 case 1: 774 asprintf(&program, "%s --parity=%s", strtmp, "ra"); 775 break; 776 case 2: 777 asprintf(&program, "%s --parity=%s", strtmp, "ls"); 778 break; 779 case 3: 780 asprintf(&program, "%s --parity=%s", strtmp, "rs"); 781 break; 782 default: 783 fatal_error("Unknown RAID parity algorithm."); 784 break; 785 } 786 paranoid_free(strtmp); 787 } 788 if (raidlist->el[i].chunk_size != -1) { 789 asprintf(&strtmp, "%s", program); 790 paranoid_free(program); 791 asprintf(&program, "%s --chunk=%d", strtmp, raidlist->el[i].chunk_size); 792 paranoid_free(strtmp); 793 } 794 if (raidlist->el[i].spare_disks.entries > 0) { 795 asprintf(&strtmp, "%s", program); 796 paranoid_free(program); 797 asprintf(&program, "%s --spare-devices=%d", strtmp, 798 raidlist->el[i].spare_disks.entries); 799 paranoid_free(strtmp); 800 } 801 asprintf(&strtmp, "%s", program); 802 paranoid_free(program); 803 asprintf(&program, "%s %s", strtmp, devices); 804 paranoid_free(strtmp); 805 res = run_program_and_log_output(program, 1); 806 // free memory 807 paranoid_free(devices); 808 paranoid_free(level); 809 paranoid_free(program); 810 // return to calling instance 811 return res; 812 } 813 814 815 /** 697 816 * Format @p device as a @p format filesystem. 698 817 * This will use the format command returned by which_format_command_do_i_need(). … … 704 823 * @return 0 for success, nonzero for failure. 705 824 */ 706 int format_device(char *device, char *format )825 int format_device(char *device, char *format, struct raidlist_itself *raidlist) 707 826 { 708 827 /** int **************************************************************/ … … 836 955 837 956 log_msg(1, "Making %s", device); 838 sprintf(program, "mkraid --really-force %s", device); 839 res = run_program_and_log_output(program, 1); 840 log_msg(1, "%s returned %d", program, res); 841 system("sync"); 842 sleep(3); 843 start_raid_device(device); 844 if (g_fprep) { 845 fprintf(g_fprep, "%s\n", program); 957 // use mkraid if it exists, otherwise use mdadm 958 if (run_program_and_log_output("which mkraid", FALSE)) { 959 res = create_raid_device_via_mdadm(raidlist, device); 960 log_msg(1, "Creating RAID device %s via mdadm returned %d", device, res); 961 } else { 962 sprintf(program, "mkraid --really-force %s", device); 963 res = run_program_and_log_output(program, 1); 964 log_msg(1, "%s returned %d", program, res); 965 system("sync"); 966 sleep(3); 967 start_raid_device(device); 968 if (g_fprep) { 969 fprintf(g_fprep, "%s\n", program); 970 } 846 971 } 847 972 system("sync"); 848 973 sleep(2); 849 850 974 // log_to_screen("Starting %s", device); 851 975 // sprintf(program, "raidstart %s", device); … … 853 977 // log_msg(1, "%s returned %d", program, res); 854 978 // system("sync"); sleep(1); 855 if (g_fprep) {856 fprintf(g_fprep, "%s\n", program);857 }858 979 #endif 859 980 system("sync"); … … 923 1044 * @return The number of errors encountered (0 for success). 924 1045 */ 925 int format_everything(struct mountlist_itself *mountlist, 926 bool interactively)1046 int format_everything(struct mountlist_itself *mountlist, bool interactively, 1047 struct raidlist_itself *raidlist) 927 1048 { 928 1049 /** int **************************************************************/ … … 983 1104 if (do_it) { 984 1105 // NB: format_device() also stops/starts RAID device if necessary 985 retval += format_device(me->device, me->format );1106 retval += format_device(me->device, me->format, raidlist); 986 1107 } 987 1108 g_current_progress += progress_step; … … 1000 1121 log_msg(1, "Creating LVMs"); 1001 1122 if (does_file_exist("/tmp/i-want-my-lvm")) { 1002 wait_until_software_raids_are_prepped("/proc/mdstat", 10 );1123 wait_until_software_raids_are_prepped("/proc/mdstat", 100); 1003 1124 log_to_screen("Configuring LVM"); 1004 1125 if (!g_text_mode) { … … 1076 1197 1077 1198 if (do_it) 1078 retval += format_device(me->device, me->format );1199 retval += format_device(me->device, me->format, raidlist); 1079 1200 } 1080 1201 … … 2247 2368 sprintf(program, "vinum stop -f %s", raid_device); 2248 2369 #else 2249 sprintf(program, "raidstop %s", raid_device); 2250 // sprintf (program, "raidstop " RAID_DEVICE_STUB "*"); 2370 // use raidstop if it exists, otherwise use mdadm 2371 if (run_program_and_log_output("which raidstop", FALSE)) { 2372 sprintf(program, "mdadm -S %s", raid_device); 2373 } else { 2374 sprintf(program, "raidstop %s", raid_device); 2375 } 2251 2376 #endif 2252 2377 log_msg(1, "program = %s", program); -
branches/stable/mondo/mondo/mondorestore/mondo-restore.c
r543 r558 837 837 } 838 838 839 fmt_errs = format_everything(mountlist, FALSE );839 fmt_errs = format_everything(mountlist, FALSE, raidlist); 840 840 if (!fmt_errs) { 841 841 log_to_screen … … 855 855 if (ask_me_yes_or_no 856 856 ("Do you want to format your hard drives?")) { 857 fmt_errs = format_everything(mountlist, TRUE );857 fmt_errs = format_everything(mountlist, TRUE, raidlist); 858 858 if (!fmt_errs) { 859 859 done = TRUE; … … 1162 1162 system("sync"); 1163 1163 log_to_screen("Please wait. This may take a few minutes."); 1164 res += format_everything(mountlist, FALSE );1164 res += format_everything(mountlist, FALSE, raidlist); 1165 1165 } 1166 1166 paranoid_fclose(g_fprep); … … 3415 3415 } 3416 3416 3417 if (argc == 4&& strcmp(argv[1], "--mdconv") == 0) {3418 finish(create_raidtab_from_mdstat(argv[2] , argv[3]));3417 if (argc == 3 && strcmp(argv[1], "--mdconv") == 0) { 3418 finish(create_raidtab_from_mdstat(argv[2])); 3419 3419 } 3420 3420 … … 3515 3515 strcpy(g_mountlist_fname, "/tmp/mountlist.txt"); 3516 3516 load_mountlist(mountlist, g_mountlist_fname); 3517 res = format_everything(mountlist, FALSE );3517 res = format_everything(mountlist, FALSE, raidlist); 3518 3518 finish(res); 3519 3519 } -
branches/stable/mondo/mondo/mondorestore/mondo-rstr-tools.c
r541 r558 2585 2585 int wait_for_percentage) 2586 2586 { 2587 struct s_mdstat *mdstat;2587 struct raidlist_itself *raidlist; 2588 2588 int unfinished_mdstat_devices = 9999, i; 2589 2589 char *screen_message; 2590 2590 2591 2591 malloc_string(screen_message); 2592 mdstat = malloc(sizeof(struct s_mdstat));2592 raidlist = malloc(sizeof(struct raidlist_itself)); 2593 2593 2594 2594 assert(wait_for_percentage <= 100); 2595 2595 iamhere("Help, my boat is sync'ing. (Get it? Urp! Urp!)"); 2596 2596 while (unfinished_mdstat_devices > 0) { 2597 if (read_mdstat(mdstat, mdstat_file)) { 2598 log_to_screen("Sorry, cannot read %s", mdstat_file); 2597 // FIXME: Prefix '/dev/' should really be dynamic! 2598 if (parse_mdstat(raidlist, "/dev/")) { 2599 log_to_screen("Sorry, cannot read %s", MDSTAT_FILE); 2600 log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE); 2599 2601 return; 2600 2602 } 2601 for (unfinished_mdstat_devices = i = 0; i < mdstat->entries; i++) {2602 if ( mdstat->el[i].progress < wait_for_percentage) {2603 for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) { 2604 if (raidlist->el[i].progress < wait_for_percentage) { 2603 2605 unfinished_mdstat_devices++; 2604 sprintf(screen_message, "Sync'ing /dev/md%d", 2605 mdstat->el[i].md); 2606 log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i); 2607 sprintf(screen_message, "Sync'ing %s", 2608 raidlist->el[i].raid_device); 2606 2609 open_evalcall_form(screen_message); 2607 if ( mdstat->el[i].progress == -1) // delayed while another partition inits2610 if (raidlist->el[i].progress == -1) // delayed while another partition inits 2608 2611 { 2609 2612 continue; 2610 2613 } 2611 while (mdstat->el[i].progress < wait_for_percentage) { 2612 update_evalcall_form(mdstat->el[i].progress); 2614 while (raidlist->el[i].progress < wait_for_percentage) { 2615 log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress); 2616 update_evalcall_form(raidlist->el[i].progress); 2613 2617 sleep(2); 2614 if (read_mdstat(mdstat, mdstat_file)) { 2618 // FIXME: Prefix '/dev/' should really be dynamic! 2619 if (parse_mdstat(raidlist, "/dev/")) { 2615 2620 break; 2616 2621 } … … 2621 2626 } 2622 2627 paranoid_free(screen_message); 2623 paranoid_free( mdstat);2624 } 2628 paranoid_free(raidlist); 2629 } -
branches/stable/mondo/mondo/mondorestore/mondoprep.h
r128 r558 58 58 int start_all_raid_devices(struct mountlist_itself *); 59 59 int stop_all_raid_devices(struct mountlist_itself *); 60 int format_everything(struct mountlist_itself *, bool );60 int format_everything(struct mountlist_itself *, bool, struct raidlist_itself *); 61 61 int partition_device(FILE *, const char *, int, int, const char *, 62 62 long long); … … 65 65 int partition_device_with_fdisk(FILE *, const char *, int, int, 66 66 const char *, long long); 67 int format_device(char *, char * );67 int format_device(char *, char *, struct raidlist_itself *); 68 68 int partition_drive(struct mountlist_itself *, char *); 69 69 int partition_everything(struct mountlist_itself *); -
branches/stable/mondo/mondo/mondorestore/mr-externs.h
r128 r558 27 27 extern int edit_mountlist(char *mountlist_fname, struct mountlist_itself *, 28 28 struct raidlist_itself *); 29 extern int format_everything(struct mountlist_itself *, bool );30 extern int format_device(char *, char * );29 extern int format_everything(struct mountlist_itself *, bool, struct raidlist_itself *); 30 extern int format_device(char *, char *, struct raidlist_itself *); 31 31 extern void finish(int); 32 32 extern void free_filelist(struct s_node *);
Note:
See TracChangeset
for help on using the changeset viewer.