repost {PATCH} parser.c stronger

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



and parser.c not trashed by the wordwrap in my email client. doh.


diff -ur raidtools-1.00.3/parser.c raidtools-1.00.3+parser_stronger/parser.c
--- raidtools-1.00.3/parser.c   Wed Jan 15 08:58:25 2003
+++ raidtools-1.00.3+parser_stronger/parser.c   Wed Dec  3 20:12:50 2003
@@ -36,7 +36,7 @@

 static int process_entry (char *par, char *val_s)
 {
-       int val, i;
+       int val, i, j;
        md_raid_info_t *array;
        md_cfg_entry_t *last;

@@ -68,6 +68,10 @@
                }
                strcpy(cfg->md_name, val_s);
                cfg->array.param.nr_disks = 0;
+               cfg->array.param.level = -9;
+               cfg->array.param.layout = -1;
+               cfg->array.param.raid_disks = -1;
+               cfg->array.param.spare_disks = -1;

                last = cfg_head;
                while (last && last->next) last = last->next;
@@ -101,37 +105,43 @@
                        fprintf(stderr, "raid level %d not supported\n", val);
                        return 1;
                }
-               array->param.level = val;
-               if ((val == 0) || (val == -1))
-                       array->param.not_persistent = 1;
-               else
-                       array->param.not_persistent = 0;
-               return 0;
+               if (array->param.level == -9) {
+                       array->param.level = val;
+                       if ((val == 0) || (val == -1))
+                               array->param.not_persistent = 1;
+                       else
+                               array->param.not_persistent = 0;
+                       return 0;
+               } else {
+                       fprintf(stderr, "raid-level defined twice in %s\n", cfg->md_name);
+                       return 1;
+               }
        } else if (strcmp(par, "nr-raid-disks") == 0) {
                if (val < 0)
                        return 1;
-               array->param.raid_disks = val;
-               return 0;
+               if (array->param.raid_disks < 0) {
+                       array->param.raid_disks = val;
+                       return 0;
+               } else {
+                       fprintf(stderr, "nr-raid-disks defined twice in %s\n", cfg->md_name);
+                       return 1;
+               }
        } else if (strcmp(par, "persistent-superblock") == 0) {
                if ((val < 0) || (val > 1))
                        return 1;
                array->param.not_persistent = 1-val;
                return 0;
        } else if (strcmp(par, "nr-spare-disks") == 0) {
-               if ((array->param.level < 1) && (array->param.level != -4) && val) {
-                       fprintf(stderr, "nr-spare-disks must be zero for raid level %d\n", array->param.level);
-                       return 1;
-               }
-
                if (val < 0)
                        return 1;
-               array->param.spare_disks = val;
-               return 0;
-       } else if (strcmp(par, "parity-algorithm") == 0) {
-               if (array->param.level != 5) {
-                       fprintf(stderr, "parity-algorithm undefined for raid level %d\n", array->param.level);
+               if (array->param.spare_disks < 0) {
+                       array->param.spare_disks = val;
+                       return 0;
+               } else {
+                       fprintf(stderr, "nr-spare-disks defined twice in %s\n", cfg->md_name);
                        return 1;
                }
+       } else if (strcmp(par, "parity-algorithm") == 0) {
                if (val < 0)
                        val = parity_algorithm_to_num(val_s);
                if (val < 0)
@@ -139,6 +149,10 @@
                array->param.layout = val;
                return 0;
        } else if (strcmp(par, "chunk-size") == 0) {
+               if (array->param.chunk_size) {
+                       fprintf(stderr, "chunk-size defined twice in %s\n", cfg->md_name);
+                       return 1;
+               }
                if (!val || val % 4 || ((1 << (ffs(val)-1)) != val)) {
                        fprintf(stderr, "invalid chunk-size (%dkB)\n", val);
                        return 1;
@@ -151,38 +165,84 @@
                        return 1;
                }
                i = array->param.nr_disks++;
+               i--;
+               if ((i > 0) && (array->disks[i].raid_disk == -1)) {
+                       fprintf(stderr, "disk index line expected\n");
+                       return 1;
+               }
+               i++;
                if ((cfg->device_name[i] = malloc(strlen(val_s) + 1)) == NULL) {
                        fprintf(stderr, "out of memory\n");
                        return 1;
                }
                strcpy(cfg->device_name[i], val_s);
-               array->disks[i].raid_disk = i;
+               array->disks[i].raid_disk = -1;
                return 0;
        } else if (strcmp(par, "raid-disk") == 0) {
+               if (array->param.level == -9) {
+                       fprintf(stderr, "raid-level not defined before disks in %s\n", cfg->md_name);
+                       return 1;
+               }
+               if (array->param.raid_disks == -1) {
+                       fprintf(stderr, "nr-raid-disks not defined before disks in %s\n", cfg->md_name);
+                       return 1;
+               }
                if (!array->param.nr_disks) {
                        fprintf(stderr, "\"device\" line expected\n");
                        return 1;
                }
-               if (val >= array->param.raid_disks) {
-                       fprintf(stderr, "raid-disk should be smaller than raid_disks\n");
+               if ((val < 0 ) || (val >= array->param.raid_disks)) {
+                       fprintf(stderr, "bad raid-disk index %d\n", val);
                        return 1;
                }
                i = array->param.nr_disks - 1;
+               if (array->disks[i].raid_disk != -1) {
+                       fprintf(stderr, "\"device\" line expected\n");
+                       return 1;
+               }
                array->disks[i].raid_disk = val;
                return 0;
        } else if (strcmp(par, "spare-disk") == 0) {
+               if (array->param.level == -9) {
+                       fprintf(stderr, "raid-level not defined before disks in %s\n", cfg->md_name);
+                       return 1;
+               }
+               if (array->param.raid_disks == -1) {
+                       fprintf(stderr, "nr-raid-disks not defined before disks in %s\n", cfg->md_name);
+                       return 1;
+               }
                if ((array->param.level != 5) && (array->param.level != 4) && (array->param.level != 1) && (array->param.level != -4)) {
                        fprintf(stderr, "spare-disk not supported for raid level %d\n", array->param.level);
                        return 1;
                }
+               if (array->param.spare_disks < 1) {
+                       fprintf(stderr, "spare-disk defined but none expected for %s\n", cfg->md_name);
+                       return 1;
+               }
                if (!array->param.nr_disks) {
                        fprintf(stderr, "\"device\" line expected\n");
                        return 1;
                }
+               if ((val < 0) || (val >= array->param.spare_disks)) {
+                       fprintf(stderr, "bad spare-disk index %d\n", val);
+                       return 1;
+               }
                i = array->param.nr_disks - 1;
-               array->disks[i].raid_disk = i;
+               if (array->disks[i].raid_disk != -1) {
+                       fprintf(stderr, "\"device\" line expected\n");
+                       return 1;
+               }
+               array->disks[i].raid_disk = array->param.raid_disks + val;
                return 0;
        } else if (strcmp(par, "parity-disk") == 0) {
+               if (array->param.level == -9) {
+                       fprintf(stderr, "raid-level not defined before disks in %s\n", cfg->md_name);
+                       return 1;
+               }
+               if (array->param.raid_disks == -1) {
+                       fprintf(stderr, "nr-raid-disks not defined before disks in %s\n", cfg->md_name);
+                       return 1;
+               }
                if (!array->param.nr_disks) {
                        fprintf(stderr, "\"device\" line expected\n");
                        return 1;
@@ -192,23 +252,116 @@
                        return 1;
                }
                i = array->param.nr_disks - 1;
+               if (array->disks[i].raid_disk != -1) {
+                       fprintf(stderr, "\"device\" line expected\n");
+                       return 1;
+               }
                array->disks[i].raid_disk = array->param.raid_disks - 1;
                return 0;
        } else if (strcmp(par, "failed-disk") == 0) {
+               if (array->param.level == -9) {
+                       fprintf(stderr, "raid-level not defined before disks in %s\n", cfg->md_name);
+                       return 1;
+               }
+               if (array->param.raid_disks == -1) {
+                       fprintf(stderr, "nr-raid-disks not defined before disks in %s\n", cfg->md_name);
+                       return 1;
+               }
                if ((array->param.level != 5) && (array->param.level != 4) && (array->param.level != 1)) {
                        fprintf(stderr, "failed-disk not supported for raid level %d\n", array->param.level);
                        return 1;
                }
-               if (val >= array->param.raid_disks) {
-                       fprintf(stderr, "failed-disk should be smaller than raid_disks\n");
+               if (!array->param.nr_disks) {
+                       fprintf(stderr, "\"device\" line expected\n");
+                       return 1;
+               }
+               if ((val < 0) || (val >= array->param.raid_disks)) {
+                       fprintf(stderr, "bad failed-disk index %d\n", val);
                        return 1;
                }
                i = array->param.nr_disks - 1;
+               if (array->disks[i].raid_disk != -1) {
+                       fprintf(stderr, "\"device\" line expected\n");
+                       return 1;
+               }
                array->disks[i].raid_disk = val;
                array->disks[i].state |= (1 << MD_DISK_FAULTY);
                array->param.failed_disks++;
                return 0;
-
+       } else if (strcmp(par, "verify-stanza") == 0) {
+               /*
+                * check for missing and incompatible options
+                * check each slot in array index has an entry
+                */
+/*             fprintf(stderr, "verifying stanza %s\n", cfg->md_name); */
+               if (array->param.spare_disks == -1)
+                       array->param.spare_disks = 0;
+               if (array->param.level == -9) {
+                       fprintf(stderr, "raid-level not defined in %s\n", cfg->md_name);
+                       return 1;
+               }
+               if (!array->param.chunk_size && (array->param.level != -1)) {
+                       fprintf(stderr, "chunk-size not defined in %s\n", cfg->md_name);
+                       return 1;
+               }
+               if (array->param.raid_disks < 0) {
+                       fprintf(stderr, "nr-raid-disks not defined in %s\n", cfg->md_name);
+                       return 1;
+               }
+               if ((array->param.level < 1) && (array->param.level != -4) && (array->param.spare_disks != 0)) {
+                       fprintf(stderr, "nr-spare-disks must be zero for raid level %d in %s\n", array->param.level, cfg->md_name);
+                       return 1;
+               }
+               if ((array->param.layout > -1) && (array->param.level != 5)) {
+                       fprintf(stderr, "parity-algorithm undefined for raid level %d in %s\n", array->param.level, cfg->md_name);
+                       return 1;
+               }
+               if ((array->param.level == 5) && (array->param.layout < 0)) {
+                       fprintf(stderr, "parity-algorithm required for raid level %d in %s\n", array->param.level, cfg->md_name);
+                       return 1;
+               }
+               if (array->param.nr_disks != array->param.raid_disks + array->param.spare_disks) {
+                       fprintf(stderr, "device entries does not match defined number of disks in %s\n", cfg->md_name);
+                       return 1;
+               }
+               for (i = 0; i < array->param.nr_disks - 1; i++) {
+                       par = cfg->device_name[i];
+                       val = array->disks[i].raid_disk;
+                       if (val == -1) {
+                               fprintf(stderr, "%s index not set in %s\n",
+                                               par, cfg->md_name);
+                               return 1;
+                       }
+                       for (j = i + 1; j < array->param.nr_disks; j++) {
+                               if (strcmp(par, cfg->device_name[j]) == 0) {
+                                       fprintf(stderr, "%s not unique in %s\n", par, cfg->md_name);
+                                       return 1;
+                               }
+                               if (val == array->disks[j].raid_disk) {
+                                       fprintf(stderr, "error in disk indexes in %s\n", cfg->md_name);
+                                       return 1;
+                               }
+                       }
+               }
+               /* check last item as loop does disks - 1 */
+               if (array->disks[i].raid_disk == -1) {
+                       fprintf(stderr, "%s index not set in %s\n", cfg->device_name[i], cfg->md_name);
+                       return 1;
+               }
+               /* sort devices as we allow any order in raidtab */
+               for (i = 0; i < array->param.nr_disks - 1; i++) {
+                       par = cfg->device_name[i];
+                       val = array->disks[i].raid_disk;
+                       while (val != i) {
+                               cfg->device_name[i] = cfg->device_name[val];
+                               array->disks[i].raid_disk = array->disks[val].raid_disk;
+                               cfg->device_name[val] = par;
+                               array->disks[val].raid_disk = val;
+                               par = cfg->device_name[i];
+                               val = array->disks[i].raid_disk;
+                       }
+               }
+               return 0;
        }
        fprintf(stderr, "unrecognized option %s\n", par);
        return 1;
@@ -216,7 +369,7 @@

 int parse_config (FILE *fp)
 {
-       int nr = 0;
+       int nr = 0, indevflag = 0;
        char line[MAX_LINE_LENGTH], par[MAX_LINE_LENGTH], val[MAX_LINE_LENGTH];

 #if DEBUG
@@ -236,11 +389,25 @@
 #if DEBUG
                printf("par == %s, val == %s\n", par, val);
 #endif /* DEBUG */
+               if (strcmp(par, "verify-stanza") == 0) {
+                       printf("detected error on line %d:\n\t%s", nr, line);
+                       return 1;
+               }
+               if (strcmp(par, "raiddev") == 0) {
+                       if (!indevflag) {
+                               indevflag++;
+                       } else {
+                               if (process_entry("verify-stanza", "0"))
+                                       return 1;
+                       }
+               }
                if (process_entry(par, val)) {
                        printf("detected error on line %d:\n\t%s", nr, line);
                        return 1;
                }
        }
+       if ((indevflag) && (process_entry("verify-stanza", "0")))
+               return 1;
 #if DEBUG
        printf("finished to parse configuration file\n");
 #endif /* DEBUG */



-
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux