Changeset 43 in MondoRescue for trunk/mondo/mondo/common/libmondo-raid.c


Ignore:
Timestamp:
Oct 4, 2005, 2:42:35 PM (19 years ago)
Author:
bcornec
Message:

asprintf + memory management on libmondo-raid.c

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$
    343*/
    35 
    364
    375/**
     
    5119#ifdef __FreeBSD__
    5220/* Nonstandard library functions: */
    53 extern void errx (int exitval, const char *fmt, ...);
    54 extern char *strsep (char **stringp, const char *delim);
     21extern void errx(int exitval, const char *fmt, ...);
     22extern char *strsep(char **stringp, const char *delim);
    5523#endif
    5624
    5725/*@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$";
    5927
    6028
     
    6937 * @return TRUE if it's supported, FALSE if not.
    7038 */
    71 bool
    72 is_this_raid_personality_registered (int raidno)
     39bool is_this_raid_personality_registered(int raidno)
    7340{
    7441#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;
    7644#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    }
    10362#endif
    10463}
    105 
    106 
    107 
    108 
    109 
    11064
    11165/**
     
    11670 */
    11771int
    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 
     72where_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}
    15092
    15193/**
     
    15698 */
    15799int
    158 which_raid_device_is_using_this_partition (struct raidlist_itself *raidlist,
    159                        char *device)
     100which_raid_device_is_using_this_partition(struct raidlist_itself *raidlist,
     101                                          char *device)
    160102{
    161103#ifdef __FreeBSD__
    162104// 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    }
    196133}
    197134
     
    200137// and one other function which FreeBSD doesn't use
    201138
    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    }
    230162}
    231163
     
    238170 */
    239171void
    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);
     172write_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);
    254185}
    255186#endif
    256 
    257 
    258 
    259 
    260 
    261 
    262 
    263187
    264188#ifdef __FreeBSD__
     
    268192 * @param device_to_add The device to add to @p p.
    269193 */
    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     ++p->subdisks;
     194void 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;
    274198
    275199}
     
    281205 * @param index The index number of the disklist entry we're creating.
    282206 */
    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;
     207void 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;
    294219}
    295220#endif
    296 
    297221
    298222/**
     
    301225 * @param fout The FILE pointer to save them to.
    302226 */
    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     }
     227void
     228save_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    }
    315240}
    316241
     
    323248 * @bug Return value is redundant.
    324249 */
    325 int
    326 save_raidlist_to_raidtab(struct raidlist_itself *raidlist, char *fname)
    327 {
    328   FILE *fout;
    329   int current_raid_device;
     250int save_raidlist_to_raidtab(struct raidlist_itself *raidlist, char *fname)
     251{
     252    FILE *fout;
     253    int current_raid_device;
    330254#ifdef __FreeBSD__
    331   int i;
     255    int i;
    332256#else
    333257// Linux
    334258#endif
    335259
    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");
    350273
    351274#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    }
    358284#endif
    359285
    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   paranoid_fclose(fout);
    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);
    366292}
    367293
     
    372298 * @param fout The stream to save it to.
    373299 */
    374 void
    375 save_raidrec_to_file( struct
     300void save_raidrec_to_file(struct
    376301#ifdef __FreeBSD__
    377 vinum_volume
     302                          vinum_volume
    378303#else
    379 raid_device_record
     304                          raid_device_record
    380305#endif
    381 *raidrec, FILE *fout )
     306                          * raidrec, FILE * fout)
    382307{
    383308#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    }
    404338#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");
    433368#endif
    434369}
     
    441376 * @return 0 if the line was read and stored successfully, 1 if we're at end of file.
    442377 */
    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 
     378int 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}
    478412
    479413
     
    485419 */
    486420#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);
     421int 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);
    598543}
    599544
     
    601546#else
    602547
    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 );
     548int 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);
    677610}
    678611#endif
    679 
    680 
    681 
    682 
    683 
    684 
    685612
    686613
     
    694621 */
    695622void
    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);
     623process_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);
    794689}
    795690#endif
     
    802697 * @param fout The stream to write to.
    803698 */
    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 
     699void
     700save_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}
    824715
    825716
     
    831722 * @param stripesize The stripe size (chunk size) of the new plex.
    832723 */
    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;
     724void 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;
    839731}
    840732
     
    842734 * For internal use only.
    843735 */
    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.");
     736char **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 */
     771char *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    }
    855779    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;
    871780}
    872781
     
    874783 * For internal use only.
    875784 */
    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;
     785char **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;
    885800}
    886801
     
    888803 * For internal use only.
    889804 */
    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;
     805bool 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;
    918813}
    919814
     
    923818long long size_spec(char *spec)
    924819{
    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;
    990894}
    991895
     
    995899
    996900
    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; }
     901int 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        }
    1022926// 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;
    1060979// 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        }
    1062985// 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
     1010int 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);
    11171041}
    11181042
     
    11201044
    11211045/* @} - end of raidGroup */
    1122 
Note: See TracChangeset for help on using the changeset viewer.