Changeset 561 in MondoRescue for trunk/mondo/mondo
- Timestamp:
- May 20, 2006, 5:51:21 PM (18 years ago)
- Location:
- trunk/mondo/mondo
- Files:
-
- 3 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/mondo/mondo/common/libmondo-raid-EXT.h
r59 r561 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); -
trunk/mondo/mondo/common/libmondo-raid.c
r507 r561 344 344 345 345 fprintf(fout, "raiddev %s\n", raidrec->raid_device); 346 if (raidrec->raid_level == -1) { 346 if (raidrec->raid_level == -2) { 347 fprintf(fout, " raid-level multipath\n"); 348 } else if (raidrec->raid_level == -1) { 347 349 fprintf(fout, " raid-level linear\n"); 348 350 } else { … … 350 352 raidrec->raid_level); 351 353 } 352 fprintf(fout, " chunk-size %d\n", raidrec->chunk_size);353 354 fprintf(fout, " nr-raid-disks %d\n", 354 355 raidrec->data_disks.entries); 355 fprintf(fout, " nr-spare-disks %d\n", 356 raidrec->spare_disks.entries); 356 if (raidrec->spare_disks.entries > 0) { 357 fprintf(fout, " nr-spare-disks %d\n", 358 raidrec->spare_disks.entries); 359 } 357 360 if (raidrec->parity_disks.entries > 0) { 358 361 fprintf(fout, " nr-parity-disks %d\n", 359 362 raidrec->parity_disks.entries); 360 363 } 361 362 364 fprintf(fout, " persistent-superblock %d\n", 363 365 raidrec->persistent_superblock); 366 if (raidrec->chunk_size > -1) { 367 fprintf(fout, " chunk-size %d\n", raidrec->chunk_size); 368 } 369 if (raidrec->parity > -1) { 370 switch(raidrec->parity) { 371 case 0: 372 fprintf(fout, " parity-algorithm left-asymmetric\n"); 373 break; 374 case 1: 375 fprintf(fout, " parity-algorithm right-asymmetric\n"); 376 break; 377 case 2: 378 fprintf(fout, " parity-algorithm left-symmetric\n"); 379 break; 380 case 3: 381 fprintf(fout, " parity-algorithm right-symmetric\n"); 382 break; 383 default: 384 fatal_error("Unknown RAID parity algorithm."); 385 break; 386 } 387 } 364 388 save_additional_vars_to_file(&raidrec->additional_vars, fout); 365 389 fprintf(fout, "\n"); … … 642 666 643 667 if (!strcmp(label, "raid-level")) { 644 if (!strcmp(value, "linear")) { 668 if (!strcmp(value, "multipath")) { 669 raidrec->raid_level = -2; 670 } else if (!strcmp(value, "linear")) { 645 671 raidrec->raid_level = -1; 646 672 } else { … … 655 681 } else if (!strcmp(label, "chunk-size")) { 656 682 raidrec->chunk_size = atoi(value); 683 } else if (!strcmp(label, "parity-algorithm")) { 684 if (!strcmp(value, "left-asymmetric")) { 685 raidrec->parity = 0; 686 } else if (!strcmp(value, "right-asymmetric")) { 687 raidrec->parity = 1; 688 } else if (!strcmp(value, "left-symmetric")) { 689 raidrec->parity = 2; 690 } else if (!strcmp(value, "right-symmetric")) { 691 raidrec->parity = 3; 692 } else { 693 log_msg(1, "Unknown RAID parity algorithm '%s'\n.", value); 694 } 657 695 } else if (!strcmp(label, "device")) { 658 696 get_next_raidtab_line(fin, labelB, valueB); … … 898 936 899 937 900 int read_mdstat(struct s_mdstat *mdstat, char *mdstat_file) 901 { 902 FILE *fin; 903 char *tmp; 904 char *stub; 905 char *incoming = NULL; 906 char *p, *q, *r; 907 int diskno; 908 size_t n = 0; 909 910 malloc_string(incoming); 911 if (!(fin = fopen(mdstat_file, "r"))) { 912 log_msg(1, "%s not found", mdstat_file); 938 int parse_mdstat(struct raidlist_itself *raidlist, char *device_prefix) { 939 940 const char delims[] = " "; 941 942 FILE *fin; 943 int res = 0, row, i, index_min; 944 int lastpos = 0; 945 size_t len = 0; 946 char *token; 947 char *string = NULL; 948 char *pos; 949 char type; 950 char *strtmp; 951 952 // open file 953 if (!(fin = fopen(MDSTAT_FILE, "r"))) { 954 log_msg(1, "Could not open %s.\n", MDSTAT_FILE); 955 return 1; 956 } 957 // initialise record, build progress and row counters 958 raidlist->entries = 0; 959 raidlist->el[raidlist->entries].progress = 999; 960 row = 1; 961 // skip first output row - contains registered RAID levels 962 res = getline(&string, &len, fin); 963 // parse the rest 964 while ( !feof_unlocked(fin) ) { 965 res = getline(&string, &len, fin); 966 if (res <= 0) break; 967 // trim leading spaces 968 pos = string; 969 while (*pos == ' ') *pos++; 970 asprintf(&string, pos); 971 // 972 // if we have newline after only spaces, this is a blank line, update 973 // counters, otherwise do normal parsing 974 if (*string == '\n') { 975 row = 1; 976 raidlist->entries++; 977 raidlist->el[raidlist->entries].progress = 999; 978 } else { 979 switch (row) { 980 case 1: // device information 981 // check whether last line of record and if so skip 982 pos = strcasestr(string, "unused devices: "); 983 if (pos == string) { 984 //raidlist->entries--; 985 break; 986 } 987 // tokenise string 988 token = mr_strtok (string, delims, &lastpos); 989 // get RAID device name 990 asprintf(&strtmp,"%s%s", device_prefix, token); 991 strcpy(raidlist->el[raidlist->entries].raid_device, strtmp); 992 paranoid_free(strtmp); 993 paranoid_free(token); 994 // skip ':' and status 995 token = strtok (string, delims, &lastpos); 996 paranoid_free(token); 997 token = strtok (string, delims, &lastpos); 998 if (!strcmp(token, "inactive")) { 999 log_msg(1, "RAID device '%s' inactive.\n", 1000 raidlist->el[raidlist->entries].raid_device); 1001 paranoid_free(string); 1002 paranoid_free(token); 1003 return 1; 1004 } 1005 paranoid_free(token); 1006 1007 // get RAID level 1008 token = strtok (string, delims, &lastpos); 1009 if (!strcmp(token, "multipath")) { 1010 raidlist->el[raidlist->entries].raid_level = -2; 1011 } else if (!strcmp(token, "linear")) { 1012 raidlist->el[raidlist->entries].raid_level = -1; 1013 } else if (!strcmp(token, "raid0")) { 1014 raidlist->el[raidlist->entries].raid_level = 0; 1015 } else if (!strcmp(token, "raid1")) { 1016 raidlist->el[raidlist->entries].raid_level = 1; 1017 } else if (!strcmp(token, "raid4")) { 1018 raidlist->el[raidlist->entries].raid_level = 4; 1019 } else if (!strcmp(token, "raid5")) { 1020 raidlist->el[raidlist->entries].raid_level = 5; 1021 } else if (!strcmp(token, "raid6")) { 1022 raidlist->el[raidlist->entries].raid_level = 6; 1023 } else if (!strcmp(token, "raid10")) { 1024 raidlist->el[raidlist->entries].raid_level = 10; 1025 } else { 1026 log_msg(1, "Unknown RAID level '%s'.\n", token); 1027 paranoid_free(string); 1028 paranoid_free(token); 1029 return 1; 1030 } 1031 paranoid_free(token); 1032 1033 // get RAID devices (type, index, device) 1034 // Note: parity disk for RAID4 is last normal disk, there is no '(P)' 1035 raidlist->el[raidlist->entries].data_disks.entries = 0; 1036 raidlist->el[raidlist->entries].spare_disks.entries = 0; 1037 raidlist->el[raidlist->entries].failed_disks.entries = 0; 1038 while((token = strtok (string, delims, &lastpos))) { 1039 if ((pos = strstr(token, "("))) { 1040 type = *(pos+1); 1041 } else { 1042 type = ' '; 1043 } 1044 pos = strstr(token, "["); 1045 *pos = '\0'; 1046 switch(type) { 1047 case ' ': // normal data disks 1048 raidlist->el[raidlist->entries].data_disks.el[raidlist->el[raidlist->entries].data_disks.entries].index = atoi(pos + 1); 1049 asprintf(&strtmp,"%s%s", device_prefix, token); 1050 strcpy(raidlist->el[raidlist->entries].data_disks.el[raidlist->el[raidlist->entries].data_disks.entries].device, strtmp); 1051 paranoid_free(strtmp); 1052 raidlist->el[raidlist->entries].data_disks.entries++; 1053 break; 1054 case 'S': // spare disks 1055 raidlist->el[raidlist->entries].spare_disks.el[raidlist->el[raidlist->entries].spare_disks.entries].index = atoi(pos + 1); 1056 asprintf(&strtmp,"%s%s", device_prefix, token); 1057 strcpy(raidlist->el[raidlist->entries].spare_disks.el[raidlist->el[raidlist->entries].spare_disks.entries].device, strtmp); 1058 paranoid_free(strtmp); 1059 raidlist->el[raidlist->entries].spare_disks.entries++; 1060 break; 1061 case 'F': // failed disks 1062 raidlist->el[raidlist->entries].failed_disks.el[raidlist->el[raidlist->entries].failed_disks.entries].index = atoi(pos + 1); 1063 asprintf(&strtmp,"%s%s", device_prefix, token); 1064 strcpy(raidlist->el[raidlist->entries].failed_disks.el[raidlist->el[raidlist->entries].failed_disks.entries].device, strtmp); 1065 paranoid_free(strtmp); 1066 raidlist->el[raidlist->entries].failed_disks.entries++; 1067 log_it("At least one failed disk found in RAID array.\n"); 1068 break; 1069 default: // error 1070 log_msg(1, "Unknown device type '%c'\n", type); 1071 paranoid_free(string); 1072 paranoid_free(token); 1073 return 1; 1074 break; 1075 } 1076 paranoid_free(token); 1077 } 1078 1079 // adjust index for each device so that it starts with 0 for every type 1080 index_min = 99; 1081 for (i=0; i<raidlist->el[raidlist->entries].data_disks.entries;i++) { 1082 if (raidlist->el[raidlist->entries].data_disks.el[i].index < index_min) { 1083 index_min = raidlist->el[raidlist->entries].data_disks.el[i].index; 1084 } 1085 } 1086 if (index_min > 0) { 1087 for (i=0; i<raidlist->el[raidlist->entries].data_disks.entries;i++) { 1088 raidlist->el[raidlist->entries].data_disks.el[i].index = raidlist->el[raidlist->entries].data_disks.el[i].index - index_min; 1089 } 1090 } 1091 index_min = 99; 1092 for (i=0; i<raidlist->el[raidlist->entries].spare_disks.entries;i++) { 1093 if (raidlist->el[raidlist->entries].spare_disks.el[i].index < index_min) { 1094 index_min = raidlist->el[raidlist->entries].spare_disks.el[i].index; 1095 } 1096 } 1097 if (index_min > 0) { 1098 for (i=0; i<raidlist->el[raidlist->entries].spare_disks.entries;i++) { 1099 raidlist->el[raidlist->entries].spare_disks.el[i].index = raidlist->el[raidlist->entries].spare_disks.el[i].index - index_min; 1100 } 1101 } 1102 index_min = 99; 1103 for (i=0; i<raidlist->el[raidlist->entries].failed_disks.entries;i++) { 1104 if (raidlist->el[raidlist->entries].failed_disks.el[i].index < index_min) { 1105 index_min = raidlist->el[raidlist->entries].failed_disks.el[i].index; 1106 } 1107 } 1108 if (index_min > 0) { 1109 for (i=0; i<raidlist->el[raidlist->entries].failed_disks.entries;i++) { 1110 raidlist->el[raidlist->entries].failed_disks.el[i].index = raidlist->el[raidlist->entries].failed_disks.el[i].index - index_min; 1111 } 1112 } 1113 break; 1114 case 2: // config information 1115 // check for persistent super block 1116 if (strcasestr(string, "super non-persistent")) { 1117 raidlist->el[raidlist->entries].persistent_superblock = 0; 1118 } else { 1119 raidlist->el[raidlist->entries].persistent_superblock = 1; 1120 } 1121 // extract chunk size 1122 if (!(pos = strcasestr(string, "k chunk"))) { 1123 raidlist->el[raidlist->entries].chunk_size = -1; 1124 } else { 1125 while (*pos != ' ') { 1126 *pos--; 1127 if (pos < string) { 1128 log_it("String underflow!\n"); 1129 paranoid_free(string); 1130 return 1; 1131 } 1132 } 1133 raidlist->el[raidlist->entries].chunk_size = atoi(pos + 1); 1134 } 1135 // extract parity if present 1136 if ((pos = strcasestr(string, "algorithm"))) { 1137 raidlist->el[raidlist->entries].parity = atoi(pos + 9); 1138 } else { 1139 raidlist->el[raidlist->entries].parity = -1; 1140 } 1141 break; 1142 case 3: // optional build status information 1143 if (!(pos = strchr(string, '\%'))) { 1144 if (strcasestr(string, "delayed")) { 1145 raidlist->el[raidlist->entries].progress = -1; // delayed (therefore, stuck at 0%) 1146 } else { 1147 raidlist->el[raidlist->entries].progress = 999; // not found 1148 } 1149 } else { 1150 while (*pos != ' ') { 1151 *pos--; 1152 if (pos < string) { 1153 printf("ERROR: String underflow!\n"); 1154 paranoid_free(string); 1155 return 1; 1156 } 1157 } 1158 raidlist->el[raidlist->entries].progress = atoi(pos); 1159 } 1160 break; 1161 default: // error 1162 log_msg(1, "Row %d should not occur in record!\n", row); 1163 break; 1164 } 1165 row++; 1166 } 1167 } 1168 // close file 1169 fclose(fin); 1170 // free string 1171 paranoid_free(string); 1172 // return success 1173 return 0; 1174 1175 } 1176 1177 1178 1179 1180 int create_raidtab_from_mdstat(char *raidtab_fname) 1181 { 1182 struct raidlist_itself *raidlist; 1183 int retval = 0; 1184 1185 raidlist = malloc(sizeof(struct raidlist_itself)); 1186 1187 // FIXME: Prefix '/dev/' should really be dynamic! 1188 if (parse_mdstat(raidlist, "/dev/")) { 1189 log_to_screen("Sorry, cannot read %s", MDSTAT_FILE); 913 1190 return (1); 914 1191 } 915 mdstat->entries = 0; 916 for (getline(&incoming, &n, fin); !feof(fin); 917 getline(&incoming, &n, fin)) { 918 p = incoming; 919 if (*p != 'm' && *(p + 1) == 'm') { 920 p++; 921 } 922 if (strncmp(p, "md", 2)) { 923 continue; 924 } 925 // read first line --- mdN : active raidX ............ 926 mdstat->el[mdstat->entries].md = atoi(p + 2); 927 log_msg(8, "Storing /dev/md%d's info", atoi(p + 2)); 928 while (*p != ':' && *p) { 929 p++; 930 } 931 while ((*p != 'r' || *(p + 1) != 'a') && *p) { 932 p++; 933 } 934 if (!strncmp(p, "raid", 4)) { 935 mdstat->el[mdstat->entries].raidlevel = *(p + 4) - '0'; 936 } 937 p += 4; 938 while (*p != ' ' && *p) { 939 p++; 940 } 941 while (*p == ' ' && *p) { 942 p++; 943 } 944 for (diskno = 0; *p; diskno++) { 945 asprintf(&stub, "%s", p); 946 q = strchr(stub, '['); 947 if (q) { 948 *q = '\0'; 949 q++; 950 r = strchr(q, ']'); 951 if (r) { 952 *r = '\0'; 953 } 954 mdstat->el[mdstat->entries].disks.el[diskno].index = 955 atoi(q); 956 } else { 957 mdstat->el[mdstat->entries].disks.el[diskno].index = -1; 958 q = strchr(stub, ' '); 959 if (q) { 960 *q = '\0'; 961 } 962 } 963 asprintf(&tmp, "/dev/%s", stub); 964 paranoid_free(stub); 965 966 log_msg(8, "/dev/md%d : disk#%d : %s (%d)", 967 mdstat->el[mdstat->entries].md, diskno, tmp, 968 mdstat->el[mdstat->entries].disks.el[diskno].index); 969 strcpy(mdstat->el[mdstat->entries].disks.el[diskno].device, 970 tmp); 971 paranoid_free(tmp); 972 973 while (*p != ' ' && *p) { 974 p++; 975 } 976 while (*p == ' ' && *p) { 977 p++; 978 } 979 } 980 mdstat->el[mdstat->entries].disks.entries = diskno; 981 // next line --- skip it 982 if (!feof(fin)) { 983 getline(&incoming, &n, fin); 984 } else { 985 continue; 986 } 987 // next line --- the 'progress' line 988 if (!feof(fin)) { 989 getline(&incoming, &n, fin); 990 } else { 991 continue; 992 } 993 // log_msg(1, "Percentage line = '%s'", incoming); 994 if (!(p = strchr(incoming, '\%'))) { 995 mdstat->el[mdstat->entries].progress = 999; // not found 996 } else if (strstr(incoming, "DELAYED")) { 997 mdstat->el[mdstat->entries].progress = -1; // delayed (therefore, stuck at 0%) 998 } else { 999 for (*p = '\0'; *p != ' '; p--); 1000 mdstat->el[mdstat->entries].progress = atoi(p); 1001 } 1002 log_msg(8, "progress =%d", mdstat->el[mdstat->entries].progress); 1003 mdstat->entries++; 1004 } 1005 fclose(fin); 1006 paranoid_free(incoming); 1007 return (0); 1008 } 1009 1010 1011 1012 int create_raidtab_from_mdstat(char *raidtab_fname, char *mdstat_fname) 1013 { 1014 struct raidlist_itself *raidlist; 1015 struct s_mdstat *mdstat; 1016 int retval = 0; 1017 int i; 1018 1019 raidlist = malloc(sizeof(struct raidlist_itself)); 1020 mdstat = malloc(sizeof(struct s_mdstat)); 1021 1022 if (read_mdstat(mdstat, mdstat_fname)) { 1023 log_to_screen("Sorry, cannot read %s", mdstat_fname); 1024 return (1); 1025 } 1026 1027 for (i = 0; i < mdstat->entries; i++) { 1028 sprintf(raidlist->el[i].raid_device, "/dev/md%d", 1029 mdstat->el[i].md); 1030 raidlist->el[i].raid_level = mdstat->el[i].raidlevel; 1031 raidlist->el[i].persistent_superblock = 1; 1032 raidlist->el[i].chunk_size = 4; 1033 memcpy((void *) &raidlist->el[i].data_disks, 1034 (void *) &mdstat->el[i].disks, 1035 sizeof(struct list_of_disks)); 1036 // FIXME --- the above line does not allow for spare disks 1037 log_to_screen 1038 (_("FIXME - create_raidtab_from_mdstat does not allow for spare disks")); 1039 } 1040 raidlist->entries = i; 1192 1041 1193 retval += save_raidlist_to_raidtab(raidlist, raidtab_fname); 1042 1194 return (retval); -
trunk/mondo/mondo/common/libmondo-raid.h
r59 r561 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); -
trunk/mondo/mondo/common/libmondo-string.c
r507 r561 2 2 $Id$ 3 3 */ 4 5 4 6 5 /** … … 1139 1138 } 1140 1139 1140 1141 /* New functions safe from a memory manageemnt point of view */ 1142 /* Developped by Andree Leidenfrost */ 1143 1144 char *mr_strtok(char *instr, const char *delims, int *lastpos) { 1145 1146 char *token = NULL; 1147 char *strptr = NULL; 1148 size_t pos1 = 0; 1149 size_t pos2 = 0; 1150 1151 if (strlen(instr) <= *lastpos) { 1152 *lastpos = 0; 1153 return token; 1154 } 1155 1156 strptr = instr + *lastpos; 1157 pos2 = strspn(strptr, delims); 1158 strptr += pos2; 1159 pos1 = strcspn(strptr, delims); 1160 token = malloc(sizeof(*token)*(pos1+1)); 1161 strncpy(token, strptr, pos1); 1162 *lastpos = *lastpos + pos1 + pos2 + 1; 1163 1164 return token; 1165 } 1141 1166 /* @} - end of stringGroup */ -
trunk/mondo/mondo/common/libmondo-string.h
r59 r561 34 34 char *media_descriptor_string(t_bkptype); 35 35 inline void turn_wildcard_chars_into_literal_chars(char *out, char *in); 36 37 /* Valid external functions */ 38 char *mr_strtok(char *instr, const char *delims, int *lastpos) -
trunk/mondo/mondo/common/libmondo-tools.c
r539 r561 282 282 assert(raidrec != NULL); 283 283 raidrec->raid_device[0] = '\0'; 284 raidrec->raid_level = 0; 285 raidrec->chunk_size = 4; 284 raidrec->raid_level = -9; 286 285 raidrec->persistent_superblock = 1; 286 raidrec->chunk_size = 64; 287 raidrec->parity = -1; 287 288 raidrec->data_disks.entries = 0; 288 289 raidrec->spare_disks.entries = 0; … … 994 995 log_to_screen 995 996 (_("You have RAID partitions but no /etc/raidtab - creating one from /proc/mdstat")); 996 create_raidtab_from_mdstat("/etc/raidtab" , "/proc/mdstat");997 create_raidtab_from_mdstat("/etc/raidtab"); 997 998 } 998 999 -
trunk/mondo/mondo/common/mondostructures.h
r539 r561 133 133 */ 134 134 int index; 135 136 /** 137 * Type of disk. 138 */ 139 char type; // ' ' = data (default), S = spare, F = faulty 140 135 141 }; 136 142 … … 224 230 */ 225 231 int chunk_size; 232 233 /** 234 * The parity algorithm of this RAID device. (RAID5 only) 235 */ 236 int parity; // 0=left-asymmetric, 1=right-asymmetric, 2=left-symmetric, 3=right-symmetric 226 237 227 238 /** … … 249 260 */ 250 261 struct additional_raid_variables additional_vars; 262 263 /** 264 * Resync progress for this device. 265 */ 266 int progress; 251 267 }; 252 268 -
trunk/mondo/mondo/common/my-stuff.h
r539 r561 22 22 * The main header file for Mondo. 23 23 */ 24 #ifndef _MY_STUFF_H_25 #define _MY_STUFF_H_26 24 27 25 /* Required for the use of getline, ... */ 28 #define __USE_GNU29 26 #define _GNU_SOURCE 30 27 … … 83 80 #ifndef S_SPLINT_S 84 81 #include <pthread.h> 82 #endif 85 83 #include <assert.h> 86 84 … … 114 112 */ 115 113 #define MONDO_CFG_FILE_STUB "tmp/mondo-restore.cfg" 114 115 /** 116 * The RAID kernel proc file 117 */ 118 #define MDSTAT_FILE "/proc/mdstat" 116 119 117 120 /** … … 428 431 429 432 430 431 433 #endif /* _MY_STUFF_H_ */ -
trunk/mondo/mondo/mondorestore/mondo-prep.c
r507 r561 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 … … 2246 2367 sprintf(program, "vinum stop -f %s", raid_device); 2247 2368 #else 2248 sprintf(program, "raidstop %s", raid_device); 2249 // sprintf (program, "raidstop " RAID_DEVICE_STUB "*"); 2369 // use raidstop if it exists, otherwise use mdadm 2370 if (run_program_and_log_output("which raidstop", FALSE)) { 2371 sprintf(program, "mdadm -S %s", raid_device); 2372 } else { 2373 sprintf(program, "raidstop %s", raid_device); 2374 } 2250 2375 #endif 2251 2376 log_msg(1, "program = %s", program); -
trunk/mondo/mondo/mondorestore/mondo-restore.c
r507 r561 839 839 } 840 840 841 fmt_errs = format_everything(mountlist, FALSE );841 fmt_errs = format_everything(mountlist, FALSE, raidlist); 842 842 if (!fmt_errs) { 843 843 log_to_screen … … 857 857 if (ask_me_yes_or_no 858 858 (_("Do you want to format your hard drives?"))) { 859 fmt_errs = format_everything(mountlist, TRUE );859 fmt_errs = format_everything(mountlist, TRUE, raidlist); 860 860 if (!fmt_errs) { 861 861 done = TRUE; … … 1164 1164 system("sync"); 1165 1165 log_to_screen(_("Please wait. This may take a few minutes.")); 1166 res += format_everything(mountlist, FALSE );1166 res += format_everything(mountlist, FALSE, raidlist); 1167 1167 } 1168 1168 paranoid_fclose(g_fprep); … … 3425 3425 } 3426 3426 3427 if (argc == 4&& strcmp(argv[1], "--mdconv") == 0) {3428 finish(create_raidtab_from_mdstat(argv[2] , argv[3]));3427 if (argc == 3 && strcmp(argv[1], "--mdconv") == 0) { 3428 finish(create_raidtab_from_mdstat(argv[2])); 3429 3429 } 3430 3430 … … 3525 3525 strcpy(g_mountlist_fname, "/tmp/mountlist.txt"); 3526 3526 load_mountlist(mountlist, g_mountlist_fname); 3527 res = format_everything(mountlist, FALSE );3527 res = format_everything(mountlist, FALSE, raidlist); 3528 3528 finish(res); 3529 3529 } -
trunk/mondo/mondo/mondorestore/mondo-rstr-tools.c
r507 r561 1 /*************************************************************************** 2 mondo-rstr-tools.c - description 3 ----------------- 4 5 begin: Sun Sep 21 16:40:35 EDT 2003 6 copyright : (C) 2002 Mondo Hugo Rabson 7 email : Hugo Rabson <hugorabson@msn.com> 8 edited by : by Stan Benoit ?/2003 9 email : troff@nakedsoul.org 10 cvsid : $Id: mondo-rstr-tools.c 11 ***************************************************************************/ 12 13 /*************************************************************************** 14 * * 15 * This program is free software; you can redistribute it and/or modify * 16 * it under the terms of the GNU General Public License as published by * 17 * the Free Software Foundation; either version 2 of the License, or * 18 * (at your option) any later version. * 19 * * 20 ***************************************************************************/ 21 /* mondo-rstr-tools.c Hugo Rabson 22 23 24 07/27 25 - if the user is foolish enough to use /dev/md0 as boot device, 26 call lilo -M /dev/hda to make sure lilo does its job properly 27 - better NFS+nuke support 28 29 07/20 30 - use backup's i-want-my-lvm file 31 - be sure to use archives' raidtab when restoring 32 33 07/18 34 - use /tmp/isodir for NFS if DR mode 35 - better support of users who boot from LVM CD and nuke-restore non-LVM backups 36 37 07/12 38 - bugfix to allow user to burn ISOs to CDs and restore from CDs (not original src) 39 40 06/29 41 - mount ext3 partitions as ext2, just in case :) 42 43 06/26 44 - delete make_relevant_partition_bootable() 45 46 06/19 47 - futzed with the call to mount floppy, to stop it from locking up on my AMD64 system 48 49 06/14 50 - shell out to /mnt/RESTORING chroot in order to let user install GRUB 51 manually if automatic GRUB installation fails 52 53 06/15 54 - Added check for different 'isodir' chosen by user than stored in the archive 55 Conor Daly <conor.daly@met.ie> 56 57 04/17 58 - replaced INTERNAL_TAPE_BLK_SIZE with bkpinfo->internal_tape_block_size 59 60 04/09 61 - don't try to mount CD if tape bkp 62 63 04/03 64 - trying to copy tmp/mondo-restore.cfg to itself - silly! - fixed 65 66 04/02 67 - when extracting cfg file and mountlist from all.tar.gz (tape copy), 68 use block size of INTERNAL_TAPE_BLK_SIZE, not TAPE_BLOCK_SIZE 69 70 02/21 71 - don't use 'mv -v' cos Busybox won't support it 72 73 02/09 74 - make hole for cfg file before moving it (line 2094 or so) 75 76 02/03 77 - changed a couple of refs to filelist.full, to filelist.full.gz 78 79 01/16/2004 80 - instead of copying filelist, use 'ln -sf' to link to original; 81 saves space 82 83 11/20/2003 84 - also retrieve /tmp/mountlist.txt if user wants 85 86 11/16 87 - fixed NFS path bug affecting the extractions of filelist/biggielist 88 during selective restore 89 90 11/02 91 - fixed mount_cdrom() to run properly w/ nfs restores 92 - mount_device() returns 0 if swap mount fails cos swap isn't crucial 93 94 10/17 95 - run_grub() uses MNT_RESTORING instead of "/mnt/RESTORING" 96 97 10/26 98 - cleaned up run_grub() 99 100 10/25 101 - fixed mount_cdrom() to run properly w/ nfs restores 102 103 10/21 104 - mount_device() returns 0 if swap mount fails cos swap isn't crucial 105 106 10/15 107 - run_grub() now uses its initiative instead 108 of calling grub-install 109 110 10/10 111 - don't leave copies of filelist.full lying around, clogging up 112 the ramdisk, there's a good fellow :-) 113 114 10/02 115 - added 'dvd' to the range of media types I'll understand 116 - fixed iso->cdr problem (thanks, Stan Benoit & Fred Beondo) 117 118 09/24 119 - try lots of tape devs if /dev/st0 fails 120 121 09/23/2003 122 - first incarnation 1 /* 2 * $Id$ 123 3 */ 124 4 … … 2569 2449 int wait_for_percentage) 2570 2450 { 2571 struct s_mdstat *mdstat;2451 struct raidlist_itself *raidlist; 2572 2452 int unfinished_mdstat_devices = 9999, i; 2573 2453 char *screen_message; 2574 2454 2575 2455 malloc_string(screen_message); 2576 mdstat = malloc(sizeof(struct s_mdstat));2456 raidlist = malloc(sizeof(struct raidlist_itself)); 2577 2457 2578 2458 assert(wait_for_percentage <= 100); 2579 2459 iamhere("Help, my boat is sync'ing. (Get it? Urp! Urp!)"); 2580 2460 while (unfinished_mdstat_devices > 0) { 2581 if (read_mdstat(mdstat, mdstat_file)) { 2582 log_to_screen(_("Sorry, cannot read %s"), mdstat_file); 2461 if (parse_mdstat(raidlist, "/dev/")) { 2462 log_to_screen("Sorry, cannot read %s", MDSTAT_FILE); 2463 log_msg(1,"Sorry, cannot read %s", MDSTAT_FILE); 2583 2464 return; 2584 2465 } 2585 for (unfinished_mdstat_devices = i = 0; i < mdstat->entries; i++) {2586 if ( mdstat->el[i].progress < wait_for_percentage) {2466 for (unfinished_mdstat_devices = i = 0; i <= raidlist->entries; i++) { 2467 if (raidlist->el[i].progress < wait_for_percentage) { 2587 2468 unfinished_mdstat_devices++; 2588 sprintf(screen_message, _("Sync'ing /dev/md%d"), 2589 mdstat->el[i].md); 2469 log_msg(1,"Sync'ing %s (i=%d)", raidlist->el[i].raid_device, i); 2470 sprintf(screen_message, "Sync'ing %s", 2471 raidlist->el[i].raid_device); 2590 2472 open_evalcall_form(screen_message); 2591 if ( mdstat->el[i].progress == -1) // delayed while another partition inits2473 if (raidlist->el[i].progress == -1) // delayed while another partition inits 2592 2474 { 2593 2475 continue; 2594 2476 } 2595 while (mdstat->el[i].progress < wait_for_percentage) { 2596 update_evalcall_form(mdstat->el[i].progress); 2477 while (raidlist->el[i].progress < wait_for_percentage) { 2478 log_msg(1,"Percentage sync'ed: %d", raidlist->el[i].progress); 2479 update_evalcall_form(raidlist->el[i].progress); 2597 2480 sleep(2); 2598 if (read_mdstat(mdstat, mdstat_file)) { 2481 // FIXME: Prefix '/dev/' should really be dynamic! 2482 if (parse_mdstat(raidlist, "/dev/")) { 2599 2483 break; 2600 2484 } … … 2605 2489 } 2606 2490 paranoid_free(screen_message); 2607 paranoid_free( mdstat);2608 } 2491 paranoid_free(raidlist); 2492 } -
trunk/mondo/mondo/mondorestore/mondoprep.h
r59 r561 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 *); -
trunk/mondo/mondo/mondorestore/mr-externs.h
r127 r561 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 *); -
trunk/mondo/mondo/test/mktest
r532 r561 5 5 # test script for library functions 6 6 # 7 gcc -O2 -I../common test-conf.c ../common/libmondo-conf.c ../common/libmondo-msg.c -o test-conf 7 8 gcc -O2 -I../common test-conf.c ../common/libmondo-conf.c ../common/libmondo-msg.c -o test-conf 9 gcc -O2 -I../common test-string.c ../common/libmondo-string.c ../common/libmondo-msg.c -o test-string 10 8 11 for f in "test-conf"; do 9 12 chmod 755 $f
Note:
See TracChangeset
for help on using the changeset viewer.