]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdadm: Add option validation for --update-subarray
authorMateusz Kusiak <mateusz.kusiak@intel.com>
Mon, 2 Jan 2023 08:35:15 +0000 (09:35 +0100)
committerJes Sorensen <jes@trained-monkey.org>
Wed, 4 Jan 2023 15:20:58 +0000 (10:20 -0500)
Subset of options available for "--update" is not same as for "--update-subarray".
Define maps and enum for update options and use them instead of direct comparisons.
Add proper error message.

Signed-off-by: Mateusz Kusiak <mateusz.kusiak@intel.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
ReadMe.c
maps.c
mdadm.c
mdadm.h

index 50a5e36d05fc0f19955362dc93f2477ea186cd74..bd8d50d286618de0001700c88e5fc24cdcbf580e 100644 (file)
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -655,3 +655,34 @@ char *mode_help[mode_count] = {
        [GROW]          = Help_grow,
        [INCREMENTAL]   = Help_incr,
 };
+
+/**
+ * fprint_update_options() - Print valid update options depending on the mode.
+ * @outf: File (output stream)
+ * @update_mode: Used to distinguish update and update_subarray
+ */
+void fprint_update_options(FILE *outf, enum update_opt update_mode)
+{
+       int counter = UOPT_NAME, breakpoint = UOPT_HELP;
+       mapping_t *map = update_options;
+
+       if (!outf)
+               return;
+       if (update_mode == UOPT_SUBARRAY_ONLY) {
+               breakpoint = UOPT_SUBARRAY_ONLY;
+               fprintf(outf, "Valid --update options for update-subarray are:\n\t");
+       } else
+               fprintf(outf, "Valid --update options are:\n\t");
+       while (map->num) {
+               if (map->num >= breakpoint)
+                       break;
+               fprintf(outf, "'%s', ", map->name);
+               if (counter % 5 == 0)
+                       fprintf(outf, "\n\t");
+               counter++;
+               map++;
+       }
+       if ((counter - 1) % 5)
+               fprintf(outf, "\n");
+       fprintf(outf, "\r");
+}
diff --git a/maps.c b/maps.c
index 20fcf719e5f7e732849df578be93a46609255d0e..b586679acc74dd9428eac44ad62cb69a003a1ad4 100644 (file)
--- a/maps.c
+++ b/maps.c
@@ -165,6 +165,37 @@ mapping_t sysfs_array_states[] = {
        { "broken", ARRAY_BROKEN },
        { NULL, ARRAY_UNKNOWN_STATE }
 };
+/**
+ * mapping_t update_options - stores supported update options.
+ */
+mapping_t update_options[] = {
+       { "name", UOPT_NAME },
+       { "ppl", UOPT_PPL },
+       { "no-ppl", UOPT_NO_PPL },
+       { "bitmap", UOPT_BITMAP },
+       { "no-bitmap", UOPT_NO_BITMAP },
+       { "sparc2.2", UOPT_SPARC22 },
+       { "super-minor", UOPT_SUPER_MINOR },
+       { "summaries", UOPT_SUMMARIES },
+       { "resync", UOPT_RESYNC },
+       { "uuid", UOPT_UUID },
+       { "homehost", UOPT_HOMEHOST },
+       { "home-cluster", UOPT_HOME_CLUSTER },
+       { "nodes", UOPT_NODES },
+       { "devicesize", UOPT_DEVICESIZE },
+       { "bbl", UOPT_BBL },
+       { "no-bbl", UOPT_NO_BBL },
+       { "force-no-bbl", UOPT_FORCE_NO_BBL },
+       { "metadata", UOPT_METADATA },
+       { "revert-reshape", UOPT_REVERT_RESHAPE },
+       { "layout-original", UOPT_LAYOUT_ORIGINAL },
+       { "layout-alternate", UOPT_LAYOUT_ALTERNATE },
+       { "layout-unspecified", UOPT_LAYOUT_UNSPECIFIED },
+       { "byteorder", UOPT_BYTEORDER },
+       { "help", UOPT_HELP },
+       { "?", UOPT_HELP },
+       { NULL, UOPT_UNDEFINED}
+};
 
 /**
  * map_num_s() - Safer alternative of map_num() function.
diff --git a/mdadm.c b/mdadm.c
index 74fdec31aa8f527cce10f3a62d3846b3c070c7de..f5f505fe80d780578727cc2af768ce3231ace7cb 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -100,7 +100,7 @@ int main(int argc, char *argv[])
        char *dump_directory = NULL;
 
        int print_help = 0;
-       FILE *outf;
+       FILE *outf = NULL;
 
        int mdfd = -1;
        int locked = 0;
@@ -723,7 +723,11 @@ int main(int argc, char *argv[])
                        continue;
 
                case O(ASSEMBLE,'U'): /* update the superblock */
