]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: Add device self-test SIGINT signal handling for wait option to abort
authorTokunori Ikegami <ikegami.t@gmail.com>
Fri, 27 Jan 2023 20:56:35 +0000 (05:56 +0900)
committerDaniel Wagner <dwagner@suse.de>
Mon, 30 Jan 2023 12:36:02 +0000 (13:36 +0100)
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
nvme.c

diff --git a/nvme.c b/nvme.c
index 8a9702e6be1b46c6d09a4306a80385cc68a0e707..832f79e3e7c354028ff8af43df195e59e1f13bf9 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -40,6 +40,7 @@
 #include <dirent.h>
 #include <libgen.h>
 #include <zlib.h>
+#include <signal.h>
 
 #ifdef CONFIG_LIBHUGETLBFS
 #include <hugetlbfs.h>
@@ -4162,6 +4163,24 @@ ret:
        return err;
 }
 
+static void intr_self_test(int signum)
+{
+       printf("\nInterrupted device self-test operation by %s\n", strsignal(signum));
+       errno = EINTR;
+}
+
+static int sleep_self_test(unsigned int seconds)
+{
+       errno = 0;
+
+       sleep(seconds);
+
+       if (errno)
+               return -errno;
+
+       return 0;
+}
+
 static const char dash[51] = {[0 ... 49] = '=', '\0'};
 static const char space[51] = {[0 ... 49] = ' ', '\0'};
 
@@ -4173,6 +4192,8 @@ static int wait_self_test(struct nvme_dev *dev)
        int err, i = 0, p = 0, cnt = 0;
        int wthr;
 
+       signal(SIGINT, intr_self_test);
+
        err = nvme_cli_identify_ctrl(dev, &ctrl);
        if (err) {
                fprintf(stderr, "identify-ctrl: %s\n", nvme_strerror(errno));
@@ -4185,7 +4206,9 @@ static int wait_self_test(struct nvme_dev *dev)
        while (true) {
                printf("\r[%.*s%c%.*s] %3d%%", p / 2, dash, spin[i % 4], 49 - p / 2, space, p);
                fflush(stdout);
-               sleep(1);
+               err = sleep_self_test(1);
+               if (err)
+                       return err;
 
                err = nvme_cli_get_log_device_self_test(dev, &log);
                if (err) {
@@ -4222,6 +4245,21 @@ static int wait_self_test(struct nvme_dev *dev)
        return 0;
 }
 
+static void abort_self_test(struct nvme_dev_self_test_args *args)
+{
+       int err;
+
+       args->stc = 0xf,
+
+       err = nvme_dev_self_test(args);
+       if (!err) {
+               printf("Aborting device self-test operation\n");
+       } else if (err > 0) {
+               nvme_show_status(err);
+       } else
+               fprintf(stderr, "Device self-test: %s\n", nvme_strerror(errno));
+}
+
 static int device_self_test(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        const char *desc  = "Implementing the device self-test feature"\
@@ -4308,6 +4346,9 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
                fprintf(stderr, "Device self-test: %s\n", nvme_strerror(errno));
 
 close_dev:
+       if (err == -EINTR)
+               abort_self_test(&args);
+
        dev_close(dev);
 ret:
        return err;