]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: sanitize: Allow sanitize action string values
authorTokunori Ikegami <ikegami.t@gmail.com>
Sun, 1 Jan 2023 15:32:35 +0000 (00:32 +0900)
committerTokunori Ikegami <ikegami.t@gmail.com>
Sun, 1 Jan 2023 15:32:35 +0000 (00:32 +0900)
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
nvme.c
util/argconfig.c
util/argconfig.h

diff --git a/nvme.c b/nvme.c
index 821237dd5cf9a1ecb983f65ab1f6a1891fdb823c..0015a8ebb7d2a6ff3684e8532461ca5d9ed153d0 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -4588,6 +4588,28 @@ ret:
        return err;
 }
 
+static int parse_sanact(char *str, __u8 *val)
+{
+       int len = strlen(str);
+
+       if (!strncasecmp(str, "exit-failure", len > 1 ? len : 1))
+               *val = NVME_SANITIZE_SANACT_EXIT_FAILURE;
+
+       if (!strncasecmp(str, "start-block-erase", len > 7 ? len : 7))
+               *val = NVME_SANITIZE_SANACT_START_BLOCK_ERASE;
+
+       if (!strncasecmp(str, "start-overwrite", len > 7 ? len : 7))
+               *val = NVME_SANITIZE_SANACT_START_OVERWRITE;
+
+       if (!strncasecmp(str, "start-crypto-erase", len > 7 ? len : 7))
+               *val = NVME_SANITIZE_SANACT_START_CRYPTO_ERASE;
+
+       if (*val)
+               return 0;
+
+       return argconfig_parse_byte("sanact", str, val);
+}
+
 static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        const char *desc = "Send a sanitize command.";
@@ -4599,13 +4621,14 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
        const char *ovrpat_desc = "Overwrite pattern.";
        struct nvme_dev *dev;
        int err;
+       __u8 sanact = 0;
 
        struct config {
                bool    no_dealloc;
                bool    oipbp;
                __u8    owpass;
                bool    ause;
-               __u8    sanact;
+               char    *sanact;
                __u32   ovrpat;
        };
 
@@ -4614,7 +4637,7 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
                .oipbp          = false,
                .owpass         = 0,
                .ause           = false,
-               .sanact         = 0,
+               .sanact         = NULL,
                .ovrpat         = 0,
        };
 
@@ -4623,7 +4646,7 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
                OPT_FLAG("oipbp",      'i', &cfg.oipbp,      oipbp_desc),
                OPT_BYTE("owpass",     'n', &cfg.owpass,     owpass_desc),
                OPT_FLAG("ause",       'u', &cfg.ause,       ause_desc),
-               OPT_BYTE("sanact",     'a', &cfg.sanact,     sanact_desc),
+               OPT_STR("sanact",      'a', &cfg.sanact,     sanact_desc),
                OPT_UINT("ovrpat",     'p', &cfg.ovrpat,     ovrpat_desc),
                OPT_END()
        };
@@ -4632,7 +4655,13 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
        if (err)
                goto ret;
 
-       switch (cfg.sanact) {
+       if (cfg.sanact) {
+               err = parse_sanact(cfg.sanact, &sanact);
+               if (err)
+                       goto close_dev;
+       }
+
+       switch (sanact) {
        case NVME_SANITIZE_SANACT_EXIT_FAILURE:
        case NVME_SANITIZE_SANACT_START_BLOCK_ERASE:
        case NVME_SANITIZE_SANACT_START_OVERWRITE:
@@ -4644,15 +4673,15 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
                goto close_dev;
        }
 
-       if (cfg.sanact == NVME_SANITIZE_SANACT_EXIT_FAILURE) {
-              if (cfg.ause || cfg.no_dealloc) {
+       if (sanact == NVME_SANITIZE_SANACT_EXIT_FAILURE) {
+               if (cfg.ause || cfg.no_dealloc) {
                        fprintf(stderr, "SANACT is Exit Failure Mode\n");
                        err = -EINVAL;
                        goto close_dev;
-              }
+               }
        }
 
-       if (cfg.sanact == NVME_SANITIZE_SANACT_START_OVERWRITE) {
+       if (sanact == NVME_SANITIZE_SANACT_START_OVERWRITE) {
                if (cfg.owpass > 16) {
                        fprintf(stderr, "OWPASS out of range [0-16]\n");
                        err = -EINVAL;
@@ -4668,7 +4697,7 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
 
        struct nvme_sanitize_nvm_args args = {
                .args_size      = sizeof(args),
-               .sanact         = cfg.sanact,
+               .sanact         = sanact,
                .ause           = cfg.ause,
                .owpass         = cfg.owpass,
                .oipbp          = cfg.oipbp,
index 2c328ffefd7a643479fa0a5a2adac3cdf40294ca..c5cf4a8b35944413f1de358f10a81d1fd63eb4af 100644 (file)
@@ -140,6 +140,23 @@ void argconfig_print_help(const char *program_desc,
                show_option(s);
 }
 
+int argconfig_parse_byte(const char *opt, const char *str, unsigned char *val)
+{
+       char *endptr;
+       unsigned long tmp = strtoul(str, &endptr, 0);
+
+       if (errno || tmp >= 1 << 8  || str == endptr) {
+               fprintf(stderr,
+                       "Expected byte argument for '%s' but got '%s'!\n", opt,
+                       str);
+               return -EINVAL;
+       }
+
+       *val = tmp;
+
+       return 0;
+}
+
 int argconfig_parse(int argc, char *argv[], const char *program_desc,
                    const struct argconfig_commandline_options *options)
 {
@@ -244,14 +261,9 @@ int argconfig_parse(int argc, char *argv[], const char *program_desc,
                        }
                        *((int *)value_addr) = tmp;
                } else if (s->config_type == CFG_BYTE) {
-                       unsigned long tmp = strtoul(optarg, &endptr, 0);
-                       if (errno || tmp >= (1 << 8)  || optarg == endptr) {
-                               fprintf(stderr,
-                                       "Expected byte argument for '%s' but got '%s'!\n",
-                                       long_opts[option_index].name, optarg);
+                       if (argconfig_parse_byte(long_opts[option_index].name,
+                                                optarg, (uint8_t *)value_addr))
                                goto out;
-                       }
-                       *((uint8_t *) value_addr) = tmp;
                } else if (s->config_type == CFG_SHORT) {
                        unsigned long tmp = strtoul(optarg, &endptr, 0);
                        if (errno || tmp >= (1 << 16) || optarg == endptr) {
index b66706a699d8b6ea2ad1e6f120b6d5a0ab63a94d..1017bbf60739a4e76d8e9a5e0b666adccfa03af8 100644 (file)
@@ -131,6 +131,7 @@ int argconfig_parse_comma_sep_array_short(char *string, unsigned short *ret,
 int argconfig_parse_comma_sep_array_long(char *string,
                                              unsigned long long *ret,
                                              unsigned max_length);
+int argconfig_parse_byte(const char *opt, const char *str, unsigned char *val);
 void argconfig_register_help_func(argconfig_help_func * f);
 
 void print_word_wrapped(const char *s, int indent, int start);