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