From fa0129c0e24bd34217dcc9ac11362850470747ae Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Thu, 20 Dec 2018 16:32:35 +0900 Subject: [PATCH] nvme_perf: Fix the issue that PRCHK cannot be set by command line If user want to set PRCHK, current Perf tool requires user to add ',' as a prefix to PRCHK. This patch removes the limitation by referring /lib/nvme/nvme.c Change-Id: I327810b38c02116b9580873b6046bdca55b5162a Signed-off-by: Shuhei Matsumoto Reviewed-on: https://review.gerrithub.io/c/437913 Chandler-Test-Pool: SPDK Automated Test System Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris --- examples/nvme/perf/perf.c | 89 +++++++++++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/examples/nvme/perf/perf.c b/examples/nvme/perf/perf.c index d96e96e9a..9db10daa5 100644 --- a/examples/nvme/perf/perf.c +++ b/examples/nvme/perf/perf.c @@ -1245,29 +1245,90 @@ add_trid(const char *trid_str) return 0; } -static int -parse_metadata(const char *metacfg_str) +static size_t +parse_next_key(const char **str, char *key, char *val, size_t key_buf_size, + size_t val_buf_size) { const char *sep; + const char *separator = ", \t\n"; + size_t key_len, val_len; - if (strstr(metacfg_str, "PRACT=1") != NULL) { - g_metacfg_pract_flag = SPDK_NVME_IO_FLAGS_PRACT; - } + *str += strspn(*str, separator); - sep = strchr(metacfg_str, ','); + sep = strchr(*str, '='); if (!sep) { + fprintf(stderr, "Key without '=' separator\n"); return 0; } - if (strstr(sep, "PRCHK=") != NULL) { - if (strstr(sep, "GUARD") != NULL) { - g_metacfg_prchk_flags = SPDK_NVME_IO_FLAGS_PRCHK_GUARD; + key_len = sep - *str; + if (key_len >= key_buf_size) { + fprintf(stderr, "Key length %zu is greater than maximum allowed %zu\n", + key_len, key_buf_size - 1); + return 0; + } + + memcpy(key, *str, key_len); + key[key_len] = '\0'; + + *str += key_len + 1; /* Skip key */ + val_len = strcspn(*str, separator); + if (val_len == 0) { + fprintf(stderr, "Key without value\n"); + return 0; + } + + if (val_len >= val_buf_size) { + fprintf(stderr, "Value length %zu is greater than maximum allowed %zu\n", + val_len, val_buf_size - 1); + return 0; + } + + memcpy(val, *str, val_len); + val[val_len] = '\0'; + + *str += val_len; + + return val_len; +} + +static int +parse_metadata(const char *metacfg_str) +{ + const char *str; + size_t val_len; + char key[32]; + char val[1024]; + + if (metacfg_str == NULL) { + return -EINVAL; + } + + str = metacfg_str; + + while (*str != '\0') { + val_len = parse_next_key(&str, key, val, sizeof(key), sizeof(val)); + if (val_len == 0) { + fprintf(stderr, "Failed to parse metadata\n"); + return -EINVAL; } - if (strstr(sep, "REFTAG") != NULL) { - g_metacfg_prchk_flags |= SPDK_NVME_IO_FLAGS_PRCHK_REFTAG; - } - if (strstr(sep, "APPTAG") != NULL) { - g_metacfg_prchk_flags |= SPDK_NVME_IO_FLAGS_PRCHK_APPTAG; + + if (strcmp(key, "PRACT") == 0) { + if (*val == '1') { + g_metacfg_prchk_flags = SPDK_NVME_IO_FLAGS_PRACT; + } + } else if (strcmp(key, "PRCHK") == 0) { + if (strstr(val, "GUARD") != NULL) { + g_metacfg_prchk_flags |= SPDK_NVME_IO_FLAGS_PRCHK_GUARD; + } + if (strstr(val, "REFTAG") != NULL) { + g_metacfg_prchk_flags |= SPDK_NVME_IO_FLAGS_PRCHK_REFTAG; + } + if (strstr(val, "APPTAG") != NULL) { + g_metacfg_prchk_flags |= SPDK_NVME_IO_FLAGS_PRCHK_APPTAG; + } + } else { + fprintf(stderr, "Unknown key '%s'\n", key); } }