-               case O(MISC,'U'):
+               case O(MISC,'U'): {
+                       enum update_opt updateopt = map_name(update_options, c.update);
+                       enum update_opt print_mode = UOPT_HELP;
+                       const char *error_addon = "update option";
+
                        if (c.update) {
                                pr_err("Can only update one aspect of superblock, both %s and %s given.\n",
                                        c.update, optarg);
@@ -733,83 +737,37 @@ int main(int argc, char *argv[])
                                pr_err("Only subarrays can be updated in misc mode\n");
                                exit(2);
                        }
+
                        c.update = optarg;
-                       if (strcmp(c.update, "sparc2.2") == 0)
-                               continue;
-                       if (strcmp(c.update, "super-minor") == 0)
-                               continue;
-                       if (strcmp(c.update, "summaries") == 0)
-                               continue;
-                       if (strcmp(c.update, "resync") == 0)
-                               continue;
-                       if (strcmp(c.update, "uuid") == 0)
-                               continue;
-                       if (strcmp(c.update, "name") == 0)
-                               continue;
-                       if (strcmp(c.update, "homehost") == 0)
-                               continue;
-                       if (strcmp(c.update, "home-cluster") == 0)
-                               continue;
-                       if (strcmp(c.update, "nodes") == 0)
-                               continue;
-                       if (strcmp(c.update, "devicesize") == 0)
-                               continue;
-                       if (strcmp(c.update, "bitmap") == 0)
-                               continue;
-                       if (strcmp(c.update, "no-bitmap") == 0)
-                               continue;
-                       if (strcmp(c.update, "bbl") == 0)
-                               continue;
-                       if (strcmp(c.update, "no-bbl") == 0)
-                               continue;
-                       if (strcmp(c.update, "force-no-bbl") == 0)
-                               continue;
-                       if (strcmp(c.update, "ppl") == 0)
-                               continue;
-                       if (strcmp(c.update, "no-ppl") == 0)
-                               continue;
-                       if (strcmp(c.update, "metadata") == 0)
-                               continue;
-                       if (strcmp(c.update, "revert-reshape") == 0)
-                               continue;
-                       if (strcmp(c.update, "layout-original") == 0 ||
-                           strcmp(c.update, "layout-alternate") == 0 ||
-                           strcmp(c.update, "layout-unspecified") == 0)
-                               continue;
-                       if (strcmp(c.update, "byteorder") == 0) {
+
+                       if (devmode == UpdateSubarray) {
+                               print_mode = UOPT_SUBARRAY_ONLY;
+                               error_addon = "update-subarray option";
+
+                               if (updateopt > UOPT_SUBARRAY_ONLY && updateopt < UOPT_HELP)
+                                       updateopt = UOPT_UNDEFINED;
+                       }
+
+                       switch (updateopt) {
+                       case UOPT_UNDEFINED:
+                               pr_err("'--update=%s' is invalid %s. ",
+                                       c.update, error_addon);
+                               outf = stderr;
+                       case UOPT_HELP:
+                               if (!outf)
+                                       outf = stdout;
+                               fprint_update_options(outf, print_mode);
+                               exit(outf == stdout ? 0 : 2);
+                       case UOPT_BYTEORDER:
                                if (ss) {
                                        pr_err("must not set metadata type with --update=byteorder.\n");
                                        exit(2);
                                }
-                               for(i = 0; !ss && superlist[i]; i++)
-                                       ss = superlist[i]->match_metadata_desc(
-                                               "0.swap");
-                               if (!ss) {
-                                       pr_err("INTERNAL ERROR cannot find 0.swap\n");
-                                       exit(2);
-                               }
-
-                               continue;
+                       default:
+                               break;
                        }
-                       if (strcmp(c.update,"?") == 0 ||
-                           strcmp(c.update, "help") == 0) {
-                               outf = stdout;
-                               fprintf(outf, "%s: ", Name);
-                       } else {
-                               outf = stderr;
-                               fprintf(outf,
-                                       "%s: '--update=%s' is invalid.  ",
-                                       Name, c.update);
-                       }
-                       fprintf(outf, "Valid --update options are:\n"
-               "     'sparc2.2', 'super-minor', 'uuid', 'name', 'nodes', 'resync',\n"
-               "     'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n"
-               "     'bitmap', 'no-bitmap', 'metadata', 'revert-reshape'\n"
-               "     'bbl', 'no-bbl', 'force-no-bbl', 'ppl', 'no-ppl'\n"
-               "     'layout-original', 'layout-alternate', 'layout-unspecified'\n"
-                               );
-                       exit(outf == stdout ? 0 : 2);
-
+                       continue;
+               }
                case O(MANAGE,'U'):
                        /* update=devicesize is allowed with --re-add */
                        if (devmode != 'A') {
diff --git a/mdadm.h b/mdadm.h
index 23ffe97748ab147602a068f8ba671c312a143cf7..51f1db2dd8565f313b7e899f5384213bb580f8b4 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -497,6 +497,36 @@ enum special_options {
        ConsistencyPolicy,
 };
 
+enum update_opt {
+       UOPT_NAME = 1,
+       UOPT_PPL,
+       UOPT_NO_PPL,
+       UOPT_BITMAP,
+       UOPT_NO_BITMAP,
+       UOPT_SUBARRAY_ONLY,
+       UOPT_SPARC22,
+       UOPT_SUPER_MINOR,
+       UOPT_SUMMARIES,
+       UOPT_RESYNC,
+       UOPT_UUID,
+       UOPT_HOMEHOST,
+       UOPT_HOME_CLUSTER,
+       UOPT_NODES,
+       UOPT_DEVICESIZE,
+       UOPT_BBL,
+       UOPT_NO_BBL,
+       UOPT_FORCE_NO_BBL,
+       UOPT_METADATA,
+       UOPT_REVERT_RESHAPE,
+       UOPT_LAYOUT_ORIGINAL,
+       UOPT_LAYOUT_ALTERNATE,
+       UOPT_LAYOUT_UNSPECIFIED,
+       UOPT_BYTEORDER,
+       UOPT_HELP,
+       UOPT_UNDEFINED
+};
+extern void fprint_update_options(FILE *outf, enum update_opt update_mode);
+
 enum prefix_standard {
        JEDEC,
        IEC
@@ -777,7 +807,7 @@ extern char *map_num(mapping_t *map, int num);
 extern int map_name(mapping_t *map, char *name);
 extern mapping_t r0layout[], r5layout[], r6layout[],
        pers[], modes[], faultylayout[];
-extern mapping_t consistency_policies[], sysfs_array_states[];
+extern mapping_t consistency_policies[], sysfs_array_states[], update_options[];
 
 extern char *map_dev_preferred(int major, int minor, int create,
                               char *prefer);