Changeset 128 in MondoRescue for branches/2.05/mondo/mondo/common/libmondo-raid.c
- Timestamp:
- Nov 19, 2005, 2:27:41 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.05/mondo/mondo/common/libmondo-raid.c
r30 r128 1 1 /* libmondo-raid.c subroutines for handling RAID 2 $Id : libmondo-raid.c,v 1.2 2004/06/10 15:29:12 hugo Exp$2 $Id$ 3 3 . 4 4 … … 51 51 #ifdef __FreeBSD__ 52 52 /* Nonstandard library functions: */ 53 extern void errx 54 extern char *strsep 53 extern void errx(int exitval, const char *fmt, ...); 54 extern char *strsep(char **stringp, const char *delim); 55 55 #endif 56 56 57 57 /*@unused@*/ 58 //static char cvsid[] = "$Id : libmondo-raid.c,v 1.2 2004/06/10 15:29:12 hugo Exp$";58 //static char cvsid[] = "$Id$"; 59 59 60 60 … … 69 69 * @return TRUE if it's supported, FALSE if not. 70 70 */ 71 bool 72 is_this_raid_personality_registered (int raidno) 71 bool is_this_raid_personality_registered(int raidno) 73 72 { 74 73 #ifdef __FreeBSD__ 75 return ((raidno == -1) || (raidno == 0) || (raidno == 1) || (raidno == 5)) ? TRUE : FALSE; 74 return ((raidno == -1) || (raidno == 0) || (raidno == 1) 75 || (raidno == 5)) ? TRUE : FALSE; 76 76 #else 77 /*@ buffer ***********************************************************/ 78 char *command; 79 int res; 80 81 command = malloc(MAX_STR_LEN*2); 82 strcpy (command, "cat /proc/mdstat | grep \""); 83 if (raidno == -1) 84 { 85 strcat (command, "linear"); 86 } 87 else 88 { 89 sprintf (command + strlen (command), "raid%d", raidno); 90 } 91 strcat (command, "\" > /dev/null 2> /dev/null"); 92 log_it ("Is raid %d registered? Command = '%s'", raidno, command); 93 res = system (command); 94 paranoid_free(command); 95 if (res) 96 { 97 return (FALSE); 98 } 99 else 100 { 101 return (TRUE); 102 } 77 /*@ buffer ********************************************************** */ 78 char *command; 79 int res; 80 81 command = malloc(MAX_STR_LEN * 2); 82 strcpy(command, "cat /proc/mdstat | grep \""); 83 if (raidno == -1) { 84 strcat(command, "linear"); 85 } else { 86 sprintf(command + strlen(command), "raid%d", raidno); 87 } 88 strcat(command, "\" > /dev/null 2> /dev/null"); 89 log_it("Is raid %d registered? Command = '%s'", raidno, command); 90 res = system(command); 91 paranoid_free(command); 92 if (res) { 93 return (FALSE); 94 } else { 95 return (TRUE); 96 } 103 97 #endif 104 98 } … … 116 110 */ 117 111 int 118 where_in_drivelist_is_drive (struct list_of_disks *disklist, char *device) 119 { 120 121 /*@ int **************************************************************/ 122 int i = 0; 123 124 assert(disklist!=NULL); 125 assert_string_is_neither_NULL_nor_zerolength(device); 126 127 for (i = 0; i < disklist->entries; i++) 128 { 129 if (!strcmp (disklist->el[i].device, device)) 130 { 131 break; 132 } 133 } 134 if (i == disklist->entries) 135 { 136 return (-1); 137 } 138 else 139 { 140 return (i); 141 } 112 where_in_drivelist_is_drive(struct list_of_disks *disklist, char *device) 113 { 114 115 /*@ int ************************************************************* */ 116 int i = 0; 117 118 assert(disklist != NULL); 119 assert_string_is_neither_NULL_nor_zerolength(device); 120 121 for (i = 0; i < disklist->entries; i++) { 122 if (!strcmp(disklist->el[i].device, device)) { 123 break; 124 } 125 } 126 if (i == disklist->entries) { 127 return (-1); 128 } else { 129 return (i); 130 } 142 131 } 143 132 … … 156 145 */ 157 146 int 158 which_raid_device_is_using_this_partition 159 147 which_raid_device_is_using_this_partition(struct raidlist_itself *raidlist, 148 char *device) 160 149 { 161 150 #ifdef __FreeBSD__ 162 151 // FreeBSD-specific version of which_raid_device_is_using_this_partition() 163 /*@ int **********************************************************/ 164 int i = 0; 165 166 for (i = 0; i < raidlist->entries; i++) 167 { 168 bool thisone = FALSE; 169 int j, k, l; 170 171 for (j = 0; j < raidlist->el[i].plexes; ++j) { 172 for (k = 0; k < raidlist->el[i].plex[j].subdisks; ++k) { 173 for (l = 0; l < raidlist->disks.entries; ++l) { 174 if (!strcmp (raidlist->disks.el[l].device, 175 device) && 176 !strcmp (raidlist->el[i].plex[j].sd[k].which_device, 177 raidlist->disks.el[l].name)) 178 thisone = TRUE; 179 } 180 } 181 } 182 183 if (thisone) 184 { 185 break; 186 } 187 } 188 if (i == raidlist->entries) 189 { 190 return (-1); 191 } 192 else 193 { 194 return (i); 195 } 152 /*@ int ********************************************************* */ 153 int i = 0; 154 155 for (i = 0; i < raidlist->entries; i++) { 156 bool thisone = FALSE; 157 int j, k, l; 158 159 for (j = 0; j < raidlist->el[i].plexes; ++j) { 160 for (k = 0; k < raidlist->el[i].plex[j].subdisks; ++k) { 161 for (l = 0; l < raidlist->disks.entries; ++l) { 162 if (!strcmp(raidlist->disks.el[l].device, 163 device) && 164 !strcmp(raidlist->el[i].plex[j].sd[k].which_device, 165 raidlist->disks.el[l].name)) 166 thisone = TRUE; 167 } 168 } 169 } 170 171 if (thisone) { 172 break; 173 } 174 } 175 if (i == raidlist->entries) { 176 return (-1); 177 } else { 178 return (i); 179 } 196 180 } 197 181 … … 200 184 // and one other function which FreeBSD doesn't use 201 185 202 int current_raiddev = 0; 203 204 assert_string_is_neither_NULL_nor_zerolength(device); 205 assert(raidlist!=NULL); 206 207 for (current_raiddev = 0; current_raiddev < raidlist->entries; 208 current_raiddev++) 209 { 210 if (where_in_drivelist_is_drive 211 (&raidlist->el[current_raiddev].data_disks, device) >= 0 212 || where_in_drivelist_is_drive (&raidlist->el[current_raiddev]. 213 spare_disks, device) >= 0 214 || where_in_drivelist_is_drive (&raidlist->el[current_raiddev]. 215 parity_disks, device) >= 0 216 || where_in_drivelist_is_drive (&raidlist->el[current_raiddev]. 217 failed_disks, device) >= 0) 218 { 219 break; 220 } 221 } 222 if (current_raiddev == raidlist->entries) 223 { 224 return (-1); 225 } 226 else 227 { 228 return (current_raiddev); 229 } 186 int current_raiddev = 0; 187 188 assert_string_is_neither_NULL_nor_zerolength(device); 189 assert(raidlist != NULL); 190 191 for (current_raiddev = 0; current_raiddev < raidlist->entries; 192 current_raiddev++) { 193 if (where_in_drivelist_is_drive 194 (&raidlist->el[current_raiddev].data_disks, device) >= 0 195 || where_in_drivelist_is_drive(&raidlist->el[current_raiddev]. 196 spare_disks, device) >= 0 197 || where_in_drivelist_is_drive(&raidlist->el[current_raiddev]. 198 parity_disks, device) >= 0 199 || where_in_drivelist_is_drive(&raidlist->el[current_raiddev]. 200 failed_disks, device) >= 0) { 201 break; 202 } 203 } 204 if (current_raiddev == raidlist->entries) { 205 return (-1); 206 } else { 207 return (current_raiddev); 208 } 230 209 } 231 210 … … 238 217 */ 239 218 void 240 write_variableINT_to_raid_var_line 241 242 { 243 /*@ buffers ***************************************************** */244 245 246 247 assert(raidrec!=NULL);248 assert(label!=NULL);249 250 sprintf(sz_value, "%d", value);251 strcpy(raidrec->additional_vars.el[lino].label, label);252 strcpy(raidrec->additional_vars.el[lino].value, sz_value);253 219 write_variableINT_to_raid_var_line(struct raid_device_record *raidrec, 220 int lino, char *label, int value) 221 { 222 /*@ buffers ***************************************************** */ 223 char *sz_value; 224 225 malloc_string(sz_value); 226 assert(raidrec != NULL); 227 assert(label != NULL); 228 229 sprintf(sz_value, "%d", value); 230 strcpy(raidrec->additional_vars.el[lino].label, label); 231 strcpy(raidrec->additional_vars.el[lino].value, sz_value); 232 paranoid_free(sz_value); 254 233 } 255 234 #endif … … 268 247 * @param device_to_add The device to add to @p p. 269 248 */ 270 void add_disk_to_raid_device(struct vinum_plex *p, char *device_to_add)271 { 272 strcpy(p->sd[p->subdisks].which_device, device_to_add);273 249 void add_disk_to_raid_device(struct vinum_plex *p, char *device_to_add) 250 { 251 strcpy(p->sd[p->subdisks].which_device, device_to_add); 252 ++p->subdisks; 274 253 275 254 } … … 281 260 * @param index The index number of the disklist entry we're creating. 282 261 */ 283 void add_disk_to_raid_device(struct list_of_disks *disklist, char*device_to_add, int index) 284 { 285 int items; 286 287 assert(disklist!=NULL); 288 assert_string_is_neither_NULL_nor_zerolength(device_to_add); 289 items = disklist->entries; 290 strcpy( disklist->el[items].device, device_to_add ); 291 disklist->el[items].index = index; 292 items++; 293 disklist->entries = items; 262 void add_disk_to_raid_device(struct list_of_disks *disklist, 263 char *device_to_add, int index) 264 { 265 int items; 266 267 assert(disklist != NULL); 268 assert_string_is_neither_NULL_nor_zerolength(device_to_add); 269 items = disklist->entries; 270 strcpy(disklist->el[items].device, device_to_add); 271 disklist->el[items].index = index; 272 items++; 273 disklist->entries = items; 294 274 } 295 275 #endif … … 301 281 * @param fout The FILE pointer to save them to. 302 282 */ 303 void 304 save_additional_vars_to_file(struct additional_raid_variables *vars, FILE *fout) 305 { 306 int i; 307 308 assert(vars!=NULL); 309 assert(fout!=NULL); 310 311 for(i = 0; i < vars->entries; i++ ) 312 { 313 fprintf(fout," %-21s %s\n",vars->el[i].label, vars->el[i].value); 314 } 283 void 284 save_additional_vars_to_file(struct additional_raid_variables *vars, 285 FILE * fout) 286 { 287 int i; 288 289 assert(vars != NULL); 290 assert(fout != NULL); 291 292 for (i = 0; i < vars->entries; i++) { 293 fprintf(fout, " %-21s %s\n", vars->el[i].label, 294 vars->el[i].value); 295 } 315 296 } 316 297 … … 323 304 * @bug Return value is redundant. 324 305 */ 325 int 326 save_raidlist_to_raidtab(struct raidlist_itself *raidlist, char *fname) 327 { 328 FILE *fout; 329 int current_raid_device; 306 int save_raidlist_to_raidtab(struct raidlist_itself *raidlist, char *fname) 307 { 308 FILE *fout; 309 int current_raid_device; 330 310 #ifdef __FreeBSD__ 331 311 int i; 332 312 #else 333 313 // Linux 334 314 #endif 335 315 336 assert(raidlist!=NULL); 337 assert_string_is_neither_NULL_nor_zerolength(fname); 338 339 if (raidlist->entries <= 0) 340 { 341 unlink(fname); 342 log_it("Deleting raidtab (no RAID devs anyway)"); 343 return(0); 344 } 345 if (!(fout=fopen(fname,"w"))) 346 { 347 log_OS_error("Failed to save raidlist");return(1); 348 } 349 fprintf (fout, "# Generated by Mondo Rescue\n"); 316 assert(raidlist != NULL); 317 assert_string_is_neither_NULL_nor_zerolength(fname); 318 319 if (raidlist->entries <= 0) { 320 unlink(fname); 321 log_it("Deleting raidtab (no RAID devs anyway)"); 322 return (0); 323 } 324 if (!(fout = fopen(fname, "w"))) { 325 log_OS_error("Failed to save raidlist"); 326 return (1); 327 } 328 fprintf(fout, "# Generated by Mondo Rescue\n"); 350 329 351 330 #ifdef __FreeBSD__ 352 for (i = 0; i < raidlist->disks.entries; ++i) { 353 fprintf (fout, "drive %s device %s\n", raidlist->disks.el[i].name, raidlist->disks.el[i].device); 354 } 355 for (i = 0; i < (raidlist->spares.entries); ++i) { 356 fprintf (fout, "drive %s device %s hotspare\n", raidlist->spares.el[i].name, raidlist->spares.el[i].device); 357 } 331 for (i = 0; i < raidlist->disks.entries; ++i) { 332 fprintf(fout, "drive %s device %s\n", raidlist->disks.el[i].name, 333 raidlist->disks.el[i].device); 334 } 335 for (i = 0; i < (raidlist->spares.entries); ++i) { 336 fprintf(fout, "drive %s device %s hotspare\n", 337 raidlist->spares.el[i].name, 338 raidlist->spares.el[i].device); 339 } 358 340 #endif 359 341 360 for(current_raid_device = 0; current_raid_device < raidlist->entries; current_raid_device++ ) 361 362 save_raidrec_to_file(&raidlist->el[current_raid_device],fout);363 364 365 return(0);342 for (current_raid_device = 0; current_raid_device < raidlist->entries; 343 current_raid_device++) { 344 save_raidrec_to_file(&raidlist->el[current_raid_device], fout); 345 } 346 paranoid_fclose(fout); 347 return (0); 366 348 } 367 349 … … 372 354 * @param fout The stream to save it to. 373 355 */ 374 void 375 save_raidrec_to_file( struct 356 void save_raidrec_to_file(struct 376 357 #ifdef __FreeBSD__ 377 vinum_volume358 vinum_volume 378 359 #else 379 raid_device_record360 raid_device_record 380 361 #endif 381 *raidrec, FILE *fout)362 * raidrec, FILE * fout) 382 363 { 383 364 #ifdef __FreeBSD__ 384 int i, j; 385 386 fprintf (fout, "\nvolume %s\n", raidrec->volname); 387 for (i = 0; i < raidrec->plexes; ++i) { 388 char org[24]; 389 switch (raidrec->plex[i].raidlevel) { 390 case -1: strcpy (org, "concat"); break; 391 case 0: strcpy (org, "striped"); break; 392 case 5: strcpy (org, "raid5"); break; 393 } 394 fprintf (fout, " plex org %s", org); 395 if (raidrec->plex[i].raidlevel != -1) { 396 fprintf (fout, " %ik", raidrec->plex[i].stripesize); 397 } 398 fprintf (fout, "\n"); 399 400 for (j = 0; j < raidrec->plex[i].subdisks; ++j) { 401 fprintf (fout, " sd drive %s size 0\n", raidrec->plex[i].sd[j].which_device); 402 } 403 } 365 int i, j; 366 367 fprintf(fout, "\nvolume %s\n", raidrec->volname); 368 for (i = 0; i < raidrec->plexes; ++i) { 369 char org[24]; 370 switch (raidrec->plex[i].raidlevel) { 371 case -1: 372 strcpy(org, "concat"); 373 break; 374 case 0: 375 strcpy(org, "striped"); 376 break; 377 case 5: 378 strcpy(org, "raid5"); 379 break; 380 } 381 fprintf(fout, " plex org %s", org); 382 if (raidrec->plex[i].raidlevel != -1) { 383 fprintf(fout, " %ik", raidrec->plex[i].stripesize); 384 } 385 fprintf(fout, "\n"); 386 387 for (j = 0; j < raidrec->plex[i].subdisks; ++j) { 388 fprintf(fout, " sd drive %s size 0\n", 389 raidrec->plex[i].sd[j].which_device); 390 } 391 } 404 392 #else 405 assert(raidrec!=NULL); 406 assert(fout!=NULL); 407 408 fprintf(fout,"raiddev %s\n",raidrec->raid_device); 409 if (raidrec->raid_level == -1 ) 410 { 411 fprintf(fout," raid-level linear\n"); 412 } 413 else 414 { 415 fprintf(fout," raid-level %d\n",raidrec->raid_level); 416 } 417 fprintf(fout," chunk-size %d\n",raidrec->chunk_size); 418 fprintf(fout," nr-raid-disks %d\n",raidrec->data_disks.entries); 419 fprintf(fout," nr-spare-disks %d\n",raidrec->spare_disks.entries); 420 if (raidrec->parity_disks.entries > 0) 421 { 422 fprintf(fout," nr-parity-disks %d\n",raidrec->parity_disks.entries); 423 } 424 425 fprintf(fout," persistent-superblock %d\n",raidrec->persistent_superblock); 426 save_additional_vars_to_file(&raidrec->additional_vars,fout); 427 fprintf(fout,"\n"); 428 save_disklist_to_file("raid-disk", &raidrec->data_disks, fout); 429 save_disklist_to_file("spare-disk", &raidrec->spare_disks, fout); 430 save_disklist_to_file("parity-disk", &raidrec->parity_disks, fout); 431 save_disklist_to_file("failed-disk", &raidrec->failed_disks, fout); 432 fprintf(fout,"\n"); 393 assert(raidrec != NULL); 394 assert(fout != NULL); 395 396 fprintf(fout, "raiddev %s\n", raidrec->raid_device); 397 if (raidrec->raid_level == -1) { 398 fprintf(fout, " raid-level linear\n"); 399 } else { 400 fprintf(fout, " raid-level %d\n", 401 raidrec->raid_level); 402 } 403 fprintf(fout, " chunk-size %d\n", raidrec->chunk_size); 404 fprintf(fout, " nr-raid-disks %d\n", 405 raidrec->data_disks.entries); 406 fprintf(fout, " nr-spare-disks %d\n", 407 raidrec->spare_disks.entries); 408 if (raidrec->parity_disks.entries > 0) { 409 fprintf(fout, " nr-parity-disks %d\n", 410 raidrec->parity_disks.entries); 411 } 412 413 fprintf(fout, " persistent-superblock %d\n", 414 raidrec->persistent_superblock); 415 save_additional_vars_to_file(&raidrec->additional_vars, fout); 416 fprintf(fout, "\n"); 417 save_disklist_to_file("raid-disk", &raidrec->data_disks, fout); 418 save_disklist_to_file("spare-disk", &raidrec->spare_disks, fout); 419 save_disklist_to_file("parity-disk", &raidrec->parity_disks, fout); 420 save_disklist_to_file("failed-disk", &raidrec->failed_disks, fout); 421 fprintf(fout, "\n"); 433 422 #endif 434 423 } … … 441 430 * @return 0 if the line was read and stored successfully, 1 if we're at end of file. 442 431 */ 443 int 444 get_next_raidtab_line( FILE *fin, char *label, char *value ) 445 { 446 char *incoming; 447 char *p; 448 449 malloc_string(incoming); 450 assert(fin!=NULL); 451 assert(label!=NULL); 452 assert(value!=NULL); 453 454 label[0] = value[0]= '\0'; 455 if ( feof(fin) ) 456 { 457 paranoid_free(incoming); 458 return( 1 ); 459 } 460 for( fgets(incoming, MAX_STR_LEN - 1, fin ); !feof( fin ); fgets(incoming, MAX_STR_LEN - 1, fin ) ) 461 { 462 strip_spaces( incoming ); 463 p = strchr( incoming,' ' ); 464 if ( strlen( incoming ) < 3 || incoming[0] == '#' || !p) 465 { 466 continue; 467 } 468 *(p++) = '\0'; 469 while(*p==' ') { p++; } 470 strcpy( label, incoming ); 471 strcpy( value, p ); 472 paranoid_free(incoming); 473 return( 0 ); 474 } 475 return( 1 ); 432 int get_next_raidtab_line(FILE * fin, char *label, char *value) 433 { 434 char *incoming; 435 char *p; 436 437 malloc_string(incoming); 438 assert(fin != NULL); 439 assert(label != NULL); 440 assert(value != NULL); 441 442 label[0] = value[0] = '\0'; 443 if (feof(fin)) { 444 paranoid_free(incoming); 445 return (1); 446 } 447 for (fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin); 448 fgets(incoming, MAX_STR_LEN - 1, fin)) { 449 strip_spaces(incoming); 450 p = strchr(incoming, ' '); 451 if (strlen(incoming) < 3 || incoming[0] == '#' || !p) { 452 continue; 453 } 454 *(p++) = '\0'; 455 while (*p == ' ') { 456 p++; 457 } 458 strcpy(label, incoming); 459 strcpy(value, p); 460 paranoid_free(incoming); 461 return (0); 462 } 463 return (1); 476 464 } 477 465 … … 485 473 */ 486 474 #ifdef __FreeBSD__ 487 int load_raidtab_into_raidlist( struct raidlist_itself *raidlist, char *fname) 488 { 489 FILE*fin; 490 char *tmp; 491 int items; 492 493 malloc_string(tmp); 494 raidlist->spares.entries = 0; 495 raidlist->disks.entries = 0; 496 if (length_of_file(fname)<5) 497 { 498 log_it("Raidtab is very small or non-existent. Ignoring it."); 499 raidlist->entries=0; 500 paranoid_free(tmp); 501 return(0); 502 } 503 if (!(fin=fopen(fname,"r"))) 504 { 505 log_it("Cannot open raidtab"); 506 paranoid_free(tmp); 507 return(1); 508 } 509 items=0; 510 log_it("Loading raidtab..."); 511 while(!feof(fin)) 512 { 513 int argc; 514 char **argv = get_next_vinum_conf_line (fin, &argc); 515 if (!argv) break; 516 if (!strcmp (argv[0], "drive")) { 517 char *drivename, *devname; 518 if (argc < 4) continue; 519 drivename = argv[1]; 520 devname = get_option_val (argc, argv, "device"); 521 if (!devname) continue; 522 523 if (get_option_state (argc, argv, "hotspare")) { 524 strcpy (raidlist->spares.el [raidlist->spares.entries].name, drivename); 525 strcpy (raidlist->spares.el [raidlist->spares.entries].device, devname); 526 raidlist->spares.el [raidlist->spares.entries].index = raidlist->disks.entries; 527 raidlist->spares.entries++; 528 } else { 529 strcpy (raidlist->disks.el [raidlist->disks.entries].name, drivename); 530 strcpy (raidlist->disks.el [raidlist->disks.entries].device, devname); 531 raidlist->disks.el [raidlist->disks.entries].index = raidlist->disks.entries; 532 raidlist->disks.entries++; 533 } 534 } 535 else if (!strcmp (argv[0], "volume")) { 536 char *volname; 537 if (argc < 2) continue; 538 volname = argv[1]; 539 strcpy (raidlist->el [raidlist->entries].volname, volname); 540 raidlist->el [raidlist->entries].plexes = 0; 541 raidlist->entries++; 542 } 543 else if (!strcmp (argv[0], "plex")) { 544 int raidlevel, stripesize; 545 char *org = 0; 546 char ** tmp = 0; 547 if (argc < 3) continue; 548 org = get_option_val (argc, argv, "org"); 549 if (!org) continue; 550 if (strcmp (org, "concat")) { 551 tmp = get_option_vals (argc, argv, "org", 2); 552 if (tmp && tmp[1]) { 553 stripesize = (int) (size_spec (tmp[1]) / 1024); 554 } 555 else stripesize = 279; 556 } 557 else stripesize = 0; 558 559 if (!strcmp (org, "concat")) { 560 raidlevel = -1; 561 } 562 else if (!strcmp (org, "striped")) { 563 raidlevel = 0; 564 } 565 else if (!strcmp (org, "raid5")) { 566 raidlevel = 5; 567 } 568 else continue; 569 570 raidlist->el[raidlist->entries - 1].plex 571 [raidlist->el [raidlist->entries - 1].plexes].raidlevel = raidlevel; 572 raidlist->el[raidlist->entries - 1].plex 573 [raidlist->el [raidlist->entries - 1].plexes].stripesize = stripesize; 574 raidlist->el[raidlist->entries - 1].plex 575 [raidlist->el [raidlist->entries - 1].plexes].subdisks = 0; 576 raidlist->el[raidlist->entries - 1].plexes++; 577 } 578 else if ((!strcmp (argv[0], "sd")) || (!strcmp (argv[0], "subdisk"))) { 579 char *drive = 0; 580 if (argc < 3) continue; 581 drive = get_option_val (argc, argv, "drive"); 582 if (!drive) continue; 583 584 strcpy (raidlist->el [raidlist->entries - 1].plex 585 [raidlist->el [raidlist->entries - 1].plexes - 1].sd 586 [raidlist->el [raidlist->entries - 1].plex 587 [raidlist->el [raidlist->entries - 1].plexes - 1].subdisks].which_device, drive); 588 raidlist->el [raidlist->entries - 1].plex 589 [raidlist->el [raidlist->entries - 1].plexes - 1].subdisks++; 590 } 591 } 592 fclose(fin); 593 log_it("Raidtab loaded successfully."); 594 sprintf(tmp,"%d RAID devices in raidtab", raidlist->entries); 595 log_it(tmp); 596 paranoid_free(tmp); 597 return(0); 475 int load_raidtab_into_raidlist(struct raidlist_itself *raidlist, 476 char *fname) 477 { 478 FILE *fin; 479 char *tmp; 480 int items; 481 482 malloc_string(tmp); 483 raidlist->spares.entries = 0; 484 raidlist->disks.entries = 0; 485 if (length_of_file(fname) < 5) { 486 log_it("Raidtab is very small or non-existent. Ignoring it."); 487 raidlist->entries = 0; 488 paranoid_free(tmp); 489 return (0); 490 } 491 if (!(fin = fopen(fname, "r"))) { 492 log_it("Cannot open raidtab"); 493 paranoid_free(tmp); 494 return (1); 495 } 496 items = 0; 497 log_it("Loading raidtab..."); 498 while (!feof(fin)) { 499 int argc; 500 char **argv = get_next_vinum_conf_line(fin, &argc); 501 if (!argv) 502 break; 503 if (!strcmp(argv[0], "drive")) { 504 char *drivename, *devname; 505 if (argc < 4) 506 continue; 507 drivename = argv[1]; 508 devname = get_option_val(argc, argv, "device"); 509 if (!devname) 510 continue; 511 512 if (get_option_state(argc, argv, "hotspare")) { 513 strcpy(raidlist->spares.el[raidlist->spares.entries].name, 514 drivename); 515 strcpy(raidlist->spares.el[raidlist->spares.entries]. 516 device, devname); 517 raidlist->spares.el[raidlist->spares.entries].index = 518 raidlist->disks.entries; 519 raidlist->spares.entries++; 520 } else { 521 strcpy(raidlist->disks.el[raidlist->disks.entries].name, 522 drivename); 523 strcpy(raidlist->disks.el[raidlist->disks.entries].device, 524 devname); 525 raidlist->disks.el[raidlist->disks.entries].index = 526 raidlist->disks.entries; 527 raidlist->disks.entries++; 528 } 529 } else if (!strcmp(argv[0], "volume")) { 530 char *volname; 531 if (argc < 2) 532 continue; 533 volname = argv[1]; 534 strcpy(raidlist->el[raidlist->entries].volname, volname); 535 raidlist->el[raidlist->entries].plexes = 0; 536 raidlist->entries++; 537 } else if (!strcmp(argv[0], "plex")) { 538 int raidlevel, stripesize; 539 char *org = 0; 540 char **tmp = 0; 541 if (argc < 3) 542 continue; 543 org = get_option_val(argc, argv, "org"); 544 if (!org) 545 continue; 546 if (strcmp(org, "concat")) { 547 tmp = get_option_vals(argc, argv, "org", 2); 548 if (tmp && tmp[1]) { 549 stripesize = (int) (size_spec(tmp[1]) / 1024); 550 } else 551 stripesize = 279; 552 } else 553 stripesize = 0; 554 555 if (!strcmp(org, "concat")) { 556 raidlevel = -1; 557 } else if (!strcmp(org, "striped")) { 558 raidlevel = 0; 559 } else if (!strcmp(org, "raid5")) { 560 raidlevel = 5; 561 } else 562 continue; 563 564 raidlist->el[raidlist->entries - 1].plex 565 [raidlist->el[raidlist->entries - 1].plexes].raidlevel = 566 raidlevel; 567 raidlist->el[raidlist->entries - 568 1].plex[raidlist->el[raidlist->entries - 569 1].plexes].stripesize = 570 stripesize; 571 raidlist->el[raidlist->entries - 572 1].plex[raidlist->el[raidlist->entries - 573 1].plexes].subdisks = 0; 574 raidlist->el[raidlist->entries - 1].plexes++; 575 } else if ((!strcmp(argv[0], "sd")) 576 || (!strcmp(argv[0], "subdisk"))) { 577 char *drive = 0; 578 if (argc < 3) 579 continue; 580 drive = get_option_val(argc, argv, "drive"); 581 if (!drive) 582 continue; 583 584 strcpy(raidlist->el[raidlist->entries - 1].plex 585 [raidlist->el[raidlist->entries - 1].plexes - 1].sd 586 [raidlist->el[raidlist->entries - 1].plex 587 [raidlist->el[raidlist->entries - 1].plexes - 588 1].subdisks].which_device, drive); 589 raidlist->el[raidlist->entries - 590 1].plex[raidlist->el[raidlist->entries - 591 1].plexes - 1].subdisks++; 592 } 593 } 594 fclose(fin); 595 log_it("Raidtab loaded successfully."); 596 sprintf(tmp, "%d RAID devices in raidtab", raidlist->entries); 597 log_it(tmp); 598 paranoid_free(tmp); 599 return (0); 598 600 } 599 601 … … 601 603 #else 602 604 603 int load_raidtab_into_raidlist( struct raidlist_itself *raidlist, char *fname) 604 605 { 606 FILE *fin; 607 char *tmp; 608 char *label; 609 char *value; 610 int items; 611 int v; 612 613 malloc_string(tmp); 614 malloc_string(label); 615 malloc_string(value); 616 assert(raidlist!=NULL); 617 assert_string_is_neither_NULL_nor_zerolength(fname); 618 619 if ( length_of_file( fname ) < 5 ) 620 { 621 log_it( "Raidtab is very small or non-existent. Ignoring it." ); 622 raidlist->entries = 0; 623 paranoid_free(tmp); 624 paranoid_free(label); 625 paranoid_free(value); 626 return( 0 ); 627 } 628 if ( !( fin = fopen( fname, "r" ) ) ) 629 { 630 log_it( "Cannot open raidtab" ); 631 paranoid_free(tmp); 632 paranoid_free(label); 633 paranoid_free(value); 634 return( 1 ); 635 } 636 items = 0; 637 log_it( "Loading raidtab..." ); 638 get_next_raidtab_line( fin, label, value ); 639 while( !feof( fin ) ) 640 { 641 log_msg(1, "Looking for raid record #%d", items); 642 initialize_raidrec( &raidlist->el[items] ); 643 v = 0; 644 /* find the 'raiddev' entry, indicating the start of the block of info */ 645 while( !feof( fin ) && strcmp( label, "raiddev") ) 646 { 647 strcpy( raidlist->el[items].additional_vars.el[v].label, label ); 648 strcpy( raidlist->el[items].additional_vars.el[v].value, value ); 649 v++; 650 get_next_raidtab_line( fin, label, value ); 651 log_it( tmp ); 652 } 653 raidlist->el[items].additional_vars.entries = v; 654 if ( feof( fin ) ) 655 { 656 log_msg(1, "No more records."); 657 continue; 658 } 659 log_msg(2, "Record #%d (%s) found", items, value); 660 strcpy( raidlist->el[items].raid_device, value ); 661 for( get_next_raidtab_line( fin, label, value); 662 !feof( fin ) && strcmp( label, "raiddev" ); 663 get_next_raidtab_line( fin, label, value ) ) 664 { 665 process_raidtab_line( fin, &raidlist->el[items], label, value ); 666 } 667 items++; 668 } 669 paranoid_fclose( fin ); 670 raidlist->entries = items; 671 log_msg(1, "Raidtab loaded successfully." ); 672 log_msg(1, "%d RAID devices in raidtab", items ); 673 paranoid_free(tmp); 674 paranoid_free(label); 675 paranoid_free(value); 676 return( 0 ); 605 int load_raidtab_into_raidlist(struct raidlist_itself *raidlist, 606 char *fname) 607 { 608 FILE *fin; 609 char *tmp; 610 char *label; 611 char *value; 612 int items; 613 int v; 614 615 malloc_string(tmp); 616 malloc_string(label); 617 malloc_string(value); 618 assert(raidlist != NULL); 619 assert_string_is_neither_NULL_nor_zerolength(fname); 620 621 if (length_of_file(fname) < 5) { 622 log_it("Raidtab is very small or non-existent. Ignoring it."); 623 raidlist->entries = 0; 624 paranoid_free(tmp); 625 paranoid_free(label); 626 paranoid_free(value); 627 return (0); 628 } 629 if (!(fin = fopen(fname, "r"))) { 630 log_it("Cannot open raidtab"); 631 paranoid_free(tmp); 632 paranoid_free(label); 633 paranoid_free(value); 634 return (1); 635 } 636 items = 0; 637 log_it("Loading raidtab..."); 638 get_next_raidtab_line(fin, label, value); 639 while (!feof(fin)) { 640 log_msg(1, "Looking for raid record #%d", items); 641 initialize_raidrec(&raidlist->el[items]); 642 v = 0; 643 /* find the 'raiddev' entry, indicating the start of the block of info */ 644 while (!feof(fin) && strcmp(label, "raiddev")) { 645 strcpy(raidlist->el[items].additional_vars.el[v].label, label); 646 strcpy(raidlist->el[items].additional_vars.el[v].value, value); 647 v++; 648 get_next_raidtab_line(fin, label, value); 649 log_it(tmp); 650 } 651 raidlist->el[items].additional_vars.entries = v; 652 if (feof(fin)) { 653 log_msg(1, "No more records."); 654 continue; 655 } 656 log_msg(2, "Record #%d (%s) found", items, value); 657 strcpy(raidlist->el[items].raid_device, value); 658 for (get_next_raidtab_line(fin, label, value); 659 !feof(fin) && strcmp(label, "raiddev"); 660 get_next_raidtab_line(fin, label, value)) { 661 process_raidtab_line(fin, &raidlist->el[items], label, value); 662 } 663 items++; 664 } 665 paranoid_fclose(fin); 666 raidlist->entries = items; 667 log_msg(1, "Raidtab loaded successfully."); 668 log_msg(1, "%d RAID devices in raidtab", items); 669 paranoid_free(tmp); 670 paranoid_free(label); 671 paranoid_free(value); 672 return (0); 677 673 } 678 674 #endif … … 694 690 */ 695 691 void 696 process_raidtab_line( FILE *fin, 697 struct raid_device_record *raidrec, 698 char *label, 699 char *value) 700 { 701 702 /*@ add mallocs **/ 703 char *tmp; 704 char *labelB; 705 char *valueB; 706 707 struct list_of_disks *disklist; 708 int index; 709 int v; 710 711 malloc_string(tmp); 712 malloc_string(labelB); 713 malloc_string(valueB); 714 assert(fin!=NULL); 715 assert(raidrec!=NULL); 716 assert_string_is_neither_NULL_nor_zerolength(label); 717 assert(value!=NULL); 718 719 if (!strcmp( label, "raid-level" ) ) 720 { 721 if (!strcmp( value, "linear" ) ) 722 { raidrec->raid_level = -1; 723 } 724 else 725 { 726 raidrec->raid_level = atoi(value); 727 } 728 } 729 else if (!strcmp(label,"nr-raid-disks") ) 730 { /* ignore it */ 731 } 732 else if (!strcmp(label,"nr-spare-disks")) 733 { /* ignore it */ 734 } 735 else if (!strcmp(label,"nr-parity-disks")) 736 { /* ignore it */ 737 } 738 else if (!strcmp(label,"nr-failed-disks")) 739 { /* ignore it */ 740 } 741 else if (!strcmp(label,"persistent-superblock")) 742 { 743 raidrec->persistent_superblock = atoi(value); 744 } 745 else if (!strcmp(label,"chunk-size")) 746 { 747 raidrec->chunk_size = atoi(value); 748 } 749 else if (!strcmp(label,"device")) 750 { 751 get_next_raidtab_line(fin,labelB,valueB); 752 if (!strcmp(labelB,"raid-disk")) 753 { 754 disklist=&raidrec->data_disks; 755 } 756 else if (!strcmp(labelB,"spare-disk")) 757 { 758 disklist=&raidrec->spare_disks; 759 } 760 else if (!strcmp(labelB,"parity-disk")) 761 { 762 disklist=&raidrec->parity_disks; 763 } 764 else if (!strcmp(labelB,"failed-disk")) 765 { 766 disklist=&raidrec->failed_disks; 767 } 768 else 769 { 770 disklist=NULL; 771 } 772 if (!disklist) 773 { 774 sprintf( tmp, 775 "Ignoring '%s %s' pair of disk %s",labelB,valueB,label); 776 log_it(tmp); 777 } 778 else 779 { 780 index = atoi(valueB); 781 add_disk_to_raid_device(disklist,value,index); 782 } 783 } 784 else 785 { 786 v = raidrec->additional_vars.entries; 787 strcpy(raidrec->additional_vars.el[v].label, label); 788 strcpy(raidrec->additional_vars.el[v].value, value); 789 raidrec->additional_vars.entries = ++v; 790 } 791 paranoid_free(tmp); 792 paranoid_free(labelB); 793 paranoid_free(valueB); 692 process_raidtab_line(FILE * fin, 693 struct raid_device_record *raidrec, 694 char *label, char *value) 695 { 696 697 /*@ add mallocs * */ 698 char *tmp; 699 char *labelB; 700 char *valueB; 701 702 struct list_of_disks *disklist; 703 int index; 704 int v; 705 706 malloc_string(tmp); 707 malloc_string(labelB); 708 malloc_string(valueB); 709 assert(fin != NULL); 710 assert(raidrec != NULL); 711 assert_string_is_neither_NULL_nor_zerolength(label); 712 assert(value != NULL); 713 714 if (!strcmp(label, "raid-level")) { 715 if (!strcmp(value, "linear")) { 716 raidrec->raid_level = -1; 717 } else { 718 raidrec->raid_level = atoi(value); 719 } 720 } else if (!strcmp(label, "nr-raid-disks")) { /* ignore it */ 721 } else if (!strcmp(label, "nr-spare-disks")) { /* ignore it */ 722 } else if (!strcmp(label, "nr-parity-disks")) { /* ignore it */ 723 } else if (!strcmp(label, "nr-failed-disks")) { /* ignore it */ 724 } else if (!strcmp(label, "persistent-superblock")) { 725 raidrec->persistent_superblock = atoi(value); 726 } else if (!strcmp(label, "chunk-size")) { 727 raidrec->chunk_size = atoi(value); 728 } else if (!strcmp(label, "device")) { 729 get_next_raidtab_line(fin, labelB, valueB); 730 if (!strcmp(labelB, "raid-disk")) { 731 disklist = &raidrec->data_disks; 732 } else if (!strcmp(labelB, "spare-disk")) { 733 disklist = &raidrec->spare_disks; 734 } else if (!strcmp(labelB, "parity-disk")) { 735 disklist = &raidrec->parity_disks; 736 } else if (!strcmp(labelB, "failed-disk")) { 737 disklist = &raidrec->failed_disks; 738 } else { 739 disklist = NULL; 740 } 741 if (!disklist) { 742 sprintf(tmp, 743 "Ignoring '%s %s' pair of disk %s", labelB, valueB, 744 label); 745 log_it(tmp); 746 } else { 747 index = atoi(valueB); 748 add_disk_to_raid_device(disklist, value, index); 749 } 750 } else { 751 v = raidrec->additional_vars.entries; 752 strcpy(raidrec->additional_vars.el[v].label, label); 753 strcpy(raidrec->additional_vars.el[v].value, value); 754 raidrec->additional_vars.entries = ++v; 755 } 756 paranoid_free(tmp); 757 paranoid_free(labelB); 758 paranoid_free(valueB); 794 759 } 795 760 #endif … … 802 767 * @param fout The stream to write to. 803 768 */ 804 void 805 save_disklist_to_file(char *listname, 806 struct list_of_disks *disklist, 807 FILE *fout) 808 { 809 int i; 810 811 assert_string_is_neither_NULL_nor_zerolength(listname); 812 assert(disklist!=NULL); 813 assert(fout!=NULL); 814 815 for(i = 0; i < disklist->entries; i++) 816 { 817 fprintf(fout," device %s\n",disklist->el[i].device); 818 fprintf(fout," %-21s %d\n",listname,disklist->el[i].index); 819 } 769 void 770 save_disklist_to_file(char *listname, 771 struct list_of_disks *disklist, FILE * fout) 772 { 773 int i; 774 775 assert_string_is_neither_NULL_nor_zerolength(listname); 776 assert(disklist != NULL); 777 assert(fout != NULL); 778 779 for (i = 0; i < disklist->entries; i++) { 780 fprintf(fout, " device %s\n", 781 disklist->el[i].device); 782 fprintf(fout, " %-21s %d\n", listname, disklist->el[i].index); 783 } 820 784 } 821 785 … … 831 795 * @param stripesize The stripe size (chunk size) of the new plex. 832 796 */ 833 void add_plex_to_volume(struct vinum_volume *v, int raidlevel, int stripesize) 834 { 835 v->plex[v->plexes].raidlevel = raidlevel; 836 v->plex[v->plexes].stripesize = stripesize; 837 v->plex[v->plexes].subdisks = 0; 838 ++v->plexes; 797 void add_plex_to_volume(struct vinum_volume *v, int raidlevel, 798 int stripesize) 799 { 800 v->plex[v->plexes].raidlevel = raidlevel; 801 v->plex[v->plexes].stripesize = stripesize; 802 v->plex[v->plexes].subdisks = 0; 803 ++v->plexes; 839 804 } 840 805 … … 842 807 * For internal use only. 843 808 */ 844 char ** get_next_vinum_conf_line (FILE *f, int *argc) 845 { 846 int cnt = 0; 847 static char *argv[64]; 848 char **ap; 849 char *line = (char *) malloc (MAX_STR_LEN); 850 if (!line) errx (1, "unable to allocate %i bytes of memory for `char *line' at %s:%i", 851 MAX_STR_LEN, __FILE__, __LINE__); 852 (void) fgets (line, MAX_STR_LEN, f); 853 if (feof (f)) { 854 log_it ("[GNVCL] Uh... I reached the EOF."); 809 char **get_next_vinum_conf_line(FILE * f, int *argc) 810 { 811 int cnt = 0; 812 static char *argv[64]; 813 char **ap; 814 char *line = (char *) malloc(MAX_STR_LEN); 815 if (!line) 816 errx(1, 817 "unable to allocate %i bytes of memory for `char *line' at %s:%i", 818 MAX_STR_LEN, __FILE__, __LINE__); 819 (void) fgets(line, MAX_STR_LEN, f); 820 if (feof(f)) { 821 log_it("[GNVCL] Uh... I reached the EOF."); 822 return 0; 823 } 824 825 for (ap = argv; (*ap = strsep(&line, " \t")) != NULL;) 826 if (**ap != '\0') { 827 if (++ap >= &argv[64]) 828 break; 829 cnt++; 830 } 831 832 if (strchr(argv[cnt - 1], '\n')) { 833 *(strchr(argv[cnt - 1], '\n')) = '\0'; 834 } 835 836 if (argc) 837 *argc = cnt; 838 return argv; 839 } 840 841 /** 842 * For internal use only. 843 */ 844 char *get_option_val(int argc, char **argv, char *option) 845 { 846 int i; 847 for (i = 0; i < (argc - 1); ++i) { 848 if (!strcmp(argv[i], option)) { 849 return argv[i + 1]; 850 } 851 } 855 852 return 0; 856 }857 858 for (ap = argv; (*ap = strsep (&line, " \t")) != NULL;)859 if (**ap != '\0') {860 if (++ap >= &argv[64])861 break;862 cnt++;863 }864 865 if (strchr (argv[cnt-1], '\n')) {866 *(strchr (argv[cnt-1], '\n')) = '\0';867 }868 869 if (argc) *argc = cnt;870 return argv;871 853 } 872 854 … … 874 856 * For internal use only. 875 857 */ 876 char * get_option_val (int argc, char ** argv, char * option) 877 { 878 int i; 879 for (i = 0; i < (argc - 1); ++i) { 880 if (!strcmp (argv[i], option)) { 881 return argv[i + 1]; 882 } 883 } 884 return 0; 858 char **get_option_vals(int argc, char **argv, char *option, int nval) 859 { 860 int i, j; 861 static char **ret; 862 ret = (char **) malloc(nval * sizeof(char *)); 863 for (i = 0; i < (argc - nval); ++i) { 864 if (!strcmp(argv[i], option)) { 865 for (j = 0; j < nval; ++j) { 866 ret[j] = (char *) malloc(strlen(argv[i + j + 1]) + 1); 867 strcpy(ret[j], argv[i + j + 1]); 868 } 869 return ret; 870 } 871 } 872 return 0; 885 873 } 886 874 … … 888 876 * For internal use only. 889 877 */ 890 char ** get_option_vals (int argc, char ** argv, char * option, int nval) 891 { 892 int i, j; 893 static char **ret; 894 ret = (char **) malloc (nval * sizeof (char *)); 895 for (i = 0; i < (argc - nval); ++i) { 896 if (!strcmp (argv[i], option)) { 897 for (j = 0; j < nval; ++j) { 898 ret[j] = (char *) malloc (strlen (argv[i + j + 1]) + 1); 899 strcpy (ret[j], argv[i + j + 1]); 900 } 901 return ret; 902 } 903 } 904 return 0; 905 } 906 907 /** 908 * For internal use only. 909 */ 910 bool get_option_state (int argc, char ** argv, char * option) 911 { 912 int i; 913 for (i = 0; i < argc; ++i) 914 if (!strcmp (argv[i], option)) 915 return TRUE; 916 917 return FALSE; 878 bool get_option_state(int argc, char **argv, char *option) 879 { 880 int i; 881 for (i = 0; i < argc; ++i) 882 if (!strcmp(argv[i], option)) 883 return TRUE; 884 885 return FALSE; 918 886 } 919 887 … … 923 891 long long size_spec(char *spec) 924 892 { 925 u_int64_t size; 926 char *s; 927 int sign = 1; /* -1 if negative */ 928 929 size = 0; 930 if (spec != NULL) { /* we have a parameter */ 931 s = spec; 932 if (*s == '-') { /* negative, */ 933 sign = -1; 934 s++; /* skip */ 935 } 936 if ((*s >= '0') && (*s <= '9')) { /* it's numeric */ 937 while ((*s >= '0') && (*s <= '9')) /* it's numeric */ 938 size = size * 10 + *s++ - '0'; /* convert it */ 939 switch (*s) { 940 case '\0': 941 return size * sign; 942 943 case 'B': 944 case 'b': 945 case 'S': 946 case 's': 947 return size * sign * 512; 948 949 case 'K': 950 case 'k': 951 return size * sign * 1024; 952 953 case 'M': 954 case 'm': 955 return size * sign * 1024 * 1024; 956 957 case 'G': 958 case 'g': 959 return size * sign * 1024 * 1024 * 1024; 960 961 case 'T': 962 case 't': 963 log_it ("Ok, I'm scared... Someone did a TERABYTE+ size-spec"); 964 return size * sign * 1024 * 1024 * 1024 * 1024; 965 966 case 'P': 967 case 'p': 968 log_it ("If I was scared last time, I'm freaked out now. Someone actually has a PETABYTE?!?!?!?!"); 969 return size * sign * 1024 * 1024 * 1024 * 1024 * 1024; 970 971 case 'E': 972 case 'e': 973 log_it ("Okay, I'm REALLY freaked out. Who could devote a whole EXABYTE to their data?!?!"); 974 return size * sign * 1024 * 1024 * 1024 * 1024 * 1024 * 1024; 975 976 case 'Z': 977 case 'z': 978 log_it ("WHAT!?!? A ZETABYTE!?!? You've GOT to be kidding me!!!"); 979 return size * sign * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024; 980 981 case 'Y': 982 case 'y': 983 log_it ("Oh my gosh. You actually think a YOTTABYTE will get you anywhere? What're you going to do with 1,208,925,819,614,629,174,706,176 bytes?!?!"); 984 popup_and_OK ("That sizespec is more than 1,208,925,819,614,629,174,706,176 bytes. You have a shocking amount of data. Please send a screenshot to the list :-)"); 985 return size * sign * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024; 986 } 987 } 988 } 989 return size * sign; 893 u_int64_t size; 894 char *s; 895 int sign = 1; /* -1 if negative */ 896 897 size = 0; 898 if (spec != NULL) { /* we have a parameter */ 899 s = spec; 900 if (*s == '-') { /* negative, */ 901 sign = -1; 902 s++; /* skip */ 903 } 904 if ((*s >= '0') && (*s <= '9')) { /* it's numeric */ 905 while ((*s >= '0') && (*s <= '9')) /* it's numeric */ 906 size = size * 10 + *s++ - '0'; /* convert it */ 907 switch (*s) { 908 case '\0': 909 return size * sign; 910 911 case 'B': 912 case 'b': 913 case 'S': 914 case 's': 915 return size * sign * 512; 916 917 case 'K': 918 case 'k': 919 return size * sign * 1024; 920 921 case 'M': 922 case 'm': 923 return size * sign * 1024 * 1024; 924 925 case 'G': 926 case 'g': 927 return size * sign * 1024 * 1024 * 1024; 928 929 case 'T': 930 case 't': 931 log_it 932 ("Ok, I'm scared... Someone did a TERABYTE+ size-spec"); 933 return size * sign * 1024 * 1024 * 1024 * 1024; 934 935 case 'P': 936 case 'p': 937 log_it 938 ("If I was scared last time, I'm freaked out now. Someone actually has a PETABYTE?!?!?!?!"); 939 return size * sign * 1024 * 1024 * 1024 * 1024 * 1024; 940 941 case 'E': 942 case 'e': 943 log_it 944 ("Okay, I'm REALLY freaked out. Who could devote a whole EXABYTE to their data?!?!"); 945 return size * sign * 1024 * 1024 * 1024 * 1024 * 1024 * 946 1024; 947 948 case 'Z': 949 case 'z': 950 log_it 951 ("WHAT!?!? A ZETABYTE!?!? You've GOT to be kidding me!!!"); 952 return size * sign * 1024 * 1024 * 1024 * 1024 * 1024 * 953 1024 * 1024; 954 955 case 'Y': 956 case 'y': 957 log_it 958 ("Oh my gosh. You actually think a YOTTABYTE will get you anywhere? What're you going to do with 1,208,925,819,614,629,174,706,176 bytes?!?!"); 959 popup_and_OK 960 ("That sizespec is more than 1,208,925,819,614,629,174,706,176 bytes. You have a shocking amount of data. Please send a screenshot to the list :-)"); 961 return size * sign * 1024 * 1024 * 1024 * 1024 * 1024 * 962 1024 * 1024 * 1024; 963 } 964 } 965 } 966 return size * sign; 990 967 } 991 968 … … 995 972 996 973 997 int read_mdstat(struct s_mdstat *mdstat, char*mdstat_file) 998 { 999 FILE*fin; 1000 char*tmp; 1001 char*stub; 1002 char*incoming; 1003 char*raid_devname; 1004 char*p, *q, *r; 1005 int diskno; 1006 1007 malloc_string(tmp); 1008 malloc_string(stub); 1009 malloc_string(incoming); 1010 malloc_string(raid_devname); 1011 if (!(fin = fopen(mdstat_file, "r"))) 1012 { 1013 log_msg(1, "%s not found", mdstat_file); 1014 return(1); 1015 } 1016 mdstat->entries = 0; 1017 for (fgets(incoming, MAX_STR_LEN - 1, fin); !feof(fin); fgets(incoming, MAX_STR_LEN - 1, fin)) 1018 { 1019 p = incoming; 1020 if (*p != 'm' && *(p+1) == 'm') { p++; } 1021 if (strncmp(p, "md", 2)) { continue; } 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); 990 return (1); 991 } 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 } 1022 1002 // read first line --- mdN : active raidX ............ 1023 mdstat->el[mdstat->entries].md = atoi(p+2); 1024 log_msg(8, "Storing /dev/md%d's info", atoi(p+2)); 1025 while(*p != ':' && *p) { p++; } 1026 while((*p!='r' || *(p+1)!='a') && *p) { p++; } 1027 if (!strncmp(p, "raid", 4)) 1028 { 1029 mdstat->el[mdstat->entries].raidlevel = *(p+4) - '0'; 1030 } 1031 p += 4; 1032 while(*p!=' '&& *p) { p++; } 1033 while(*p==' '&& *p) { p++; } 1034 for(diskno=0; *p; diskno++) 1035 { 1036 strcpy(stub, p); 1037 // log_msg(1, "diskno=%d; tmp=%s", diskno, tmp); 1038 q = strchr(stub, '['); 1039 if (q) 1040 { 1041 *q = '\0'; 1042 q++; 1043 r = strchr(q, ']'); 1044 if (r) { *r='\0'; } 1045 mdstat->el[mdstat->entries].disks.el[diskno].index = atoi(q); 1046 } 1047 else 1048 { 1049 mdstat->el[mdstat->entries].disks.el[diskno].index = -1; 1050 q = strchr(stub, ' '); 1051 if (q) { *q = '\0'; } 1052 } 1053 sprintf(tmp, "/dev/%s", stub); 1054 log_msg(8, "/dev/md%d : disk#%d : %s (%d)", mdstat->el[mdstat->entries].md, diskno, tmp, mdstat->el[mdstat->entries].disks.el[diskno].index); 1055 strcpy(mdstat->el[mdstat->entries].disks.el[diskno].device, tmp); 1056 while(*p!=' '&& *p) { p++; } 1057 while(*p==' '&& *p) { p++; } 1058 } 1059 mdstat->el[mdstat->entries].disks.entries = diskno; 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; 1060 1055 // next line --- skip it 1061 if (!feof(fin)) { fgets(incoming, MAX_STR_LEN - 1, fin); } else {continue; } 1056 if (!feof(fin)) { 1057 fgets(incoming, MAX_STR_LEN - 1, fin); 1058 } else { 1059 continue; 1060 } 1062 1061 // next line --- the 'progress' line 1063 if (!feof(fin)) { fgets(incoming, MAX_STR_LEN - 1, fin); } else {continue; } 1064 // log_msg(1, "Percentage line = '%s'", incoming); 1065 if (!(p=strchr(incoming, '\%'))) 1066 { 1067 mdstat->el[mdstat->entries].progress = 999; // not found 1068 } 1069 else if (strstr(incoming, "DELAYED")) 1070 { 1071 mdstat->el[mdstat->entries].progress = -1; // delayed (therefore, stuck at 0%) 1072 } 1073 else 1074 { 1075 for(*p='\0'; *p!=' '; p--); 1076 mdstat->el[mdstat->entries].progress = atoi(p); 1077 } 1078 log_msg(8, "progress =%d", mdstat->el[mdstat->entries].progress); 1079 mdstat->entries ++; 1080 } 1081 fclose(fin); 1082 paranoid_free(tmp); 1083 paranoid_free(stub); 1084 paranoid_free(incoming); 1085 paranoid_free(raid_devname); 1086 return(0); 1087 } 1088 1089 1090 1091 int create_raidtab_from_mdstat(char*raidtab_fname, char *mdstat_fname) 1092 { 1093 struct raidlist_itself *raidlist; 1094 struct s_mdstat *mdstat; 1095 int retval=0; 1096 int i; 1097 1098 raidlist = malloc(sizeof(struct raidlist_itself)); 1099 mdstat = malloc(sizeof(struct s_mdstat)); 1100 1101 if (read_mdstat(mdstat, mdstat_fname)) 1102 { log_to_screen("Sorry, cannot read %s", mdstat_fname); return(1); } 1103 1104 for(i=0; i<mdstat->entries; i++) 1105 { 1106 sprintf(raidlist->el[i].raid_device, "/dev/md%d", 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, (void*)&mdstat->el[i].disks, sizeof(struct list_of_disks)); 1111 // FIXME --- the above line does not allow for spare disks 1112 log_to_screen("FIXME - create_raidtab_from_mdstat does not allow for spare disks"); 1113 } 1114 raidlist->entries = i; 1115 retval += save_raidlist_to_raidtab(raidlist, raidtab_fname); 1116 return(retval); 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; 1118 retval += save_raidlist_to_raidtab(raidlist, raidtab_fname); 1119 return (retval); 1117 1120 } 1118 1121 … … 1120 1123 1121 1124 /* @} - end of raidGroup */ 1122
Note:
See TracChangeset
for help on using the changeset viewer.