]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
feat: add timstamp support(Optional)
authordingjian <jian.ding@memblaze.com>
Thu, 27 Aug 2020 23:44:55 +0000 (07:44 +0800)
committerKeith Busch <kbusch@kernel.org>
Thu, 11 Feb 2021 18:13:03 +0000 (11:13 -0700)
1. Follow NVMe spec 1.4;
2. Change the code about feature id 0x0E;
3. Examples of commands using the -d option:
   3.1. date +"%s%3N" > timestamp.log
   3.2. sudo ./nvme set-feature /dev/nvme0 -f 0x0E -d timestamp.log
4. Examples of commands using the -v option:
   4.1. sudo ./nvme set-feature /dev/nvme0 -f 0x0E -v $[`date +"%s%3N"`]

Signed-off-by: dingjian <jian.ding@memblaze.com>
nvme.c

diff --git a/nvme.c b/nvme.c
index 5324e8bbe79f4c959e8778e9b29c277a35a5d486..66f40dface44077d5878d119c7268676e89b4f8a 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -3242,6 +3242,11 @@ ret:
        return nvme_status_to_errno(err, false);
 }
 
+#define STRTOUL_AUTO_BASE              (0)
+#define NVME_FEAT_LBA_RANGE_LEN        (4096)
+#define NVME_FEAT_TIMESTAMP_STR_LEN    (13)
+#define NVME_FEAT_TIMESTAMP_DATA_SIZE  (6)
+
 static int set_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        const char *desc = "Modify the saveable or changeable "\
@@ -3264,12 +3269,14 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
        __u32 result;
        void *buf = NULL;
        int fd, ffd = STDIN_FILENO;
+       char *endptr = NULL;
+       long int number = 0;
 
        struct config {
                char *file;
                __u32 namespace_id;
                __u8  feature_id;
-               __u32 value;
+               __u64 value;
                __u32 cdw12;
                __u32 data_len;
                int   save;
@@ -3287,7 +3294,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
        OPT_ARGS(opts) = {
                OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
                OPT_UINT("feature-id",   'f', &cfg.feature_id,   feature_id),
-               OPT_UINT("value",        'v', &cfg.value,        value),
+               OPT_LONG("value",        'v', &cfg.value,        value),
                OPT_UINT("cdw12",        'c', &cfg.cdw12,        cdw12),
                OPT_UINT("data-len",     'l', &cfg.data_len,     data_len),
                OPT_FILE("data",         'd', &cfg.file,         data),
@@ -3316,8 +3323,14 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
                err = -EINVAL;
                goto close_fd;
        }
-       if (cfg.feature_id == NVME_FEAT_LBA_RANGE)
-               cfg.data_len = 4096;
+
+    if (NVME_FEAT_LBA_RANGE == cfg.feature_id) {
+        cfg.data_len = NVME_FEAT_LBA_RANGE_LEN;
+    }
+    else if (NVME_FEAT_TIMESTAMP == cfg.feature_id) {
+        cfg.data_len = NVME_FEAT_TIMESTAMP_STR_LEN;
+    }
+
        if (cfg.data_len) {
                if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
                        fprintf(stderr, "can not allocate feature payload\n");
@@ -3328,22 +3341,34 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
        }
 
        if (buf) {
-               if (strlen(cfg.file)) {
-                       ffd = open(cfg.file, O_RDONLY);
-                       if (ffd <= 0) {
-                               fprintf(stderr, "Failed to open file %s: %s\n",
-                                               cfg.file, strerror(errno));
-                               err = -EINVAL;
-                               goto free;
-                       }
-               }
-               err = read(ffd, (void *)buf, cfg.data_len);
-               if (err < 0) {
-                       err = -errno;
-                       fprintf(stderr, "failed to read data buffer from input"
-                                       " file: %s\n", strerror(errno));
-                       goto close_ffd;
-               }
+        if ((NVME_FEAT_TIMESTAMP == cfg.feature_id) &&  (0 != cfg.value)) { //if feature ID is 0x0E, get timestamp value by -v option
+            cfg.data_len = NVME_FEAT_TIMESTAMP_DATA_SIZE;
+            memcpy(buf, &cfg.value, NVME_FEAT_TIMESTAMP_DATA_SIZE);
+        }
+        else {
+            if (strlen(cfg.file)) {
+                ffd = open(cfg.file, O_RDONLY);
+                if (ffd <= 0) {
+                    fprintf(stderr, "Failed to open file %s: %s\n",
+                    cfg.file, strerror(errno));
+                    err = -EINVAL;
+                    goto free;
+                }
+            }
+            err = read(ffd, (void *)buf, cfg.data_len);
+            if (err < 0) {
+                err = -errno;
+                fprintf(stderr, "failed to read data buffer from input"
+                " file: %s\n", strerror(errno));
+                goto close_ffd;
+            }
+            if (NVME_FEAT_TIMESTAMP == cfg.feature_id) { //if feature ID is 0x0E, then change string from file to integer
+                number = strtoul(buf, &endptr, STRTOUL_AUTO_BASE);
+                memset(buf, 0, cfg.data_len);
+                cfg.data_len = NVME_FEAT_TIMESTAMP_DATA_SIZE;
+                memcpy(buf, &number, NVME_FEAT_TIMESTAMP_DATA_SIZE);
+            }
+        }
        }
 
        err = nvme_set_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.value,
@@ -3351,7 +3376,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
        if (err < 0) {
                perror("set-feature");
        } else if (!err) {
-               printf("set-feature:%02x (%s), value:%#08x\n", cfg.feature_id,
+               printf("set-feature:%02x (%s), value:%#08llx\n", cfg.feature_id,
                        nvme_feature_to_string(cfg.feature_id), cfg.value);
                if (buf) {
                        if (cfg.feature_id == NVME_FEAT_LBA_RANGE)