]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
tree: Combine NVMe file descriptor into struct nvme_dev
authorJeremy Kerr <jk@codeconstruct.com.au>
Tue, 12 Jul 2022 06:55:34 +0000 (14:55 +0800)
committerDaniel Wagner <dwagner@suse.de>
Fri, 12 Aug 2022 06:50:51 +0000 (08:50 +0200)
Currently, our references to the nvme device are fragmented: we have the
device name and stat buf stored in the global nvme_dev, and then a
separate nvme device file descriptor passed between functions

This change moves the fd into the struct nvme_dev:

     struct nvme_dev {
    +        int fd;
             struct stat stat;
             const char *name;
     };

and changes parse_and_open to now populate a pointer to the dev on
successful return. Callers can now access the fd through dev->fd,
unifying this with the name and statbuf.

[At the moment, this just uses the global nvme_dev variable, but we'll
make that neater in a future change]

There are a large number of functions that use the fd directly, hence
the size of this patch. I've attempted to make this as atomic as
possible, but there are some call sites which warrant some reformatting
as we go here.

There may be some future opportunities to pass around the struct
nvme_dev * rather than the fd, but this change just implements the
minimal change to group our nvme device into the one struct.

Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
21 files changed:
nvme-rpmb.c
nvme.c
nvme.h
plugins/dera/dera-nvme.c
plugins/innogrit/innogrit-nvme.c
plugins/intel/intel-nvme.c
plugins/memblaze/memblaze-nvme.c
plugins/micron/micron-nvme.c
plugins/ocp/ocp-nvme.c
plugins/scaleflux/sfx-nvme.c
plugins/seagate/seagate-nvme.c
plugins/shannon/shannon-nvme.c
plugins/solidigm/solidigm-garbage-collection.c
plugins/solidigm/solidigm-latency-tracking.c
plugins/solidigm/solidigm-smart.c
plugins/toshiba/toshiba-nvme.c
plugins/transcend/transcend-nvme.c
plugins/virtium/virtium-nvme.c
plugins/wdc/wdc-nvme.c
plugins/ymtc/ymtc-nvme.c
plugins/zns/zns.c

index 8f6e6a0fa3b2e367f8f4b806f06650c77eebe758..b460510f9ab0b3a4005921f3e51c260c59a8acaa 100644 (file)
@@ -872,8 +872,9 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p
        unsigned char *msg_buf = NULL;
        unsigned int msg_size = 0;
        unsigned int key_size = 0;
-       int fd = -1, err = -1;
        struct nvme_id_ctrl ctrl;
+       struct nvme_dev *dev;
+       int err = -1;
 
        union ctrl_rpmbs_reg {
                struct {
@@ -886,11 +887,11 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p
                unsigned int rpmbs;
        } regs;
        
-       if ((fd = parse_and_open(argc, argv, desc, opts)) < 0)
-               return fd;
+       if ((err = parse_and_open(&dev, argc, argv, desc, opts)) < 0)
+               return err;
        
        /* before parsing  commands, check if controller supports any RPMB targets */
-       err = nvme_identify_ctrl(fd, &ctrl);
+       err = nvme_identify_ctrl(dev->fd, &ctrl);
        if (err)
                goto out;
        
@@ -959,13 +960,14 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p
        
        switch (cfg.opt) {
                case RPMB_REQ_READ_WRITE_CNTR:
-                       err = rpmb_read_write_counter(fd, cfg.target, &write_cntr);
+                       err = rpmb_read_write_counter(dev->fd, cfg.target,
+                                                     &write_cntr);
                        if (err == 0)
                                printf("Write Counter is: %u\n", write_cntr);
                        break;
        
                case RPMB_REQ_AUTH_DCB_READ:
-                       write_cntr = rpmb_read_config_block(fd, &msg_buf);
+                       write_cntr = rpmb_read_config_block(dev->fd, &msg_buf);
                        if (msg_buf == NULL) {
                                fprintf(stderr, "failed read config blk\n");
                                goto out;
@@ -997,8 +999,9 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p
                                        msg_size);
                                break;
                        }
-                       err = rpmb_auth_data_read(fd, cfg.target, cfg.address,
-                                                 &msg_buf, cfg.blocks,
+                       err = rpmb_auth_data_read(dev->fd, cfg.target,
+                                                 cfg.address, &msg_buf,
+                                                 cfg.blocks,
                                                  (regs.access_size + 1));
                        if (err > 0 && msg_buf != NULL) {
                                printf("Writting %d bytes to file %s\n",
@@ -1017,7 +1020,8 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p
                        } else if ((cfg.blocks * 512) < msg_size) {
                                msg_size = cfg.blocks * 512;
                        }
-                       err = rpmb_auth_data_write(fd, cfg.target, cfg.address,
+                       err = rpmb_auth_data_write(dev->fd, cfg.target,
+                                                  cfg.address,
                                                  ((regs.access_size + 1) * 512),
                                                   msg_buf, msg_size,
                                                   key_buf, key_size);
@@ -1028,11 +1032,13 @@ int rpmb_cmd_option(int argc, char **argv, struct command *cmd, struct plugin *p
                        break;
 
                case RPMB_REQ_AUTH_DCB_WRITE:
-                       err = rpmb_write_config_block(fd, msg_buf, key_buf, key_size);
+                       err = rpmb_write_config_block(dev->fd, msg_buf,
+                                                     key_buf, key_size);
                        break;
        
                case RPMB_REQ_AUTH_KEY_PROGRAM:
-                       err = rpmb_program_auth_key(fd, cfg.target, key_buf, key_size);
+                       err = rpmb_program_auth_key(dev->fd, cfg.target,
+                                                   key_buf, key_size);
                        break;
                default:
                        break;
@@ -1043,8 +1049,8 @@ out:
        free(key_buf);
        free(msg_buf);
        
-       /* close file descriptor */
-       close(fd);
+       /* close device */
+       dev_close(dev);
        
        return err;
 }
diff --git a/nvme.c b/nvme.c
index 025eb6fd93118778c113e68fc180de223c352083..86d624de13fd1c0bbeaa0b8057b826b1011a4727 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -218,10 +218,16 @@ static bool is_blkdev(void)
        return S_ISBLK(nvme_dev->stat.st_mode);
 }
 
-static int open_dev(char *dev, int flags)
+static int open_dev(struct nvme_dev **devp, char *dev, int flags)
 {
        int err, fd;
 
+       /* Temporary: we use the global nvme_dev pointer for the nvme device.
+        * This keeps the global in sync with the returned device. Later, we'll
+        * remove the global entirely and allocate here instead.
+        */
+       *devp = nvme_dev;
+
        nvme_dev->name = basename(dev);
        err = open(dev, flags);
        if (err < 0)
@@ -238,7 +244,8 @@ static int open_dev(char *dev, int flags)
                close(fd);
                return -ENODEV;
        }
-       return fd;
+       nvme_dev->fd = fd;
+       return 0;
 perror:
        perror(dev);
        return err;
@@ -254,7 +261,7 @@ static int check_arg_dev(int argc, char **argv)
        return 0;
 }
 
-static int get_dev(int argc, char **argv, int flags)
+static int get_dev(struct nvme_dev **dev, int argc, char **argv, int flags)
 {
        int ret;
 
@@ -262,11 +269,12 @@ static int get_dev(int argc, char **argv, int flags)
        if (ret)
                return ret;
 
-       return open_dev(argv[optind], flags);
+       return open_dev(dev, argv[optind], flags);
 }
 
-int parse_and_open(int argc, char **argv, const char *desc,
-       const struct argconfig_commandline_options *opts)
+int parse_and_open(struct nvme_dev **dev, int argc, char **argv,
+                  const char *desc,
+                  const struct argconfig_commandline_options *opts)
 {
        int ret;
 
@@ -274,21 +282,22 @@ int parse_and_open(int argc, char **argv, const char *desc,
        if (ret)
                return ret;
 
-       ret = get_dev(argc, argv, O_RDONLY);
+       ret = get_dev(dev, argc, argv, O_RDONLY);
        if (ret < 0)
                argconfig_print_help(desc, opts);
 
        return ret;
 }
 
-int open_exclusive(int argc, char **argv, int ignore_exclusive)
+int open_exclusive(struct nvme_dev **dev, int argc, char **argv,
+                  int ignore_exclusive)
 {
-    int flags = O_RDONLY;
+       int flags = O_RDONLY;
 
        if (!ignore_exclusive)
                flags |= O_EXCL;
 
-    return get_dev(argc, argv, flags);
+       return get_dev(dev, argc, argv, flags);
 }
 
 enum nvme_print_flags validate_output_format(const char *format)
@@ -304,6 +313,11 @@ enum nvme_print_flags validate_output_format(const char *format)
        return -EINVAL;
 }
 
+void dev_close(struct nvme_dev *dev)
+{
+       close(dev->fd);
+}
+
 static int get_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        struct nvme_smart_log smart_log;
@@ -314,7 +328,8 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
        const char *raw = "output in binary format";
        const char *human_readable = "show info in readable format";
        enum nvme_print_flags flags;
-       int err = -1, fd;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                __u32   namespace_id;
@@ -339,8 +354,8 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
@@ -351,7 +366,7 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
        if (cfg.human_readable)
                flags |= VERBOSE;
 
-       err = nvme_get_log_smart(fd, cfg.namespace_id, false, &smart_log);
+       err = nvme_get_log_smart(dev->fd, cfg.namespace_id, false, &smart_log);
        if (!err)
                nvme_show_smart_log(&smart_log, cfg.namespace_id,
                                    nvme_dev->name, flags);
@@ -360,7 +375,7 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug
        else
                fprintf(stderr, "smart log: %s\n", nvme_strerror(errno));
 close_fd:
-       close(fd);
+       dev_close(dev);
 ret:
        return err;
 }
@@ -372,11 +387,12 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
                            "decoded format (default), json or binary.";
        const char *groups = "Return ANA groups only.";
        void *ana_log;
-       int err = -1, fd;
        size_t ana_log_len;
        struct nvme_id_ctrl ctrl;
        enum nvme_print_flags flags;
        enum nvme_log_ana_lsp lsp;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                bool    groups;
@@ -394,15 +410,15 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
                goto close_fd;
 
-       err = nvme_identify_ctrl(fd, &ctrl);
+       err = nvme_identify_ctrl(dev->fd, &ctrl);
        if (err) {
                fprintf(stderr, "ERROR : nvme_identify_ctrl() failed: %s\n",
                        nvme_strerror(errno));
@@ -423,7 +439,7 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
        lsp = cfg.groups ? NVME_LOG_ANA_LSP_RGO_GROUPS_ONLY :
                NVME_LOG_ANA_LSP_RGO_NAMESPACES;
 
-       err = nvme_get_log_ana(fd, lsp, true, 0, ana_log_len, ana_log);
+       err = nvme_get_log_ana(dev->fd, lsp, true, 0, ana_log_len, ana_log);
        if (!err) {
                nvme_show_ana_log(ana_log, nvme_dev->name, flags, ana_log_len);
        } else if (err > 0)
@@ -432,7 +448,7 @@ static int get_ana_log(int argc, char **argv, struct command *cmd,
                fprintf(stderr, "ana-log: %s", nvme_strerror(errno));
        free(ana_log);
 close_fd:
-       close(fd);
+       dev_close(dev);
 ret:
        return err;
 }
@@ -446,10 +462,11 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
        const char *cgen = "Gather report generated by the controller.";
        const char *dgen = "Pick which telemetry data area to report. Default is 3 to fetch areas 1-3. Valid options are 1, 2, 3, 4.";
        struct nvme_telemetry_log *log;
-       int err = 0, fd, output;
+       int err = 0, output;
        size_t total_size;
        __u8 *data_ptr = NULL;
        int data_written = 0, data_remaining = 0;
+       struct nvme_dev *dev;
 
        struct config {
                char    *file_name;
@@ -472,14 +489,14 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (!cfg.file_name) {
                fprintf(stderr, "Please provide an output file!\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        cfg.host_gen = !!cfg.host_gen;
@@ -488,15 +505,18 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
                fprintf(stderr, "Failed to open output file %s: %s!\n",
                                cfg.file_name, strerror(errno));
                err = output;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.ctrl_init)
-               err = nvme_get_ctrl_telemetry(fd, true, &log, cfg.data_area, &total_size);
+               err = nvme_get_ctrl_telemetry(dev->fd, true, &log,
+                                             cfg.data_area, &total_size);
        else if (cfg.host_gen)
-               err = nvme_get_new_host_telemetry(fd, &log, cfg.data_area, &total_size);
+               err = nvme_get_new_host_telemetry(dev->fd, &log,
+                                                 cfg.data_area, &total_size);
        else
-               err = nvme_get_host_telemetry(fd, &log, cfg.data_area, &total_size);
+               err = nvme_get_host_telemetry(dev->fd, &log,
+                                             cfg.data_area, &total_size);
 
        if (err < 0) {
                fprintf(stderr, "get-telemetry-log: %s\n",
@@ -536,8 +556,8 @@ static int get_telemetry_log(int argc, char **argv, struct command *cmd,
 
 close_output:
        close(output);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -548,7 +568,8 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct
        const char *desc = "Retrieves endurance groups log page and prints the log.";
        const char *group_id = "The endurance group identifier";
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                char    *output_format;
@@ -566,15 +587,16 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
-       err = nvme_get_log_endurance_group(fd, cfg.group_id, &endurance_log);
+       err = nvme_get_log_endurance_group(dev->fd, cfg.group_id,
+                                          &endurance_log);
        if (!err)
                nvme_show_endurance_log(&endurance_log, cfg.group_id,
                                        nvme_dev->name, flags);
@@ -582,8 +604,8 @@ static int get_endurance_log(int argc, char **argv, struct command *cmd, struct
                nvme_show_status(err);
        else
                fprintf(stderr, "endurance log: %s\n", nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -617,10 +639,11 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
        const char *csi = "";
        struct list_head log_pages;
        nvme_effects_log_node_t *node;
+       struct nvme_dev *dev;
 
        void *bar = NULL;
 
-       int err = -1, fd;
+       int err = -1;
        enum nvme_print_flags flags;
 
        struct config {
@@ -645,13 +668,13 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
        if (cfg.human_readable)
@@ -669,7 +692,7 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
                nvme_free_tree(nvme_root);
 
                if (!bar) {
-                       goto close_fd;
+                       goto close_dev;
                }
                cap = mmio_read64(bar + NVME_REG_CAP);
                munmap(bar, getpagesize());
@@ -678,15 +701,15 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
                other_command_sets_supported = NVME_CAP_CSS(cap) & NVME_CAP_CSS_CSI;
 
                if (nvme_command_set_supported)
-                       err = collect_effects_log(fd, NVME_CSI_NVM,
+                       err = collect_effects_log(dev->fd, NVME_CSI_NVM,
                                                  &log_pages, flags);
 
                if (!err && other_command_sets_supported)
-                       err = collect_effects_log(fd, NVME_CSI_ZNS,
+                       err = collect_effects_log(dev->fd, NVME_CSI_ZNS,
                                                  &log_pages, flags);
 
        } else {
-               err = collect_effects_log(fd, cfg.csi, &log_pages, flags);
+               err = collect_effects_log(dev->fd, cfg.csi, &log_pages, flags);
        }
 
        if (!err)
@@ -696,10 +719,12 @@ static int get_effects_log(int argc, char **argv, struct command *cmd, struct pl
        else
                perror("effects log page");
 
-close_fd:
-       while ((node = list_pop(&log_pages, nvme_effects_log_node_t, node)))
+close_dev:
+       while ((node = list_pop(&log_pages, nvme_effects_log_node_t, node))) {
                free(node);
-       close(fd);
+       }
+
+       dev_close(dev);
 ret:
        return err;
 }
@@ -710,9 +735,9 @@ static int get_supported_log_pages(int argc, char **argv, struct command *cmd,
        const char *desc = "Retrieve supported logs and print the table.";
        const char *verbose = "Increase output verbosity";
        struct nvme_supported_log_pages supports;
-
-       int err = -1, fd;
        enum nvme_print_flags flags;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                char    *output_format;
@@ -730,18 +755,18 @@ static int get_supported_log_pages(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
        if (cfg.verbose)
                flags |= VERBOSE;
 
-       err = nvme_get_log_supported_log_pages(fd, false, &supports);
+       err = nvme_get_log_supported_log_pages(dev->fd, false, &supports);
        if (!err)
                nvme_show_supported_log(&supports, nvme_dev->name, flags);
        else if (err > 0)
@@ -750,8 +775,8 @@ static int get_supported_log_pages(int argc, char **argv, struct command *cmd,
                fprintf(stderr, "supported log pages: %s",
                        nvme_strerror(errno));
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -766,7 +791,8 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
        struct nvme_error_log_page *err_log;
        struct nvme_id_ctrl ctrl;
        enum nvme_print_flags flags;
-       int err = -1, fd;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                __u32   log_entries;
@@ -787,40 +813,40 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
 
        if (!cfg.log_entries) {
                fprintf(stderr, "non-zero log-entries is required param\n");
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_identify_ctrl(fd, &ctrl);
+       err = nvme_identify_ctrl(dev->fd, &ctrl);
        if (err < 0) {
                perror("identify controller");
-               goto close_fd;
+               goto close_dev;
        } else if (err) {
                fprintf(stderr, "could not identify controller\n");
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
 
        cfg.log_entries = min(cfg.log_entries, ctrl.elpe + 1);
        err_log = calloc(cfg.log_entries, sizeof(struct nvme_error_log_page));
        if (!err_log) {
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_get_log_error(fd, cfg.log_entries, false, err_log);
+       err = nvme_get_log_error(dev->fd, cfg.log_entries, false, err_log);
        if (!err)
                nvme_show_error_log(err_log, cfg.log_entries,
                                    nvme_dev->name, flags);
@@ -829,8 +855,8 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
        else
                perror("error log");
        free(err_log);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -842,7 +868,8 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin
        const char *raw = "use binary output";
        struct nvme_firmware_slot fw_log;
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                char    *output_format;
@@ -860,25 +887,25 @@ static int get_fw_log(int argc, char **argv, struct command *cmd, struct plugin
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
 
-       err = nvme_get_log_fw_slot(fd, false, &fw_log);
+       err = nvme_get_log_fw_slot(dev->fd, false, &fw_log);
        if (!err)
                nvme_show_fw_log(&fw_log, nvme_dev->name, flags);
        else if (err > 0)
                nvme_show_status(err);
        else
                fprintf(stderr, "fw log: %s\n", nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -891,7 +918,8 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s
        const char *raw = "output in binary format";
        struct nvme_ns_list changed_ns_list_log;
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                char    *output_format;
@@ -909,17 +937,17 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
 
-       err = nvme_get_log_changed_ns_list(fd, true, &changed_ns_list_log);
+       err = nvme_get_log_changed_ns_list(dev->fd, true, &changed_ns_list_log);
        if (!err)
                nvme_show_changed_ns_list_log(&changed_ns_list_log,
                                              nvme_dev->name, flags);
@@ -928,8 +956,8 @@ static int get_changed_ns_list_log(int argc, char **argv, struct command *cmd, s
        else
                fprintf(stderr, "changed ns list log: %s\n",
                        nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -944,7 +972,8 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv,
        const char *raw = "use binary output";
        struct nvme_nvmset_predictable_lat_log plpns_log;
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u16   nvmset_id;
@@ -965,17 +994,18 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
 
-       err = nvme_get_log_predictable_lat_nvmset(fd, cfg.nvmset_id, &plpns_log);
+       err = nvme_get_log_predictable_lat_nvmset(dev->fd, cfg.nvmset_id,
+                                                 &plpns_log);
        if (!err)
                nvme_show_predictable_latency_per_nvmset(&plpns_log,
                        cfg.nvmset_id, nvme_dev->name, flags);
@@ -985,8 +1015,8 @@ static int get_pred_lat_per_nvmset_log(int argc, char **argv,
                fprintf(stderr, "predictable latency per nvm set: %s\n",
                        nvme_strerror(errno));
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -1004,9 +1034,10 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
        const char *raw = "use binary output";
        enum nvme_print_flags flags;
        struct nvme_id_ctrl ctrl;
+       struct nvme_dev *dev;
        __u32 log_size;
        void *pea_log;
-       int err, fd;
+       int err;
 
        struct config {
                __u64   log_entries;
@@ -1030,30 +1061,30 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
 
        if (!cfg.log_entries) {
                fprintf(stderr, "non-zero log-entries is required param\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_identify_ctrl(fd, &ctrl);
+       err = nvme_identify_ctrl(dev->fd, &ctrl);
        if (err < 0) {
                fprintf(stderr, "identify controller: %s\n",
                        nvme_strerror(errno));
-               goto close_fd;
+               goto close_dev;
        } else if (err) {
                nvme_show_status(err);
-               goto close_fd;
+               goto close_dev;
        }
 
        cfg.log_entries = min(cfg.log_entries, le32_to_cpu(ctrl.nsetidmax));
@@ -1061,10 +1092,11 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
        pea_log = calloc(log_size, 1);
        if (!pea_log) {
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_get_log_predictable_lat_event(fd, cfg.rae, 0, log_size, pea_log);
+       err = nvme_get_log_predictable_lat_event(dev->fd, cfg.rae, 0, log_size,
+                                                pea_log);
        if (!err)
                nvme_show_predictable_latency_event_agg_log(pea_log, cfg.log_entries,
                        log_size, nvme_dev->name, flags);
@@ -1075,8 +1107,8 @@ static int get_pred_lat_event_agg_log(int argc, char **argv,
                        nvme_strerror(errno));
        free(pea_log);
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -1094,8 +1126,9 @@ static int get_persistent_event_log(int argc, char **argv,
        struct nvme_persistent_event_log *pevent, *pevent_collected;
        enum nvme_print_flags flags;
        void *pevent_log_info;
-       int err, fd;
+       struct nvme_dev *dev;
        bool huge;
+       int err;
 
        struct config {
                __u8    action;
@@ -1119,23 +1152,23 @@ static int get_persistent_event_log(int argc, char **argv,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
 
        pevent = calloc(sizeof(*pevent), 1);
        if (!pevent) {
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_get_log_persistent_event(fd, cfg.action,
+       err = nvme_get_log_persistent_event(dev->fd, cfg.action,
                        sizeof(*pevent), pevent);
        if (err < 0) {
                fprintf(stderr, "persistent event log: %s\n",
@@ -1173,10 +1206,10 @@ static int get_persistent_event_log(int argc, char **argv,
                err = -ENOMEM;
                goto free_pevent;
        }
-       err = nvme_get_log_persistent_event(fd, cfg.action,
+       err = nvme_get_log_persistent_event(dev->fd, cfg.action,
                cfg.log_len, pevent_log_info);
        if (!err) {
-               err = nvme_get_log_persistent_event(fd, cfg.action,
+               err = nvme_get_log_persistent_event(dev->fd, cfg.action,
                                sizeof(*pevent), pevent);
                if (err < 0) {
                        fprintf(stderr, "persistent event log: %s\n",
@@ -1205,8 +1238,8 @@ free:
        nvme_free(pevent_log_info, huge);
 free_pevent:
        free(pevent);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -1225,8 +1258,9 @@ static int get_endurance_event_agg_log(int argc, char **argv,
        void *endurance_log;
        struct nvme_id_ctrl ctrl;
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
        __u32 log_size;
+       int err;
 
        struct config {
                __u64   log_entries;
@@ -1250,31 +1284,31 @@ static int get_endurance_event_agg_log(int argc, char **argv,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
 
        if (!cfg.log_entries) {
                fprintf(stderr, "non-zero log-entries is required param\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_identify_ctrl(fd, &ctrl);
+       err = nvme_identify_ctrl(dev->fd, &ctrl);
        if (err < 0) {
                fprintf(stderr, "identify controller: %s\n",
                        nvme_strerror(errno));
-               goto close_fd;
+               goto close_dev;
        } else if (err) {
                fprintf(stderr, "could not identify controller\n");
                err = -ENODEV;
-               goto close_fd;
+               goto close_dev;
        }
 
        cfg.log_entries = min(cfg.log_entries, le16_to_cpu(ctrl.endgidmax));
@@ -1282,10 +1316,11 @@ static int get_endurance_event_agg_log(int argc, char **argv,
        endurance_log = calloc(log_size, 1);
        if (!endurance_log) {
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_get_log_endurance_grp_evt(fd, cfg.rae, 0, log_size, endurance_log);
+       err = nvme_get_log_endurance_grp_evt(dev->fd, cfg.rae, 0, log_size,
+                                            endurance_log);
        if (!err)
                nvme_show_endurance_group_event_agg_log(endurance_log, cfg.log_entries,
                        log_size, nvme_dev->name, flags);
@@ -1296,8 +1331,8 @@ static int get_endurance_event_agg_log(int argc, char **argv,
                        nvme_strerror(errno));
        free(endurance_log);
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -1311,8 +1346,9 @@ static int get_lba_status_log(int argc, char **argv,
        const char *rae = "Retain an Asynchronous Event";
        void *lab_status;
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
        __u32 lslplen;
+       int err;
 
        struct config {
                bool    rae;
@@ -1330,31 +1366,31 @@ static int get_lba_status_log(int argc, char **argv,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
-       err = nvme_get_log_lba_status(fd, true, 0, sizeof(__u32), &lslplen);
+       err = nvme_get_log_lba_status(dev->fd, true, 0, sizeof(__u32), &lslplen);
        if (err < 0) {
                fprintf(stderr, "lba status log page: %s\n",
                        nvme_strerror(errno));
-               goto close_fd;
+               goto close_dev;
        } else if (err) {
                nvme_show_status(err);
-               goto close_fd;
+               goto close_dev;
        }
 
        lab_status = calloc(lslplen, 1);
        if (!lab_status) {
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_get_log_lba_status(fd, cfg.rae, 0, lslplen, lab_status);
+       err = nvme_get_log_lba_status(dev->fd, cfg.rae, 0, lslplen, lab_status);
        if (!err)
                nvme_show_lba_status_log(lab_status, lslplen, nvme_dev->name, flags);
        else if (err > 0)
@@ -1364,8 +1400,8 @@ static int get_lba_status_log(int argc, char **argv,
                        nvme_strerror(errno));
        free(lab_status);
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -1380,7 +1416,8 @@ static int get_resv_notif_log(int argc, char **argv,
                "json or binary.";
        struct nvme_resv_notification_log resv;
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                char    *output_format;
@@ -1395,15 +1432,15 @@ static int get_resv_notif_log(int argc, char **argv,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
-       err = nvme_get_log_reservation(fd, false, &resv);
+       err = nvme_get_log_reservation(dev->fd, false, &resv);
        if (!err)
                nvme_show_resv_notif_log(&resv, nvme_dev->name, flags);
        else if (err > 0)
@@ -1412,8 +1449,8 @@ static int get_resv_notif_log(int argc, char **argv,
                fprintf(stderr, "resv notifi log: %s\n",
                        nvme_strerror(errno));
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 
@@ -1430,7 +1467,8 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
        struct nvme_boot_partition boot;
        __u8 *bp_log;
        enum nvme_print_flags flags;
-       int err = -1, fd = 0, output = 0;
+       int err = -1, output = 0;
+       struct nvme_dev *dev;
        __u32 bpsz = 0;
 
        struct config {
@@ -1452,24 +1490,24 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
        if (!cfg.file_name) {
                fprintf(stderr, "Please provide an output file!\n");
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.lsp > 128) {
                fprintf(stderr, "invalid lsp param: %u\n", cfg.lsp);
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
 
        output = open(cfg.file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
@@ -1477,10 +1515,10 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
                fprintf(stderr, "Failed to open output file %s: %s!\n",
                                cfg.file_name, strerror(errno));
                err = output;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_get_log_boot_partition(fd, false, cfg.lsp,
+       err = nvme_get_log_boot_partition(dev->fd, false, cfg.lsp,
                                          sizeof(boot), &boot);
        if (err < 0) {
                fprintf(stderr, "boot partition log: %s\n",
@@ -1498,7 +1536,7 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
                goto close_output;
        }
 
-       err = nvme_get_log_boot_partition(fd, false, cfg.lsp,
+       err = nvme_get_log_boot_partition(dev->fd, false, cfg.lsp,
                                          sizeof(boot) + bpsz,
                                          (struct nvme_boot_partition *)bp_log);
        if (!err)
@@ -1522,8 +1560,8 @@ static int get_boot_part_log(int argc, char **argv, struct command *cmd, struct
 
 close_output:
        close(output);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -1535,9 +1573,9 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd,
        const char *domainid = "Domain Identifier";
        const char *raw = "use binary output";
        struct nvme_media_unit_stat_log mus;
-
-       int err = -1, fd;
        enum nvme_print_flags flags;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                __u16   domainid;
@@ -1558,18 +1596,18 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
        if (cfg.raw_binary)
                flags = BINARY;
 
-       err = nvme_get_log_media_unit_stat(fd, cfg.domainid, &mus);
+       err = nvme_get_log_media_unit_stat(dev->fd, cfg.domainid, &mus);
        if (!err)
                nvme_show_media_unit_stat_log(&mus, flags);
        else if (err > 0)
@@ -1578,8 +1616,8 @@ static int get_media_unit_stat_log(int argc, char **argv, struct command *cmd,
                fprintf(stderr, "media unit status log: %s\n",
                        nvme_strerror(errno));
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -1591,9 +1629,9 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd,
        const char *domainid = "Domain Identifier";
        const char *raw = "use binary output";
        struct nvme_supported_cap_config_list_log cap_log;
-
-       int err = -1, fd;
        enum nvme_print_flags flags;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                __u16   domainid;
@@ -1614,18 +1652,18 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
        if (cfg.raw_binary)
                flags = BINARY;
 
-       err = nvme_get_log_support_cap_config_list(fd, cfg.domainid, &cap_log);
+       err = nvme_get_log_support_cap_config_list(dev->fd, cfg.domainid, &cap_log);
        if (!err)
                nvme_show_supported_cap_config_log(&cap_log, flags);
        else if (err > 0)
@@ -1633,8 +1671,8 @@ static int get_supp_cap_config_log(int argc, char **argv, struct command *cmd,
        else
                perror("supported capacity configuration list log");
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -1656,8 +1694,9 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
        const char *uuid_index = "UUID index";
        const char *csi = "command set identifier";
        const char *offset_type = "offset type";
-       int err, fd;
+       struct nvme_dev *dev;
        unsigned char *log;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -1705,8 +1744,8 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (cfg.aen) {
@@ -1717,31 +1756,31 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
        if (!cfg.log_len) {
                perror("non-zero log-len is required param\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.lsp > 128) {
                perror("invalid lsp param\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.uuid_index > 128) {
                perror("invalid uuid index param\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        log = malloc(cfg.log_len);
        if (!log) {
                perror("could not alloc buffer for log\n");
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_get_log_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .lid            = cfg.log_id,
                .nsid           = cfg.namespace_id,
                .lpo            = cfg.lpo,
@@ -1771,8 +1810,8 @@ static int get_log(int argc, char **argv, struct command *cmd, struct plugin *pl
                fprintf(stderr, "log page: %s\n", nvme_strerror(errno));
        free(log);
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -1785,7 +1824,8 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
        const char *human_readable = "show log in readable format";
        struct nvme_sanitize_log_page sanitize_log;
        enum nvme_print_flags flags;
-       int fd, err;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                bool    rae;
@@ -1809,19 +1849,19 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
        if (cfg.human_readable)
                flags |= VERBOSE;
 
-       err = nvme_get_log_sanitize(fd, cfg.rae, &sanitize_log);
+       err = nvme_get_log_sanitize(dev->fd, cfg.rae, &sanitize_log);
        if (!err)
                nvme_show_sanitize_log(&sanitize_log, nvme_dev->name, flags);
        else if (err > 0)
@@ -1829,8 +1869,8 @@ static int sanitize_log(int argc, char **argv, struct command *command, struct p
        else
                fprintf(stderr, "sanitize status log: %s\n",
                        nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -1842,7 +1882,8 @@ static int get_fid_support_effects_log(int argc, char **argv, struct command *cm
        const char *human_readable = "show log in readable format";
        struct nvme_fid_supported_effects_log fid_support_log;
        enum nvme_print_flags flags;
-       int fd, err = -1;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                char    *output_format;
@@ -1860,17 +1901,17 @@ static int get_fid_support_effects_log(int argc, char **argv, struct command *cm
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.human_readable)
                flags |= VERBOSE;
 
-       err = nvme_get_log_fid_supported_effects(fd, false, &fid_support_log);
+       err = nvme_get_log_fid_supported_effects(dev->fd, false, &fid_support_log);
        if (!err)
                nvme_show_fid_support_effects_log(&fid_support_log,
                                                  nvme_dev->name, flags);
@@ -1879,8 +1920,8 @@ static int get_fid_support_effects_log(int argc, char **argv, struct command *cm
        else
                fprintf(stderr, "fid support effects log: %s\n",
                        nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -1892,7 +1933,8 @@ static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command
        const char *human_readable = "show log in readable format";
        struct nvme_mi_cmd_supported_effects_log mi_cmd_support_log;
        enum nvme_print_flags flags;
-       int fd, err = -1;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                char    *output_format;
@@ -1910,17 +1952,17 @@ static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.human_readable)
                flags |= VERBOSE;
 
-       err = nvme_get_log_mi_cmd_supported_effects(fd, false, &mi_cmd_support_log);
+       err = nvme_get_log_mi_cmd_supported_effects(dev->fd, false, &mi_cmd_support_log);
        if (!err)
                nvme_show_mi_cmd_support_effects_log(&mi_cmd_support_log,
                                                     nvme_dev->name, flags);
@@ -1929,8 +1971,8 @@ static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command
        else
                fprintf(stderr, "mi command support effects log: %s\n",
                        nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -1941,9 +1983,10 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
                "given device is part of, or optionally controllers attached to a specific namespace.";
        const char *controller = "controller to display";
        const char *namespace_id = "optional namespace attached to controller";
-       int err, fd;
        struct nvme_ctrl_list *cntlist;
        enum nvme_print_flags flags;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u16   cntid;
@@ -1964,25 +2007,25 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
        if (posix_memalign((void *)&cntlist, getpagesize(), 0x1000)) {
                fprintf(stderr, "can not allocate controller list payload\n");
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.namespace_id == NVME_NSID_NONE)
-                 err = nvme_identify_ctrl_list(fd, cfg.cntid, cntlist);
-        else
-                 err = nvme_identify_nsid_ctrl_list(fd, cfg.namespace_id,
-                                          cfg.cntid, cntlist);
+               err = nvme_identify_ctrl_list(dev->fd, cfg.cntid, cntlist);
+       else
+               err = nvme_identify_nsid_ctrl_list(dev->fd, cfg.namespace_id,
+                                                  cfg.cntid, cntlist);
        if (!err)
                nvme_show_list_ctrl(cntlist, flags);
        else if (err > 0)
@@ -1992,8 +2035,8 @@ static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *
                        nvme_strerror(errno));
 
        free(cntlist);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -2005,9 +2048,10 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
        const char *namespace_id = "first nsid returned list should start from";
        const char *csi = "I/O command set identifier";
        const char *all = "show all namespaces in the subsystem, whether attached or inactive";
-       int err, fd;
        struct nvme_ns_list ns_list;
        enum nvme_print_flags flags;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -2031,27 +2075,27 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (flags != JSON && flags != NORMAL) {
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (!cfg.namespace_id) {
                err = -EINVAL;
                fprintf(stderr, "invalid nsid parameter\n");
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_identify_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .timeout        = NVME_DEFAULT_IOCTL_TIMEOUT,
                .data           = &ns_list,
                .nsid           = cfg.namespace_id - 1.
@@ -2074,8 +2118,8 @@ static int list_ns(int argc, char **argv, struct command *cmd, struct plugin *pl
        else
                fprintf(stderr, "id namespace list: %s",
                        nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -2091,7 +2135,8 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p
        const char *verbose = "Increase output verbosity";
        enum nvme_print_flags flags;
        struct nvme_id_ns ns;
-       int err = -1, fd;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                __u16   lba_format_index;
@@ -2115,18 +2160,18 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
        if (cfg.verbose)
                flags |= VERBOSE;
 
-       err = nvme_identify_ns_csi_user_data_format(fd, cfg.lba_format_index,
+       err = nvme_identify_ns_csi_user_data_format(dev->fd, cfg.lba_format_index,
                                                                                cfg.uuid_index, NVME_CSI_NVM, &ns);
        if (!err)
                nvme_show_id_ns(&ns, 0, cfg.lba_format_index, true, flags);
@@ -2134,8 +2179,8 @@ static int id_ns_lba_format(int argc, char **argv, struct command *cmd, struct p
                nvme_show_status(err);
        else
                perror("identify namespace for specific LBA format");
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return nvme_status_to_errno(err, false);
 }
@@ -2146,9 +2191,10 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
        const char *desc = "Show endurance group list information for the given endurance "\
                "group id";
        const char *endurance_grp_id = "Endurance Group ID";
-       int err = -1, fd;
        struct nvme_id_endurance_group_list *endgrp_list;
        enum nvme_print_flags flags;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                __u16   endgrp_id;
@@ -2166,25 +2212,25 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (flags != JSON && flags != NORMAL) {
                err = -EINVAL;
                fprintf(stderr, "invalid output format\n");
-               goto close_fd;
+               goto close_dev;
        }
 
        if (posix_memalign((void *)&endgrp_list, getpagesize(), 0x1000)) {
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_identify_endurance_group_list(fd, cfg.endgrp_id, endgrp_list);
+       err = nvme_identify_endurance_group_list(dev->fd, cfg.endgrp_id, endgrp_list);
        if (!err)
                nvme_show_endurance_group_list(endgrp_list, flags);
        else if (err > 0)
@@ -2194,8 +2240,8 @@ static int id_endurance_grp_list(int argc, char **argv, struct command *cmd,
                        nvme_strerror(errno));
 
        free(endgrp_list);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -2210,7 +2256,8 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
                "the namespace is not already inactive, once deleted.";
        const char *namespace_id = "namespace to delete";
        const char *timeout = "timeout value, in milliseconds";
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -2228,20 +2275,20 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n",
                                nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
-       err = nvme_ns_mgmt_delete(fd, cfg.namespace_id);
+       err = nvme_ns_mgmt_delete(dev->fd, cfg.namespace_id);
        if (!err)
                printf("%s: Success, deleted nsid:%d\n", cmd->name,
                                                                cfg.namespace_id);
@@ -2250,16 +2297,17 @@ static int delete_ns(int argc, char **argv, struct command *cmd, struct plugin *
        else
                fprintf(stderr, "delete namespace: %s\n", nvme_strerror(errno));
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
 
 static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, struct command *cmd)
 {
-       int err, num, fd, i, list[2048];
        struct nvme_ctrl_list cntlist;
+       int err, num, i, list[2048];
+       struct nvme_dev *dev;
        __u16 ctrlist[2048];
 
        const char *namespace_id = "namespace to attach";
@@ -2281,15 +2329,15 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (!cfg.namespace_id) {
                fprintf(stderr, "%s: namespace-id parameter required\n",
                                                cmd->name);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        num = argconfig_parse_comma_sep_array(cfg.cntlist, list, 2047);
@@ -2301,7 +2349,7 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
                fprintf(stderr, "%s: controller id list is malformed\n",
                                                cmd->name);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        for (i = 0; i < num; i++)
@@ -2310,9 +2358,9 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
        nvme_init_ctrl_list(&cntlist, num, ctrlist);
 
        if (attach)
-               err = nvme_ns_attach_ctrls(fd, cfg.namespace_id, &cntlist);
+               err = nvme_ns_attach_ctrls(dev->fd, cfg.namespace_id, &cntlist);
        else
-               err = nvme_ns_detach_ctrls(fd, cfg.namespace_id, &cntlist);
+               err = nvme_ns_detach_ctrls(dev->fd, cfg.namespace_id, &cntlist);
 
        if (!err)
                printf("%s: Success, nsid:%d\n", cmd->name, cfg.namespace_id);
@@ -2321,8 +2369,8 @@ static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, s
        else
                perror(attach ? "attach namespace" : "detach namespace");
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -2367,8 +2415,9 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
        const char *bs = "target block size, specify only if \'FLBAS\' "\
                "value not entered";
 
-       int err = 0, fd, i;
        struct nvme_id_ns ns;
+       struct nvme_dev *dev;
+       int err = 0, i;
        __u32 nsid;
 
        struct config {
@@ -2414,15 +2463,15 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (cfg.flbas != 0xff && cfg.bs != 0x00) {
                fprintf(stderr,
                        "Invalid specification of both FLBAS and Block Size, please specify only one\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.bs) {
                if ((cfg.bs & (~cfg.bs + 1)) != cfg.bs) {
@@ -2430,9 +2479,9 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
                                "Invalid value for block size (%"PRIu64"). Block size must be a power of two\n",
                                (uint64_t)cfg.bs);
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
-               err = nvme_identify_ns(fd, NVME_NSID_ALL, &ns);
+               err = nvme_identify_ns(dev->fd, NVME_NSID_ALL, &ns);
                if (err) {
                        if (err < 0)
                                fprintf(stderr, "identify-namespace: %s",
@@ -2441,7 +2490,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
                                fprintf(stderr, "identify failed\n");
                                nvme_show_status(err);
                        }
-                       goto close_fd;
+                       goto close_dev;
                }
                for (i = 0; i <= ns.nlbaf; ++i) {
                        if ((1 << ns.lbaf[i].ds) == cfg.bs && ns.lbaf[i].ms == 0) {
@@ -2459,7 +2508,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
                        "Please correct block size, or specify FLBAS directly\n");
 
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_id_ns ns2 = {
@@ -2473,7 +2522,7 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
                .lbstm = cpu_to_le64(cfg.lbstm),
        };
 
-       err = nvme_ns_mgmt_create(fd, &ns2, &nsid, cfg.timeout, cfg.csi);
+       err = nvme_ns_mgmt_create(dev->fd, &ns2, &nsid, cfg.timeout, cfg.csi);
        if (!err)
                printf("%s: Success, created nsid:%d\n", cmd->name, nsid);
        else if (err > 0)
@@ -2481,8 +2530,8 @@ static int create_ns(int argc, char **argv, struct command *cmd, struct plugin *
        else
                fprintf(stderr, "create namespace: %s\n", nvme_strerror(errno));
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -2677,7 +2726,8 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
        const char *human_readable = "show identify in readable format";
        enum nvme_print_flags flags;
        struct nvme_id_ctrl ctrl;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                bool    vendor_specific;
@@ -2701,13 +2751,13 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
        if (cfg.vendor_specific)
@@ -2715,15 +2765,15 @@ int __id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin,
        if (cfg.human_readable)
                flags |= VERBOSE;
 
-       err = nvme_identify_ctrl(fd, &ctrl);
+       err = nvme_identify_ctrl(dev->fd, &ctrl);
        if (!err)
                nvme_show_id_ctrl(&ctrl, flags, vs);
        else if (err > 0)
                nvme_show_status(err);
        else
                fprintf(stderr, "identify controller: %s\n", nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -2741,7 +2791,8 @@ static int nvm_id_ctrl(int argc, char **argv, struct command *cmd,
                "the specified controller in various formats.";
        enum nvme_print_flags flags;
        struct nvme_id_ctrl_nvm ctrl_nvm;
-       int fd, err = -1;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                char    *output_format;
@@ -2756,23 +2807,23 @@ static int nvm_id_ctrl(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
-       err = nvme_nvm_identify_ctrl(fd, &ctrl_nvm);
+       err = nvme_nvm_identify_ctrl(dev->fd, &ctrl_nvm);
        if (!err)
                nvme_show_id_ctrl_nvm(&ctrl_nvm, flags);
        else if (err > 0)
                nvme_show_status(err);
        else
                fprintf(stderr, "nvm identify controller: %s\n", nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -2789,7 +2840,8 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd,
        enum nvme_print_flags flags;
        struct nvme_nvm_id_ns id_ns;
        struct nvme_id_ns ns;
-       int fd, err = -1;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                __u32   namespace_id;
@@ -2813,32 +2865,32 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
        if (cfg.verbose)
                flags |= VERBOSE;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        perror("get-namespace-id");
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
-       err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+       err = nvme_identify_ns(dev->fd, cfg.namespace_id, &ns);
        if (err) {
                nvme_show_status(err);
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_identify_ns_csi(fd, cfg.namespace_id, cfg.uuid_index,
+       err = nvme_identify_ns_csi(dev->fd, cfg.namespace_id, cfg.uuid_index,
                                                        NVME_CSI_NVM, &id_ns);
        if (!err)
                nvme_show_nvm_id_ns(&id_ns, cfg.namespace_id, &ns, 0, false, flags);
@@ -2846,8 +2898,8 @@ static int nvm_id_ns(int argc, char **argv, struct command *cmd,
                nvme_show_status(err);
        else
                perror("nvm identify namespace");
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return nvme_status_to_errno(err, false);
 }
@@ -2865,7 +2917,8 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru
        enum nvme_print_flags flags;
        struct nvme_id_ns ns;
        struct nvme_nvm_id_ns nvm_ns;
-       int err = -1, fd;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                __u16   lba_format_index;
@@ -2889,23 +2942,23 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
        if (cfg.verbose)
                flags |= VERBOSE;
 
-       err = nvme_identify_ns(fd, NVME_NSID_ALL, &ns);
+       err = nvme_identify_ns(dev->fd, NVME_NSID_ALL, &ns);
        if (err) {
                ns.nlbaf = NVME_FEAT_LBA_RANGE_MAX - 1;
                ns.nulbaf = 0;
        }
-       err = nvme_identify_iocs_ns_csi_user_data_format(fd, cfg.lba_format_index,
+       err = nvme_identify_iocs_ns_csi_user_data_format(dev->fd, cfg.lba_format_index,
                                                                                cfg.uuid_index, NVME_CSI_NVM, &nvm_ns);
        if (!err)
                nvme_show_nvm_id_ns(&nvm_ns, 0, &ns, cfg.lba_format_index, true,
@@ -2914,8 +2967,8 @@ static int nvm_id_ns_lba_format(int argc, char **argv, struct command *cmd, stru
                nvme_show_status(err);
        else
                perror("NVM identify namespace for specific LBA format");
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return nvme_status_to_errno(err, false);
 }
@@ -2928,8 +2981,9 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
        const char *raw = "show descriptors in binary format";
        const char *namespace_id = "identifier of desired namespace";
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
        void *nsdescs;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -2950,30 +3004,30 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        if (posix_memalign(&nsdescs, getpagesize(), 0x1000)) {
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_identify_ns_descs(fd, cfg.namespace_id, nsdescs);
+       err = nvme_identify_ns_descs(dev->fd, cfg.namespace_id, nsdescs);
        if (!err)
                nvme_show_id_ns_descs(nsdescs, cfg.namespace_id, flags);
        else if (err > 0)
@@ -2981,8 +3035,8 @@ static int ns_descs(int argc, char **argv, struct command *cmd, struct plugin *p
        else
                fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
        free(nsdescs);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3001,7 +3055,8 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
 
        enum nvme_print_flags flags;
        struct nvme_id_ns ns;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -3031,13 +3086,13 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
        if (cfg.vendor_specific)
@@ -3046,17 +3101,17 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
                flags |= VERBOSE;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        if (cfg.force)
-               err = nvme_identify_allocated_ns(fd, cfg.namespace_id, &ns);
+               err = nvme_identify_allocated_ns(dev->fd, cfg.namespace_id, &ns);
        else
-               err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+               err = nvme_identify_ns(dev->fd, cfg.namespace_id, &ns);
 
        if (!err)
                nvme_show_id_ns(&ns, cfg.namespace_id, 0, false, flags);
@@ -3064,8 +3119,8 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
                nvme_show_status(err);
        else
                fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3082,7 +3137,8 @@ static int cmd_set_independent_id_ns(int argc, char **argv,
 
        enum nvme_print_flags flags;
        struct nvme_id_independent_id_ns ns;
-       int err = -1, fd;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                __u32   namespace_id;
@@ -3106,35 +3162,35 @@ static int cmd_set_independent_id_ns(int argc, char **argv,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
        if (cfg.human_readable)
                flags |= VERBOSE;
 
        if (!cfg.namespace_id) {
-               err = cfg.namespace_id = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = cfg.namespace_id = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        perror("get-namespace-id");
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
-       err = nvme_identify_independent_identify_ns(fd, cfg.namespace_id, &ns);
+       err = nvme_identify_independent_identify_ns(dev->fd, cfg.namespace_id, &ns);
        if (!err)
                nvme_show_cmd_set_independent_id_ns(&ns, cfg.namespace_id, flags);
        else if (err > 0)
                nvme_show_status(err);
        else
                fprintf(stderr, "I/O command set independent identify namespace: %s\n", nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3147,7 +3203,8 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
 
        struct nvme_id_ns_granularity_list *granularity_list;
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                char    *output_format;
@@ -3162,21 +3219,21 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
        if (posix_memalign((void *)&granularity_list, getpagesize(), NVME_IDENTIFY_DATA_SIZE)) {
                fprintf(stderr, "can not allocate granularity list payload\n");
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_identify_ns_granularity(fd, granularity_list);
+       err = nvme_identify_ns_granularity(dev->fd, granularity_list);
        if (!err)
                nvme_show_id_ns_granularity_list(granularity_list, flags);
        else if (err > 0)
@@ -3184,8 +3241,8 @@ static int id_ns_granularity(int argc, char **argv, struct command *cmd, struct
        else
                fprintf(stderr, "identify namespace granularity: %s\n", nvme_strerror(errno));
        free(granularity_list);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3200,7 +3257,8 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
 
        struct nvme_id_nvmset_list nvmset;
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u16   nvmset_id;
@@ -3218,15 +3276,15 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
-       err = nvme_identify_nvmset_list(fd, cfg.nvmset_id, &nvmset);
+       err = nvme_identify_nvmset_list(dev->fd, cfg.nvmset_id, &nvmset);
        if (!err)
                nvme_show_id_nvmset(&nvmset, cfg.nvmset_id, flags);
        else if (err > 0)
@@ -3234,8 +3292,8 @@ static int id_nvmset(int argc, char **argv, struct command *cmd, struct plugin *
        else
                fprintf(stderr, "identify nvm set list: %s\n", nvme_strerror(errno));
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3250,7 +3308,8 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
 
        struct nvme_id_uuid_list uuid_list;
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                char    *output_format;
@@ -3271,27 +3330,27 @@ static int id_uuid(int argc, char **argv, struct command *cmd, struct plugin *pl
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
        if (cfg.human_readable)
                flags |= VERBOSE;
 
-       err = nvme_identify_uuid(fd, &uuid_list);
+       err = nvme_identify_uuid(dev->fd, &uuid_list);
        if (!err)
                nvme_show_id_uuid_list(&uuid_list, flags);
        else if (err > 0)
                nvme_show_status(err);
        else
                fprintf(stderr, "identify UUID list: %s\n", nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;;
 }
@@ -3303,7 +3362,8 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl
                "in either human-readable or binary format.";
        const char *controller_id = "identifier of desired controller";
        struct nvme_id_iocs iocs;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u16   cntid;
@@ -3318,13 +3378,11 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               err = fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
-       }
 
-       err = nvme_identify_iocs(fd, cfg.cntid, &iocs);
+       err = nvme_identify_iocs(dev->fd, cfg.cntid, &iocs);
        if (!err) {
                printf("NVMe Identify I/O Command Set:\n");
                nvme_show_id_iocs(&iocs);
@@ -3333,7 +3391,7 @@ static int id_iocs(int argc, char **argv, struct command *cmd, struct plugin *pl
        else
                fprintf(stderr, "NVMe Identify I/O Command Set: %s\n", nvme_strerror(errno));
 
-       close(fd);
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3345,7 +3403,8 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *
        const char *domain_id = "identifier of desired domain";
        struct nvme_id_domain_list id_domain;
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u16   dom_id;
@@ -3363,17 +3422,15 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               err = fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
-       }
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
-       err = nvme_identify_domain_list(fd, cfg.dom_id, &id_domain);
+       err = nvme_identify_domain_list(dev->fd, cfg.dom_id, &id_domain);
        if (!err) {
                printf("NVMe Identify command for Domain List is successful:\n");
                printf("NVMe Identify Domain List:\n");
@@ -3383,8 +3440,8 @@ static int id_domain(int argc, char **argv, struct command *cmd, struct plugin *
        else
                fprintf(stderr, "NVMe Identify Domain List: %s\n", nvme_strerror(errno));
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3392,18 +3449,19 @@ ret:
 static int get_ns_id(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        const char *desc = "Get namespace ID of a the block device.";
-       int err = 0, fd;
+       struct nvme_dev *dev;
        unsigned int nsid;
+       int err = 0;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
-       err = nvme_get_nsid(fd, &nsid);
+       err = nvme_get_nsid(dev->fd, &nsid);
        if (err < 0) {
                fprintf(stderr, "get namespace ID: %s\n", nvme_strerror(errno));
                err = errno;
@@ -3413,7 +3471,7 @@ static int get_ns_id(int argc, char **argv, struct command *cmd, struct plugin *
        printf("%s: namespace-id:%d\n", nvme_dev->name, nsid);
 
 close_fd:
-       close(fd);
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3435,8 +3493,9 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi
                "8h: Secondary Assign\n"\
                "9h: Secondary Online";
        const char *nr = "Number of Controller Resources(NR)";
-       int fd, err;
+       struct nvme_dev *dev;
        __u32 result;
+       int err;
 
        struct config {
                __u16   cntlid;
@@ -3460,13 +3519,13 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        struct nvme_virtual_mgmt_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .act            = cfg.act,
                .rt             = cfg.rt,
                .cntlid         = cfg.cntlid,
@@ -3483,7 +3542,7 @@ static int virtual_mgmt(int argc, char **argv, struct command *cmd, struct plugi
        } else
                fprintf(stderr, "virt-mgmt: %s\n", nvme_strerror(errno));
 
-       close(fd);
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3496,9 +3555,9 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct
                "decoded format (default), json or binary.";
        const char *human_readable = "show info in readable format";
        struct nvme_primary_ctrl_cap caps;
-
-       int err, fd;
        enum nvme_print_flags flags;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u16   cntlid;
@@ -3519,25 +3578,25 @@ static int primary_ctrl_caps(int argc, char **argv, struct command *cmd, struct
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.human_readable)
                flags |= VERBOSE;
 
-       err = nvme_identify_primary_ctrl(fd, cfg.cntlid, &caps);
+       err = nvme_identify_primary_ctrl(dev->fd, cfg.cntlid, &caps);
        if (!err)
                nvme_show_primary_ctrl_cap(&caps, flags);
        else if (err > 0)
                nvme_show_status(err);
        else
                fprintf(stderr, "identify primary controller capabilities: %s\n", nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3552,7 +3611,8 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
 
        struct nvme_secondary_ctrl_list *sc_list;
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u16   cntid;
@@ -3576,27 +3636,28 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_err;
 
        if (!cfg.num_entries) {
                fprintf(stderr, "non-zero num-entries is required param\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_err;
        }
 
        if (posix_memalign((void *)&sc_list, getpagesize(), sizeof(*sc_list))) {
                fprintf(stderr, "can not allocate controller list payload\n");
                err = -ENOMEM;
-               goto close_fd;
+               goto close_err;
        }
 
-       err = nvme_identify_secondary_ctrl_list(fd, cfg.namespace_id, cfg.cntid, sc_list);
+       err = nvme_identify_secondary_ctrl_list(dev->fd, cfg.namespace_id,
+                                               cfg.cntid, sc_list);
        if (!err)
                nvme_show_list_secondary_ctrl(sc_list, cfg.num_entries, flags);
        else if (err > 0)
@@ -3605,9 +3666,9 @@ static int list_secondary_ctrl(int argc, char **argv, struct command *cmd, struc
                fprintf(stderr, "id secondary controller list: %s\n", nvme_strerror(errno));
 
        free(sc_list);
-
-close_fd:
-       close(fd);
+
+close_err:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3623,7 +3684,8 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
                "2h Start a extended device self-test operation\n"\
                "eh Start a vendor specific device self-test operation\n"\
                "fh abort the device self-test operation\n";
-       int fd, err;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -3641,13 +3703,13 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        struct nvme_dev_self_test_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .stc            = cfg.stc,
                .timeout        = NVME_DEFAULT_IOCTL_TIMEOUT,
@@ -3666,7 +3728,7 @@ static int device_self_test(int argc, char **argv, struct command *cmd, struct p
        } else
                fprintf(stderr, "Device self-test: %s\n", nvme_strerror(errno));
 
-       close(fd);
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3682,7 +3744,8 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug
 
        struct nvme_self_test_log log;
        enum nvme_print_flags flags;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u8    dst_entries;
@@ -3703,17 +3766,17 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.verbose)
                flags |= VERBOSE;
 
-       err = nvme_get_log_device_self_test(fd, &log);
+       err = nvme_get_log_device_self_test(dev->fd, &log);
        if (!err)
                nvme_show_self_test_log(&log, cfg.dst_entries, 0,
                                        nvme_dev->name, flags);
@@ -3721,8 +3784,8 @@ static int self_test_log(int argc, char **argv, struct command *cmd, struct plug
                nvme_show_status(err);
        else
                fprintf(stderr, "self test log: %s\n", nvme_strerror(errno));
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -3871,8 +3934,8 @@ static int get_feature(int argc, char **argv, struct command *cmd,
        const char *cdw11 = "dword 11 for interrupt vector config";
        const char *human_readable = "show feature in readable format";
        const char *uuid_index = "specify uuid index";
+       struct nvme_dev *dev;
        int err;
-       int fd;
 
        struct feat_cfg cfg = {
                .feature_id     = 0,
@@ -3897,16 +3960,16 @@ static int get_feature(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        if (errno != ENOTTY) {
                                fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                               goto close_fd;
+                               goto close_dev;
                        }
                        cfg.namespace_id = NVME_NSID_ALL;
                }
@@ -3915,19 +3978,19 @@ static int get_feature(int argc, char **argv, struct command *cmd,
        if (cfg.sel > 8) {
                fprintf(stderr, "invalid 'select' param:%d\n", cfg.sel);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.uuid_index > 128) {
                fprintf(stderr, "invalid uuid index param: %u\n", cfg.uuid_index);
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = get_feature_ids(fd, cfg);
+       err = get_feature_ids(dev->fd, cfg);
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 
 ret:
        return err;
@@ -3946,10 +4009,11 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
        const char *fw = "firmware file (required)";
        const char *xfer = "transfer chunksize limit";
        const char *offset = "starting dword offset, default 0";
-       int err, fd, fw_fd = -1;
        unsigned int fw_size;
-       struct stat sb;
+       struct nvme_dev *dev;
        void *fw_buf, *buf;
+       int err, fw_fd = -1;
+       struct stat sb;
        bool huge;
 
        struct config {
@@ -3971,8 +4035,8 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        fw_fd = open(cfg.fw, O_RDONLY);
@@ -3981,7 +4045,7 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
                fprintf(stderr, "Failed to open firmware file %s: %s\n",
                                cfg.fw, strerror(errno));
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        err = fstat(fw_fd, &sb);
@@ -4022,7 +4086,7 @@ static int fw_download(int argc, char **argv, struct command *cmd, struct plugin
 
                struct nvme_fw_download_args args = {
                        .args_size      = sizeof(args),
-                       .fd             = fd,
+                       .fd             = dev->fd,
                        .offset         = cfg.offset,
                        .data_len       = cfg.xfer,
                        .data           = fw_buf,
@@ -4048,8 +4112,8 @@ free:
        nvme_free(buf, huge);
 close_fw_fd:
        close(fw_fd);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -4074,8 +4138,9 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
        const char *slot = "[0-7]: firmware slot for commit action";
        const char *action = "[0-7]: commit action";
        const char *bpid = "[0,1]: boot partition identifier, if applicable (default: 0)";
-       int err, fd;
+       struct nvme_dev *dev;
        __u32 result;
+       int err;
 
        struct config {
                __u8    slot;
@@ -4096,29 +4161,29 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (cfg.slot > 7) {
                fprintf(stderr, "invalid slot:%d\n", cfg.slot);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.action > 7 || cfg.action == 4 || cfg.action == 5) {
                fprintf(stderr, "invalid action:%d\n", cfg.action);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.bpid > 1) {
                fprintf(stderr, "invalid boot partition id:%d\n", cfg.bpid);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_fw_commit_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .slot           = cfg.slot,
                .action         = cfg.action,
                .bpid           = cfg.bpid,
@@ -4161,8 +4226,8 @@ static int fw_commit(int argc, char **argv, struct command *cmd, struct plugin *
                                "sequence due to processing a command from an Admin SQ on a controller");
        }
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -4170,17 +4235,18 @@ ret:
 static int subsystem_reset(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        const char *desc = "Resets the NVMe subsystem\n";
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
-       err = nvme_subsystem_reset(fd);
+       err = nvme_subsystem_reset(dev->fd);
        if (err < 0) {
                if (errno == ENOTTY)
                        fprintf(stderr,
@@ -4189,7 +4255,7 @@ static int subsystem_reset(int argc, char **argv, struct command *cmd, struct pl
                        fprintf(stderr, "Subsystem-reset: %s\n", nvme_strerror(errno));
        }
 
-       close(fd);
+       dev_close(dev);
 ret:
        return err;
 }
@@ -4197,21 +4263,22 @@ ret:
 static int reset(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        const char *desc = "Resets the NVMe controller\n";
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
-       err = nvme_ctrl_reset(fd);
+       err = nvme_ctrl_reset(dev->fd);
        if (err < 0)
                fprintf(stderr, "Reset: %s\n", nvme_strerror(errno));
 
-       close(fd);
+       dev_close(dev);
 ret:
        return err;
 }
@@ -4219,21 +4286,22 @@ ret:
 static int ns_rescan(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        const char *desc = "Rescans the NVMe namespaces\n";
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
-       err = nvme_ns_rescan(fd);
+       err = nvme_ns_rescan(dev->fd);
        if (err < 0)
                fprintf(stderr, "Namespace Rescan");
 
-       close(fd);
+       dev_close(dev);
 ret:
        return err;
 }
@@ -4247,7 +4315,8 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
        const char *ause_desc = "Allow unrestricted sanitize exit.";
        const char *sanact_desc = "Sanitize action.";
        const char *ovrpat_desc = "Overwrite pattern.";
-       int fd, err;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                bool    no_dealloc;
@@ -4277,8 +4346,8 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        switch (cfg.sanact) {
@@ -4290,14 +4359,14 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
        default:
                fprintf(stderr, "Invalid Sanitize Action\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.sanact == NVME_SANITIZE_SANACT_EXIT_FAILURE) {
               if (cfg.ause || cfg.no_dealloc) {
                        fprintf(stderr, "SANACT is Exit Failure Mode\n");
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
               }
        }
 
@@ -4305,19 +4374,19 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
                if (cfg.owpass > 16) {
                        fprintf(stderr, "OWPASS out of range [0-16]\n");
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
        } else {
                if (cfg.owpass || cfg.oipbp || cfg.ovrpat) {
                        fprintf(stderr, "SANACT is not Overwrite\n");
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        struct nvme_sanitize_nvm_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .sanact         = cfg.sanact,
                .ause           = cfg.ause,
                .owpass         = cfg.owpass,
@@ -4333,8 +4402,8 @@ static int sanitize(int argc, char **argv, struct command *cmd, struct plugin *p
        else if (err > 0)
                nvme_show_status(err);
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -4430,10 +4499,11 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
                                        "output_format == normal";
 
        enum nvme_print_flags flags;
-       nvme_root_t r;
+       struct nvme_dev *dev;
        bool fabrics = true;
-       int fd, err;
+       nvme_root_t r;
        void *bar;
+       int err;
 
        struct config {
                char    *output_format;
@@ -4451,18 +4521,18 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        r = nvme_scan(NULL);
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.human_readable)
                flags |= VERBOSE;
 
-       err = nvme_get_properties(fd, &bar);
+       err = nvme_get_properties(dev->fd, &bar);
        if (err) {
                bar = mmap_registers(r, nvme_dev->name);
                fabrics = false;
@@ -4470,15 +4540,15 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
                        err = 0;
        }
        if (!bar)
-               goto close_fd;
+               goto close_dev;
 
        nvme_show_ctrl_registers(bar, fabrics, flags);
        if (fabrics)
                free(bar);
        else
                munmap(bar, getpagesize());
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
        nvme_free_tree(r);
 ret:
        return err;
@@ -4492,8 +4562,9 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
        const char *offset = "offset of the requested property";
        const char *human_readable = "show property in readable format";
 
-       int fd, err;
+       struct nvme_dev *dev;
        __u64 value;
+       int err;
 
        struct config {
                int     offset;
@@ -4511,19 +4582,19 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (cfg.offset == -1) {
                fprintf(stderr, "offset required param\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_get_property_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .offset         = cfg.offset,
                .value          = &value,
                .timeout        = NVME_DEFAULT_IOCTL_TIMEOUT,
@@ -4537,8 +4608,8 @@ static int get_property(int argc, char **argv, struct command *cmd, struct plugi
                nvme_show_status(err);
        }
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -4549,7 +4620,8 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
                           "for NVMe over Fabric";
        const char *offset = "the offset of the property";
        const char *value = "the value of the property to be set";
-       int fd, err;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                int     offset;
@@ -4567,24 +4639,24 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (cfg.offset == -1) {
                fprintf(stderr, "offset required param\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.value == -1) {
                fprintf(stderr, "value required param\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_set_property_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .offset         = cfg.offset,
                .value          = cfg.value,
                .timeout        = NVME_DEFAULT_IOCTL_TIMEOUT,
@@ -4600,8 +4672,8 @@ static int set_property(int argc, char **argv, struct command *cmd, struct plugi
                nvme_show_status(err);
        }
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -4624,9 +4696,10 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
        const char *force = "The \"I know what I'm doing\" flag, skip confirmation before sending command";
        struct nvme_id_ns ns;
        struct nvme_id_ctrl ctrl;
-       int err, fd, i;
-       int block_size;
+       struct nvme_dev *dev;
        __u8 prev_lbaf = 0;
+       int block_size;
+       int err, i;
 
        struct config {
                __u32   namespace_id;
@@ -4672,8 +4745,8 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
        if (err)
                goto ret;
 
-       err = fd = open_exclusive(argc, argv, cfg.force);
-       if (fd < 0) {
+       err = open_exclusive(&dev, argc, argv, cfg.force);
+       if (err < 0) {
                if (errno == EBUSY) {
                        fprintf(stderr, "Failed to open %s.\n",
                                basename(argv[optind]));
@@ -4692,7 +4765,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
                fprintf(stderr,
                        "Invalid specification of both LBAF and Block Size, please specify only one\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.bs) {
                if ((cfg.bs & (~cfg.bs + 1)) != cfg.bs) {
@@ -4700,14 +4773,14 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
                                "Invalid value for block size (%"PRIu64"), must be a power of two\n",
                                       (uint64_t) cfg.bs);
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
-       err = nvme_identify_ctrl(fd, &ctrl);
+       err = nvme_identify_ctrl(dev->fd, &ctrl);
        if (err) {
                fprintf(stderr, "identify-ctrl: %s\n", nvme_strerror(errno));
-               goto close_fd;
+               goto close_dev;
        }
 
        if ((ctrl.fna & 1) == 1) {
@@ -4718,10 +4791,10 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
                 */
                cfg.namespace_id = NVME_NSID_ALL;
        } else if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
@@ -4731,11 +4804,11 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
                        "specify a namespace to format or use '-n 0xffffffff' "
                        "to format all namespaces on this controller.\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.namespace_id != NVME_NSID_ALL) {
-               err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+               err = nvme_identify_ns(dev->fd, cfg.namespace_id, &ns);
                if (err) {
                        if (err < 0)
                                fprintf(stderr, "identify-namespace: %s\n", nvme_strerror(errno));
@@ -4743,7 +4816,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
                                fprintf(stderr, "identify failed\n");
                                nvme_show_status(err);
                        }
-                       goto close_fd;
+                       goto close_dev;
                }
                nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &prev_lbaf);
 
@@ -4762,7 +4835,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
                                fprintf(stderr,
                                        "Please correct block size, or specify LBAF directly\n");
                                err = -EINVAL;
-                               goto close_fd;
+                               goto close_dev;
                        }
                } else  if (cfg.lbaf == 0xff)
                        cfg.lbaf = prev_lbaf;
@@ -4774,27 +4847,27 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
        if (cfg.ses > 7) {
                fprintf(stderr, "invalid secure erase settings:%d\n", cfg.ses);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.lbaf > 63) {
                fprintf(stderr, "invalid lbaf:%d\n", cfg.lbaf);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.pi > 7) {
                fprintf(stderr, "invalid pi:%d\n", cfg.pi);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.pil > 1) {
                fprintf(stderr, "invalid pil:%d\n", cfg.pil);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.ms > 1) {
                fprintf(stderr, "invalid ms:%d\n", cfg.ms);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (!cfg.force) {
@@ -4811,7 +4884,7 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
 
        struct nvme_format_nvm_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .lbafu          = (cfg.lbaf & NVME_NS_FLBAS_HIGHER_MASK) >> 4,
                .lbaf           = cfg.lbaf & NVME_NS_FLBAS_LOWER_MASK,
@@ -4831,10 +4904,10 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
                printf("Success formatting namespace:%x\n", cfg.namespace_id);
                if (cfg.lbaf != prev_lbaf){
                        if (is_chardev()) {
-                               if(ioctl(fd, NVME_IOCTL_RESCAN) < 0){
+                               if (ioctl(dev->fd, NVME_IOCTL_RESCAN) < 0) {
                                        fprintf(stderr, "failed to rescan namespaces\n");
                                        err = -errno;
-                                       goto close_fd;
+                                       goto close_dev;
                                }
                        } else {
                                block_size = 1 << ns.lbaf[cfg.lbaf].ds;
@@ -4846,26 +4919,26 @@ static int format(int argc, char **argv, struct command *cmd, struct plugin *plu
                                 * to the given one because blkdev will not
                                 * update by itself without re-opening fd.
                                 */
-                               if (ioctl(fd, BLKBSZSET, &block_size) < 0) {
+                               if (ioctl(dev->fd, BLKBSZSET, &block_size) < 0) {
                                        fprintf(stderr, "failed to set block size to %d\n",
                                                        block_size);
                                        err = -errno;
-                                       goto close_fd;
+                                       goto close_dev;
                                }
 
-                               if(ioctl(fd, BLKRRPART) < 0) {
+                               if (ioctl(dev->fd, BLKRRPART) < 0) {
                                        fprintf(stderr, "failed to re-read partition table\n");
                                        err = -errno;
-                                       goto close_fd;
+                                       goto close_dev;
                                }
                        }
                }
                if (cfg.reset && is_chardev())
-                       nvme_ctrl_reset(fd);
+                       nvme_ctrl_reset(dev->fd);
        }
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -4892,10 +4965,11 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
        const char *cdw12 = "feature cdw12, if used";
        const char *save = "specifies that the controller shall save the attribute";
        const char *uuid_index = "specify uuid index";
+       struct nvme_dev *dev;
        int err;
        __u32 result;
        void *buf = NULL;
-       int fd, ffd = STDIN_FILENO;
+       int ffd = STDIN_FILENO;
 
        struct config {
                __u32   namespace_id;
@@ -4930,16 +5004,16 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        if (errno != ENOTTY) {
                                fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                               goto close_fd;
+                               goto close_dev;
                        }
 
                        cfg.namespace_id = NVME_NSID_ALL;
@@ -4949,13 +5023,13 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
        if (!cfg.feature_id) {
                fprintf(stderr, "feature-id required param\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.uuid_index > 128) {
                fprintf(stderr, "invalid uuid index param: %u\n", cfg.uuid_index);
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (!cfg.data_len)
@@ -4966,7 +5040,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
                if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
                        fprintf(stderr, "can not allocate feature payload\n");
                        err = -ENOMEM;
-                       goto close_fd;
+                       goto close_dev;
                }
                memset(buf, 0, cfg.data_len);
        }
@@ -5003,7 +5077,7 @@ static int set_feature(int argc, char **argv, struct command *cmd, struct plugin
 
        struct nvme_set_features_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .fid            = cfg.feature_id,
                .nsid           = cfg.namespace_id,
                .cdw11          = cfg.value,
@@ -5043,8 +5117,8 @@ close_ffd:
                close(ffd);
 free:
        free(buf);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -5063,7 +5137,8 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
        const char *tl = "transfer length (cf. SPC-4)";
        const char *namespace_id = "desired namespace";
        const char *nssf = "NVMe Security Specific Field";
-       int err, fd, sec_fd = STDIN_FILENO;
+       int err, sec_fd = STDIN_FILENO;
+       struct nvme_dev *dev;
        void *sec_buf;
        unsigned int sec_size;
 
@@ -5095,14 +5170,14 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (cfg.tl == 0) {
                fprintf(stderr, "--tl unspecified or zero\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
        if ((cfg.tl & 3) != 0)
                fprintf(stderr, "WARNING: --tl not dword aligned; unaligned bytes may be truncated\n");
@@ -5116,7 +5191,7 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
                        fprintf(stderr, "Failed to open %s: %s\n",
                                        cfg.file, strerror(errno));
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
 
                err = fstat(sec_fd, &sb);
@@ -5146,7 +5221,7 @@ static int sec_send(int argc, char **argv, struct command *cmd, struct plugin *p
 
        struct nvme_security_send_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .nssf           = cfg.nssf,
                .spsp0          = cfg.spsp & 0xff,
@@ -5170,8 +5245,8 @@ free:
        free(sec_buf);
 close_sec_fd:
        close(sec_fd);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -5190,11 +5265,12 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
        const char *ttype = "target directive type to be enabled/disabled";
        const char *human_readable = "show directive in readable format";
        const char *input = "write/send file (default stdin)";
-       int err, fd;
+       struct nvme_dev *dev;
        __u32 result;
        __u32 dw12 = 0;
        void *buf = NULL;
        int ffd = STDIN_FILENO;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -5236,8 +5312,8 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        switch (cfg.dtype) {
@@ -5247,14 +5323,14 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
                        if (!cfg.ttype) {
                                fprintf(stderr, "target-dir required param\n");
                                err = -EINVAL;
-                               goto close_fd;
+                               goto close_dev;
                        }
                        dw12 = cfg.ttype << 8 | cfg.endir;
                        break;
                default:
                        fprintf(stderr, "invalid directive operations for Identify Directives\n");
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
                break;
        case NVME_DIRECTIVE_DTYPE_STREAMS:
@@ -5265,20 +5341,20 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
                default:
                        fprintf(stderr, "invalid directive operations for Streams Directives\n");
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
                break;
        default:
                fprintf(stderr, "invalid directive type\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
 
        if (cfg.data_len) {
                if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
                        err = -ENOMEM;
-                       goto close_fd;
+                       goto close_dev;
                }
                memset(buf, 0, cfg.data_len);
        }
@@ -5304,7 +5380,7 @@ static int dir_send(int argc, char **argv, struct command *cmd, struct plugin *p
 
        struct nvme_directive_send_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .dspec          = cfg.dspec,
                .doper          = cfg.doper,
@@ -5336,20 +5412,21 @@ close_ffd:
        close(ffd);
 free:
        free(buf);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
 
 static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       int err, fd;
        const char *desc = "The Write Uncorrectable command is used to set a "\
                        "range of logical blocks to invalid.";
        const char *namespace_id = "desired namespace";
        const char *start_block = "64-bit LBA of first block to access";
        const char *block_count = "number of blocks (zeroes based) on device to access";
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -5370,21 +5447,21 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        struct nvme_io_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .slba           = cfg.start_block,
                .nlb            = cfg.block_count,
@@ -5399,8 +5476,8 @@ static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin
        else
                printf("NVME Write Uncorrectable Success\n");
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -5440,11 +5517,12 @@ static int invalid_tags(__u64 storage_tag, __u64 ref_tag, __u8 sts, __u8 pif)
 
 static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       int err, fd;
        __u16 control = 0;
        __u8 lba_index, sts = 0, pif = 0;
        struct nvme_id_ns ns;
+       struct nvme_dev *dev;
        struct nvme_nvm_id_ns nvm_ns;
+       int err;
 
        const char *desc = "The Write Zeroes command is used to set a "\
                        "range of logical blocks to zero.";
@@ -5508,13 +5586,13 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (cfg.prinfo > 0xf) {
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        control |= (cfg.prinfo << 10);
@@ -5527,23 +5605,23 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
        if (cfg.storage_tag_check)
                control |= NVME_IO_STC;
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
-       err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+       err = nvme_identify_ns(dev->fd, cfg.namespace_id, &ns);
        if (err) {
                nvme_show_status(err);
-               goto close_fd;
+               goto close_dev;
        } else if (err < 0) {
                fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_identify_ns_csi(fd, cfg.namespace_id, 0, NVME_CSI_NVM, &nvm_ns);
+       err = nvme_identify_ns_csi(dev->fd, cfg.namespace_id, 0, NVME_CSI_NVM, &nvm_ns);
        if (!err) {
                nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
                sts = nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
@@ -5552,12 +5630,12 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
 
        if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif)) {
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_io_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .slba           = cfg.start_block,
                .nlb            = cfg.block_count,
@@ -5579,8 +5657,8 @@ static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugi
        else
                printf("NVME Write Zeroes Success\n");
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -5600,12 +5678,13 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
        const char *idr = "Attribute Integral Dataset for Read";
        const char *cdw11 = "All the command DWORD 11 attributes. Use instead of specifying individual attributes";
 
-       int err, fd;
        uint16_t nr, nc, nb, ns;
        __u32 ctx_attrs[256] = {0,};
        __u32 nlbs[256] = {0,};
        __u64 slbas[256] = {0,};
        struct nvme_dsm_range dsm[256];
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -5641,8 +5720,8 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        nc = argconfig_parse_comma_sep_array(cfg.ctx_attrs, (int *)ctx_attrs, ARRAY_SIZE(ctx_attrs));
@@ -5652,14 +5731,14 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
        if (!nr || nr > 256) {
                fprintf(stderr, "No range definition provided\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
        if (!cfg.cdw11)
@@ -5668,7 +5747,7 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
        nvme_init_dsm_range(dsm, ctx_attrs, nlbs, slbas, nr);
        struct nvme_dsm_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .attrs          = cfg.cdw11,
                .nr_ranges      = nr,
@@ -5684,8 +5763,8 @@ static int dsm(int argc, char **argv, struct command *cmd, struct plugin *plugin
        else
                printf("NVMe DSM: success\n");
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -5715,10 +5794,11 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
        const char *d_dspec = "directive specific (write part)";
        const char *d_format = "source range entry format";
 
-       int err, fd;
        uint16_t nr, nb, ns, nrts, natms, nats;
        __u16 nlbs[128] = { 0 };
        unsigned long long slbas[128] = {0,};
+       struct nvme_dev *dev;
+       int err;
 
        union {
                __u32 f0[128];
@@ -5794,11 +5874,9 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               err = fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
-       }
 
        nb = argconfig_parse_comma_sep_array_short(cfg.nlbs, nlbs, ARRAY_SIZE(nlbs));
        ns = argconfig_parse_comma_sep_array_long(cfg.slbas, slbas, ARRAY_SIZE(slbas));
@@ -5810,7 +5888,7 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
        else {
                fprintf(stderr, "invalid format\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        natms = argconfig_parse_comma_sep_array(cfg.elbatms, (int *)elbatms, ARRAY_SIZE(elbatms));
@@ -5820,14 +5898,14 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
        if (!nr || nr > 128 || (cfg.format == 1 && nr > 101)) {
                fprintf(stderr, "invalid range\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
@@ -5840,7 +5918,7 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
 
        struct nvme_copy_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .copy           = copy.f0,
                .sdlba          = cfg.sdlba,
@@ -5866,8 +5944,8 @@ static int copy(int argc, char **argv, struct command *cmd, struct plugin *plugi
        else
                printf("NVMe Copy: success\n");
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -5880,7 +5958,8 @@ static int flush(int argc, char **argv, struct command *cmd, struct plugin *plug
                "flushed by the controller, from any namespace, depending on controller and "\
                "associated namespace status.";
        const char *namespace_id = "identifier of desired namespace";
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -5895,27 +5974,27 @@ static int flush(int argc, char **argv, struct command *cmd, struct plugin *plug
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
-       err = nvme_flush(fd, cfg.namespace_id);
+       err = nvme_flush(dev->fd, cfg.namespace_id);
        if (err < 0)
                fprintf(stderr, "flush: %s\n", nvme_strerror(errno));
        else if (err != 0)
                nvme_show_status(err);
        else
                printf("NVMe Flush: success\n");
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -5934,7 +6013,8 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
        const char *rtype = "reservation type";
        const char *racqa = "reservation acquire action";
        const char *iekey = "ignore existing res. key";
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -5964,26 +6044,26 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
        if (cfg.racqa > 7) {
                fprintf(stderr, "invalid racqa:%d\n", cfg.racqa);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_resv_acquire_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .rtype          = cfg.rtype,
                .racqa          = cfg.racqa,
@@ -6001,8 +6081,8 @@ static int resv_acquire(int argc, char **argv, struct command *cmd, struct plugi
        else
                printf("NVME Reservation Acquire success\n");
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -6018,7 +6098,8 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
        const char *nrkey = "new reservation key";
        const char *rrega = "reservation registration action";
        const char *cptpl = "change persistence through power loss setting";
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -6047,32 +6128,32 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
        if (cfg.cptpl > 3) {
                fprintf(stderr, "invalid cptpl:%d\n", cfg.cptpl);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.rrega > 7) {
                fprintf(stderr, "invalid rrega:%d\n", cfg.rrega);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_resv_register_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .rrega          = cfg.rrega,
                .cptpl          = cfg.cptpl,
@@ -6090,8 +6171,8 @@ static int resv_register(int argc, char **argv, struct command *cmd, struct plug
        else
                printf("NVME Reservation  success\n");
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -6111,7 +6192,8 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
        const char *iekey = "ignore existing res. key";
        const char *rtype = "reservation type";
        const char *rrela = "reservation release action";
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -6138,26 +6220,26 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
        if (cfg.rrela > 7) {
                fprintf(stderr, "invalid rrela:%d\n", cfg.rrela);
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_resv_release_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .rtype          = cfg.rtype,
                .rrela          = cfg.rrela,
@@ -6174,8 +6256,8 @@ static int resv_release(int argc, char **argv, struct command *cmd, struct plugi
        else
                printf("NVME Reservation Release success\n");
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -6194,7 +6276,8 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
 
        struct nvme_resv_status *status;
        enum nvme_print_flags flags;
-       int err, fd, size;
+       struct nvme_dev *dev;
+       int err, size;
 
        struct config {
                __u32   namespace_id;
@@ -6221,21 +6304,21 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.raw_binary)
                flags = BINARY;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
@@ -6249,13 +6332,13 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
        if (posix_memalign((void **)&status, getpagesize(), size)) {
                fprintf(stderr, "No memory for resv report:%d\n", size);
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
        memset(status, 0, size);
 
        struct nvme_resv_report_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .eds            = cfg.eds,
                .len            = size,
@@ -6271,8 +6354,8 @@ static int resv_report(int argc, char **argv, struct command *cmd, struct plugin
        else
                fprintf(stderr, "reservation report: %s\n", nvme_strerror(errno));
        free(status);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -6291,7 +6374,7 @@ static int submit_io(int opcode, char *command, const char *desc,
        struct timeval start_time, end_time;
        void *buffer, *mbuffer = NULL;
        int err = 0;
-       int dfd, mfd, fd;
+       int dfd, mfd;
        int flags = opcode & 1 ? O_RDONLY : O_WRONLY | O_CREAT;
        int mode = S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP| S_IROTH;
        __u16 control = 0;
@@ -6302,6 +6385,7 @@ static int submit_io(int opcode, char *command, const char *desc,
        struct nvme_id_ns ns;
        struct nvme_nvm_id_ns nvm_ns;
        __u8 lba_index, ms = 0, sts = 0, pif = 0;
+       struct nvme_dev *dev;
 
        const char *namespace_id = "Identifier of desired namespace";
        const char *start_block = "64-bit addr of first block to access";
@@ -6404,14 +6488,14 @@ static int submit_io(int opcode, char *command, const char *desc,
        };
 
        if (opcode != nvme_cmd_write) {
-               err = fd = parse_and_open(argc, argv, desc, opts);
-               if (fd < 0)
+               err = parse_and_open(&dev, argc, argv, desc, opts);
+               if (err < 0)
                        goto ret;
        } else {
                err = argconfig_parse(argc, argv, desc, opts);
                if (err)
                        goto ret;
-               err = fd = open_exclusive(argc, argv, cfg.force);
+               err = open_exclusive(&dev, argc, argv, cfg.force);
                if (err < 0) {
                        if (errno == EBUSY) {
                                fprintf(stderr, "Failed to open %s.\n",
@@ -6429,17 +6513,17 @@ static int submit_io(int opcode, char *command, const char *desc,
        }
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        dfd = mfd = opcode & 1 ? STDIN_FILENO : STDOUT_FILENO;
        if (cfg.prinfo > 0xf) {
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        dsmgmt = cfg.dsmgmt;
@@ -6455,7 +6539,7 @@ static int submit_io(int opcode, char *command, const char *desc,
                        fprintf(stderr, "Invalid directive type, %x\n",
                                cfg.dtype);
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
                control |= cfg.dtype << 4;
                dsmgmt |= ((__u32)cfg.dspec) << 16;
@@ -6466,7 +6550,7 @@ static int submit_io(int opcode, char *command, const char *desc,
                if (dfd < 0) {
                        perror(cfg.data);
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
@@ -6485,9 +6569,9 @@ static int submit_io(int opcode, char *command, const char *desc,
                goto close_mfd;
        }
 
-       if (nvme_get_logical_block_size(fd, cfg.namespace_id,
+       if (nvme_get_logical_block_size(dev->fd, cfg.namespace_id,
                                        &logical_block_size) < 0)
-                       goto close_mfd;
+               goto close_mfd;
 
        buffer_size = ((long long)cfg.block_count + 1) * logical_block_size;
        if (cfg.data_size < buffer_size) {
@@ -6504,7 +6588,7 @@ static int submit_io(int opcode, char *command, const char *desc,
        }
 
        if (cfg.metadata_size) {
-               err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+               err = nvme_identify_ns(dev->fd, cfg.namespace_id, &ns);
                if (err > 0) {
                        nvme_show_status(err);
                        goto free_buffer;
@@ -6516,7 +6600,7 @@ static int submit_io(int opcode, char *command, const char *desc,
                nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
                ms = ns.lbaf[lba_index].ms;
 
-               err = nvme_identify_ns_csi(fd, 1, 0, NVME_CSI_NVM, &nvm_ns);
+               err = nvme_identify_ns_csi(dev->fd, 1, 0, NVME_CSI_NVM, &nvm_ns);
                if (!err) {
                        sts = nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
                        pif = (nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_PIF_MASK) >> 7; 
@@ -6585,7 +6669,7 @@ static int submit_io(int opcode, char *command, const char *desc,
 
        struct nvme_io_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .slba           = cfg.start_block,
                .nlb            = cfg.block_count,
@@ -6638,8 +6722,8 @@ close_mfd:
                close(mfd);
 close_dfd:
        close(dfd);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -6669,11 +6753,12 @@ static int write_cmd(int argc, char **argv, struct command *cmd, struct plugin *
 
 static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       int err, fd;
        __u16 control = 0;
        __u8 lba_index, sts = 0, pif = 0;
        struct nvme_id_ns ns;
        struct nvme_nvm_id_ns nvm_ns;
+       struct nvme_dev *dev;
+       int err;
 
        const char *desc = "Verify specified logical blocks on the given device.";
        const char *namespace_id = "desired namespace";
@@ -6732,13 +6817,13 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (cfg.prinfo > 0xf) {
                err = EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        control |= (cfg.prinfo << 10);
@@ -6750,23 +6835,23 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
                control |= NVME_IO_STC;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        fprintf(stderr, "get-namespace-id: %s\n", nvme_strerror(errno));
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
-       err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+       err = nvme_identify_ns(dev->fd, cfg.namespace_id, &ns);
        if (err) {
                nvme_show_status(err);
-               goto close_fd;
+               goto close_dev;
        } else if (err < 0) {
                fprintf(stderr, "identify namespace: %s\n", nvme_strerror(errno));
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_identify_ns_csi(fd, cfg.namespace_id, 0, NVME_CSI_NVM, &nvm_ns);
+       err = nvme_identify_ns_csi(dev->fd, cfg.namespace_id, 0, NVME_CSI_NVM, &nvm_ns);
        if (!err) {
                nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
                sts = nvm_ns.elbaf[lba_index] & NVME_NVM_ELBAF_STS_MASK;
@@ -6775,12 +6860,12 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
 
        if (invalid_tags(cfg.storage_tag, cfg.ref_tag, sts, pif)) {
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_io_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .slba           = cfg.start_block,
                .nlb            = cfg.block_count,
@@ -6802,8 +6887,8 @@ static int verify_cmd(int argc, char **argv, struct command *cmd, struct plugin
        else
                printf("NVME Verify Success\n");
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -6823,8 +6908,9 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
        const char *raw = "dump output in binary format";
        const char *namespace_id = "desired namespace";
        const char *nssf = "NVMe Security Specific Field";
-       int err, fd;
+       struct nvme_dev *dev;
        void *sec_buf = NULL;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -6857,8 +6943,8 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (cfg.size) {
@@ -6866,13 +6952,13 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
                        fprintf(stderr, "No memory for security size:%d\n",
                                                                cfg.size);
                        err = -ENOMEM;
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        struct nvme_security_receive_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .nssf           = cfg.nssf,
                .spsp0          = cfg.spsp & 0xff,
@@ -6899,8 +6985,8 @@ static int sec_recv(int argc, char **argv, struct command *cmd, struct plugin *p
 
        free(sec_buf);
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -6923,8 +7009,9 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
 
        enum nvme_print_flags flags;
        unsigned long buf_len;
-       int err, fd;
+       struct nvme_dev *dev;
        void *buf;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -6957,30 +7044,30 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto err;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
        if (!cfg.atype) {
                fprintf(stderr, "action type (--action) has to be given\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        buf_len = (cfg.mndw + 1) * 4;
        buf = calloc(1, buf_len);
        if (!buf) {
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_get_lba_status_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .slba           = cfg.slba,
                .mndw           = cfg.mndw,
@@ -6998,8 +7085,8 @@ static int get_lba_status(int argc, char **argv, struct command *cmd,
        else
                fprintf(stderr, "get lba status: %s\n", nvme_strerror(errno));
        free(buf);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 err:
        return err;
 }
@@ -7017,7 +7104,8 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug
        const char *cap_upper = "Most significant 32 bits of the capacity in bytes of the "\
                "Endurance Group or NVM Set to be created";
 
-       int err = -1, fd;
+       struct nvme_dev *dev;
+       int err = -1;
        __u32 result;
 
        struct config {
@@ -7042,19 +7130,19 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (cfg.operation > 0xf) {
                fprintf(stderr, "invalid operation field: %u\n", cfg.operation);
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_capacity_mgmt_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .op             = cfg.operation,
                .element_id     = cfg.element_id,
                .cdw11          = cfg.dw11,
@@ -7075,8 +7163,8 @@ static int capacity_mgmt(int argc, char **argv, struct command *cmd, struct plug
        else if (err < 0)
                fprintf(stderr, "capacity management: %s\n", nvme_strerror(errno));
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -7095,10 +7183,11 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
        const char *human_readable = "show directive in readable format";
 
        enum nvme_print_flags flags = NORMAL;
-       int err, fd;
+       struct nvme_dev *dev;
        __u32 result;
        __u32 dw12 = 0;
        void *buf = NULL;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -7134,8 +7223,8 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (cfg.human_readable)
@@ -7153,7 +7242,7 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
                default:
                        fprintf(stderr, "invalid directive operations for Identify Directives\n");
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
                break;
        case NVME_DIRECTIVE_DTYPE_STREAMS:
@@ -7172,26 +7261,26 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
                default:
                        fprintf(stderr, "invalid directive operations for Streams Directives\n");
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
                break;
        default:
                fprintf(stderr, "invalid directive type\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.data_len) {
                if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
                        err = -ENOMEM;
-                       goto close_fd;
+                       goto close_dev;
                }
                memset(buf, 0, cfg.data_len);
        }
 
        struct nvme_directive_recv_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .dspec          = cfg.dspec,
                .doper          = cfg.doper,
@@ -7213,8 +7302,8 @@ static int dir_receive(int argc, char **argv, struct command *cmd, struct plugin
                fprintf(stderr, "dir-receive: %s\n", nvme_strerror(errno));
 
        free(buf);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -7247,7 +7336,8 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi
                "List that is used by the command.If this field is cleared to 0h,"\
                "then no UUID index is specified";
 
-       int fd, err = -1;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                __u8    ofi;
@@ -7274,35 +7364,35 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        /* check for input argument limit */
        if (cfg.ifc > 3) {
                fprintf(stderr, "invalid interface settings:%d\n", cfg.ifc);
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.prhbt > 1) {
                fprintf(stderr, "invalid prohibit settings:%d\n", cfg.prhbt);
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.scp > 15) {
                fprintf(stderr, "invalid scope settings:%d\n", cfg.scp);
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.uuid > 127) {
                fprintf(stderr, "invalid UUID index settings:%d\n", cfg.uuid);
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
 
        struct nvme_lockdown_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .scp            = cfg.scp,
                .prhbt          = cfg.prhbt,
                .ifc            = cfg.ifc,
@@ -7319,8 +7409,8 @@ static int lockdown_cmd(int argc, char **argv, struct command *cmd, struct plugi
        else
                printf("Lockdown Command is Successful\n");
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -7356,7 +7446,8 @@ static int passthru(int argc, char **argv, bool admin,
        int flags;
        int mode = S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP| S_IROTH;
        void *data = NULL, *mdata = NULL;
-       int err = 0, dfd, mfd, fd;
+       int err = 0, dfd, mfd;
+       struct nvme_dev *dev;
        __u32 result;
        bool huge = false;
        const char *cmd_name = NULL;
@@ -7444,8 +7535,8 @@ static int passthru(int argc, char **argv, bool admin,
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        if (cfg.opcode & 0x01)
@@ -7469,7 +7560,7 @@ static int passthru(int argc, char **argv, bool admin,
                if (dfd < 0) {
                        perror(cfg.input_file);
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
@@ -7546,13 +7637,13 @@ static int passthru(int argc, char **argv, bool admin,
        gettimeofday(&start_time, NULL);
 
        if (admin)
-               err = nvme_admin_passthru(fd, cfg.opcode, cfg.flags, cfg.rsvd,
+               err = nvme_admin_passthru(dev->fd, cfg.opcode, cfg.flags, cfg.rsvd,
                                cfg.namespace_id, cfg.cdw2, cfg.cdw3, cfg.cdw10,
                                cfg.cdw11, cfg.cdw12, cfg.cdw13, cfg.cdw14,
                                cfg.cdw15, cfg.data_len, data, cfg.metadata_len,
                                mdata, cfg.timeout, &result);
        else
-               err = nvme_io_passthru(fd, cfg.opcode, cfg.flags, cfg.rsvd,
+               err = nvme_io_passthru(dev->fd, cfg.opcode, cfg.flags, cfg.rsvd,
                                cfg.namespace_id, cfg.cdw2, cfg.cdw3, cfg.cdw10,
                                cfg.cdw11, cfg.cdw12, cfg.cdw13, cfg.cdw14,
                                cfg.cdw15, cfg.data_len, data, cfg.metadata_len,
@@ -7597,8 +7688,8 @@ close_dfd:
 close_mfd:
        if (strlen(cfg.metadata))
                close(mfd);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
diff --git a/nvme.h b/nvme.h
index ca193250c00128bde6a89bf56dcbde6eeed82699..c149ed352931dd05269383f76d128f9021142437 100644 (file)
--- a/nvme.h
+++ b/nvme.h
@@ -37,15 +37,22 @@ enum nvme_print_flags {
 
 #define SYS_NVME "/sys/class/nvme"
 
-void register_extension(struct plugin *plugin);
-int parse_and_open(int argc, char **argv, const char *desc,
-       const struct argconfig_commandline_options *clo);
-
 struct nvme_dev {
+       int fd;
        struct stat stat;
        const char *name;
 };
 
+void register_extension(struct plugin *plugin);
+
+/*
+ * parse_and_open - parses arguments and opens the NVMe device, populating @dev
+ */
+int parse_and_open(struct nvme_dev **dev, int argc, char **argv, const char *desc,
+       const struct argconfig_commandline_options *clo);
+
+void dev_close(struct nvme_dev *dev);
+
 extern struct nvme_dev *nvme_dev;
 extern const char *output_format;
 
index 1390be055ebf715ba61b9782e4549067db484abf..a4ec0a0712753b3530664816ffb0f4208f5902da 100644 (file)
@@ -117,20 +117,21 @@ static int nvme_dera_get_device_status(int fd, enum dera_device_status *result)
 
 static int get_status(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       int fd, err;
        struct nvme_dera_smart_info_log log;
        enum dera_device_status state = DEVICE_STATUS_FATAL_ERROR;
        char *desc = "Get the Dera device status";
+       struct nvme_dev *dev;
+       int err;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
        
-       err = nvme_get_log_simple(fd, 0xc0, sizeof(log), &log);
+       err = nvme_get_log_simple(dev->fd, 0xc0, sizeof(log), &log);
        if (err) {
                goto exit;
        }
@@ -153,7 +154,7 @@ static int get_status(int argc, char **argv, struct command *cmd, struct plugin
                "Runtime Low",
        };
 
-       err = nvme_dera_get_device_status(fd, &state);
+       err = nvme_dera_get_device_status(dev->fd, &state);
        if (!err){
                if (state > 0 && state < 4){
                        printf("device_status                       : %s %d%% completed\n", dev_status[state], log.rebuild_percent);
@@ -205,7 +206,7 @@ exit:
        if (err > 0)
                nvme_show_status(err);
 
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
index fc017b1467cc6bf0a2a4bc071fe8d28c18d85a2b..2e720a923c2fe3ef1b2f81ca8b398e39f75267ed 100644 (file)
@@ -20,10 +20,11 @@ static int innogrit_smart_log_additional(int argc, char **argv,
                                         struct plugin *plugin)
 {
        struct nvme_smart_log smart_log = { 0 };
-       int fd, i, iindex;
        struct vsc_smart_log *pvsc_smart = (struct vsc_smart_log *)smart_log.rsvd232;
        const char *desc = "Retrieve additional SMART log for the given device ";
        const char *namespace = "(optional) desired namespace";
+       struct nvme_dev *dev;
+       int err, i, iindex;
 
        struct config {
                __u32 namespace_id;
@@ -38,11 +39,11 @@ static int innogrit_smart_log_additional(int argc, char **argv,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
-       nvme_get_log_smart(fd, cfg.namespace_id, false, &smart_log);
+       nvme_get_log_smart(dev->fd, cfg.namespace_id, false, &smart_log);
        nvme_show_smart_log(&smart_log, cfg.namespace_id,
                            nvme_dev->name, NORMAL);
 
@@ -164,9 +165,10 @@ static int innogrit_vsc_geteventlog(int argc, char **argv,
        unsigned int isize, icheck_stopvalue, iend;
        unsigned char bSortLog = false, bget_nextlog = true;
        struct evlg_flush_hdr *pevlog = (struct evlg_flush_hdr *)data;
-       int fd, ret = -1;
        const char *desc = "Recrieve event log for the given device ";
        const char *clean_opt = "(optional) 1 for clean event log";
+       struct nvme_dev *dev;
+       int ret = -1;
 
        struct config {
                __u32 clean_flg;
@@ -181,9 +183,9 @@ static int innogrit_vsc_geteventlog(int argc, char **argv,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
 
        if (getcwd(currentdir, 128) == NULL)
@@ -212,8 +214,10 @@ static int innogrit_vsc_geteventlog(int argc, char **argv,
                icount++;
 
                memset(data, 0, 4096);
-               ret = nvme_vucmd(fd, NVME_VSC_GET_EVENT_LOG, 0, 0, (SRB_SIGNATURE >> 32),
-                       (SRB_SIGNATURE & 0xFFFFFFFF), (char *)data, 4096);
+               ret = nvme_vucmd(dev->fd, NVME_VSC_GET_EVENT_LOG, 0, 0,
+                                (SRB_SIGNATURE >> 32),
+                                (SRB_SIGNATURE & 0xFFFFFFFF),
+                                (char *)data, 4096);
                if (ret == -1)
                        return ret;
 
@@ -278,10 +282,12 @@ static int innogrit_vsc_geteventlog(int argc, char **argv,
 
        if (cfg.clean_flg == 1) {
                printf("Clean eventlog\n");
-               nvme_vucmd(fd, NVME_VSC_CLEAN_EVENT_LOG, 0, 0, (SRB_SIGNATURE >> 32),
+               nvme_vucmd(dev->fd, NVME_VSC_CLEAN_EVENT_LOG, 0, 0, (SRB_SIGNATURE >> 32),
                        (SRB_SIGNATURE & 0xFFFFFFFF), (char *)NULL, 0);
        }
 
+       dev_close(dev);
+
        return ret;
 }
 
@@ -297,16 +303,17 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
        unsigned char busevsc = false;
        unsigned int ipackcount, ipackindex;
        char fwvera[32];
-       int fd, ret = -1;
        const char *desc = "Recrieve cdump data for the given device ";
+       struct nvme_dev *dev;
+       int ret = -1;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        if (getcwd(currentdir, 128) == NULL)
                return -1;
@@ -316,8 +323,9 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
 
        ipackindex = 0;
        memset(data, 0, 4096);
-       if (nvme_vucmd(fd, NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, (SRB_SIGNATURE >> 32),
-               (SRB_SIGNATURE & 0xFFFFFFFF), (char *)data, 4096) == 0) {
+       if (nvme_vucmd(dev->fd, NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00,
+                      (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF),
+                      (char *)data, 4096) == 0) {
                memcpy(&cdumpinfo, &data[3072], sizeof(cdumpinfo));
                if (cdumpinfo.sig == 0x5a5b5c5d) {
                        busevsc = true;
@@ -338,7 +346,8 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
 
        if (busevsc == false) {
                memset(data, 0, 4096);
-               ret = nvme_get_nsid_log(fd, true, 0x07, NVME_NSID_ALL, 4096, data);
+               ret = nvme_get_nsid_log(dev->fd, true, 0x07, NVME_NSID_ALL,
+                                       4096, data);
                if (ret != 0)
                        return ret;
 
@@ -361,10 +370,14 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
                for (icur = 0; icur < itotal; icur += 4096) {
                        memset(data, 0, 4096);
                        if (busevsc)
-                               ret = nvme_vucmd(fd, NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, (SRB_SIGNATURE >> 32),
-                                       (SRB_SIGNATURE & 0xFFFFFFFF), (char *)data, 4096);
+                               ret = nvme_vucmd(dev->fd, NVME_VSC_GET,
+                                                VSC_FN_GET_CDUMP, 0x00,
+                                                (SRB_SIGNATURE >> 32),
+                                                (SRB_SIGNATURE & 0xFFFFFFFF),
+                                                (char *)data, 4096);
                        else
-                               ret = nvme_get_nsid_log(fd, true, 0x07, NVME_NSID_ALL, 4096, data);
+                               ret = nvme_get_nsid_log(dev->fd, true, 0x07,
+                                                       NVME_NSID_ALL, 4096, data);
                        if (ret != 0)
                                return ret;
 
@@ -380,10 +393,15 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
                if (ipackindex != ipackcount) {
                        memset(data, 0, 4096);
                        if (busevsc)
-                               ret = nvme_vucmd(fd, NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, (SRB_SIGNATURE >> 32),
-                                       (SRB_SIGNATURE & 0xFFFFFFFF), (char *)data, 4096);
+                               ret = nvme_vucmd(dev->fd, NVME_VSC_GET,
+                                                VSC_FN_GET_CDUMP, 0x00,
+                                                (SRB_SIGNATURE >> 32),
+                                                (SRB_SIGNATURE & 0xFFFFFFFF),
+                                                (char *)data, 4096);
                        else
-                               ret = nvme_get_nsid_log(fd, true, 0x07, NVME_NSID_ALL, 4096, data);
+                               ret = nvme_get_nsid_log(dev->fd, true, 0x07,
+                                                       NVME_NSID_ALL, 4096,
+                                                       data);
                        if (ret != 0)
                                return ret;
 
@@ -399,5 +417,6 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
        }
 
        printf("\n");
+       dev_close(dev);
        return ret;
 }
index 7351d6689604ce4390666dcd67663078725e9b87..6bde99999ed403e48fad949b411d53ac63842ef3 100644 (file)
@@ -344,7 +344,8 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
        const char *json= "Dump output in json format";
 
        struct nvme_additional_smart_log smart_log;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32 namespace_id;
@@ -363,11 +364,11 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
-       err = nvme_get_log_simple(fd, 0xca, sizeof(smart_log), &smart_log);
+       err = nvme_get_log_simple(dev->fd, 0xca, sizeof(smart_log), &smart_log);
        if (!err) {
                if (cfg.json)
                        show_intel_smart_log_jsn(&smart_log, cfg.namespace_id,
@@ -380,7 +381,7 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
        }
        else if (err > 0)
                nvme_show_status(err);
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -388,9 +389,9 @@ static int get_market_log(int argc, char **argv, struct command *cmd, struct plu
 {
        const char *desc = "Get Intel Marketing Name log and show it.";
        const char *raw = "dump output in binary format";
-
+       struct nvme_dev *dev;
        char log[512];
-       int err, fd;
+       int err;
 
        struct config {
                bool  raw_binary;
@@ -404,11 +405,11 @@ static int get_market_log(int argc, char **argv, struct command *cmd, struct plu
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
-       err = nvme_get_log_simple(fd, 0xdd, sizeof(log), log);
+       err = nvme_get_log_simple(dev->fd, 0xdd, sizeof(log), log);
        if (!err) {
                if (!cfg.raw_binary)
                        printf("Intel Marketing Name Log:\n%s\n", log);
@@ -416,7 +417,7 @@ static int get_market_log(int argc, char **argv, struct command *cmd, struct plu
                        d_raw((unsigned char *)&log, sizeof(log));
        } else if (err > 0)
                nvme_show_status(err);
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -449,7 +450,8 @@ static void show_temp_stats(struct intel_temp_stats *stats)
 static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        struct intel_temp_stats stats;
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        const char *desc = "Get Temperature Statistics log and show it.";
        const char *raw = "dump output in binary format";
@@ -465,11 +467,11 @@ static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
-       err = nvme_get_log_simple(fd, 0xc5, sizeof(stats), &stats);
+       err = nvme_get_log_simple(dev->fd, 0xc5, sizeof(stats), &stats);
        if (!err) {
                if (!cfg.raw_binary)
                        show_temp_stats(&stats);
@@ -477,7 +479,7 @@ static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct
                        d_raw((unsigned char *)&stats, sizeof(stats));
        } else if (err > 0)
                nvme_show_status(err);
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -1026,9 +1028,9 @@ static void show_lat_stats(int write)
 
 static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-
-       int err, fd;
        __u8 data[NAND_LAT_STATS_LEN];
+       struct nvme_dev *dev;
+       int err;
 
        const char *desc = "Get Intel Latency Statistics log and show it.";
        const char *raw = "Dump output in binary format";
@@ -1051,14 +1053,14 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        /* For optate, latency stats are deleted every time their LID is pulled.
         * Therefore, we query the longest lat_stats log page first.
         */
-       err = nvme_get_log_simple(fd, cfg.write ? 0xc2 : 0xc1,
+       err = nvme_get_log_simple(dev->fd, cfg.write ? 0xc2 : 0xc1,
                           sizeof(data), &data);
 
        media_version[0] = (data[1] << 8) | data[0];
@@ -1073,7 +1075,7 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
 
                struct nvme_get_features_args args = {
                        .args_size      = sizeof(args),
-                       .fd             = fd,
+                       .fd             = dev->fd,
                        .fid            = 0xf7,
                        .nsid           = 0,
                        .sel            = 0,
@@ -1125,7 +1127,7 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
        }
 
 close_fd:
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -1340,13 +1342,14 @@ static int get_internal_log(int argc, char **argv, struct command *command,
 {
        __u8 buf[0x2000];
        char f[0x100];
-       int err, fd, output, i, j, count = 0, core_num = 1;
+       int err, output, i, j, count = 0, core_num = 1;
        struct nvme_passthru_cmd cmd;
        struct intel_cd_log cdlog;
        struct intel_vu_log *intel = malloc(sizeof(struct intel_vu_log));
        struct intel_vu_nlog *intel_nlog = (struct intel_vu_nlog *)buf;
        struct intel_assert_dump *ad = (struct intel_assert_dump *) intel->reserved;
        struct intel_event_header *ehdr = (struct intel_event_header *)intel->reserved;
+       struct nvme_dev *dev;
 
        const char *desc = "Get Intel Firmware Log and save it.";
        const char *log = "Log type: 0, 1, or 2 for nlog, event log, and assert log, respectively.";
@@ -1382,10 +1385,10 @@ static int get_internal_log(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0) {
                free(intel);
-               return fd;
+               return err;
        }
 
        if (cfg.log > 2 || cfg.core > 4 || cfg.lnum > 255) {
@@ -1394,7 +1397,7 @@ static int get_internal_log(int argc, char **argv, struct command *command,
        }
 
        if (!cfg.file) {
-               err = setup_file(f, cfg.file, fd, cfg.log);
+               err = setup_file(f, cfg.file, dev->fd, cfg.log);
                if (err)
                        goto out_free;
                cfg.file = f;
@@ -1412,7 +1415,7 @@ static int get_internal_log(int argc, char **argv, struct command *command,
                goto out_free;
        }
 
-       err = read_header(&cmd, buf, fd, cdlog.u.entireDword, cfg.namespace_id);
+       err = read_header(&cmd, buf, dev->fd, cdlog.u.entireDword, cfg.namespace_id);
        if (err)
                goto out;
        memcpy(intel, buf, sizeof(*intel));
@@ -1421,7 +1424,7 @@ static int get_internal_log(int argc, char **argv, struct command *command,
        if ((intel->ver.major < 1 && intel->ver.minor < 1) ||
            (intel->ver.major <= 1 && intel->ver.minor <= 1 && cfg.log == 0)) {
                cmd.addr = (unsigned long)(void *)buf;
-               err = get_internal_log_old(buf, output, fd, &cmd);
+               err = get_internal_log_old(buf, output, dev->fd, &cmd);
                goto out;
        }
 
@@ -1465,7 +1468,8 @@ static int get_internal_log(int argc, char **argv, struct command *command,
                                cmd.cdw10 = 0x400;
                                cmd.data_len = min(0x400, ad[i].assertsize) * 4;
                                err = read_entire_cmd(&cmd, ad[i].assertsize,
-                                                     0x400, output, fd, buf);
+                                                     0x400, output, dev->fd,
+                                                     buf);
                                if (err)
                                        goto out;
 
@@ -1474,8 +1478,9 @@ static int get_internal_log(int argc, char **argv, struct command *command,
                                if (count > 1)
                                        cdlog.u.fields.selectNlog = i;
 
-                               err = read_header(&cmd, buf, fd, cdlog.u.entireDword,
-                                               cfg.namespace_id);
+                               err = read_header(&cmd, buf, dev->fd,
+                                                 cdlog.u.entireDword,
+                                                 cfg.namespace_id);
                                if (err)
                                        goto out;
                                err = write_header(buf, output, sizeof(*intel_nlog));
@@ -1487,7 +1492,8 @@ static int get_internal_log(int argc, char **argv, struct command *command,
                                cmd.cdw10 = 0x400;
                                cmd.data_len = min(0x1000, intel_nlog->nlogbytesize);
                                err = read_entire_cmd(&cmd, intel_nlog->nlogbytesize / 4,
-                                                     0x400, output, fd, buf);
+                                                     0x400, output, dev->fd,
+                                                     buf);
                                if (err)
                                        goto out;
                        } else if (cfg.log == 1) {
@@ -1495,7 +1501,8 @@ static int get_internal_log(int argc, char **argv, struct command *command,
                                cmd.cdw10 = 0x400;
                                cmd.data_len = 0x400;
                                err = read_entire_cmd(&cmd, ehdr->edumps[j].coresize,
-                                                     0x400, output, fd, buf);
+                                                     0x400, output, dev->fd,
+                                                     buf);
                                if (err)
                                        goto out;
                        }
@@ -1513,14 +1520,13 @@ out:
        close(output);
 out_free:
        free(intel);
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
 static int enable_lat_stats_tracking(int argc, char **argv,
                struct command *command, struct plugin *plugin)
 {
-       int err, fd;
        const char *desc = (
                        "Enable/Disable Intel Latency Statistics Tracking.\n"
                        "No argument prints current status.");
@@ -1533,8 +1539,10 @@ static int enable_lat_stats_tracking(int argc, char **argv,
        const __u32 cdw12 = 0x0;
        const __u32 data_len = 32;
        const __u32 save = 0;
-       __u32 result;
+       struct nvme_dev *dev;
        void *buf = NULL;
+       __u32 result;
+       int err;
 
        struct config {
                bool enable, disable;
@@ -1551,7 +1559,7 @@ static int enable_lat_stats_tracking(int argc, char **argv,
                {NULL}
        };
 
-       fd = parse_and_open(argc, argv, desc, command_line_options);
+       err = parse_and_open(&dev, argc, argv, desc, command_line_options);
 
        enum Option {
                None = -1,
@@ -1566,12 +1574,12 @@ static int enable_lat_stats_tracking(int argc, char **argv,
        else if (cfg.enable || cfg.disable)
                option = cfg.enable;
 
-       if (fd < 0)
-               return fd;
+       if (err < 0)
+               return err;
 
        struct nvme_get_features_args args_get = {
                .args_size      = sizeof(args_get),
-               .fd             = fd,
+               .fd             = dev->fd,
                .fid            = fid,
                .nsid           = nsid,
                .sel            = sel,
@@ -1585,7 +1593,7 @@ static int enable_lat_stats_tracking(int argc, char **argv,
 
        struct nvme_set_features_args args_set = {
                .args_size      = sizeof(args_set),
-               .fd             = fd,
+               .fd             = dev->fd,
                .fid            = fid,
                .nsid           = nsid,
                .cdw11          = option,
@@ -1608,7 +1616,7 @@ static int enable_lat_stats_tracking(int argc, char **argv,
                                fid, result);
                } else {
                        printf("Could not read feature id 0xE2.\n");
-                       close(fd);
+                       dev_close(dev);
                        return err;
                }
                break;
@@ -1629,14 +1637,13 @@ static int enable_lat_stats_tracking(int argc, char **argv,
                printf("%d not supported.\n", option);
                return EINVAL;
        }
-       close(fd);
-       return fd;
+       dev_close(dev);
+       return err;
 }
 
 static int set_lat_stats_thresholds(int argc, char **argv,
                struct command *command, struct plugin *plugin)
 {
-       int err, fd, num;
        const char *desc = "Write Intel Bucket Thresholds for Latency Statistics Tracking";
        const char *bucket_thresholds = "Bucket Threshold List, comma separated list: 0, 10, 20 ...";
        const char *write = "Set write bucket Thresholds for latency tracking (read default)";
@@ -1645,7 +1652,9 @@ static int set_lat_stats_thresholds(int argc, char **argv,
        const __u8 fid = 0xf7;
        const __u32 cdw12 = 0x0;
        const __u32 save = 0;
+       struct nvme_dev *dev;
        __u32 result;
+       int err, num;
 
        struct config {
                bool write;
@@ -1664,21 +1673,21 @@ static int set_lat_stats_thresholds(int argc, char **argv,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
+       err = parse_and_open(&dev, argc, argv, desc, opts);
 
-       if (fd < 0)
-               return fd;
+       if (err < 0)
+               return err;
 
        /* Query maj and minor version first to figure out the amount of
         * valid buckets a user is allowed to modify. Read or write doesn't
         * matter
         */
-       err = nvme_get_log_simple(fd, 0xc2,
+       err = nvme_get_log_simple(dev->fd, 0xc2,
                           sizeof(media_version), media_version);
        if (err) {
                fprintf(stderr, "Querying media version failed. ");
                nvme_show_status(err);
-               goto close_fd;
+               goto close_dev;
        }
 
        if (media_version[0] == 1000) {
@@ -1688,13 +1697,13 @@ static int set_lat_stats_thresholds(int argc, char **argv,
                                                      sizeof(thresholds));
                if (num == -1) {
                        fprintf(stderr, "ERROR: Bucket list is malformed\n");
-                       goto close_fd;
+                       goto close_dev;
 
                }
 
                struct nvme_set_features_args args = {
                        .args_size      = sizeof(args),
-                       .fd             = fd,
+                       .fd             = dev->fd,
                        .fid            = fid,
                        .nsid           = nsid,
                        .cdw11          = cfg.write ? 0x1 : 0x0,
@@ -1719,8 +1728,8 @@ static int set_lat_stats_thresholds(int argc, char **argv,
                fprintf(stderr, "Unsupported command\n");
        }
 
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
        return err;
 }
 
index f8eeb078606ecf07938a6694e8ae5d7780056ad1..856a579091cdecbcd6b469b6374b0ba32af817b1 100644 (file)
@@ -453,15 +453,16 @@ int parse_params(char *str, int number, ...)
 static int mb_get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        struct nvme_memblaze_smart_log smart_log;
-       int err, fd;
        char *desc = "Get Memblaze vendor specific additional smart log (optionally, "\
                      "for the specified namespace), and show it.";
        const char *namespace = "(optional) desired namespace";
        const char *raw = "dump output in binary format";
+       struct nvme_dev *dev;
        struct config {
                __u32 namespace_id;
                bool  raw_binary;
        };
+       int err;
 
        struct config cfg = {
                .namespace_id = NVME_NSID_ALL,
@@ -473,15 +474,15 @@ static int mb_get_additional_smart_log(int argc, char **argv, struct command *cm
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
-       err = nvme_get_nsid_log(fd, false, 0xca, cfg.namespace_id,
+       err = nvme_get_nsid_log(dev->fd, false, 0xca, cfg.namespace_id,
                sizeof(smart_log), &smart_log);
        if (!err) {
                if (!cfg.raw_binary)
-                       err = show_memblaze_smart_log(fd, cfg.namespace_id,
+                       err = show_memblaze_smart_log(dev->fd, cfg.namespace_id,
                                                      nvme_dev->name,
                                                      &smart_log);
                else
@@ -490,7 +491,7 @@ static int mb_get_additional_smart_log(int argc, char **argv, struct command *cm
        if (err > 0)
                nvme_show_status(err);
 
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -507,20 +508,22 @@ static char *mb_feature_to_string(int feature)
 static int mb_get_powermanager_status(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
     const char *desc = "Get Memblaze power management ststus\n (value 0 - 25w, 1 - 20w, 2 - 15w)";
-    int err, fd;
     __u32 result;
     __u32 feature_id = MB_FEAT_POWER_MGMT;
+    struct nvme_dev *dev;
+    int err;
 
     OPT_ARGS(opts) = {
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0) return fd;
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0)
+           return err;
 
     struct nvme_get_features_args args = {
            .args_size          = sizeof(args),
-           .fd                 = fd,
+           .fd                 = dev->fd,
            .fid                = feature_id,
            .nsid               = 0,
            .sel                = 0,
@@ -541,7 +544,7 @@ static int mb_get_powermanager_status(int argc, char **argv, struct command *cmd
             nvme_select_to_string(0), result);
     } else if (err > 0)
            nvme_show_status(err);
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -550,8 +553,9 @@ static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd
     const char *desc = "Set Memblaze power management status\n (value 0 - 25w, 1 - 20w, 2 - 15w)";
     const char *value = "new value of feature (required)";
     const char *save = "specifies that the controller shall save the attribute";
-    int err, fd;
+    struct nvme_dev *dev;
     __u32 result;
+    int err;
 
     struct config {
         __u32 feature_id;
@@ -571,12 +575,13 @@ static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0) return fd;
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0)
+           return err;
 
     struct nvme_set_features_args args = {
            .args_size          = sizeof(args),
-           .fd                 = fd,
+           .fd                 = dev->fd,
            .fid                = cfg.feature_id,
            .nsid               = 0,
            .cdw11              = cfg.value,
@@ -599,7 +604,7 @@ static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd
     } else if (err > 0)
        nvme_show_status(err);
 
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -613,9 +618,10 @@ static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, s
                        "       p1 value: 0 is disable, 1 is enable\n"\
                        "       p2 value: 1 .. 5000 ms";
     const char *param = "input parameters";
-    int err, fd;
-    __u32 result;
     int param1 = 0, param2 = 0;
+    struct nvme_dev *dev;
+    __u32 result;
+    int err;
 
     struct config {
         __u32 feature_id;
@@ -634,24 +640,25 @@ static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, s
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0) return fd;
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0)
+           return err;
 
     if (parse_params(cfg.param, 2, &param1, &param2)) {
         printf("setfeature: invalid formats %s\n", cfg.param);
-        close(fd);
+        dev_close(dev);
         return EINVAL;
     }
     if ((param1 == 1) && (param2 < P2MIN || param2 > P2MAX)) {
         printf("setfeature: invalid high io latency threshold %d\n", param2);
-        close(fd);
+        dev_close(dev);
         return EINVAL;
     }
     cfg.value = (param1 << MB_FEAT_HIGH_LATENCY_VALUE_SHIFT) | param2;
 
     struct nvme_set_features_args args = {
            .args_size          = sizeof(args),
-           .fd                 = fd,
+           .fd                 = dev->fd,
            .fid                = cfg.feature_id,
            .nsid               = 0,
            .cdw11              = cfg.value,
@@ -674,7 +681,7 @@ static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, s
     } else if (err > 0)
        nvme_show_status(err);
 
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -776,25 +783,29 @@ static int glp_high_latency(FILE *fdi, char *buf, int buflen, int print)
 static int mb_high_latency_log_print(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
     const char *desc = "Get Memblaze high latency log";
-    int err, fd;
     char buf[LOG_PAGE_SIZE];
+    struct nvme_dev *dev;
     FILE *fdi = NULL;
+    int err;
 
     OPT_ARGS(opts) = {
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0) return fd;
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0)
+           return err;
 
     fdi = fopen(FID_C3_LOG_FILENAME, "w+");
 
     glp_high_latency_show_bar(fdi, DO_PRINT_FLAG);
-    err = nvme_get_log_simple(fd, GLP_ID_VU_GET_HIGH_LATENCY_LOG, sizeof(buf), &buf);
+    err = nvme_get_log_simple(dev->fd, GLP_ID_VU_GET_HIGH_LATENCY_LOG,
+                             sizeof(buf), &buf);
 
     while (1) {
         if (!glp_high_latency(fdi, buf, LOG_PAGE_SIZE, DO_PRINT_FLAG)) break;
-        err = nvme_get_log_simple(fd, GLP_ID_VU_GET_HIGH_LATENCY_LOG, sizeof(buf), &buf);
+        err = nvme_get_log_simple(dev->fd, GLP_ID_VU_GET_HIGH_LATENCY_LOG,
+                                 sizeof(buf), &buf);
         if ( err) {
            nvme_show_status(err);
             break;
@@ -802,7 +813,7 @@ static int mb_high_latency_log_print(int argc, char **argv, struct command *cmd,
     }
 
     if (NULL != fdi) fclose(fdi);
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -831,7 +842,8 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str
        const char *select = "FW Select (e.g., --select=OOB, EEP, ALL)";
        int xfer = 4096;
        void *fw_buf;
-       int fd, selectNo,fw_fd,fw_size,err,offset = 0;
+       int selectNo,fw_fd,fw_size,err,offset = 0;
+       struct nvme_dev *dev;
        struct stat sb;
        int i;
 
@@ -851,9 +863,9 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        if (strlen(cfg.select) != 3) {
                fprintf(stderr, "Invalid select flag\n");
@@ -914,7 +926,7 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str
 
                struct nvme_fw_download_args args = {
                        .args_size      = sizeof(args),
-                       .fd             = fd,
+                       .fd             = dev->fd,
                        .offset         = offset,
                        .data_len       = xfer,
                        .data           = fw_buf,
@@ -934,7 +946,7 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str
                offset += xfer;
        }
 
-       err = memblaze_fw_commit(fd,selectNo);
+       err = memblaze_fw_commit(dev->fd, selectNo);
 
        if(err == 0x10B || err == 0x20B) {
                err = 0;
@@ -946,7 +958,7 @@ out_free:
 out_close:
        close(fw_fd);
 out:
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -1053,10 +1065,10 @@ int io_latency_histogram(char *file, char *buf, int print, int logid)
 static int mb_lat_stats_log_print(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
     char stats[LOG_PAGE_SIZE];
-    int err = 0;
-    int fd;
     char f1[] = FID_C1_LOG_FILENAME;
     char f2[] = FID_C2_LOG_FILENAME;
+    struct nvme_dev *dev;
+    int err;
 
     const char *desc = "Get Latency Statistics log and show it.";
     const char *write = "Get write statistics (read default)";
@@ -1073,17 +1085,19 @@ static int mb_lat_stats_log_print(int argc, char **argv, struct command *cmd, st
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0) return fd;
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0)
+           return err;
 
-    err = nvme_get_log_simple(fd, cfg.write ? 0xc2 : 0xc1, sizeof(stats), &stats);
+    err = nvme_get_log_simple(dev->fd, cfg.write ? 0xc2 : 0xc1,
+                             sizeof(stats), &stats);
     if (!err)
         io_latency_histogram(cfg.write ? f2 : f1, stats, DO_PRINT_FLAG,
          cfg.write ? GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM : GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM);
     else
        nvme_show_status(err);
 
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -1091,8 +1105,9 @@ static int mb_lat_stats_log_print(int argc, char **argv, struct command *cmd, st
 #define FID        0x68
 static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-    int err, fd;
     char *desc = "Clear Memblaze devices error log.";
+    struct nvme_dev *dev;
+    int err;
 
     //const char *value = "new value of feature (required)";
     //const char *save = "specifies that the controller shall save the attribute";
@@ -1114,13 +1129,13 @@ static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd,
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0)
-        return fd;
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0)
+        return err;
 
     struct nvme_set_features_args args = {
         .args_size      = sizeof(args),
-        .fd             = fd,
+        .fd             = dev->fd,
         .fid            = cfg.feature_id,
         .nsid           = 0,
         .cdw11          = cfg.value,
@@ -1156,14 +1171,13 @@ static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd,
                printf("NVMe Status:%s(%x)\n", nvme_status_to_string(err), err);
        };
 */
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
 static int mb_set_lat_stats(int argc, char **argv,
                struct command *command, struct plugin *plugin)
 {
-       int err, fd;
        const char *desc = (
                        "Enable/Disable Latency Statistics Tracking.\n"
                        "No argument prints current status.");
@@ -1176,8 +1190,10 @@ static int mb_set_lat_stats(int argc, char **argv,
        const __u32 cdw12 = 0x0;
        const __u32 data_len = 32;
        const __u32 save = 0;
-       __u32 result;
+       struct nvme_dev *dev;
        void *buf = NULL;
+       __u32 result;
+       int err;
 
        struct config {
                bool enable, disable;
@@ -1194,7 +1210,7 @@ static int mb_set_lat_stats(int argc, char **argv,
                {NULL}
        };
 
-       fd = parse_and_open(argc, argv, desc, command_line_options);
+       err = parse_and_open(&dev, argc, argv, desc, command_line_options);
 
        enum Option {
                None = -1,
@@ -1210,7 +1226,7 @@ static int mb_set_lat_stats(int argc, char **argv,
 
        struct nvme_get_features_args args_get = {
                .args_size      = sizeof(args_get),
-               .fd             = fd,
+               .fd             = dev->fd,
                .fid            = fid,
                .nsid           = nsid,
                .sel            = sel,
@@ -1224,7 +1240,7 @@ static int mb_set_lat_stats(int argc, char **argv,
 
        struct nvme_set_features_args args_set = {
                .args_size      = sizeof(args_set),
-               .fd             = fd,
+               .fd             = dev->fd,
                .fid            = fid,
                .nsid           = nsid,
                .cdw11          = option,
@@ -1238,8 +1254,8 @@ static int mb_set_lat_stats(int argc, char **argv,
                .result         = &result,
        };
 
-       if (fd < 0)
-               return fd;
+       if (err < 0)
+               return err;
        switch (option) {
        case None:
                err = nvme_get_features(&args_get);
@@ -1249,7 +1265,7 @@ static int mb_set_lat_stats(int argc, char **argv,
                                fid, result);
                } else {
                        printf("Could not read feature id 0xE2.\n");
-                       close(fd);
+                       dev_close(dev);
                        return err;
                }
                break;
@@ -1270,7 +1286,7 @@ static int mb_set_lat_stats(int argc, char **argv,
                printf("%d not supported.\n", option);
                err = EINVAL;
        }
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
index 1c3c51d183eee1744cc1b545ccd78792a70f87b7..db76ef7b747d96abf9fdf399342bc51831fd95cd 100644 (file)
@@ -453,13 +453,15 @@ exit_status:
 /*
  * Plugin Commands
  */
-static int micron_parse_options(int argc, char **argv, const char *desc,
-    const struct argconfig_commandline_options *opts, eDriveModel *modelp)
+static int micron_parse_options(struct nvme_dev **dev, int argc, char **argv,
+                               const char *desc,
+                               const struct argconfig_commandline_options *opts,
+                               eDriveModel *modelp)
 {
     int idx = 0;
-    int fd = parse_and_open(argc, argv, desc, opts);
+    int err = parse_and_open(dev, argc, argv, desc, opts);
 
-    if (fd < 0) {
+    if (err < 0) {
         perror("open");
         return -1;
     }
@@ -469,7 +471,7 @@ static int micron_parse_options(int argc, char **argv, const char *desc,
         *modelp = GetDriveModel(idx);
     }
 
-    return fd;
+    return 0;
 }
 
 static int micron_fw_commit(int fd, int select)
@@ -496,7 +498,8 @@ static int micron_selective_download(int argc, char **argv,
     const char *select = "FW Select (e.g., --select=ALL)";
     int xfer = 4096;
     void *fw_buf;
-    int fd, selectNo, fw_fd, fw_size, err, offset = 0;
+    int selectNo, fw_fd, fw_size, err, offset = 0;
+    struct nvme_dev *dev;
     struct stat sb;
 
     struct config {
@@ -515,13 +518,13 @@ static int micron_selective_download(int argc, char **argv,
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0)
-        return fd;
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0)
+        return err;
 
     if (strlen(cfg.select) != 3) {
         fprintf(stderr, "Invalid select flag\n");
-        close(fd);
+        dev_close(dev);
         return EINVAL;
     }
 
@@ -537,14 +540,14 @@ static int micron_selective_download(int argc, char **argv,
         selectNo = 26;
     } else {
         fprintf(stderr, "Invalid select flag\n");
-        close(fd);
+        dev_close(dev);
         return EINVAL;
     }
 
     fw_fd = open(cfg.fw, O_RDONLY);
     if (fw_fd < 0) {
         fprintf(stderr, "no firmware file provided\n");
-        close(fd);
+        dev_close(dev);
         return EINVAL;
     }
 
@@ -578,7 +581,7 @@ static int micron_selective_download(int argc, char **argv,
 
        struct nvme_fw_download_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .offset         = offset,
                .data_len       = xfer,
                .data           = fw_buf,
@@ -598,7 +601,7 @@ static int micron_selective_download(int argc, char **argv,
         offset += xfer;
     }
 
-    err = micron_fw_commit(fd, selectNo);
+    err = micron_fw_commit(dev->fd, selectNo);
 
     if (err == 0x10B || err == 0x20B) {
         err = 0;
@@ -610,7 +613,7 @@ out_free:
     free(fw_buf);
 out:
     close(fw_fd);
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -625,10 +628,10 @@ static int micron_smbus_option(int argc, char **argv,
                         "temperature (default) for enable option, 0 (current), "
                         "1 (default), 2 (saved) for status options";
     const char *save = "1 - persistent, 0 - non-persistent (default)";
-    int err = 0;
-    int fd = 0;
     int fid = MICRON_FEATURE_SMBUS_OPTION;
     eDriveModel model = UNKNOWN_MODEL;
+    struct nvme_dev *dev;
+    int err = 0;
 
     struct {
         char *option;
@@ -649,18 +652,20 @@ static int micron_smbus_option(int argc, char **argv,
         OPT_END()
     };
 
-    if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+    err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+    if (err < 0)
         return err;
 
     if (model != M5407 && model != M5411) {
         printf ("This option is not supported for specified drive\n");
-        close(fd);
+        dev_close(dev);
         return err;
     }
 
     if (!strcmp(opt.option, "enable")) {
         cdw11 = opt.value << 1 | 1;
-        err = nvme_set_features_simple(fd, fid, 1, cdw11, opt.save, &result);
+        err = nvme_set_features_simple(dev->fd, fid, 1, cdw11, opt.save,
+                                      &result);
         if (err == 0) {
             printf("successfully enabled SMBus on drive\n");
         } else {
@@ -670,7 +675,7 @@ static int micron_smbus_option(int argc, char **argv,
     else if (!strcmp(opt.option, "status")) {
        struct nvme_get_features_args args = {
                 .args_size      = sizeof(args),
-                .fd             = fd,
+                .fd             = dev->fd,
                 .fid            = fid,
                 .nsid           = 1,
                 .sel            = opt.value,
@@ -692,7 +697,8 @@ static int micron_smbus_option(int argc, char **argv,
     }
     else if (!strcmp(opt.option, "disable")) {
         cdw11 = opt.value << 1 | 0;
-        err = nvme_set_features_simple(fd, fid, 1, cdw11, opt.save, &result);
+        err = nvme_set_features_simple(dev->fd, fid, 1, cdw11, opt.save,
+                                      &result);
         if (err == 0) {
             printf("Successfully disabled SMBus on drive\n");
         } else {
@@ -701,11 +707,11 @@ static int micron_smbus_option(int argc, char **argv,
     } else {
         printf("Invalid option %s, valid values are enable, disable or status\n",
                 opt.option);
-        close(fd);
+        dev_close(dev);
         return -1;
     }
 
-    close(fd);
+    close(dev->fd);
     return err;
 }
 
@@ -727,15 +733,15 @@ static int micron_temp_stats(int argc, char **argv, struct command *cmd,
     bool is_json = false;
     struct json_object *root;
     struct json_object *logPages;
-    int fd;
+    struct nvme_dev *dev;
 
     OPT_ARGS(opts) = {
         OPT_FMT("format", 'f', &cfg.fmt, fmt),
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0) {
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0) {
         printf("\nDevice not found \n");;
         return -1;
     }
@@ -743,7 +749,7 @@ static int micron_temp_stats(int argc, char **argv, struct command *cmd,
     if (strcmp(cfg.fmt, "json") == 0)
         is_json = true;
 
-    err = nvme_get_log_smart(fd, 0xffffffff, false, &smart_log);
+    err = nvme_get_log_smart(dev->fd, 0xffffffff, false, &smart_log);
     if (!err) {
         temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]);
         temperature = temperature ? temperature - 273 : 0;
@@ -778,15 +784,16 @@ static int micron_temp_stats(int argc, char **argv, struct command *cmd,
             }
         }
     }
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
 static int micron_pcie_stats(int argc, char **argv,
                              struct command *cmd, struct plugin *plugin)
 {
-    int  i, fd, err = 0, bus = 0, domain = 0, device = 0, function = 0, ctrlIdx;
+    int  i, err = 0, bus = 0, domain = 0, device = 0, function = 0, ctrlIdx;
     char strTempFile[1024], strTempFile2[1024], command[1024];
+    struct nvme_dev *dev;
     char *businfo = NULL;
     char *devicename = NULL;
     char tdevice[NAME_MAX] = { 0 };
@@ -875,8 +882,8 @@ static int micron_pcie_stats(int argc, char **argv,
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0) {
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0) {
         printf("\nDevice not found \n");;
         return -1;
     }
@@ -896,7 +903,7 @@ static int micron_pcie_stats(int argc, char **argv,
         admin_cmd.addr = (__u64)(uintptr_t)&pcie_error_counters;
         admin_cmd.data_len = sizeof(pcie_error_counters);
         admin_cmd.cdw10 = 1;
-        err = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+        err = nvme_submit_admin_passthru(dev->fd, &admin_cmd, NULL);
         if (!err) {
             counters = true;
             correctable_errors = 10;
@@ -1017,8 +1024,7 @@ print_stats:
     }
 
 out:
-    if (fd > 0)
-        close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -1028,6 +1034,7 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv,
 {
     int err = -EINVAL, bus = 0, domain = 0, device = 0, function = 0;
     char strTempFile[1024], strTempFile2[1024], command[1024];
+    struct nvme_dev *dev;
     char *businfo = NULL;
     char *devicename = NULL;
     char tdevice[PATH_MAX] = { 0 };
@@ -1035,7 +1042,6 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv,
     eDriveModel model = UNKNOWN_MODEL;
     struct nvme_passthru_cmd admin_cmd = { 0 };
     char correctable[8] = { 0 };
-    int  fd = -1;
     FILE *fp;
     char *res;
     const char *desc = "Clear PCIe Device Correctable Errors";
@@ -1045,12 +1051,14 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv,
         OPT_END()
     };
 
-    if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+    err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+    if (err < 0)
         return err;
 
     /* For M51CX models, PCIe errors are cleared using 0xC3 feature */
     if (model == M51CX) {
-       err = nvme_set_features_simple(fd, fid, 0, (1 << 31), false, &result);
+       err = nvme_set_features_simple(dev->fd, fid, 0, (1 << 31), false,
+                                      &result);
         if (err == 0 && (err = (int)result) == 0) {
             printf("Device correctable errors are cleared!\n");
             goto out;
@@ -1059,7 +1067,7 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv,
         admin_cmd.opcode = 0xD6;
         admin_cmd.addr = 0;
         admin_cmd.cdw10 = 0;
-        err = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+        err = nvme_submit_admin_passthru(dev->fd, &admin_cmd, NULL);
         if (err == 0) {
             printf("Device correctable error counters are cleared!\n");
             goto out;
@@ -1134,7 +1142,7 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv,
     printf("Device correctable errors detected: %s\n", correctable);
     err = 0;
 out:
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -1490,7 +1498,8 @@ static int micron_nand_stats(int argc, char **argv,
     unsigned int logFB[FB_log_size/sizeof(int)] = { 0 };
     eDriveModel eModel = UNKNOWN_MODEL;
     struct nvme_id_ctrl ctrl;
-    int fd, err, ctrlIdx;
+    struct nvme_dev *dev;
+    int err, ctrlIdx;
     __u8 nsze;
     bool has_d0_log = true;
     bool has_fb_log = false;
@@ -1508,8 +1517,8 @@ static int micron_nand_stats(int argc, char **argv,
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0) {
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0) {
         printf("\nDevice not found \n");;
         return -1;
     }
@@ -1517,7 +1526,7 @@ static int micron_nand_stats(int argc, char **argv,
     if (strcmp(cfg.fmt, "normal") == 0)
         is_json = false;
 
-    err = nvme_identify_ctrl(fd, &ctrl);
+    err = nvme_identify_ctrl(dev->fd, &ctrl);
     if (err) {
         printf("Error %d retrieving controller identification data\n", err);
         goto out;
@@ -1532,12 +1541,12 @@ static int micron_nand_stats(int argc, char **argv,
         goto out;
     }
 
-    err = nvme_get_log_simple(fd, 0xD0, D0_log_size, extSmartLog);
+    err = nvme_get_log_simple(dev->fd, 0xD0, D0_log_size, extSmartLog);
     has_d0_log = (0 == err);
 
     /* should check for firmware version if this log is supported or not */
     if (eModel == M5407 || eModel == M5410) {
-        err = nvme_get_log_simple(fd, 0xFB, FB_log_size, logFB);
+        err = nvme_get_log_simple(dev->fd, 0xFB, FB_log_size, logFB);
         has_fb_log = (0 == err);
     }
 
@@ -1555,7 +1564,7 @@ static int micron_nand_stats(int argc, char **argv,
         err = -ENOTTY;
     }
 out:
-    close(fd);
+    dev_close(dev);
     if (err > 0)
        nvme_show_status(err);
 
@@ -1595,7 +1604,8 @@ static int micron_smart_ext_log(int argc, char **argv,
     const char *desc = "Retrieve extended SMART logs for the given device ";
     unsigned int extSmartLog[E1_log_size/sizeof(int)] = { 0 };
     eDriveModel eModel = UNKNOWN_MODEL;
-    int fd = 0, err = 0, ctrlIdx = 0;
+    int err = 0, ctrlIdx = 0;
+    struct nvme_dev *dev;
     bool is_json = true;
     struct format {
         char *fmt;
@@ -1609,8 +1619,8 @@ static int micron_smart_ext_log(int argc, char **argv,
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0) {
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0) {
         printf("\nDevice not found \n");;
         return -1;
     }
@@ -1623,13 +1633,13 @@ static int micron_smart_ext_log(int argc, char **argv,
         err = -1;
         goto out;
     }
-    err = nvme_get_log_simple(fd, 0xE1, E1_log_size, extSmartLog);
+    err = nvme_get_log_simple(dev->fd, 0xE1, E1_log_size, extSmartLog);
     if (!err) {
         print_ext_smart_logs_e1((__u8 *)extSmartLog, is_json);
     }
 
 out:
-    close(fd);
+    dev_close(dev);
     if (err > 0)
         nvme_show_status(err);
     return err;
@@ -2005,7 +2015,6 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd,
                                 struct plugin *plugin)
 {
     const char *desc = "Get drive HW information";
-    int fd, err = 0;
     struct nvme_id_ctrl ctrl =  { 0 };
     struct nvme_passthru_cmd admin_cmd = { 0 };
     struct fb_drive_info {
@@ -2018,9 +2027,11 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd,
     eDriveModel model = UNKNOWN_MODEL;
     bool is_json = false;
     struct json_object *root, *driveInfo;
+    struct nvme_dev *dev;
     struct format {
         char *fmt;
     };
+    int err = 0;
 
     const char *fmt = "output format normal";
     struct format cfg = {
@@ -2032,12 +2043,13 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd,
         OPT_END()
     };
 
-    if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+    err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+    if (err < 0)
         return err;
 
     if (model == UNKNOWN_MODEL) {
         fprintf(stderr, "ERROR : Unsupported drive for vs-drive-info cmd");
-        close(fd);
+        dev_close(dev);
         return -1;
     }
 
@@ -2049,17 +2061,17 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd,
         admin_cmd.addr = (__u64) (uintptr_t) &dinfo;
         admin_cmd.data_len = (__u32)sizeof(dinfo);
         admin_cmd.cdw12 = 3;
-        err = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+        err = nvme_submit_admin_passthru(dev->fd, &admin_cmd, NULL);
         if (err) {
             fprintf(stderr, "ERROR : drive-info opcode failed with 0x%x\n", err);
-            close(fd);
+            dev_close(dev);
             return -1;
         }
     } else {
-        err = nvme_identify_ctrl(fd, &ctrl);
+        err = nvme_identify_ctrl(dev->fd, &ctrl);
         if (err) {
             fprintf(stderr, "ERROR : identify_ctrl() failed with 0x%x\n", err);
-            close(fd);
+            dev_close(dev);
             return -1;
         }
         dinfo.hw_ver_major = ctrl.vs[820];
@@ -2103,7 +2115,7 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd,
         }
     }
 
-    close(fd);
+    dev_close(dev);
     return 0;
 }
 
@@ -2242,10 +2254,11 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
     int count = 0;
     unsigned int logC2[C2_log_size/sizeof(int)] = { 0 };
     eDriveModel eModel = UNKNOWN_MODEL;
-    int fd, err;
+    struct nvme_dev *dev;
     struct format {
         char *fmt;
     };
+    int err;
 
     const char *fmt = "output format normal";
     struct format cfg = {
@@ -2257,13 +2270,13 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
         OPT_END()
     };
 
-    if ((fd = micron_parse_options(argc, argv, desc, opts, &eModel)) < 0) {
+    err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel);
+    if (err < 0)
         return -1;
-    }
 
     if (strcmp(cfg.fmt, "normal") != 0) {
         fprintf (stderr, "only normal format is supported currently\n");
-        close(fd);
+        dev_close(dev);
         return -1;
     }
 
@@ -2274,7 +2287,7 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
         goto out;
     }
 
-    err = nvme_get_log_simple(fd, 0xC2, C2_log_size, logC2);
+    err = nvme_get_log_simple(dev->fd, 0xC2, C2_log_size, logC2);
     if (err)  {
         fprintf(stderr, "Failed to retrieve fw activation history log, error: %x\n", err);
         goto out;
@@ -2308,7 +2321,7 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
         }
     }
 out:
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -2327,12 +2340,12 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
     const char *thrtime = "The threshold value to use for latency monitoring in"
                           " milliseconds, default is 800ms";
 
-    int fd = 0;
     int fid = MICRON_FID_LATENCY_MONITOR;
     eDriveModel model = UNKNOWN_MODEL;
     uint32_t command_mask = 0x7;       /* 1:read 2:write 4:trim 7:all */
     uint32_t timing_mask = 0x08080800; /* R[31-24]:W[23:16]:T[15:8]:0 */
     uint32_t enable = 2;
+    struct nvme_dev *dev;
     struct {
         char *option;
         char *command;
@@ -2351,9 +2364,9 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
     };
 
 
-    if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0) {
+    err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+    if (err < 0)
         return -1;
-    }
 
     if (!strcmp(opt.option, "enable")) {
         enable = 1;
@@ -2361,13 +2374,13 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
         enable = 0;
     } else if (strcmp(opt.option, "status")) {
         printf("Invalid control option %s specified\n", opt.option);
-        close(fd);
+        dev_close(dev);
         return -1;
     }
 
     struct nvme_get_features_args g_args = {
         .args_size     = sizeof(g_args),
-        .fd            = fd,
+        .fd            = dev->fd,
         .fid            = fid,
         .nsid          = 0,
         .sel           = 0,
@@ -2382,7 +2395,7 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
     err = nvme_get_features(&g_args);
     if (err != 0) {
         printf("Failed to retrieve latency monitoring feature status\n");
-        close(fd);
+        dev_close(dev);
        return err;
     }
 
@@ -2407,7 +2420,7 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
         } else if (result == 0) {
                printf("\n");
         }
-        close(fd);
+        dev_close(dev);
         return err;
     }
 
@@ -2415,13 +2428,13 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
     if (enable == 1) {
         if (opt.threshold > 2550) {
             printf("The maximum threshold value cannot be more than 2550 ms\n");
-            close(fd);
+            dev_close(dev);
             return -1;
         }
        /* timing mask is in terms of 10ms units, so min allowed is 10ms */
        else if ((opt.threshold % 10) != 0) {
             printf("The threshold value should be multiple of 10 ms\n");
-            close(fd);
+            dev_close(dev);
             return -1;
        }
        opt.threshold /= 10;
@@ -2440,13 +2453,13 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
     } else if (strcmp(opt.command, "all")) {
         printf("Invalid command %s specified for option %s\n",
                opt.command, opt.option);
-        close(fd);
+        dev_close(dev);
         return -1;
     }
 
     struct nvme_set_features_args args = {
             .args_size      = sizeof(args),
-            .fd             = fd,
+            .fd             = dev->fd,
             .fid            = MICRON_FID_LATENCY_MONITOR,
             .nsid           = 0,
             .cdw11          = enable,
@@ -2469,7 +2482,7 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
                 opt.option, opt.command, opt.threshold == 0 ? 800 : opt.threshold * 10);
     }
 
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -2510,21 +2523,22 @@ static int micron_latency_stats_logs(int argc, char **argv, struct command *cmd,
         uint32_t   rfu[6];
     } log[LATENCY_LOG_ENTRIES];
     eDriveModel model = UNKNOWN_MODEL;
+    struct nvme_dev *dev;
     int err = -1;
-    int fd = -1;
     const char *desc = "Display Latency tracking log information";
     OPT_ARGS(opts) = {
         OPT_END()
     };
 
-    if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+    err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+    if (err)
         return err;
     memset(&log, 0, sizeof(log));
-    err = nvme_get_log_simple(fd, 0xD1, sizeof(log), &log);
+    err = nvme_get_log_simple(dev->fd, 0xD1, sizeof(log), &log);
     if (err) {
         if (err < 0)
             printf("Unable to retrieve latency stats log the drive\n");
-        close(fd);
+        dev_close(dev);
         return err;
     }
     /* print header and each log entry */
@@ -2538,7 +2552,7 @@ static int micron_latency_stats_logs(int argc, char **argv, struct command *cmd,
               log[i].deac, log[i].prinfo, log[i].fua, log[i].lr);
     }
     printf("\n");
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -2549,7 +2563,7 @@ static int micron_latency_stats_info(int argc, char **argv, struct command *cmd,
     const char *command = "command to display stats - all|read|write|trim"
                          "default is all";
     int err = 0;
-    int fd = -1;
+    struct nvme_dev *dev;
     eDriveModel model = UNKNOWN_MODEL;
     #define LATENCY_BUCKET_COUNT 32
     #define LATENCY_BUCKET_RSVD  32
@@ -2592,7 +2606,8 @@ static int micron_latency_stats_info(int argc, char **argv, struct command *cmd,
         OPT_END()
     };
 
-    if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+    err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+    if (err < 0)
         return err;
     if (!strcmp(opt.command, "read")) {
         cmd_stats = &log.read_cmds[0];
@@ -2605,16 +2620,16 @@ static int micron_latency_stats_info(int argc, char **argv, struct command *cmd,
        cmd_str = "Trim";
     } else if (strcmp(opt.command, "all")) {
         printf("Invalid command option %s to display latency stats\n", opt.command);
-        close(fd);
+        dev_close(dev);
        return -1;
     }
 
     memset(&log, 0, sizeof(log));
-    err = nvme_get_log_simple(fd, 0xD0, sizeof(log), &log);
+    err = nvme_get_log_simple(dev->fd, 0xD0, sizeof(log), &log);
     if (err) {
         if (err < 0)
             printf("Unable to retrieve latency stats log the drive\n");
-        close(fd);
+        dev_close(dev);
         return err;
     }
     printf("Micron IO %s Command Latency Statistics\n"
@@ -2636,7 +2651,7 @@ static int micron_latency_stats_info(int argc, char **argv, struct command *cmd,
        printf("%2d   %8s    %8s    %8"PRIu64"\n",
               bucket, start, end, cmd_stats[b]);
     }
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -2648,7 +2663,7 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c
     unsigned int logFB[FB_log_size/sizeof(int)] = { 0 };
     struct nvme_id_ctrl ctrl;
     eDriveModel eModel = UNKNOWN_MODEL;
-    int fd, err = 0;
+    struct nvme_dev *dev;
     bool is_json = true;
     struct format {
         char *fmt;
@@ -2657,15 +2672,16 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c
     struct format cfg = {
         .fmt = "json",
     };
+    int err = 0;
 
     OPT_ARGS(opts) = {
         OPT_FMT("format", 'f', &cfg.fmt, fmt),
         OPT_END()
     };
 
-    if ((fd = micron_parse_options(argc, argv, desc, opts, &eModel)) < 0) {
+    err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel);
+    if (err < 0)
         return -1;
-    }
 
     if (strcmp(cfg.fmt, "normal") == 0)
         is_json = false;
@@ -2675,8 +2691,8 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c
         __u8 spec = (eModel == M5410) ? 0 : 1;
         __u8 nsze;
 
-        if ((err = nvme_identify_ctrl(fd, &ctrl)) == 0)
-            err = nvme_get_log_simple(fd, 0xFB,
+        if ((err = nvme_identify_ctrl(dev->fd, &ctrl)) == 0)
+            err = nvme_get_log_simple(dev->fd, 0xFB,
                                      FB_log_size, logFB);
         if (err) {
             if (err < 0)
@@ -2698,14 +2714,14 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c
         goto out;
     }
 
-    err = nvme_get_log_simple(fd, 0xC0, C0_log_size, logC0);
+    err = nvme_get_log_simple(dev->fd, 0xC0, C0_log_size, logC0);
     if (err == 0) {
         print_smart_cloud_health_log((__u8 *)logC0, is_json);
     } else if (err < 0) {
         printf("Unable to retrieve extended smart log 0xC0 for the drive\n");
     }
 out:
-    close(fd);
+    dev_close(dev);
     if (err > 0)
        nvme_show_status(err);
     return err;
@@ -2715,28 +2731,30 @@ static int micron_clr_fw_activation_history(int argc, char **argv,
                                 struct command *cmd, struct plugin *plugin)
 {
     const char *desc = "Clear FW activation history";
-    int fd, err = 0;
     __u32 result = 0;
     __u8 fid = MICRON_FEATURE_CLEAR_FW_ACTIVATION_HISTORY;
     eDriveModel model = UNKNOWN_MODEL;
+    struct nvme_dev *dev;
     OPT_ARGS(opts) = {
         OPT_END()
     };
+    int err = 0;
 
-    if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+    err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+    if (err < 0)
         return err;
 
     if (model != M51CX) {
         printf ("This option is not supported for specified drive\n");
-        close(fd);
+        dev_close(dev);
         return err;
     }
 
-    err = nvme_set_features_simple(fd, fid, 1 << 31, 0, 0, &result);
+    err = nvme_set_features_simple(dev->fd, fid, 1 << 31, 0, 0, &result);
     if (err == 0) err = (int)result;
     else printf ("Failed to clear fw activation history, error = 0x%x\n", err);
 
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -2750,10 +2768,10 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
     const char *select = "select/save values: enable/disable options"
                          "1 - save (persistent), 0 - non-persistent and for "
                          "status options: 0 - current, 1 - default, 2-saved";
-    int fd = 0;
     int fid = MICRON_FEATURE_TELEMETRY_CONTROL_OPTION;
     eDriveModel model = UNKNOWN_MODEL;
     struct nvme_id_ctrl ctrl =  { 0 };
+    struct nvme_dev *dev;
 
     struct {
         char *option;
@@ -2769,21 +2787,21 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
         OPT_END()
     };
 
-    if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0) {
+    err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+    if (err < 0)
         return -1;
-    }
 
-    err = nvme_identify_ctrl(fd, &ctrl);
+    err = nvme_identify_ctrl(dev->fd, &ctrl);
     if ((ctrl.lpa & 0x8) != 0x8) {
            printf("drive doesn't support host/controller generated telemetry logs\n");
-           close(fd);
+           dev_close(dev);
            return err;
     }
 
     if (!strcmp(opt.option, "enable")) {
         struct nvme_set_features_args args = {
                 .args_size      = sizeof(args),
-                .fd             = fd,
+                .fd             = dev->fd,
                 .fid            = fid,
                 .nsid           = 1,
                 .cdw11          = 1,
@@ -2805,7 +2823,7 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
     } else if (!strcmp(opt.option, "disable")) {
         struct nvme_set_features_args args = {
                 .args_size      = sizeof(args),
-                .fd             = fd,
+                .fd             = dev->fd,
                 .fid            = fid,
                 .nsid           = 1,
                 .cdw11          = 0,
@@ -2827,7 +2845,7 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
     } else if (!strcmp(opt.option, "status")) {
        struct nvme_get_features_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .fid            = fid,
                .nsid           = 1,
                .sel            = opt.select & 0x3,
@@ -2847,11 +2865,11 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
         }
     } else {
         printf("invalid option %s, valid values are enable,disable or status\n", opt.option);
-        close(fd);
+        dev_close(dev);
         return -1;
     }
 
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -3010,7 +3028,6 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
                                 struct plugin *plugin)
 {
     int err = -EINVAL;
-    int fd = 0;
     int ctrlIdx, telemetry_option = 0;
     char strOSDirName[1024];
     char strCtrlDirName[1024];
@@ -3021,6 +3038,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
     char sn[20] = { 0 };
     char msg[256] = { 0 };
     int  c_logs_index = 8; /* should be current size of aVendorLogs */
+    struct nvme_dev *dev;
     struct {
         unsigned char ucLogPage;
         const char *strFileName;
@@ -3104,10 +3122,9 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-
-    if (fd < 0)
-        return fd;
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0)
+        return err;
 
     /* if telemetry type is specified, check for data area */
     if (strlen(cfg.type) != 0) {
@@ -3143,7 +3160,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
         goto out;
     }
 
-    err = nvme_identify_ctrl(fd, &ctrl);
+    err = nvme_identify_ctrl(dev->fd, &ctrl);
     if (err)
         goto out;
 
@@ -3151,11 +3168,12 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
     if (telemetry_option) {
         if ((ctrl.lpa & 0x8) != 0x8) {
            printf("telemetry option is not supported for specified drive\n");
-           close(fd);
+           dev_close(dev);
            goto out;
         }
         int logSize = 0; __u8 *buffer = NULL; const char *dir = ".";
-        err = micron_telemetry_log(fd, cfg.log,  &buffer, &logSize, cfg.data_area);
+        err = micron_telemetry_log(dev->fd, cfg.log,  &buffer, &logSize,
+                                  cfg.data_area);
         if (err == 0 && logSize > 0 && buffer != NULL) {
             sprintf(msg, "telemetry log: 0x%X", cfg.log);
             WriteData(buffer, logSize, dir, cfg.package, msg);
@@ -3184,16 +3202,16 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
     GetDriveInfo(strOSDirName, ctrlIdx, &ctrl);
 
     for (int i = 1; i <= ctrl.nn; i++)
-        GetNSIDDInfo(fd, strCtrlDirName, i);
+        GetNSIDDInfo(dev->fd, strCtrlDirName, i);
 
-    GetSmartlogData(fd, strCtrlDirName);
-    GetErrorlogData(fd, ctrl.elpe, strCtrlDirName);
-    GetGenericLogs(fd, strCtrlDirName);
+    GetSmartlogData(dev->fd, strCtrlDirName);
+    GetErrorlogData(dev->fd, ctrl.elpe, strCtrlDirName);
+    GetGenericLogs(dev->fd, strCtrlDirName);
     /* pull if telemetry log data is supported */
     if ((ctrl.lpa & 0x8) == 0x8)
-        GetTelemetryData(fd, strCtrlDirName);
+        GetTelemetryData(dev->fd, strCtrlDirName);
 
-    GetFeatureSettings(fd, strCtrlDirName);
+    GetFeatureSettings(dev->fd, strCtrlDirName);
 
     if (eModel != M5410 && eModel != M5407) {
         memcpy(&aVendorLogs[c_logs_index], aM51XXLogs, sizeof(aM51XXLogs));
@@ -3221,15 +3239,16 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
         case 0xE4:
         case 0xE8:
         case 0xEA:
-            err = get_common_log(fd, aVendorLogs[i].ucLogPage, &dataBuffer, &bSize);
+            err = get_common_log(dev->fd, aVendorLogs[i].ucLogPage,
+                                &dataBuffer, &bSize);
             break;
 
         case 0xC1:
         case 0xC2:
         case 0xC4:
-            err = GetLogPageSize(fd, aVendorLogs[i].ucLogPage, &bSize);
+            err = GetLogPageSize(dev->fd, aVendorLogs[i].ucLogPage, &bSize);
             if (err == 0 && bSize > 0)
-                err = GetCommonLogPage(fd, aVendorLogs[i].ucLogPage, &dataBuffer, bSize);
+                err = GetCommonLogPage(dev->fd, aVendorLogs[i].ucLogPage, &dataBuffer, bSize);
             break;
 
         case 0xE6:
@@ -3248,9 +3267,9 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
             if (bSize != 0 && (dataBuffer = (unsigned char *)malloc(bSize)) != NULL) {
                 memset(dataBuffer, 0, bSize);
                 if (eModel == M5410 || eModel == M5407)
-                    err = NVMEGetLogPage(fd, aVendorLogs[i].ucLogPage, dataBuffer, bSize);
+                    err = NVMEGetLogPage(dev->fd, aVendorLogs[i].ucLogPage, dataBuffer, bSize);
                 else
-                    err = nvme_get_log_simple(fd, aVendorLogs[i].ucLogPage,
+                    err = nvme_get_log_simple(dev->fd, aVendorLogs[i].ucLogPage,
                                              bSize, dataBuffer);
             }
             break;
@@ -3260,7 +3279,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
         case 0xFC:
         case 0xFD:
             if (eModel == M51BX) {
-                (void)NVMEResetLog(fd, aVendorLogs[i].ucLogPage,
+                (void)NVMEResetLog(dev->fd, aVendorLogs[i].ucLogPage,
                                    aVendorLogs[i].nLogSize, aVendorLogs[i].nMaxSize);
             }
             /* fallthrough */
@@ -3271,13 +3290,13 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
                break;
             }
             memset(dataBuffer, 0, bSize);
-            err = nvme_get_log_simple(fd, aVendorLogs[i].ucLogPage,
+            err = nvme_get_log_simple(dev->fd, aVendorLogs[i].ucLogPage,
                                      bSize, dataBuffer);
             maxSize = aVendorLogs[i].nMaxSize - bSize;
             while (err == 0 && maxSize > 0 && ((unsigned int *)dataBuffer)[0] != 0xdeadbeef) {
                 sprintf(msg, "log 0x%x", aVendorLogs[i].ucLogPage);
                 WriteData(dataBuffer, bSize, strCtrlDirName, aVendorLogs[i].strFileName, msg);
-                err = nvme_get_log_simple(fd, aVendorLogs[i].ucLogPage,
+                err = nvme_get_log_simple(dev->fd, aVendorLogs[i].ucLogPage,
                                          bSize, dataBuffer);
                 if (err || (((unsigned int *)dataBuffer)[0] == 0xdeadbeef))
                     break;
@@ -3299,7 +3318,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
 
     err = ZipAndRemoveDir(strMainDirName, cfg.package);
 out:
-    close(fd);
+    dev_close(dev);
     return err;
 }
 
@@ -3308,17 +3327,18 @@ static int micron_logpage_dir(int argc, char **argv, struct command *cmd,
                               struct plugin *plugin)
 {
     int err = -1;
-    int fd  = -1;
     const char *desc = "List the supported log pages";
     eDriveModel model = UNKNOWN_MODEL;
     char logbuf[MIN_LOG_SIZE];
+    struct nvme_dev *dev;
     int i;
 
     OPT_ARGS(opts) = {
         OPT_END()
     };
 
-    if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+    err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+    if (err < 0)
         return err;
 
     struct nvme_supported_logs {
@@ -3359,7 +3379,7 @@ static int micron_logpage_dir(int argc, char **argv, struct command *cmd,
 
     printf("Supported log page list\nLog ID : Description\n");
     for (i = 0; i < sizeof(log_list)/sizeof(log_list[0]); i++) {
-        err = nvme_get_log_simple(fd, log_list[i].log_id,
+        err = nvme_get_log_simple(dev->fd, log_list[i].log_id,
                                   MIN_LOG_SIZE, &logbuf[0]);
         if (err) continue;
         printf("%02Xh    : %s\n", log_list[i].log_id, log_list[i].desc);
index a9f23caedd3dda236be2e805aba8b37c2d56941d..60a2bdfb6cb4b7ac4b16e8af04fc8b071c0933d2 100644 (file)
@@ -401,7 +401,7 @@ static int ocp_smart_add_log(int argc, char **argv, struct command *cmd,
                 struct plugin *plugin)
 {
         const char *desc = "Retrieve latency monitor log data.";
-        int fd;
+       struct nvme_dev *dev;
         int ret = 0;
 
         struct config {
@@ -417,15 +417,15 @@ static int ocp_smart_add_log(int argc, char **argv, struct command *cmd,
                 OPT_END()
         };
 
-        fd = parse_and_open(argc, argv, desc, opts);
-        if (fd < 0)
-                return fd;
+        ret = parse_and_open(&dev, argc, argv, desc, opts);
+        if (ret < 0)
+                return ret;
 
-        ret = get_c0_log_page(fd, cfg.output_format);
+        ret = get_c0_log_page(dev->fd, cfg.output_format);
         if (ret)
                 fprintf(stderr, "ERROR : OCP : Failure reading the C0 Log Page, ret = %d\n",
                         ret);
-        close(fd);
+        dev_close(dev);
         return ret;
 }
 
@@ -745,7 +745,7 @@ static int ocp_latency_monitor_log(int argc, char **argv, struct command *comman
                 struct plugin *plugin)
 {
         const char *desc = "Retrieve latency monitor log data.";
-        int fd;
+       struct nvme_dev *dev;
         int ret = 0;
 
         struct config {
@@ -762,15 +762,15 @@ static int ocp_latency_monitor_log(int argc, char **argv, struct command *comman
                 OPT_END()
         };
 
-        fd = parse_and_open(argc, argv, desc, opts);
-        if (fd < 0)
-                return fd;
+        ret = parse_and_open(&dev, argc, argv, desc, opts);
+        if (ret < 0)
+                return ret;
 
-        ret = get_c3_log_page(fd, cfg.output_format);
+        ret = get_c3_log_page(dev->fd, cfg.output_format);
         if (ret)
                 fprintf(stderr,
                         "ERROR : OCP : Failure reading the C3 Log Page, ret = %d\n",
                         ret);
-        close(fd);
+        dev_close(dev);
         return ret;
 }
index 81aa768a1b34fb2615c46abf1440e352df3aa086..e42c28fa20d2a4f22fde60e2c246346cf886d2c2 100644 (file)
@@ -398,17 +398,18 @@ static void show_sfx_smart_log(struct nvme_additional_smart_log *smart,
 static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        struct nvme_additional_smart_log smart_log;
-       int err, fd;
        char *desc = "Get ScaleFlux vendor specific additional smart log (optionally, "\
                          "for the specified namespace), and show it.";
        const char *namespace = "(optional) desired namespace";
        const char *raw = "dump output in binary format";
        const char *json= "Dump output in json format";
+       struct nvme_dev *dev;
        struct config {
                __u32 namespace_id;
                bool  raw_binary;
                bool  json;
        };
+       int err;
 
        struct config cfg = {
                .namespace_id = 0xffffffff,
@@ -422,12 +423,11 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
        };
 
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               return fd;
-       }
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
-       err = nvme_get_nsid_log(fd, false, 0xca, cfg.namespace_id,
+       err = nvme_get_nsid_log(dev->fd, false, 0xca, cfg.namespace_id,
                sizeof(smart_log), (void *)&smart_log);
        if (!err) {
                if (cfg.json)
@@ -441,7 +441,7 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
        }
        else if (err > 0)
                nvme_show_status(err);
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -618,15 +618,15 @@ static void show_lat_stats_myrtle(struct sfx_lat_stats_myrtle *stats, int write)
 static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        struct sfx_lat_stats stats;
-       int err, fd;
-
        char *desc = "Get ScaleFlux Latency Statistics log and show it.";
        const char *raw = "dump output in binary format";
        const char *write = "Get write statistics (read default)";
+       struct nvme_dev *dev;
        struct config {
                bool raw_binary;
                bool write;
        };
+       int err;
 
        struct config cfg = {
        };
@@ -637,12 +637,12 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               return fd;
-       }
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
-       err = nvme_get_log_simple(fd, cfg.write ? 0xc3 : 0xc1, sizeof(stats), (void *)&stats);
+       err = nvme_get_log_simple(dev->fd, cfg.write ? 0xc3 : 0xc1,
+                                 sizeof(stats), (void *)&stats);
        if (!err) {
                if ((stats.ver.maj == VANDA_MAJOR_IDX) && (stats.ver.min == VANDA_MINOR_IDX)) {
                        if (!cfg.raw_binary) {
@@ -662,7 +662,7 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
                }
        } else if (err > 0)
                nvme_show_status(err);
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -766,9 +766,9 @@ static void bd_table_show(unsigned char *bd_table, __u64 table_size)
  */
 static int sfx_get_bad_block(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       int fd;
-       unsigned char *data_buf;
        const __u64 buf_size = 256*4096*sizeof(unsigned char);
+       unsigned char *data_buf;
+       struct nvme_dev *dev;
        int err = 0;
 
        char *desc = "Get bad block table of sfx block device.";
@@ -777,19 +777,18 @@ static int sfx_get_bad_block(int argc, char **argv, struct command *cmd, struct
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               return fd;
-       }
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        data_buf = malloc(buf_size);
        if (!data_buf) {
                fprintf(stderr, "malloc fail, errno %d\r\n", errno);
-               close(fd);
+               dev_close(dev);
                return -1;
        }
 
-       err = get_bb_table(fd, 0xffffffff, data_buf, buf_size);
+       err = get_bb_table(dev->fd, 0xffffffff, data_buf, buf_size);
        if (err < 0) {
                perror("get-bad-block");
        } else if (err != 0) {
@@ -800,7 +799,7 @@ static int sfx_get_bad_block(int argc, char **argv, struct command *cmd, struct
        }
 
        free(data_buf);
-       close(fd);
+       dev_close(dev);
        return 0;
 }
 
@@ -821,25 +820,25 @@ static void show_cap_info(struct sfx_freespace_ctx *ctx)
 static int query_cap_info(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        struct sfx_freespace_ctx ctx = { 0 };
-       int err = 0, fd;
        char *desc = "query current capacity info";
        const char *raw = "dump output in binary format";
+       struct nvme_dev *dev;
        struct config {
                bool  raw_binary;
        };
        struct config cfg;
+       int err = 0;
 
        OPT_ARGS(opts) = {
                OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               return fd;
-       }
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
-       if (nvme_query_cap(fd, 0xffffffff, sizeof(ctx), &ctx)) {
+       if (nvme_query_cap(dev->fd, 0xffffffff, sizeof(ctx), &ctx)) {
                perror("sfx-query-cap");
                err = -1;
        }
@@ -851,7 +850,7 @@ static int query_cap_info(int argc, char **argv, struct command *cmd, struct plu
                        d_raw((unsigned char *)&ctx, sizeof(ctx));
                }
        }
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -941,14 +940,15 @@ static int sfx_confirm_change(const char *str)
 
 static int change_cap(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       int err = -1, fd;
        char *desc = "dynamic change capacity";
        const char *cap_gb = "cap size in GB";
        const char *cap_byte = "cap size in byte";
        const char *force = "The \"I know what I'm doing\" flag, skip confirmation before sending command";
+       struct nvme_dev *dev;
        __u64 cap_in_4k = 0;
        __u64 cap_in_sec = 0;
        int shrink = 0;
+       int err = -1;
 
        struct config {
                __u64 cap_in_byte;
@@ -969,10 +969,9 @@ static int change_cap(int argc, char **argv, struct command *cmd, struct plugin
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               return fd;
-       }
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        cap_in_sec = IDEMA_CAP(cfg.capacity_in_gb);
        cap_in_4k = cap_in_sec >> 3;
@@ -981,27 +980,27 @@ static int change_cap(int argc, char **argv, struct command *cmd, struct plugin
        printf("%dG %"PRIu64"B %"PRIu64" 4K\n",
                cfg.capacity_in_gb, (uint64_t)cfg.cap_in_byte, (uint64_t)cap_in_4k);
 
-       if (change_sanity_check(fd, cap_in_4k, &shrink)) {
+       if (change_sanity_check(dev->fd, cap_in_4k, &shrink)) {
                printf("ScaleFlux change-capacity: fail\n");
-               close(fd);
+               dev_close(dev);
                return err;
        }
 
        if (!cfg.force && shrink && !sfx_confirm_change("Changing Cap may irrevocably delete this device's data")) {
-               close(fd);
+               dev_close(dev);
                return 0;
        }
 
-       err = nvme_change_cap(fd, 0xffffffff, cap_in_4k);
+       err = nvme_change_cap(dev->fd, 0xffffffff, cap_in_4k);
        if (err < 0)
                perror("sfx-change-cap");
        else if (err != 0)
                nvme_show_status(err);
        else {
                printf("ScaleFlux change-capacity: success\n");
-               ioctl(fd, BLKRRPART);
+               ioctl(dev->fd, BLKRRPART);
        }
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -1053,7 +1052,6 @@ char *sfx_feature_to_string(int feature)
 
 static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       int err = 0, fd;
        char *desc = "ScaleFlux internal set features\n"
                                 "feature id 1: ATOMIC\n"
                                 "value 0: Disable atomic write\n"
@@ -1062,8 +1060,9 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl
        const char *feature_id = "hex feature name (required)";
        const char *namespace_id = "desired namespace";
        const char *force = "The \"I know what I'm doing\" flag, skip confirmation before sending command";
-
+       struct nvme_dev *dev;
        struct nvme_id_ns ns;
+       int err = 0;
 
        struct config {
                __u32 namespace_id;
@@ -1086,37 +1085,36 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               return fd;
-       }
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        if (!cfg.feature_id) {
                fprintf(stderr, "feature-id required param\n");
-               close(fd);
+               dev_close(dev);
                return EINVAL;
        }
 
        if (cfg.feature_id == SFX_FEAT_CLR_CARD) {
                /*Warning for clean card*/
                if (!cfg.force && !sfx_confirm_change("Going to clean device's data, confirm umount fs and try again")) {
-                       close(fd);
+                       dev_close(dev);
                        return 0;
                } else {
-                       return sfx_clean_card(fd);
+                       return sfx_clean_card(dev->fd);
                }
 
        }
 
        if (cfg.feature_id == SFX_FEAT_ATOMIC && cfg.value != 0) {
                if (cfg.namespace_id != 0xffffffff) {
-                       err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+                       err = nvme_identify_ns(dev->fd, cfg.namespace_id, &ns);
                        if (err) {
                                if (err < 0)
                                        perror("identify-namespace");
                                else
                                        nvme_show_status(err);
-                               close(fd);
+                               dev_close(dev);
                                return err;
                        }
                        /*
@@ -1124,29 +1122,30 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl
                         */
                        if ((ns.flbas & 0xf) != 1) {
                                printf("Please change-sector size to 4K, then retry\n");
-                               close(fd);
+                               dev_close(dev);
                                return EFAULT;
                        }
                }
        } else if (cfg.feature_id == SFX_FEAT_UP_P_CAP) {
                if (cfg.value <= 0) {
                        fprintf(stderr, "Invalid Param\n");
-                       close(fd);
+                       dev_close(dev);
                        return EINVAL;
                }
 
                /*Warning for change pacp by GB*/
                if (!cfg.force && !sfx_confirm_change("Changing physical capacity may irrevocably delete this device's data")) {
-                       close(fd);
+                       dev_close(dev);
                        return 0;
                }
        }
 
-       err = nvme_sfx_set_features(fd, cfg.namespace_id, cfg.feature_id, cfg.value);
+       err = nvme_sfx_set_features(dev->fd, cfg.namespace_id, cfg.feature_id,
+                                   cfg.value);
 
        if (err < 0) {
                perror("ScaleFlux-set-feature");
-               close(fd);
+               dev_close(dev);
                return errno;
        } else if (!err) {
                printf("ScaleFlux set-feature:%#02x (%s), value:%d\n", cfg.feature_id,
@@ -1154,18 +1153,19 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl
        } else if (err > 0)
                nvme_show_status(err);
 
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
 static int sfx_get_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       int err = 0, fd;
        char *desc = "ScaleFlux internal set features\n"
                                 "feature id 1: ATOMIC";
        const char *feature_id = "hex feature name (required)";
        const char *namespace_id = "desired namespace";
+       struct nvme_dev *dev;
        __u32 result = 0;
+       int err = 0;
 
        struct config {
                __u32 namespace_id;
@@ -1182,21 +1182,20 @@ static int sfx_get_feature(int argc, char **argv, struct command *cmd, struct pl
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               return fd;
-       }
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        if (!cfg.feature_id) {
                fprintf(stderr, "feature-id required param\n");
-               close(fd);
+               dev_close(dev);
                return EINVAL;
        }
 
-       err = nvme_sfx_get_features(fd, cfg.namespace_id, cfg.feature_id, &result);
+       err = nvme_sfx_get_features(dev->fd, cfg.namespace_id, cfg.feature_id, &result);
        if (err < 0) {
                perror("ScaleFlux-get-feature");
-               close(fd);
+               dev_close(dev);
                return errno;
        } else if (!err) {
                printf("ScaleFlux get-feature:%02x (%s), value:%d\n", cfg.feature_id,
@@ -1204,7 +1203,7 @@ static int sfx_get_feature(int argc, char **argv, struct command *cmd, struct pl
        } else if (err > 0)
                nvme_show_status(err);
 
-       close(fd);
+       dev_close(dev);
        return err;
 
 }
index 7281c40eefd1b6a3e679a5fee4208d97f3f4960d..63ff5261e381287bd01be5293acdb6dbc65724dc 100644 (file)
@@ -155,11 +155,11 @@ static int log_pages_supp(int argc, char **argv, struct command *cmd,
                          struct plugin *plugin)
 {
        int err = 0;
-       int fd = 0;
        __u32 i = 0;
        log_page_map logPageMap;
        const char *desc = "Retrieve Seagate Supported Log-Page information for the given device ";
        const char *output_format = "output in binary format";
+       struct nvme_dev *dev;
        int fmt;
 
        struct config {
@@ -175,10 +175,11 @@ static int log_pages_supp(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
-       err = nvme_get_log_simple(fd, 0xc5, sizeof(logPageMap), &logPageMap);
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
+       err = nvme_get_log_simple(dev->fd, 0xc5,
+                                 sizeof(logPageMap), &logPageMap);
        if (!err) {
                if (strcmp(cfg.output_format,"json")) {
                        printf ("Seagate Supported Log-pages count :%d\n",
@@ -203,7 +204,7 @@ static int log_pages_supp(int argc, char **argv, struct command *cmd,
 
        if (err > 0)
                nvme_show_status(err);
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -715,13 +716,13 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
 {
        EXTENDED_SMART_INFO_T   ExtdSMARTInfo;
        vendor_log_page_CF      logPageCF;
-       int fd;
        struct json_object *root = json_create_object();
        struct json_object *lbafs = json_create_array();
        struct json_object *lbafs_ExtSmart, *lbafs_DramSmart;
 
        const char *desc = "Retrieve Seagate Extended SMART information for the given device ";
        const char *output_format = "output in binary format";
+       struct nvme_dev *dev;
        int err, index=0;
        struct config {
                char *output_format;
@@ -736,8 +737,8 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0) {
                printf ("\nDevice not found \n");
                return -1;
        }
@@ -745,7 +746,8 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
        if (strcmp(cfg.output_format,"json"))
                printf("Seagate Extended SMART Information :\n");
 
-       err = nvme_get_log_simple(fd, 0xC4, sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
+       err = nvme_get_log_simple(dev->fd, 0xC4,
+                                 sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
        if (!err) {
                if (strcmp(cfg.output_format,"json")) {
                        printf("%-39s %-15s %-19s \n", "Description", "Ext-Smart-Id", "Ext-Smart-Value");
@@ -767,7 +769,8 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
                 * Next get Log Page 0xCF
                 */
 
-               err = nvme_get_log_simple(fd, 0xCF, sizeof(logPageCF), &logPageCF);
+               err = nvme_get_log_simple(dev->fd, 0xCF,
+                                         sizeof(logPageCF), &logPageCF);
                if (!err) {
                        if(strcmp(cfg.output_format,"json")) {
                                /*printf("Seagate DRAM Supercap SMART Attributes :\n");*/
@@ -784,7 +787,7 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
        } else if (err > 0)
                nvme_show_status(err);
 
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -819,13 +822,13 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
        EXTENDED_SMART_INFO_T ExtdSMARTInfo;
        vendor_log_page_CF    logPageCF;
 
-       int fd;
        int err, cf_err;
        int index;
        const char *desc = "Retrieve Seagate Temperature Stats information for the given device ";
        const char *output_format = "output in binary format";
        unsigned int temperature = 0, PcbTemp = 0, SocTemp = 0, scCurrentTemp = 0, scMaxTemp = 0;
        unsigned long long maxTemperature = 0, MaxSocTemp = 0;
+       struct nvme_dev *dev;
        struct config {
                char *output_format;
        };
@@ -839,8 +842,8 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0) {
                printf ("\nDevice not found \n");;
                return -1;
        }
@@ -848,7 +851,7 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
        if(strcmp(cfg.output_format,"json"))
                printf("Seagate Temperature Stats Information :\n");
        /*STEP-1 : Get Current Temperature from SMART */
-       err = nvme_get_log_smart(fd, 0xffffffff, false, &smart_log);
+       err = nvme_get_log_smart(dev->fd, 0xffffffff, false, &smart_log);
        if (!err) {
                temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]);
                temperature = temperature ? temperature - 273 : 0;
@@ -864,7 +867,8 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
        }
 
        /* STEP-2 : Get Max temperature form Ext SMART-id 194 */
-       err = nvme_get_log_simple(fd, 0xC4, sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
+       err = nvme_get_log_simple(dev->fd, 0xC4,
+                                 sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
        if (!err) {
                for(index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++) {
                        if (ExtdSMARTInfo.vendorData[index].AttributeNumber == VS_ATTR_ID_MAX_LIFE_TEMPERATURE) {
@@ -885,7 +889,8 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
        else if (err > 0)
                nvme_show_status(err);
 
-       cf_err = nvme_get_log_simple(fd, 0xCF, sizeof(ExtdSMARTInfo), &logPageCF);
+       cf_err = nvme_get_log_simple(dev->fd, 0xCF,
+                                    sizeof(ExtdSMARTInfo), &logPageCF);
 
        if(!cf_err) {
                scCurrentTemp = logPageCF.AttrCF.SuperCapCurrentTemperature;
@@ -900,7 +905,7 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
        if(!strcmp(cfg.output_format,"json"))
                json_temp_stats(temperature, PcbTemp, SocTemp, maxTemperature, MaxSocTemp, cf_err, scCurrentTemp, scMaxTemp);
 
-       close(fd);
+       dev_close(dev);
        return err;
 }
 /* EOF Temperature Stats information */
@@ -993,7 +998,7 @@ static void json_vs_pcie_error_log(pcie_error_log_page pcieErrorLog)
 static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        pcie_error_log_page pcieErrorLog;
-       int fd;
+       struct nvme_dev *dev;
 
        const char *desc = "Retrieve Seagate PCIe error counters for the given device ";
        const char *output_format = "output in binary format";
@@ -1011,8 +1016,8 @@ static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0) {
                printf ("\nDevice not found \n");;
                return -1;
        }
@@ -1020,7 +1025,8 @@ static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct
        if(strcmp(cfg.output_format,"json"))
                printf("Seagate PCIe error counters Information :\n");
 
-       err = nvme_get_log_simple(fd, 0xCB, sizeof(pcieErrorLog), &pcieErrorLog);
+       err = nvme_get_log_simple(dev->fd, 0xCB,
+                                 sizeof(pcieErrorLog), &pcieErrorLog);
        if (!err) {
                if(strcmp(cfg.output_format,"json")) {
                        print_vs_pcie_error_log(pcieErrorLog);
@@ -1030,7 +1036,7 @@ static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct
        } else if (err > 0)
                nvme_show_status(err);
 
-       close(fd);
+       dev_close(dev);
        return err;
 }
 /* EOF PCIE error-log information */
@@ -1039,8 +1045,9 @@ static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *c
 {
        const char *desc = "Clear Seagate PCIe Correctable counters for the given device ";
        const char *save = "specifies that the controller shall save the attribute";
-       int err, fd;
+       struct nvme_dev *dev;
        __u32 result;
+       int err;
 
        struct config {
                bool   save;
@@ -1055,19 +1062,20 @@ static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *c
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0) {
                printf ("\nDevice not found \n");;
                return -1;
        }
 
-       err = nvme_set_features_simple(fd, 0xE1, 0, 0xCB, cfg.save, &result);
+       err = nvme_set_features_simple(dev->fd, 0xE1, 0, 0xCB, cfg.save,
+                                      &result);
 
        if (err < 0) {
                perror("set-feature");
        }
 
-       close(fd);
+       dev_close(dev);
        return err;
 
 }
@@ -1081,11 +1089,12 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
                "state of the controller at the time the command is processed. " \
                "0 - controller shall not update the Telemetry Host Initiated Data.";
        const char *raw = "output in raw format";
-       int err, fd, dump_fd;
        struct nvme_temetry_log_hdr tele_log;
-       __le64  offset = 0;
        int blkCnt, maxBlk = 0, blksToGet;
+       struct nvme_dev *dev;
        unsigned char  *log;
+       __le64  offset = 0;
+       int err, dump_fd;
 
        struct config {
                __u32 namespace_id;
@@ -1105,13 +1114,13 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        dump_fd = STDOUT_FILENO;
        cfg.log_id = (cfg.log_id << 8) | 0x07;
-       err = nvme_get_nsid_log(fd, false, cfg.log_id, cfg.namespace_id,
+       err = nvme_get_nsid_log(dev->fd, false, cfg.log_id, cfg.namespace_id,
                             sizeof(tele_log), (void *)(&tele_log));
        if (!err) {
                maxBlk = tele_log.tele_data_area3;
@@ -1140,7 +1149,7 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
                blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ) ? TELEMETRY_BLOCKS_TO_READ : (maxBlk - blkCnt);
 
                if(blksToGet == 0) {
-                       close(fd);
+                       dev_close(dev);
                        return err;
                }
 
@@ -1149,7 +1158,7 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
 
                if (!log) {
                        fprintf(stderr, "could not alloc buffer for log\n");
-                       close(fd);
+                       dev_close(dev);
                        return EINVAL;
                }
 
@@ -1157,7 +1166,7 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
 
                struct nvme_get_log_args args = {
                        .args_size      = sizeof(args),
-                       .fd             = fd,
+                       .fd             = dev->fd,
                        .lid            = cfg.log_id,
                        .nsid           = cfg.namespace_id,
                        .lpo            = offset,
@@ -1192,7 +1201,7 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
                free(log);
        }
 
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -1202,7 +1211,8 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug
                "hex-dump (default) or binary format";
        const char *namespace_id = "desired namespace";
        const char *raw = "output in raw format";
-       int err, fd, dump_fd;
+       struct nvme_dev *dev;
+       int err, dump_fd;
        struct nvme_temetry_log_hdr tele_log;
        __le64  offset = 0;
        __u16 log_id;
@@ -1224,14 +1234,14 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        dump_fd = STDOUT_FILENO;
 
        log_id = 0x08;
-       err = nvme_get_nsid_log(fd, false, log_id, cfg.namespace_id,
+       err = nvme_get_nsid_log(dev->fd, false, log_id, cfg.namespace_id,
                             sizeof(tele_log), (void *)(&tele_log));
        if (!err) {
                maxBlk = tele_log.tele_data_area3;
@@ -1273,7 +1283,7 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug
 
                struct nvme_get_log_args args = {
                        .args_size      = sizeof(args),
-                       .fd             = fd,
+                       .fd             = dev->fd,
                        .lid            = log_id,
                        .nsid           = cfg.namespace_id,
                        .lpo            = offset,
@@ -1308,7 +1318,7 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug
                free(log);
        }
 
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -1333,7 +1343,8 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl
        const char *namespace_id = "desired namespace";
 
        const char *file = "dump file";
-       int err, fd, dump_fd;
+       struct nvme_dev *dev;
+       int err, dump_fd;
        int flags = O_WRONLY | O_CREAT;
        int mode = S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP| S_IROTH;
        struct nvme_temetry_log_hdr tele_log;
@@ -1358,22 +1369,22 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        dump_fd = STDOUT_FILENO;
        if(strlen(cfg.file)) {
                dump_fd = open(cfg.file, flags, mode);
                if (dump_fd < 0) {
                        perror(cfg.file);
-                       close(fd);
+                       dev_close(dev);
                        return EINVAL;
                }
        }
 
        log_id = 0x08;
-       err = nvme_get_nsid_log(fd, false, log_id, cfg.namespace_id,
+       err = nvme_get_nsid_log(dev->fd, false, log_id, cfg.namespace_id,
                             sizeof(tele_log), (void *)(&tele_log));
        if (!err) {
                maxBlk = tele_log.tele_data_area3;
@@ -1413,7 +1424,7 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl
 
                struct nvme_get_log_args args = {
                        .args_size      = sizeof(args),
-                       .fd             = fd,
+                       .fd             = dev->fd,
                        .lid            = log_id,
                        .nsid           = cfg.namespace_id,
                        .lpo            = offset,
@@ -1447,7 +1458,7 @@ out:
        if(strlen(cfg.file))
                close(dump_fd);
 
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
index 801fdc3b5684f8ef18bdbe6b5966ca0ab6243f72..7b02b452c20fed89b484fdb1050f3c5c39c202b4 100644 (file)
@@ -117,15 +117,16 @@ static void show_shannon_smart_log(struct nvme_shannon_smart_log *smart,
 static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        struct nvme_shannon_smart_log smart_log;
-       int err, fd;
        char *desc = "Get Shannon vendor specific additional smart log (optionally, "\
                      "for the specified namespace), and show it.";
        const char *namespace = "(optional) desired namespace";
        const char *raw = "dump output in binary format";
+       struct nvme_dev *dev;
        struct config {
                __u32 namespace_id;
                bool  raw_binary;
        };
+       int err;
 
        struct config cfg = {
                .namespace_id = NVME_NSID_ALL,
@@ -137,10 +138,10 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
-       err = nvme_get_nsid_log(fd, false, 0xca, cfg.namespace_id,
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
+       err = nvme_get_nsid_log(dev->fd, false, 0xca, cfg.namespace_id,
                   sizeof(smart_log), &smart_log);
        if (!err) {
                if (!cfg.raw_binary)
@@ -151,7 +152,7 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
        }
        else if (err > 0)
                nvme_show_status(err);
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -175,9 +176,10 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st
        const char *data_len = "buffer len (if) data is returned";
        const char *cdw11 = "dword 11 for interrupt vector config";
        const char *human_readable = "show infos in readable format";
-       int err, fd;
-       __u32 result;
+       struct nvme_dev *dev;
        void *buf = NULL;
+       __u32 result;
+       int err;
 
        struct config {
                __u32 namespace_id;
@@ -208,24 +210,24 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        if (cfg.sel > 7) {
                fprintf(stderr, "invalid 'select' param:%d\n", cfg.sel);
-               close(fd);
+               dev_close(dev);
                return EINVAL;
        }
        if (!cfg.feature_id) {
                fprintf(stderr, "feature-id required param\n");
-               close(fd);
+               dev_close(dev);
                return EINVAL;
        }
        if (cfg.data_len) {
                if (posix_memalign(&buf, getpagesize(), cfg.data_len))
                {
-                       close(fd);
+                       dev_close(dev);
                        exit(ENOMEM);
                }
                memset(buf, 0, cfg.data_len);
@@ -233,7 +235,7 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st
 
        struct nvme_get_features_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .fid            = cfg.feature_id,
                .nsid           = cfg.namespace_id,
                .sel            = cfg.sel,
@@ -287,10 +289,11 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st
        const char *data = "optional file for feature data (default stdin)";
        const char *value = "new value of feature (required)";
        const char *save = "specifies that the controller shall save the attribute";
-       int err, fd;
-       __u32 result;
-       void *buf = NULL;
        int ffd = STDIN_FILENO;
+       struct nvme_dev *dev;
+       void *buf = NULL;
+       __u32 result;
+       int err;
 
        struct config {
                char *file;
@@ -320,20 +323,20 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        if (!cfg.feature_id) {
                fprintf(stderr, "feature-id required param\n");
-               close(fd);
+               dev_close(dev);
                return EINVAL;
        }
 
        if (cfg.data_len) {
                if (posix_memalign(&buf, getpagesize(), cfg.data_len)){
                        fprintf(stderr, "can not allocate feature payload\n");
-                       close(fd);
+                       dev_close(dev);
                        return ENOMEM;
                }
                memset(buf, 0, cfg.data_len);
@@ -358,7 +361,7 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st
 
        struct nvme_set_features_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .fid            = cfg.feature_id,
                .nsid           = cfg.namespace_id,
                .cdw11          = cfg.value,
index 92be7362e9d24909996a5d39fb7adab29d75256c..bd0041c62111cbb938fe9adae918f0d8c5daf9b3 100644 (file)
@@ -63,6 +63,8 @@ static void vu_gc_log_show(garbage_control_collection_log_t *payload, const char
 int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
        const char *desc = "Get and parse Solidigm vendor specific garbage collection event log.";
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                char    *output_format;
@@ -77,22 +79,22 @@ int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *c
                OPT_END()
        };
 
-       int fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)     {
-               return fd;
-       }
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        enum nvme_print_flags flags = validate_output_format(cfg.output_format);
        if (flags == -EINVAL) {
                fprintf(stderr, "Invalid output format '%s'\n", cfg.output_format);
-               close(fd);
+               dev_close(dev);
                return flags;
        }
 
        garbage_control_collection_log_t gc_log;
        const int solidigm_vu_gc_log_id = 0xfd;
 
-       int err = nvme_get_log_simple(fd, solidigm_vu_gc_log_id, sizeof(gc_log), &gc_log);
+       err = nvme_get_log_simple(dev->fd, solidigm_vu_gc_log_id,
+                                 sizeof(gc_log), &gc_log);
        if (!err) {
                if (flags & BINARY)     {
                        d_raw((unsigned char *)&gc_log, sizeof(gc_log));
@@ -105,7 +107,7 @@ int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *c
        else if (err > 0) {
                nvme_show_status(err);
        }
-       
-       close(fd);
+
+       dev_close(dev);
        return err;
 }
index 0bfd6119c7438d17986378f548d63ece25157fe4..17b1c95eaaaed27b77b5e10aaa3a83f1cef8cf9c 100644 (file)
@@ -385,6 +385,7 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd
                                      struct plugin *plugin)
 {
        const char *desc = "Get and Parse Solidigm Latency Tracking Statistics log.";
+       struct nvme_dev *dev;
        __u32 enabled;
        int err;
 
@@ -407,43 +408,45 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd
                OPT_END()
        };
 
-       lt.fd = parse_and_open(argc, argv, desc, opts);
-       if (lt.fd < 0)
-               return lt.fd;
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
+
+       lt.fd = dev->fd;
 
        lt.print_flags = validate_output_format(lt.cfg.output_format);
        if (lt.print_flags == -EINVAL) {
                fprintf(stderr, "Invalid output format '%s'\n", lt.cfg.output_format);
-               close(lt.fd);
+               dev_close(dev);
                return EINVAL;
        }
 
        if (lt.cfg.type > 0xf) {
                fprintf(stderr, "Invalid Log type value '%d'\n", lt.cfg.type);
-               close(lt.fd);
+               dev_close(dev);
                return EINVAL;
        }
 
        if (lt.cfg.type && !(lt.cfg.read || lt.cfg.write)) {
                fprintf(stderr, "Log type option valid only when retrieving statistics\n");
-               close(lt.fd);
+               dev_close(dev);
                return EINVAL;
        }
 
        err = latency_tracking_enable(&lt);
        if (err){
-               close(lt.fd);
+               dev_close(dev);
                return err;
        }
 
        err = latency_tracker_get_log(&lt);
        if (err){
-               close(lt.fd);
+               dev_close(dev);
                return err;
        }
 
        if ((lt.cfg.read || lt.cfg.write || lt.cfg.enable || lt.cfg.disable)) {
-               close(lt.fd);
+               dev_close(dev);
                return 0;
        }
 
@@ -465,6 +468,6 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd
        } else {
                fprintf(stderr, "Could not read feature id 0xE2.\n");
        }
-       close(lt.fd);
+       dev_close(dev);
        return err;
 }
index 483cc7ae8fd4648214364084c268394b6672332d..7d885951a35fc398b42e6a9c8034a133f7ef1b14 100644 (file)
@@ -201,7 +201,8 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd
        const int solidigm_vu_smart_log_id = 0xCA;
        vu_smart_log_t smart_log_payload;
        enum nvme_print_flags flags;
-       int fd, err;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32   namespace_id;
@@ -219,19 +220,19 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               return fd;
-       }
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
+               return err;
 
        flags = validate_output_format(cfg.output_format);
        if (flags == -EINVAL) {
                fprintf(stderr, "Invalid output format '%s'\n", cfg.output_format);
-               close(fd);
+               dev_close(dev);
                return flags;
        }
 
-       err = nvme_get_log_simple(fd, solidigm_vu_smart_log_id, sizeof(smart_log_payload), &smart_log_payload);
+       err = nvme_get_log_simple(dev->fd, solidigm_vu_smart_log_id,
+                                 sizeof(smart_log_payload), &smart_log_payload);
        if (!err) {
                if (flags & JSON) {
                        vu_smart_log_show_json(&smart_log_payload,
@@ -247,7 +248,7 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd
                nvme_show_status(err);
        }
 
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
index 5c121ac8b050acae485693c0fee1ac4d751d933e..30d62b067c45718f5a67c7d83cc8a073da0a70d9 100644 (file)
@@ -434,11 +434,12 @@ end:
 
 static int vendor_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       int err, fd;
        char *desc = "Get extended SMART information and show it.";
        const char *namespace = "(optional) desired namespace";
        const char *output_file = "(optional) binary output filename";
        const char *log = "(optional) log ID (0xC0, or 0xCA), default 0xCA";
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u32 namespace_id;
@@ -459,8 +460,8 @@ static int vendor_log(int argc, char **argv, struct command *cmd, struct plugin
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0) {
                fprintf(stderr,"%s: failed to parse arguments\n", __func__);
                return EINVAL;
        }
@@ -471,22 +472,24 @@ static int vendor_log(int argc, char **argv, struct command *cmd, struct plugin
                goto end;
        }
 
-       err = nvme_get_vendor_log(fd, cfg.namespace_id, cfg.log, cfg.output_file);
+       err = nvme_get_vendor_log(dev->fd, cfg.namespace_id, cfg.log,
+                                 cfg.output_file);
        if (err)
                fprintf(stderr, "%s: couldn't get vendor log 0x%x\n", __func__, cfg.log);
 end:
        if (err > 0)
                nvme_show_status(err);
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
 static int internal_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       int err, fd;
        char *desc = "Get internal status log and show it.";
        const char *output_file = "(optional) binary output filename";
        const char *prev_log = "(optional) use previous log. Otherwise uses current log.";
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                const char* output_file;
@@ -504,8 +507,8 @@ static int internal_log(int argc, char **argv, struct command *cmd, struct plugi
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0) {
                fprintf(stderr,"%s: failed to parse arguments\n", __func__);
                return EINVAL;
        }
@@ -515,46 +518,48 @@ static int internal_log(int argc, char **argv, struct command *cmd, struct plugi
        else
                printf("Getting current log\n");
 
-       err = nvme_get_internal_log_file(fd, cfg.output_file, !cfg.prev_log);
+       err = nvme_get_internal_log_file(dev->fd, cfg.output_file,
+                                        !cfg.prev_log);
        if (err < 0)
                fprintf(stderr, "%s: couldn't get fw log \n", __func__);
        if (err > 0)
                nvme_show_status(err);
 
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
 static int clear_correctable_errors(int argc, char **argv, struct command *cmd,
                                struct plugin *plugin)
 {
-       int err, fd;
        char *desc = "Clear PCIe correctable error count.";
        const __u32 namespace_id = 0xFFFFFFFF;
        const __u32 feature_id = 0xCA;
        const __u32 value = 1; /* Bit0 - reset clear PCIe correctable count */
        const __u32 cdw12 = 0;
        const bool save = false;
+       struct nvme_dev *dev;
        __u32 result;
+       int err;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0) {
                fprintf(stderr,"%s: failed to parse arguments\n", __func__);
                return EINVAL;
        }
 
        /* Check device supported */
-       err = nvme_get_sct_status(fd, MASK_0 | MASK_1);
+       err = nvme_get_sct_status(dev->fd, MASK_0 | MASK_1);
        if (err)
                goto end;
 
        struct nvme_set_features_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .fid            = feature_id,
                .nsid           = namespace_id,
                .cdw11          = value,
@@ -574,6 +579,6 @@ static int clear_correctable_errors(int argc, char **argv, struct command *cmd,
 end:
        if (err > 0)
                nvme_show_status(err);
-       close(fd);
+       dev_close(dev);
        return err;
 }
index a3b739d645c45210ac9c838ed7b0426317c51f0d..c75e7eea9712584511bd1620771501f707cb2c95 100644 (file)
@@ -21,20 +21,20 @@ static int getHealthValue(int argc, char **argv, struct command *cmd, struct plu
 {
        struct nvme_smart_log smart_log;
        char *desc = "Get nvme health percentage.";
-       int result=0, fd;
        int  percent_used = 0, healthvalue=0;
-        
+       struct nvme_dev *dev;
+       int result;
+
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-        
-       if (fd < 0) {
+       result = parse_and_open(&dev, argc, argv, desc, opts);
+       if (result < 0) {
                printf("\nDevice not found \n");;
                return -1;
        }
-       result = nvme_get_log_smart(fd, 0xffffffff, false, &smart_log);
+       result = nvme_get_log_smart(dev->fd, 0xffffffff, false, &smart_log);
        if (!result) {
                printf("Transcend NVME heath value: ");
                percent_used =smart_log.percent_used;
@@ -50,7 +50,7 @@ static int getHealthValue(int argc, char **argv, struct command *cmd, struct plu
                }
                         
        }
-       close(fd);
+       dev_close(dev);
        return result;
 }
 
@@ -59,15 +59,16 @@ static int getBadblock(int argc, char **argv, struct command *cmd, struct plugin
 {
 
        char *desc = "Get nvme bad block number.";
-       int result=0, fd;
+       struct nvme_dev *dev;
+       int result;
  
        OPT_ARGS(opts) = {
                 
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
+       result = parse_and_open(&dev, argc, argv, desc, opts);
+       if (result < 0) {
                printf("\nDevice not found \n");;
                return -1;
        }
@@ -79,11 +80,11 @@ static int getBadblock(int argc, char **argv, struct command *cmd, struct plugin
        nvmecmd.cdw12=DW12_BAD_BLOCK;
        nvmecmd.addr = (__u64)(uintptr_t)data;
        nvmecmd.data_len = 0x1;
-       result = nvme_submit_admin_passthru(fd, &nvmecmd, NULL);
+       result = nvme_submit_admin_passthru(dev->fd, &nvmecmd, NULL);
        if(!result) {
                int badblock  = data[0];
                printf("Transcend NVME badblock count: %d\n",badblock);
        }
-       close(fd);
+       dev_close(dev);
        return result;
 }
index b8cefe6fe5c4f9af0ab9fb8c2ca5fbf2c5ac9c61..d9742ea746aaf3f9da027abd955740e2ad209d29 100644 (file)
@@ -927,8 +927,7 @@ static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl)
 
 static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       int err = 0;
-       int fd, ret;
+       int ret, err = 0;
        long int total_time = 0;
        long int freq_time = 0;
        long int cur_time = 0;
@@ -949,6 +948,7 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm
        const char *freq = "(optional) How often you want to log SMART data (0.25 = 15' , 0.5 = 30' , 1 = 1 hour, 2 = 2 hours, etc.). Default = 10 hours.";
        const char *output_file = "(optional) Name of the log file (give it a name that easy for you to remember what the test is). You can leave it blank too, we will take care it for you.";
        const char *test_name = "(optional) Name of the test you are doing. We use this as part of the name of the log file.";
+       struct nvme_dev *dev;
 
        struct vtview_save_log_settings cfg = {
                .run_time_hrs = 20,
@@ -975,10 +975,10 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm
                strcpy(path, argv[1]);
        }
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               printf("Error parse and open (fd = %d)\n", fd);
-               return (fd);
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0) {
+               printf("Error parse and open (err = %d)\n", err);
+               return err;
        }
 
        printf("Running...\n");
@@ -986,10 +986,10 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm
        printf("Running for %lf hour(s)\n", cfg.run_time_hrs);
        printf("Logging SMART data for every %lf hour(s)\n", cfg.log_record_frequency_hrs);
 
-       ret = vt_update_vtview_log_header(fd, path, &cfg);
+       ret = vt_update_vtview_log_header(dev->fd, path, &cfg);
        if (ret) {
                err = EINVAL;
-               close(fd);
+               dev_close(dev);
                return (err);
        }
 
@@ -1009,7 +1009,7 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm
                if(cur_time >= end_time)
                        break;
 
-               ret = vt_add_entry_to_log(fd, path, &cfg);
+               ret = vt_add_entry_to_log(dev->fd, path, &cfg);
                if (ret) {
                        printf("Cannot update driver log\n");
                        break;
@@ -1021,15 +1021,15 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm
                fflush(stdout);
        }
 
-       close (fd);
+       dev_close(dev);
        return (err);
 }
 
 static int vt_show_identify(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
-       int err = 0;
-       int fd ,ret;
+       int ret, err = 0;
        struct nvme_id_ctrl ctrl;
+       struct nvme_dev *dev;
        char *desc = "Parse identify data to json format\n\n"
                "Typical usages:\n\n"
                "virtium show-identify /dev/yourDevice\n";
@@ -1038,16 +1038,16 @@ static int vt_show_identify(int argc, char **argv, struct command *cmd, struct p
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
-               printf("Error parse and open (fd = %d)\n", fd);
-               return (fd);
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0) {
+               printf("Error parse and open (err = %d)\n", err);
+               return err;
        }
 
-       ret = nvme_identify_ctrl(fd, &ctrl);
+       ret = nvme_identify_ctrl(dev->fd, &ctrl);
        if (ret) {
                printf("Cannot read identify device\n");
-               close (fd);
+               dev_close(dev);
                return (-1);
        }
 
@@ -1055,6 +1055,6 @@ static int vt_show_identify(int argc, char **argv, struct command *cmd, struct p
        vt_process_string(ctrl.mn, sizeof(ctrl.mn));
        vt_parse_detail_identify(&ctrl);
 
-       close(fd);
+       dev_close(dev);
        return (err);
 }
index ab2578d021c70348d1396ad5bc6c08393fd760f6..c2e4669d07527b938fea0323296056841b131e77 100644 (file)
@@ -2932,10 +2932,11 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
        char *desc = "Capture Diagnostics Log.";
        char *file = "Output file pathname.";
        char *size = "Data retrieval transfer size.";
+       __u64 capabilities = 0;
        char f[PATH_MAX] = {0};
+       struct nvme_dev *dev;
        __u32 xfer_size = 0;
-       int fd, ret = 0;
-       __u64 capabilities = 0;
+       int ret = 0;
 
        struct config {
                char *file;
@@ -2953,9 +2954,9 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
 
@@ -2963,7 +2964,7 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
                strncpy(f, cfg.file, PATH_MAX - 1);
        if (cfg.xfer_size != 0)
                xfer_size = cfg.xfer_size;
-       ret = wdc_get_serial_name(fd, f, PATH_MAX, "cap_diag");
+       ret = wdc_get_serial_name(dev->fd, f, PATH_MAX, "cap_diag");
        if (ret) {
                fprintf(stderr, "ERROR : WDC: failed to generate file name\n");
                goto out;
@@ -2977,15 +2978,15 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
                strcat(f, ".bin");
        }
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_CAP_DIAG) == WDC_DRIVE_CAP_CAP_DIAG)
-               ret = wdc_do_cap_diag(r, fd, f, xfer_size, 0, 0);
+               ret = wdc_do_cap_diag(r, dev->fd, f, xfer_size, 0, 0);
        else
                fprintf(stderr,
                        "ERROR : WDC: unsupported device for this command\n");
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -3232,13 +3233,14 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
        char *verbose = "Display more debug messages.";
        char f[PATH_MAX] = {0};
        char fileSuffix[PATH_MAX] = {0};
+       struct nvme_dev *dev;
        nvme_root_t r;
        __u32 xfer_size = 0;
-       int fd, ret = -1;
        int telemetry_type = 0, telemetry_data_area = 0;
        UtilsTimeInfo             timeInfo;
        __u8                      timeStamp[MAX_PATH_LEN];
        __u64 capabilities = 0;
+       int ret = -1;
 
        struct config {
                char *file;
@@ -3271,12 +3273,12 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       if (!wdc_check_device(r, fd))
+       if (!wdc_check_device(r, dev->fd))
                goto out;
 
        if (cfg.xfer_size != 0)
@@ -3305,7 +3307,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
                        timeInfo.hour, timeInfo.minute, timeInfo.second);
                snprintf(fileSuffix, PATH_MAX, "_internal_fw_log_%s", (char*)timeStamp);
 
-               ret = wdc_get_serial_name(fd, f, PATH_MAX, fileSuffix);
+               ret = wdc_get_serial_name(dev->fd, f, PATH_MAX, fileSuffix);
                if (ret) {
                        fprintf(stderr, "ERROR : WDC: failed to generate file name\n");
                        goto out;
@@ -3349,12 +3351,12 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
                goto out;
        }
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_INTERNAL_LOG) == WDC_DRIVE_CAP_INTERNAL_LOG) {
                if (telemetry_data_area == 0)
                        telemetry_data_area = 3;       /* Set the default DA to 3 if not specified */
 
-               ret = wdc_do_cap_diag(r, fd, f, xfer_size,
+               ret = wdc_do_cap_diag(r, dev->fd, f, xfer_size,
                                      telemetry_type, telemetry_data_area);
                goto out;
        }
@@ -3364,7 +3366,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
                        if (telemetry_data_area == 0)
                                telemetry_data_area = 3;       /* Set the default DA to 3 if not specified */
                        /* Get the desired telemetry log page */
-                       ret = wdc_do_cap_telemetry_log(fd, f, xfer_size,
+                       ret = wdc_do_cap_telemetry_log(dev->fd, f, xfer_size,
                                        telemetry_type, telemetry_data_area);
                        goto out;
                } else {
@@ -3374,7 +3376,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
                        /* FW requirement - xfer size must be 256k for data area 4 */
                        if (cfg.data_area >= 4)
                                xfer_size = 0x40000;
-                       ret = wdc_do_cap_dui(fd, f, xfer_size, cfg.data_area,
+                       ret = wdc_do_cap_dui(dev->fd, f, xfer_size, cfg.data_area,
                                             cfg.verbose, cfg.file_size,
                                             cfg.offset);
                        goto out;
@@ -3386,25 +3388,25 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
                        if (telemetry_data_area == 0)
                                telemetry_data_area = 3;       /* Set the default DA to 3 if not specified */
                        /* Get the desired telemetry log page */
-                       ret = wdc_do_cap_telemetry_log(fd, f, xfer_size,
+                       ret = wdc_do_cap_telemetry_log(dev->fd, f, xfer_size,
                                        telemetry_type, telemetry_data_area);
                        goto out;
                } else {
-                       ret = wdc_do_cap_dui(fd, f, xfer_size,
+                       ret = wdc_do_cap_dui(dev->fd, f, xfer_size,
                                             WDC_NVME_DUI_MAX_DATA_AREA,
                                             cfg.verbose, 0, 0);
                        goto out;
                }
        }
        if ((capabilities & WDC_SN730B_CAP_VUC_LOG) == WDC_SN730B_CAP_VUC_LOG)
-               ret = wdc_do_sn730_get_and_tar(fd, f);
+               ret = wdc_do_sn730_get_and_tar(dev->fd, f);
        else {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
        }
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -3548,7 +3550,7 @@ static int wdc_drive_log(int argc, char **argv, struct command *command,
        const char *desc = "Capture Drive Log.";
        const char *file = "Output file pathname.";
        char f[PATH_MAX] = {0};
-       int fd;
+       struct nvme_dev *dev;
        int ret;
        nvme_root_t r;
        __u64 capabilities = 0;
@@ -3565,18 +3567,18 @@ static int wdc_drive_log(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
 
-       if (!wdc_check_device(r, fd)) {
+       if (!wdc_check_device(r, dev->fd)) {
                nvme_free_tree(r);
-               close(fd);
+               dev_close(dev);
                return -1;
        }
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_DRIVE_LOG) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -3585,14 +3587,14 @@ static int wdc_drive_log(int argc, char **argv, struct command *command,
                if (cfg.file != NULL) {
                        strncpy(f, cfg.file, PATH_MAX - 1);
                }
-               ret = wdc_get_serial_name(fd, f, PATH_MAX, "drive_log");
+               ret = wdc_get_serial_name(dev->fd, f, PATH_MAX, "drive_log");
                if (ret)
                        fprintf(stderr, "ERROR : WDC : failed to generate file name\n");
                else
-                       ret = wdc_do_drive_log(fd, f);
+                       ret = wdc_do_drive_log(dev->fd, f);
        }
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -3601,9 +3603,10 @@ static int wdc_get_crash_dump(int argc, char **argv, struct command *command,
 {
        const char *desc = "Get Crash Dump.";
        const char *file = "Output file pathname.";
-       int fd, ret;
-       nvme_root_t r;
        __u64 capabilities = 0;
+       struct nvme_dev *dev;
+       nvme_root_t r;
+       int ret;
 
        struct config {
                char *file;
@@ -3618,32 +3621,32 @@ static int wdc_get_crash_dump(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
 
-       if (!wdc_check_device(r, fd)) {
+       if (!wdc_check_device(r, dev->fd)) {
                nvme_free_tree(r);
-               close(fd);
+               dev_close(dev);
                return -1;
 
        }
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_CRASH_DUMP) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
        } else {
-               ret = wdc_crash_dump(fd, cfg.file, WDC_NVME_CRASH_DUMP_TYPE);
+               ret = wdc_crash_dump(dev->fd, cfg.file, WDC_NVME_CRASH_DUMP_TYPE);
                if (ret != 0) {
                        fprintf(stderr, "ERROR : WDC : failed to read crash dump\n");
                }
        }
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -3652,13 +3655,13 @@ static int wdc_get_pfail_dump(int argc, char **argv, struct command *command,
 {
        char *desc = "Get Pfail Crash Dump.";
        char *file = "Output file pathname.";
-       int fd;
-       int ret;
-       nvme_root_t r;
        __u64 capabilities = 0;
+       struct nvme_dev *dev;
        struct config {
                char *file;
        };
+       nvme_root_t r;
+       int ret;
 
        struct config cfg = {
                .file = NULL,
@@ -3669,30 +3672,30 @@ static int wdc_get_pfail_dump(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
 
-       if (!wdc_check_device(r, fd)) {
+       if (!wdc_check_device(r, dev->fd)) {
                nvme_free_tree(r);
-               close(fd);
+               dev_close(dev);
                return -1;
        }
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_PFAIL_DUMP) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
        } else {
-               ret = wdc_crash_dump(fd, cfg.file, WDC_NVME_PFAIL_DUMP_TYPE);
+               ret = wdc_crash_dump(dev->fd, cfg.file, WDC_NVME_PFAIL_DUMP_TYPE);
                if (ret != 0) {
                        fprintf(stderr, "ERROR : WDC : failed to read pfail crash dump\n");
                }
        }
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -3748,29 +3751,30 @@ static int wdc_purge(int argc, char **argv,
                struct command *command, struct plugin *plugin)
 {
        const char *desc = "Send a Purge command.";
-       char *err_str;
-       int fd, ret;
-       nvme_root_t r;
        struct nvme_passthru_cmd admin_cmd;
        __u64 capabilities = 0;
+       struct nvme_dev *dev;
+       char *err_str;
+       nvme_root_t r;
+       int ret;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
 
-       if (!wdc_check_device(r, fd)) {
+       if (!wdc_check_device(r, dev->fd)) {
                nvme_free_tree(r);
-               close(fd);
+               dev_close(dev);
                return -1;
        }
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if((capabilities & WDC_DRIVE_CAP_PURGE) == 0) {
                ret = -1;
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -3779,7 +3783,7 @@ static int wdc_purge(int argc, char **argv,
                memset(&admin_cmd, 0, sizeof (admin_cmd));
                admin_cmd.opcode = WDC_NVME_PURGE_CMD_OPCODE;
 
-               ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+               ret = nvme_submit_admin_passthru(dev->fd, &admin_cmd, NULL);
                if (ret > 0) {
                        switch (ret) {
                        case WDC_NVME_PURGE_CMD_SEQ_ERR:
@@ -3798,7 +3802,7 @@ static int wdc_purge(int argc, char **argv,
                nvme_show_status(ret);
        }
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -3806,30 +3810,31 @@ static int wdc_purge_monitor(int argc, char **argv,
                struct command *command, struct plugin *plugin)
 {
        const char *desc = "Send a Purge Monitor command.";
-       int fd, ret;
-       nvme_root_t r;
        __u8 output[WDC_NVME_PURGE_MONITOR_DATA_LEN];
        double progress_percent;
        struct nvme_passthru_cmd admin_cmd;
        struct wdc_nvme_purge_monitor_data *mon;
+       struct nvme_dev *dev;
        __u64 capabilities;
+       nvme_root_t r;
+       int ret;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       if (!wdc_check_device(r, fd)) {
+       if (!wdc_check_device(r, dev->fd)) {
                nvme_free_tree(r);
-               close(fd);
+               dev_close(dev);
                return -1;
        }
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if((capabilities & WDC_DRIVE_CAP_PURGE) == 0) {
                ret = -1;
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -3842,7 +3847,7 @@ static int wdc_purge_monitor(int argc, char **argv,
                admin_cmd.cdw10 = WDC_NVME_PURGE_MONITOR_CMD_CDW10;
                admin_cmd.timeout_ms = WDC_NVME_PURGE_MONITOR_TIMEOUT;
 
-               ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+               ret = nvme_submit_admin_passthru(dev->fd, &admin_cmd, NULL);
                if (ret == 0) {
                        mon = (struct wdc_nvme_purge_monitor_data *) output;
                        printf("Purge state = 0x%0x\n", admin_cmd.result);
@@ -3858,7 +3863,7 @@ static int wdc_purge_monitor(int argc, char **argv,
                nvme_show_status(ret);
        }
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -7036,10 +7041,10 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
 {
        const char *desc = "Retrieve additional performance statistics.";
        const char *interval = "Interval to read the statistics from [1, 15].";
-       int fd;
        const char *log_page_version = "Log Page Version: 0 = vendor, 1 = WDC";
        const char *log_page_mask = "Log Page Mask, comma separated list: 0xC0, 0xC1, 0xCA, 0xD0";
        const char *namespace_id = "desired namespace id";
+       struct nvme_dev *dev;
        nvme_root_t r;
        int ret = 0;
        int uuid_index = 0;
@@ -7072,9 +7077,9 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
        if (cfg.log_page_version == 0) {
@@ -7121,7 +7126,7 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
                fprintf(stderr, "ERROR : WDC: Unknown log page mask - %s\n", cfg.log_page_mask);
 
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_SMART_LOG_MASK) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7132,35 +7137,37 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
        if (((capabilities & WDC_DRIVE_CAP_C0_LOG_PAGE) == WDC_DRIVE_CAP_C0_LOG_PAGE) &&
                (page_mask & WDC_C0_PAGE_MASK)) {
                /* Get 0xC0 log page if possible. */
-               ret = wdc_get_c0_log_page(r, fd, cfg.output_format, uuid_index, cfg.namespace_id);
+               ret = wdc_get_c0_log_page(r, dev->fd, cfg.output_format,
+                                         uuid_index, cfg.namespace_id);
                if (ret)
                        fprintf(stderr, "ERROR : WDC : Failure reading the C0 Log Page, ret = %d\n", ret);
        }
        if (((capabilities & (WDC_DRIVE_CAP_CA_LOG_PAGE)) == (WDC_DRIVE_CAP_CA_LOG_PAGE))  &&
                (page_mask & WDC_CA_PAGE_MASK)) {
                /* Get the CA Log Page */
-               ret = wdc_get_ca_log_page(r, fd, cfg.output_format);
+               ret = wdc_get_ca_log_page(r, dev->fd, cfg.output_format);
                if (ret)
                        fprintf(stderr, "ERROR : WDC : Failure reading the CA Log Page, ret = %d\n", ret);
        }
        if (((capabilities & WDC_DRIVE_CAP_C1_LOG_PAGE) == WDC_DRIVE_CAP_C1_LOG_PAGE) &&
                (page_mask & WDC_C1_PAGE_MASK)) {
                /* Get the C1 Log Page */
-               ret = wdc_get_c1_log_page(r, fd, cfg.output_format, cfg.interval);
+               ret = wdc_get_c1_log_page(r, dev->fd, cfg.output_format,
+                                         cfg.interval);
                if (ret)
                        fprintf(stderr, "ERROR : WDC : Failure reading the C1 Log Page, ret = %d\n", ret);
        }
        if (((capabilities & WDC_DRIVE_CAP_D0_LOG_PAGE) == WDC_DRIVE_CAP_D0_LOG_PAGE) &&
                (page_mask & WDC_D0_PAGE_MASK)) {
                /* Get the D0 Log Page */
-               ret = wdc_get_d0_log_page(r, fd, cfg.output_format);
+               ret = wdc_get_d0_log_page(r, dev->fd, cfg.output_format);
                if (ret)
                        fprintf(stderr, "ERROR : WDC : Failure reading the D0 Log Page, ret = %d\n", ret);
        }
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -7169,12 +7176,11 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command,
 {
        const char *desc = "Retrieve Cloud Log Smart/Health Information";
        const char *namespace_id = "desired namespace id";
-       int fd;
-       nvme_root_t r;
-       int ret = 0;
        __u64 capabilities = 0;
+       struct nvme_dev *dev;
+       int ret, fmt = -1;
+       nvme_root_t r;
        __u8 *data;
-       int fmt = -1;
 
        struct config {
                char *output_format;
@@ -7192,13 +7198,13 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_CLOUD_LOG_PAGE) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7207,7 +7213,7 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command,
        }
 
        data = NULL;
-       ret = nvme_get_ext_smart_cloud_log(fd, &data, 0, cfg.namespace_id);
+       ret = nvme_get_ext_smart_cloud_log(dev->fd, &data, 0, cfg.namespace_id);
 
        if (strcmp(cfg.output_format, "json"))
                nvme_show_status(ret);
@@ -7231,7 +7237,7 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command,
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -7240,12 +7246,11 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command,
 {
        const char *desc = "Retrieve Hardware Revision Log Information";
        const char *namespace_id = "desired namespace id";
-       int fd;
-       nvme_root_t r;
-       int ret = 0;
        __u64 capabilities = 0;
+       struct nvme_dev *dev;
+       int ret, fmt = -1;
        __u8 *data = NULL;
-       int fmt = -1;
+       nvme_root_t r;
 
        struct config {
                char *output_format;
@@ -7263,13 +7268,13 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_HW_REV_LOG_PAGE) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7277,7 +7282,7 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command,
                goto out;
        }
 
-       ret = nvme_get_hw_rev_log(fd, &data, 0, cfg.namespace_id);
+       ret = nvme_get_hw_rev_log(dev->fd, &data, 0, cfg.namespace_id);
 
        if (strcmp(cfg.output_format, "json"))
                nvme_show_status(ret);
@@ -7314,7 +7319,7 @@ free_buf:
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -7324,8 +7329,8 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
        const char *desc = "Retrieve Device Write Amplication Factor";
        const char *namespace_id = "desired namespace id";
        struct nvme_smart_log smart_log;
+       struct nvme_dev *dev;
        __u8 *data;
-       int fd;
        nvme_root_t r;
        int ret = 0;
        int fmt = -1;
@@ -7354,13 +7359,13 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_DEVICE_WAF) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7369,7 +7374,7 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
        }
 
        /* get data units written from the smart log page */
-       ret = nvme_get_log_smart(fd, cfg.namespace_id, false, &smart_log);
+       ret = nvme_get_log_smart(dev->fd, cfg.namespace_id, false, &smart_log);
        if (!ret) {
                data_units_written = int128_to_double(smart_log.data_units_written);
        }
@@ -7385,7 +7390,7 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
 
        /* get Physical Media Units Written from extended smart/C0 log page */
        data = NULL;
-       ret = nvme_get_ext_smart_cloud_log(fd, &data, 0, cfg.namespace_id);
+       ret = nvme_get_ext_smart_cloud_log(dev->fd, &data, 0, cfg.namespace_id);
 
        if (ret == 0) {
                ext_smart_log_ptr = (wdc_nvme_ext_smart_log *)data;
@@ -7438,7 +7443,7 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -7446,10 +7451,10 @@ static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *co
                struct plugin *plugin)
 {
        const char *desc = "Retrieve latency monitor log data.";
+       __u64 capabilities = 0;
+       struct nvme_dev *dev;
        nvme_root_t r;
-       int fd;
        int ret = 0;
-       __u64 capabilities = 0;
 
        struct config {
                char *output_format;
@@ -7464,12 +7469,12 @@ static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *co
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_C3_LOG_PAGE) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7477,13 +7482,13 @@ static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *co
                goto out;
        }
 
-       ret = wdc_get_c3_log_page(r, fd, cfg.output_format);
+       ret = wdc_get_c3_log_page(r, dev->fd, cfg.output_format);
        if (ret)
                fprintf(stderr, "ERROR : WDC : Failure reading the Latency Monitor (C3) Log Page, ret = %d\n", ret);
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -7491,10 +7496,10 @@ static int wdc_get_error_recovery_log(int argc, char **argv, struct command *com
                struct plugin *plugin)
 {
        const char *desc = "Retrieve error recovery log data.";
+       __u64 capabilities = 0;
+       struct nvme_dev *dev;
        nvme_root_t r;
-       int fd;
        int ret = 0;
-       __u64 capabilities = 0;
 
        struct config {
                char *output_format;
@@ -7509,12 +7514,12 @@ static int wdc_get_error_recovery_log(int argc, char **argv, struct command *com
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_OCP_C1_LOG_PAGE) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7522,13 +7527,13 @@ static int wdc_get_error_recovery_log(int argc, char **argv, struct command *com
                goto out;
        }
 
-       ret = wdc_get_ocp_c1_log_page(r, fd, cfg.output_format);
+       ret = wdc_get_ocp_c1_log_page(r, dev->fd, cfg.output_format);
        if (ret)
                fprintf(stderr, "ERROR : WDC : Failure reading the Error Recovery (C1) Log Page, ret = 0x%x\n", ret);
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -7536,10 +7541,10 @@ static int wdc_get_dev_capabilities_log(int argc, char **argv, struct command *c
                struct plugin *plugin)
 {
        const char *desc = "Retrieve device capabilities log data.";
+       __u64 capabilities = 0;
+       struct nvme_dev *dev;
        nvme_root_t r;
-       int fd;
        int ret = 0;
-       __u64 capabilities = 0;
 
        struct config {
                char *output_format;
@@ -7554,12 +7559,12 @@ static int wdc_get_dev_capabilities_log(int argc, char **argv, struct command *c
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_OCP_C4_LOG_PAGE) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7567,13 +7572,13 @@ static int wdc_get_dev_capabilities_log(int argc, char **argv, struct command *c
                goto out;
        }
 
-       ret = wdc_get_ocp_c4_log_page(r, fd, cfg.output_format);
+       ret = wdc_get_ocp_c4_log_page(r, dev->fd, cfg.output_format);
        if (ret)
                fprintf(stderr, "ERROR : WDC : Failure reading the Device Capabilities (C4) Log Page, ret = 0x%x\n", ret);
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -7581,10 +7586,10 @@ static int wdc_get_unsupported_reqs_log(int argc, char **argv, struct command *c
                struct plugin *plugin)
 {
        const char *desc = "Retrieve unsupported requirements log data.";
+       __u64 capabilities = 0;
+       struct nvme_dev *dev;
        nvme_root_t r;
-       int fd;
        int ret = 0;
-       __u64 capabilities = 0;
 
        struct config {
                char *output_format;
@@ -7599,12 +7604,12 @@ static int wdc_get_unsupported_reqs_log(int argc, char **argv, struct command *c
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_OCP_C5_LOG_PAGE) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7612,13 +7617,13 @@ static int wdc_get_unsupported_reqs_log(int argc, char **argv, struct command *c
                goto out;
        }
 
-       ret = wdc_get_ocp_c5_log_page(r, fd, cfg.output_format);
+       ret = wdc_get_ocp_c5_log_page(r, dev->fd, cfg.output_format);
        if (ret)
                fprintf(stderr, "ERROR : WDC : Failure reading the Unsupported Requirements (C5) Log Page, ret = 0x%x\n", ret);
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -7667,25 +7672,26 @@ static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct comma
                struct plugin *plugin)
 {
        char *desc = "Clear PCIE Correctable Errors.";
-       int fd, ret;
-       nvme_root_t r;
        __u64 capabilities = 0;
+       struct nvme_dev *dev;
+       nvme_root_t r;
+       int ret;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       if (!wdc_check_device(r, fd)) {
+       if (!wdc_check_device(r, dev->fd)) {
                ret = -1;
                goto out;
        }
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_CLEAR_PCIE_MASK) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
@@ -7693,18 +7699,18 @@ static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct comma
        }
         
        if (capabilities & WDC_DRIVE_CAP_CLEAR_PCIE) {
-               ret = wdc_do_clear_pcie_correctable_errors(fd);
+               ret = wdc_do_clear_pcie_correctable_errors(dev->fd);
        }
        else if (capabilities & WDC_DRIVE_CAP_VUC_CLEAR_PCIE) {
-               ret = wdc_do_clear_pcie_correctable_errors_vuc(fd);
+               ret = wdc_do_clear_pcie_correctable_errors_vuc(dev->fd);
        }
        else {
-               ret = wdc_do_clear_pcie_correctable_errors_fid(fd);
+               ret = wdc_do_clear_pcie_correctable_errors_fid(dev->fd);
        }
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -7712,7 +7718,7 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
                struct plugin *plugin)
 {
        char *desc = "Get Drive Status.";
-       int fd;
+       struct nvme_dev *dev;
        int ret = 0;
        nvme_root_t r;
        __le32 system_eol_state;
@@ -7727,12 +7733,12 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_DRIVE_STATUS) != WDC_DRIVE_CAP_DRIVE_STATUS) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
@@ -7740,41 +7746,42 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
        }
 
        /* verify the 0xC2 Device Manageability log page is supported */
-       if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE) == false) {
+       if (wdc_nvme_check_supported_log_page(r, dev->fd,
+                                             WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE) == false) {
                fprintf(stderr, "ERROR : WDC : 0xC2 Log Page not supported\n");
                ret = -1;
                goto out;
        }
 
        /* Get the assert dump present status */
-       if (!wdc_nvme_get_dev_status_log_data(r, fd, &assert_status,
+       if (!wdc_nvme_get_dev_status_log_data(r, dev->fd, &assert_status,
                        WDC_C2_ASSERT_DUMP_PRESENT_ID))
                fprintf(stderr, "ERROR : WDC : Get Assert Status Failed\n");
 
        /* Get the thermal throttling status */
-       if (!wdc_nvme_get_dev_status_log_data(r, fd, &thermal_status,
+       if (!wdc_nvme_get_dev_status_log_data(r, dev->fd, &thermal_status,
                        WDC_C2_THERMAL_THROTTLE_STATUS_ID))
                fprintf(stderr, "ERROR : WDC : Get Thermal Throttling Status Failed\n");
 
        /* Get EOL status */
-       if (!wdc_nvme_get_dev_status_log_data(r, fd, &eol_status,
+       if (!wdc_nvme_get_dev_status_log_data(r, dev->fd, &eol_status,
                        WDC_C2_USER_EOL_STATUS_ID)) {
                fprintf(stderr, "ERROR : WDC : Get User EOL Status Failed\n");
                eol_status = cpu_to_le32(-1);
        }
 
        /* Get Customer EOL state */
-       if (!wdc_nvme_get_dev_status_log_data(r, fd, &user_eol_state,
+       if (!wdc_nvme_get_dev_status_log_data(r, dev->fd, &user_eol_state,
                        WDC_C2_USER_EOL_STATE_ID))
                fprintf(stderr, "ERROR : WDC : Get User EOL State Failed\n");
 
        /* Get System EOL state*/
-       if (!wdc_nvme_get_dev_status_log_data(r, fd, &system_eol_state,
+       if (!wdc_nvme_get_dev_status_log_data(r, dev->fd, &system_eol_state,
                        WDC_C2_SYSTEM_EOL_STATE_ID))
                fprintf(stderr, "ERROR : WDC : Get System EOL State Failed\n");
 
        /* Get format corrupt reason*/
-       if (!wdc_nvme_get_dev_status_log_data(r, fd, &format_corrupt_reason,
+       if (!wdc_nvme_get_dev_status_log_data(r, dev->fd, &format_corrupt_reason,
                        WDC_C2_FORMAT_CORRUPT_REASON_ID))
                fprintf(stderr, "ERROR : WDC : Get Format Corrupt Reason Failed\n");
 
@@ -7822,7 +7829,7 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -7830,7 +7837,7 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command,
                struct plugin *plugin)
 {
        char *desc = "Clear Assert Dump Present Status.";
-       int fd;
+       struct nvme_dev *dev;
        int ret = -1;
        nvme_root_t r;
        __le32 assert_status = cpu_to_le32(0xFFFFFFFF);
@@ -7841,18 +7848,18 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_CLEAR_ASSERT) != WDC_DRIVE_CAP_CLEAR_ASSERT) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
                goto out;
        }
-       if (!wdc_nvme_get_dev_status_log_data(r, fd, &assert_status,
+       if (!wdc_nvme_get_dev_status_log_data(r, dev->fd, &assert_status,
                        WDC_C2_ASSERT_DUMP_PRESENT_ID)) {
                fprintf(stderr, "ERROR : WDC : Get Assert Status Failed\n");
                ret = -1;
@@ -7866,14 +7873,14 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command,
                admin_cmd.cdw12 = ((WDC_NVME_CLEAR_ASSERT_DUMP_SUBCMD << WDC_NVME_SUBCMD_SHIFT) |
                                WDC_NVME_CLEAR_ASSERT_DUMP_CMD);
 
-               ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+               ret = nvme_submit_admin_passthru(dev->fd, &admin_cmd, NULL);
                nvme_show_status(ret);
        } else
                fprintf(stderr, "INFO : WDC : No Assert Dump Present\n");
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -8018,12 +8025,11 @@ freeData:
 static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *command,
                struct plugin *plugin)
 {
-       int fd;
-       int ret = 0;
-       nvme_root_t r;
-       __u64 capabilities = 0;
        const char *desc = "Retrieve FW activate history table.";
-
+       __u64 capabilities = 0;
+       struct nvme_dev *dev;
+       nvme_root_t r;
+       int ret;
 
        struct config {
                char *output_format;
@@ -8038,13 +8044,12 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_MASK) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
@@ -8068,7 +8073,7 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
                /* Get the 0xC0 log data */
                struct nvme_get_log_args args = {
                        .args_size      = sizeof(args),
-                       .fd             = fd,
+                       .fd             = dev->fd,
                        .lid            = WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_OPCODE,
                        .nsid           = 0xFFFFFFFF,
                        .lpo            = 0,
@@ -8101,21 +8106,22 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
 
                free(data);
                if (c0GuidMatch) {
-                       ret = wdc_get_fw_act_history_C2(r, fd,
+                       ret = wdc_get_fw_act_history_C2(r, dev->fd,
                                                        cfg.output_format);
                }
                else {
-                       ret = wdc_get_fw_act_history(r, fd, cfg.output_format);
+                       ret = wdc_get_fw_act_history(r, dev->fd,
+                                                    cfg.output_format);
                }
        } else {
-               ret = wdc_get_fw_act_history_C2(r, fd, cfg.output_format);
+               ret = wdc_get_fw_act_history_C2(r, dev->fd, cfg.output_format);
        }
 
        if (ret)
                fprintf(stderr, "ERROR : WDC : Failure reading the FW Activate History, ret = %d\n", ret);
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -8152,21 +8158,21 @@ static int wdc_clear_fw_activate_history(int argc, char **argv, struct command *
                struct plugin *plugin)
 {
        char *desc = "Clear FW activate history table.";
-       int fd;
-       int ret = -1;
-       nvme_root_t r;
        __u64 capabilities = 0;
+       struct nvme_dev *dev;
+       nvme_root_t r;
+       int ret;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY_MASK) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
@@ -8174,13 +8180,13 @@ static int wdc_clear_fw_activate_history(int argc, char **argv, struct command *
        }
 
        if (capabilities & WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY)
-               ret = wdc_do_clear_fw_activate_history_vuc(fd);
+               ret = wdc_do_clear_fw_activate_history_vuc(dev->fd);
        else
-               ret = wdc_do_clear_fw_activate_history_fid(fd);
+               ret = wdc_do_clear_fw_activate_history_fid(dev->fd);
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -8191,11 +8197,11 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
        char *disable = "Disable controller option of the telemetry log page.";
        char *enable = "Enable controller option of the telemetry log page.";
        char *status = "Displays the current state of the controller initiated log page.";
-       int fd;
-       int ret = -1;
-       nvme_root_t r;
        __u64 capabilities = 0;
+       struct nvme_dev *dev;
+       nvme_root_t r;
        __u32 result;
+       int ret = -1;
 
 
        struct config {
@@ -8217,12 +8223,12 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG) != WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
@@ -8238,19 +8244,22 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
        }
 
        if (cfg.disable) {
-               ret = nvme_set_features_simple(fd, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0, 1,
-                                      false, &result);
+               ret = nvme_set_features_simple(dev->fd,
+                                              WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID,
+                                              0, 1, false, &result);
 
-               wdc_clear_reason_id(fd);
+               wdc_clear_reason_id(dev->fd);
        }
        else {
           if (cfg.enable) {
-                       ret = nvme_set_features_simple(fd, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0, 0,
-                                              false, &result);
+                       ret = nvme_set_features_simple(dev->fd,
+                                                      WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID,
+                                                      0, 0, false, &result);
           }
           else if (cfg.status) {
-                       ret = nvme_get_features_simple(fd, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0,
-                                       &result);
+                       ret = nvme_get_features_simple(dev->fd,
+                                                      WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID,
+                                                      0, &result);
                        if (ret == 0) {
                                if (result)
                                        fprintf(stderr, "Controller Option Telemetry Log Page State: Disabled\n");
@@ -8271,7 +8280,7 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -8987,10 +8996,11 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command,
        char *dirName = "Output directory pathname.";
        char d[PATH_MAX] = {0};
        char k[PATH_MAX] = {0};
-       char *d_ptr;
-       int fd, ret;
-       nvme_root_t r;
        __u64 capabilities = 0;
+       struct nvme_dev *dev;
+       nvme_root_t r;
+       char *d_ptr;
+       int ret;
 
        struct config {
                char *dirName;
@@ -9006,12 +9016,12 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command,
        };
 
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_DRIVE_ESSENTIALS) != WDC_DRIVE_CAP_DRIVE_ESSENTIALS) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
@@ -9025,10 +9035,10 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command,
                d_ptr = NULL;
        }
 
-       ret = wdc_do_drive_essentials(r, fd, d_ptr, k);
+       ret = wdc_do_drive_essentials(r, dev->fd, d_ptr, k);
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -9084,9 +9094,10 @@ static int wdc_drive_resize(int argc, char **argv,
 {
        const char *desc = "Send a Resize command.";
        const char *size = "The new size (in GB) to resize the drive to.";
-       nvme_root_t r;
        uint64_t capabilities = 0;
-       int fd, ret;
+       struct nvme_dev *dev;
+       nvme_root_t r;
+       int ret;
 
        struct config {
                uint64_t size;
@@ -9101,15 +9112,15 @@ static int wdc_drive_resize(int argc, char **argv,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       wdc_check_device(r, fd);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       wdc_check_device(r, dev->fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_RESIZE) == WDC_DRIVE_CAP_RESIZE) {
-               ret = wdc_do_drive_resize(fd, cfg.size);
+               ret = wdc_do_drive_resize(dev->fd, cfg.size);
        } else {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
@@ -9120,7 +9131,7 @@ static int wdc_drive_resize(int argc, char **argv,
 
        nvme_show_status(ret);
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -9130,9 +9141,10 @@ static int wdc_namespace_resize(int argc, char **argv,
        const char *desc = "Send a Namespace Resize command.";
        const char *namespace_id = "The namespace id to resize.";
        const char *op_option = "The over provisioning option to set for namespace.";
-       nvme_root_t r;
        uint64_t capabilities = 0;
-       int fd, ret;
+       struct nvme_dev *dev;
+       nvme_root_t r;
+       int ret;
 
        struct config {
                __u32 namespace_id;
@@ -9150,9 +9162,9 @@ static int wdc_namespace_resize(int argc, char **argv,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        if ((cfg.op_option != 0x1) &&
                (cfg.op_option != 0x2) &&
@@ -9160,15 +9172,16 @@ static int wdc_namespace_resize(int argc, char **argv,
                (cfg.op_option != 0xF))
        {
                fprintf(stderr, "ERROR : WDC: unsupported OP option parameter\n");
-               close(fd);
+               dev_close(dev);
                return -1;
        }
 
        r = nvme_scan(NULL);
-       wdc_check_device(r, fd);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       wdc_check_device(r, dev->fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_NS_RESIZE) == WDC_DRIVE_CAP_NS_RESIZE) {
-               ret = wdc_do_namespace_resize(fd, cfg.namespace_id, cfg.op_option);
+               ret = wdc_do_namespace_resize(dev->fd, cfg.namespace_id,
+                                             cfg.op_option);
 
                if (ret != 0)
                        printf("ERROR : WDC: Namespace Resize of namespace id 0x%x, op option 0x%x failed\n", cfg.namespace_id, cfg.op_option);
@@ -9179,7 +9192,7 @@ static int wdc_namespace_resize(int argc, char **argv,
 
        nvme_show_status(ret);
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -9189,8 +9202,8 @@ static int wdc_reason_identifier(int argc, char **argv,
        const char *desc = "Retrieve telemetry log reason identifier.";
        const char *log_id = "Log ID to retrieve - host - 7 or controller - 8";
        const char *fname = "File name to save raw binary identifier";
+       struct nvme_dev *dev;
        nvme_root_t r;
-       int fd;
        int ret;
        uint64_t capabilities = 0;
        char f[PATH_MAX] = {0};
@@ -9214,10 +9227,10 @@ static int wdc_reason_identifier(int argc, char **argv,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
 
-       if (fd < 0)
-               return fd;
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
 
@@ -9250,7 +9263,7 @@ static int wdc_reason_identifier(int argc, char **argv,
                else
                        snprintf(fileSuffix, PATH_MAX, "_error_reason_identifier_host_%s", (char*)timeStamp);
 
-               if (wdc_get_serial_name(fd, f, PATH_MAX, fileSuffix) == -1) {
+               if (wdc_get_serial_name(dev->fd, f, PATH_MAX, fileSuffix) == -1) {
                        fprintf(stderr, "ERROR : WDC: failed to generate file name\n");
                        ret = -1;
                        goto close_fd;
@@ -9265,9 +9278,9 @@ static int wdc_reason_identifier(int argc, char **argv,
 
        fprintf(stderr, "%s: filename = %s\n", __func__, f);
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_REASON_ID) == WDC_DRIVE_CAP_REASON_ID) {
-               ret = wdc_do_get_reason_id(fd, f, cfg.log_id);
+               ret = wdc_do_get_reason_id(dev->fd, f, cfg.log_id);
        } else {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
@@ -9276,7 +9289,7 @@ static int wdc_reason_identifier(int argc, char **argv,
        nvme_show_status(ret);
 
  close_fd:
-       close(fd);
+       dev_close(dev);
        nvme_free_tree(r);
        return ret;
 }
@@ -9328,7 +9341,7 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
                struct plugin *plugin)
 {
        const char *desc = "Retrieve Log Page Directory.";
-       int fd;
+       struct nvme_dev *dev;
        int ret = 0;
        nvme_root_t r;
        __u64 capabilities = 0;
@@ -9350,20 +9363,20 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        ret = validate_output_format(cfg.output_format);
        if (ret < 0) {
                fprintf(stderr, "%s: ERROR : WDC : invalid output format\n", __func__);
-               close(fd);
+               dev_close(dev);
                return ret;
        }
        ret = 0;
 
        r = nvme_scan(NULL);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_LOG_PAGE_DIR) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -9373,13 +9386,13 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
                log_id = (device_id == WDC_NVME_ZN350_DEV_ID || device_id == WDC_NVME_ZN350_DEV_ID_1) ?
                        WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE_C8 : WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE;
                /* verify the 0xC2 Device Manageability log page is supported */
-               if (wdc_nvme_check_supported_log_page(r, fd, log_id) == false) {
+               if (wdc_nvme_check_supported_log_page(r, dev->fd, log_id) == false) {
                        fprintf(stderr, "%s: ERROR : WDC : 0x%x Log Page not supported\n", __func__, log_id);
                        ret = -1;
                        goto out;
                }
 
-               if (get_dev_mgment_cbs_data(r, fd, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) {
+               if (get_dev_mgment_cbs_data(r, dev->fd, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) {
                        if (cbs_data != NULL) {
                                printf("Log Page Directory\n");
                                /* print the supported pages */
@@ -9416,7 +9429,7 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
 
  out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -10011,12 +10024,11 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
                struct plugin *plugin)
 {
        const char *desc = "Retrieve NAND statistics.";
-
-       int fd;
-       int ret = 0;
+       struct nvme_dev *dev;
        nvme_root_t r;
        __u64 capabilities = 0;
        uint32_t read_device_id = 0, read_vendor_id = 0;
+       int ret;
 
        struct config {
                char *output_format;
@@ -10031,12 +10043,12 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_NAND_STATS) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -10051,10 +10063,11 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
 
                switch (read_device_id) {
                case WDC_NVME_SN820CL_DEV_ID:
-                       ret = wdc_do_vs_nand_stats_sn810_2(fd, cfg.output_format);
+                       ret = wdc_do_vs_nand_stats_sn810_2(dev->fd,
+                                                          cfg.output_format);
                        break;
                default:
-                       ret = wdc_do_vs_nand_stats(fd, cfg.output_format);
+                       ret = wdc_do_vs_nand_stats(dev->fd, cfg.output_format);
                        break;
                }
        }
@@ -10063,7 +10076,7 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
                fprintf(stderr, "ERROR : WDC : Failure reading NAND statistics, ret = %d\n", ret);
 
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -10088,8 +10101,7 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
                struct plugin *plugin)
 {
        const char *desc = "Retrieve PCIE statistics.";
-
-       int fd;
+       struct nvme_dev *dev;
        int ret = 0;
        nvme_root_t r;
        __u64 capabilities = 0;
@@ -10111,9 +10123,9 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
 
        r = nvme_scan(NULL);
@@ -10133,13 +10145,13 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
 
        memset((void *)pcieStatsPtr, 0, pcie_stats_size);
 
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_PCIE_STATS) == 0) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
        } else {
-               ret = wdc_do_vs_pcie_stats(fd, pcieStatsPtr);
+               ret = wdc_do_vs_pcie_stats(dev->fd, pcieStatsPtr);
                if (ret)
                        fprintf(stderr, "ERROR : WDC : Failure reading PCIE statistics, ret = 0x%x\n", ret);
                else {
@@ -10159,7 +10171,7 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
 
 out:
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -10169,7 +10181,8 @@ static int wdc_vs_drive_info(int argc, char **argv,
        const char *desc = "Send a vs-drive-info command.";
        nvme_root_t r;
        uint64_t capabilities = 0;
-       int fd, ret;
+       struct nvme_dev *dev;
+       int ret;
        __le32 result;
        __u16 size;
        double rev;
@@ -10199,29 +10212,29 @@ static int wdc_vs_drive_info(int argc, char **argv,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        fmt = validate_output_format(cfg.output_format);
        if (fmt < 0) {
                fprintf(stderr, "ERROR : WDC %s invalid output format\n", __func__);
-               close(fd);
+               dev_close(dev);
                return fmt;
        }
 
        /* get the id ctrl data used to fill in drive info below */
-       ret = nvme_identify_ctrl(fd, &ctrl);
+       ret = nvme_identify_ctrl(dev->fd, &ctrl);
 
        if (ret) {
                fprintf(stderr, "ERROR : WDC %s: Identify Controller failed\n", __func__);
-               close(fd);
+               dev_close(dev);
                return ret;
        }
 
        r = nvme_scan(NULL);
-       wdc_check_device(r, fd);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       wdc_check_device(r, dev->fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_INFO) == WDC_DRIVE_CAP_INFO) {
                ret = wdc_get_pci_ids(r, &read_device_id, &read_vendor_id);
                if (ret < 0)
@@ -10247,7 +10260,7 @@ static int wdc_vs_drive_info(int argc, char **argv,
                case WDC_NVME_SN550_DEV_ID:
                case WDC_NVME_ZN350_DEV_ID:
                case WDC_NVME_ZN350_DEV_ID_1:
-                       ret = wdc_do_drive_info(fd, &result);
+                       ret = wdc_do_drive_info(dev->fd, &result);
 
                        if (!ret) {
                                size = (__u16)((cpu_to_le32(result) & 0xffff0000) >> 16);
@@ -10299,7 +10312,8 @@ static int wdc_vs_drive_info(int argc, char **argv,
                        break;
                case WDC_NVME_SN820CL_DEV_ID:
                        /* Get the Drive HW Rev from the C6 Log page */
-                       ret = nvme_get_hw_rev_log(fd, &data, 0, NVME_NSID_ALL);
+                       ret = nvme_get_hw_rev_log(dev->fd, &data, 0,
+                                                 NVME_NSID_ALL);
                        if (ret == 0) {
                                wdc_nvme_hw_rev_log *log_data = (wdc_nvme_hw_rev_log *)data;
                                major_rev = log_data->hw_rev_gdr;
@@ -10319,7 +10333,7 @@ static int wdc_vs_drive_info(int argc, char **argv,
                                goto out;
                        }
 
-                       ret = nvme_get_ext_smart_cloud_log(fd, &data, 0, NVME_NSID_ALL);
+                       ret = nvme_get_ext_smart_cloud_log(dev->fd, &data, 0, NVME_NSID_ALL);
 
                        if (ret == 0) {
                                ext_smart_log_ptr = (wdc_nvme_ext_smart_log *)data;
@@ -10376,7 +10390,7 @@ static int wdc_vs_drive_info(int argc, char **argv,
 out:
        nvme_show_status(ret);
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -10386,12 +10400,12 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
        const char *desc = "Send a vs-temperature-stats command.";
        struct nvme_smart_log smart_log;
        struct nvme_id_ctrl id_ctrl;
+       struct nvme_dev *dev;
        nvme_root_t r;
        uint64_t capabilities = 0;
        __u32 hctm_tmt;
-       int fd, ret;
        int temperature, temp_tmt1, temp_tmt2;
-       int fmt = -1;
+       int ret, fmt = -1;
 
        struct config {
                char *output_format;
@@ -10406,9 +10420,9 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        r = nvme_scan(NULL);
        fmt = validate_output_format(cfg.output_format);
@@ -10419,8 +10433,8 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
        }
 
        /* check if command is supported */
-       wdc_check_device(r, fd);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       wdc_check_device(r, dev->fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
        if ((capabilities & WDC_DRIVE_CAP_TEMP_STATS) != WDC_DRIVE_CAP_TEMP_STATS) {
                fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
                ret = -1;
@@ -10428,10 +10442,10 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
        } 
 
        /* get the temperature stats or report errors */
-       ret = nvme_identify_ctrl(fd, &id_ctrl);
+       ret = nvme_identify_ctrl(dev->fd, &id_ctrl);
        if (ret != 0)
                goto out;
-       ret = nvme_get_log_smart(fd, NVME_NSID_ALL, false, &smart_log);
+       ret = nvme_get_log_smart(dev->fd, NVME_NSID_ALL, false, &smart_log);
        if (ret != 0)
                goto out;
 
@@ -10439,7 +10453,7 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
        temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]) - 273;
 
        /* retrieve HCTM Thermal Management Temperatures */
-       nvme_get_features_simple(fd, 0x10, 0, &hctm_tmt);
+       nvme_get_features_simple(dev->fd, 0x10, 0, &hctm_tmt);
        temp_tmt1 = ((hctm_tmt >> 16) & 0xffff) ? ((hctm_tmt >> 16) & 0xffff) - 273 : 0;
        temp_tmt2 = (hctm_tmt & 0xffff) ? (hctm_tmt & 0xffff) - 273 : 0;
 
@@ -10493,7 +10507,7 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
 out:
        nvme_show_status(ret);
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -10501,23 +10515,24 @@ static int wdc_capabilities(int argc, char **argv,
         struct command *command, struct plugin *plugin) 
 {
     const char *desc = "Send a capabilities command.";
-    nvme_root_t r;
     uint64_t capabilities = 0;
-    int fd;
+    struct nvme_dev *dev;
+    nvme_root_t r;
+    int ret;
 
     OPT_ARGS(opts) = 
     {
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0)
-        return fd;
+    ret = parse_and_open(&dev, argc, argv, desc, opts);
+    if (ret < 0)
+        return ret;
 
     /* get capabilities */
     r = nvme_scan(NULL);
-    wdc_check_device(r, fd);
-    capabilities = wdc_get_drive_capabilities(r, fd);
+    wdc_check_device(r, dev->fd);
+    capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
     /* print command and supported status */
     printf("WDC Plugin Capabilities for NVME device:%s\n", nvme_dev->name);
@@ -10598,7 +10613,7 @@ static int wdc_capabilities(int argc, char **argv,
                        capabilities & WDC_DRIVE_CAP_DEVICE_WAF ? "Supported" : "Not Supported");
    printf("capabilities                  : Supported\n");
     nvme_free_tree(r);
-    close(fd);
+    dev_close(dev);
     return 0;
 }
 
@@ -10606,22 +10621,23 @@ static int wdc_cloud_ssd_plugin_version(int argc, char **argv,
         struct command *command, struct plugin *plugin)
 {
        const char *desc = "Get Cloud SSD Plugin Version command.";
-       nvme_root_t r;
        uint64_t capabilities = 0;
-       int fd;
+       struct nvme_dev *dev;
+       nvme_root_t r;
+       int ret;
 
        OPT_ARGS(opts) = {
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        /* get capabilities */
        r = nvme_scan(NULL);
-       wdc_check_device(r, fd);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       wdc_check_device(r, dev->fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_CLOUD_SSD_VERSION) == WDC_DRIVE_CAP_CLOUD_SSD_VERSION) {
            /* print command and supported status */
@@ -10631,7 +10647,7 @@ static int wdc_cloud_ssd_plugin_version(int argc, char **argv,
        }
 
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return 0;
 }
 
@@ -10642,7 +10658,8 @@ static int wdc_cloud_boot_SSD_version(int argc, char **argv,
        const char *namespace_id = "desired namespace id";
        nvme_root_t r;
        uint64_t capabilities = 0;
-       int fd, ret = -1;
+       struct nvme_dev *dev;
+       int ret;
        int major = 0, minor = 0;
        __u8 *data = NULL;
        wdc_nvme_ext_smart_log *ext_smart_log_ptr = NULL;
@@ -10660,18 +10677,19 @@ static int wdc_cloud_boot_SSD_version(int argc, char **argv,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
-               return fd;
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret < 0)
+               return ret;
 
        /* get capabilities */
        r = nvme_scan(NULL);
-       wdc_check_device(r, fd);
-       capabilities = wdc_get_drive_capabilities(r, fd);
+       wdc_check_device(r, dev->fd);
+       capabilities = wdc_get_drive_capabilities(r, dev->fd);
 
        if ((capabilities & WDC_DRIVE_CAP_CLOUD_BOOT_SSD_VERSION) == WDC_DRIVE_CAP_CLOUD_BOOT_SSD_VERSION) {
                /* Get the 0xC0 Smart Cloud Attribute V1 log data */
-               ret = nvme_get_ext_smart_cloud_log(fd, &data, 0, cfg.namespace_id);
+               ret = nvme_get_ext_smart_cloud_log(dev->fd, &data, 0,
+                                                  cfg.namespace_id);
 
                ext_smart_log_ptr = (wdc_nvme_ext_smart_log *)data;
                if (ret == 0) {
@@ -10693,7 +10711,7 @@ static int wdc_cloud_boot_SSD_version(int argc, char **argv,
        }
 
        nvme_free_tree(r);
-       close(fd);
+       dev_close(dev);
        return ret;
 }
 
@@ -10704,9 +10722,9 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command,
        char *file = "Output file pathname.";
        char *size = "Data retrieval transfer size.";
        char *log = "Enclosure Log Page ID.";
+       struct nvme_dev *dev;
        FILE *output_fd;
        int xfer_size = 0;
-       int fd;
        int len;
        int err = 0;
 
@@ -10729,12 +10747,11 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command,
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0) {
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
-       }
 
-       if (!wdc_enc_check_model(fd)) {
+       if (!wdc_enc_check_model(dev->fd)) {
                err = -EINVAL;
                goto closed_fd;
        }
@@ -10770,10 +10787,15 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command,
                if (cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_1 || cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_2
                                || cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_3 || cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_4) {
                        fprintf(stderr, "args - sz:%x logid:%x of:%s\n",xfer_size,cfg.log_id,cfg.file);
-                       err = wdc_enc_get_nic_log(fd, cfg.log_id, xfer_size, WDC_NVME_ENC_NIC_LOG_SIZE, output_fd);
+                       err = wdc_enc_get_nic_log(dev->fd, cfg.log_id,
+                                                 xfer_size,
+                                                 WDC_NVME_ENC_NIC_LOG_SIZE,
+                                                 output_fd);
                } else {
                        fprintf(stderr, "args - sz:%x logid:%x of:%s\n",xfer_size,cfg.log_id,cfg.file);
-                       err = wdc_enc_submit_move_data(fd, NULL, 0, xfer_size, output_fd, cfg.log_id, 0, 0);
+                       err = wdc_enc_submit_move_data(dev->fd, NULL, 0,
+                                                      xfer_size, output_fd,
+                                                      cfg.log_id, 0, 0);
                }
 
                if (err == WDC_RESULT_NOT_AVAILABLE) {
@@ -10784,7 +10806,7 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command,
                }
        }
 closed_fd:
-       close(fd);
+       dev_close(dev);
 ret:
        return err;
 }
index 0d3002b5e2176df252ac2c6eb710fd29dba8ab5a..a2fcf87ab60735ae520b690e2f267672361e1faa 100644 (file)
@@ -119,15 +119,16 @@ static int show_ymtc_smart_log(int fd, __u32 nsid, const char *devname,
 static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
 {
     struct nvme_ymtc_smart_log smart_log;
-    int err, fd;
     char *desc = "Get Ymtc vendor specific additional smart log (optionally, "\
               "for the specified namespace), and show it.";
     const char *namespace = "(optional) desired namespace";
     const char *raw = "dump output in binary format";
+    struct nvme_dev *dev;
     struct config {
         __u32 namespace_id;
         bool  raw_binary;
     };
+    int err;
 
     struct config cfg = {
         .namespace_id = NVME_NSID_ALL,
@@ -139,21 +140,21 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
         OPT_END()
     };
 
-    fd = parse_and_open(argc, argv, desc, opts);
-    if (fd < 0)
-        return fd;
+    err = parse_and_open(&dev, argc, argv, desc, opts);
+    if (err < 0)
+        return err;
 
-    err = nvme_get_nsid_log(fd, false, 0xca, cfg.namespace_id,
+    err = nvme_get_nsid_log(dev->fd, false, 0xca, cfg.namespace_id,
                            sizeof(smart_log), &smart_log);
     if (!err) {
         if (!cfg.raw_binary)
-            err = show_ymtc_smart_log(fd, cfg.namespace_id, nvme_dev->name, &smart_log);
+            err = show_ymtc_smart_log(dev->fd, cfg.namespace_id, nvme_dev->name, &smart_log);
         else
             d_raw((unsigned char *)&smart_log, sizeof(smart_log));
     }
     if (err > 0)
         nvme_show_status(err);
 
-    close(fd);
+    dev_close(dev);
     return err;
 }
index 0b96346fc30a8268e7761f560767dc9dac0687a6..c5f528e44383971b98e437574b3962db2215ed63 100644 (file)
@@ -120,7 +120,8 @@ static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *pl
 
        enum nvme_print_flags flags;
        struct nvme_zns_id_ctrl ctrl;
-       int fd, err = -1;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                char *output_format;
@@ -135,15 +136,15 @@ static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *pl
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                return errno;
 
        err = flags = validate_output_format(cfg.output_format);
        if (flags < 0)
                goto close_fd;
 
-       err = nvme_zns_identify_ctrl(fd, &ctrl);
+       err = nvme_zns_identify_ctrl(dev->fd, &ctrl);
        if (!err)
                nvme_show_zns_id_ctrl(&ctrl, flags);
        else if (err > 0)
@@ -151,7 +152,7 @@ static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *pl
        else
                perror("zns identify controller");
 close_fd:
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -166,7 +167,8 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
        enum nvme_print_flags flags;
        struct nvme_zns_id_ns ns;
        struct nvme_id_ns id_ns;
-       int fd, err = -1;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                char *output_format;
@@ -187,8 +189,8 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                return errno;
 
        flags = validate_output_format(cfg.output_format);
@@ -200,20 +202,20 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
                flags |= VERBOSE;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        perror("get-namespace-id");
                        goto close_fd;
                }
        }
 
-       err = nvme_identify_ns(fd, cfg.namespace_id, &id_ns);
+       err = nvme_identify_ns(dev->fd, cfg.namespace_id, &id_ns);
        if (err) {
                nvme_show_status(err);
                goto close_fd;
        }
 
-       err = nvme_zns_identify_ns(fd, cfg.namespace_id, &ns);
+       err = nvme_zns_identify_ns(dev->fd, cfg.namespace_id, &ns);
        if (!err)
                nvme_show_zns_id_ns(&ns, &id_ns, flags);
        else if (err > 0)
@@ -221,7 +223,7 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
        else
                perror("zns identify namespace");
 close_fd:
-       close(fd);
+       dev_close(dev);
        return err;
 }
 
@@ -231,8 +233,8 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
        const char *zslba = "starting LBA of the zone for this command";
        const char *select_all = "send command to all zones";
        const char *timeout = "timeout value, in milliseconds";
-
-       int err, fd, zcapc = 0;
+       struct nvme_dev *dev;
+       int err, zcapc = 0;
        char *command;
        __u32 result;
 
@@ -253,16 +255,16 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
                OPT_END()
        };
 
-       err = fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                goto ret;
 
        err = asprintf(&command, "%s-%s", plugin->name, cmd->name);
        if (err < 0)
-               goto close_fd;
+               goto close_dev;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        perror("get-namespace-id");
                        goto free;
@@ -271,7 +273,7 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
 
        struct nvme_zns_mgmt_send_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .slba           = cfg.zslba,
                .zsa            = zsa,
@@ -297,8 +299,8 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
                perror(desc);
 free:
        free(command);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
 ret:
        return err;
 }
@@ -344,7 +346,8 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
        const char *data = "optional file for data (default stdin)";
        const char *timeout = "timeout value, in milliseconds";
 
-       int fd, ffd = STDIN_FILENO, err = -1;
+       int ffd = STDIN_FILENO, err = -1;
+       struct nvme_dev *dev;
        void *buf = NULL;
 
        struct config {
@@ -372,41 +375,41 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                return errno;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        perror("get-namespace-id");
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        if (!cfg.zsa) {
                fprintf(stderr, "zone send action must be specified\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.zsa == NVME_ZNS_ZSA_SET_DESC_EXT) {
                if(!cfg.data_len) {
-                       int data_len = get_zdes_bytes(fd, cfg.namespace_id);
+                       int data_len = get_zdes_bytes(dev->fd, cfg.namespace_id);
 
                        if (data_len == 0) {
                                fprintf(stderr, 
                                        "Zone Descriptor Extensions are not supported\n");
-                               goto close_fd;
+                               goto close_dev;
                        } else if (data_len < 0) {
                                err = data_len;
-                               goto close_fd;
+                               goto close_dev;
                        }
                        cfg.data_len = data_len;
                }
                if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
                        fprintf(stderr, "can not allocate feature payload\n");
-                       goto close_fd;
+                       goto close_dev;
                }
                memset(buf, 0, cfg.data_len);
 
@@ -428,13 +431,13 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
                        fprintf(stderr, 
                        "data, data_len only valid with set extended descriptor\n");
                        err = -EINVAL;
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        struct nvme_zns_mgmt_send_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .slba           = cfg.zslba,
                .zsa            = cfg.zsa,
@@ -461,8 +464,8 @@ close_ffd:
                close(ffd);
 free:
        free(buf);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
        return err;
 }
 
@@ -487,8 +490,8 @@ static int open_zone(int argc, char **argv, struct command *cmd, struct plugin *
        const char *zrwaa = "Allocate Zone Random Write Area to zone";
        const char *select_all = "send command to all zones";
        const char *timeout = "timeout value, in milliseconds";
-
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u64   zslba;
@@ -510,21 +513,21 @@ static int open_zone(int argc, char **argv, struct command *cmd, struct plugin *
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                return errno;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        perror("get-namespace-id");
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        struct nvme_zns_mgmt_send_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .slba           = cfg.zslba,
                .zsa            = NVME_ZNS_ZSA_OPEN,
@@ -541,8 +544,8 @@ static int open_zone(int argc, char **argv, struct command *cmd, struct plugin *
                        (uint64_t)cfg.zslba, cfg.namespace_id);
        else
                nvme_show_status(err);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
        return err;
 }
 
@@ -568,7 +571,8 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
        const char *data = "optional file for zone extention data (default stdin)";
        const char *timeout = "timeout value, in milliseconds";
 
-       int fd, ffd = STDIN_FILENO, err;
+       int ffd = STDIN_FILENO, err;
+       struct nvme_dev *dev;
        void *buf = NULL;
        int data_len;
 
@@ -591,33 +595,33 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                return errno;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        perror("get-namespace-id");
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
-       data_len = get_zdes_bytes(fd, cfg.namespace_id);
+       data_len = get_zdes_bytes(dev->fd, cfg.namespace_id);
 
        if (!data_len || data_len < 0) {
                fprintf(stderr,
                        "zone format does not provide descriptor extention\n");
                errno = EINVAL;
                err = -1;
-               goto close_fd;
+               goto close_dev;
        }
 
        buf = calloc(1, data_len);
        if (!buf) {
                perror("could not alloc memory for zone desc");
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.file) {
@@ -637,7 +641,7 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
 
        struct nvme_zns_mgmt_send_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .slba           = cfg.zslba,
                .zsa            = NVME_ZNS_ZSA_SET_DESC_EXT,
@@ -661,8 +665,8 @@ close_ffd:
                close(ffd);
 free:
        free(buf);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
        return err;
 }
 
@@ -672,8 +676,8 @@ static int zrwa_flush_zone(int argc, char **argv, struct command *cmd, struct pl
        const char *desc = "Flush Explicit ZRWA Range";
        const char *slba = "LBA to flush up to";
        const char *timeout = "timeout value, in milliseconds";
-
-       int err, fd;
+       struct nvme_dev *dev;
+       int err;
 
        struct config {
                __u64   lba;
@@ -690,21 +694,21 @@ static int zrwa_flush_zone(int argc, char **argv, struct command *cmd, struct pl
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                return errno;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        perror("get-namespace-id");
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        struct nvme_zns_mgmt_send_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .slba           = cfg.lba,
                .zsa            = NVME_ZNS_ZSA_ZRWA_FLUSH,
@@ -721,8 +725,8 @@ static int zrwa_flush_zone(int argc, char **argv, struct command *cmd, struct pl
                        (uint64_t)cfg.lba, cfg.namespace_id);
        else
                nvme_show_status(err);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
        return err;
 }
 
@@ -736,8 +740,9 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu
        const char *data_len = "length of data in bytes";
 
        enum nvme_print_flags flags;
-       int fd, err = -1;
+       struct nvme_dev *dev;
        void *data = NULL;
+       int err = -1;
 
        struct config {
                char *output_format;
@@ -764,39 +769,39 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                return errno;
 
        flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        perror("get-namespace-id");
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        if (cfg.zra == NVME_ZNS_ZRA_REPORT_ZONES && !cfg.data_len) {
                fprintf(stderr, "error: data len is needed for NVME_ZRA_ZONE_REPORT\n");
                err = -EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
        if (cfg.data_len) {
                data = calloc(1, cfg.data_len);
                if (!data) {
                        perror("could not alloc memory for zone mgmt receive data");
                        err = -ENOMEM;
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        struct nvme_zns_mgmt_recv_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .slba           = cfg.zslba,
                .zra            = cfg.zra,
@@ -817,8 +822,8 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu
                perror("zns zone-mgmt-recv");
 
        free(data);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
        return err;
 }
 
@@ -833,7 +838,8 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
        const char *verbose = "show report zones verbosity";
 
        enum nvme_print_flags flags;
-       int fd, zdes = 0, err = -1;
+       int zdes = 0, err = -1;
+       struct nvme_dev *dev;
        __u32 report_size;
        void *report;
        bool huge = false;
@@ -879,39 +885,39 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                return errno;
 
        flags = validate_output_format(cfg.output_format);
        if (flags < 0)
-               goto close_fd;
+               goto close_dev;
        if (cfg.verbose)
                flags |= VERBOSE;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        perror("get-namespace-id");
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
        if (cfg.extended) {
-               zdes = get_zdes_bytes(fd, cfg.namespace_id);
+               zdes = get_zdes_bytes(dev->fd, cfg.namespace_id);
                if (zdes < 0) {
                        err = zdes;
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
-       err = nvme_identify_ns(fd, cfg.namespace_id, &id_ns);
+       err = nvme_identify_ns(dev->fd, cfg.namespace_id, &id_ns);
        if (err) {
                nvme_show_status(err);
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_zns_identify_ns(fd, cfg.namespace_id, &id_zns);
+       err = nvme_zns_identify_ns(dev->fd, cfg.namespace_id, &id_zns);
        if (!err) {
                /* get zsze field from zns id ns data - needed for offset calculation */
                nvme_id_ns_flbas_to_lbaf_inuse(id_ns.flbas, &lbaf);
@@ -919,17 +925,17 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
        }
        else {
                nvme_show_status(err);
-               goto close_fd;
+               goto close_dev;
        }
 
        log_len = sizeof(struct nvme_zone_report);
        buff = calloc(1, log_len);
        if (!buff) {
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
 
-       err = nvme_zns_report_zones(fd, cfg.namespace_id, 0,
+       err = nvme_zns_report_zones(dev->fd, cfg.namespace_id, 0,
                                    cfg.state, false, false,
                                    log_len, buff,
                                    NVME_DEFAULT_IOCTL_TIMEOUT, NULL);
@@ -959,7 +965,7 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
        if (!report) {
                perror("alloc");
                err = -ENOMEM;
-               goto close_fd;
+               goto close_dev;
        }
 
        offset = cfg.zslba;
@@ -977,7 +983,7 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
                        log_len = sizeof(struct nvme_zone_report) + ((sizeof(struct nvme_zns_desc) * nr_zones_chunks) + (nr_zones_chunks * zdes));
                }
 
-               err = nvme_zns_report_zones(fd, cfg.namespace_id, offset,
+               err = nvme_zns_report_zones(dev->fd, cfg.namespace_id, offset,
                                            cfg.state, cfg.extended,
                                            cfg.partial, log_len, report,
                                            NVME_DEFAULT_IOCTL_TIMEOUT, NULL);
@@ -1001,8 +1007,8 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
 
 free_buff:
        free(buff);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
        return err;
 }
 
@@ -1025,10 +1031,11 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
        const char *data_size = "size of data in bytes";
        const char *latency = "output latency statistics";
 
-       int err = -1, fd, dfd = STDIN_FILENO, mfd = STDIN_FILENO;
+       int err = -1, dfd = STDIN_FILENO, mfd = STDIN_FILENO;
        unsigned int lba_size, meta_size;
        void *buf = NULL, *mbuf = NULL;
        __u16 nblocks, control = 0;
+       struct nvme_dev *dev;
        __u64 result;
        __u8 lba_index;
        struct timeval start_time, end_time;
@@ -1072,28 +1079,28 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                return errno;
 
        if (!cfg.data_size) {
                fprintf(stderr, "Append size not provided\n");
                errno = EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        perror("get-namespace-id");
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
-       err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+       err = nvme_identify_ns(dev->fd, cfg.namespace_id, &ns);
        if (err) {
                nvme_show_status(err);
-               goto close_fd;
+               goto close_dev;
        }
 
        nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
@@ -1103,7 +1110,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
                        "Data size:%#"PRIx64" not aligned to lba size:%#x\n",
                        (uint64_t)cfg.data_size, lba_size);
                errno = EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        meta_size = ns.lbaf[lba_index].ms;
@@ -1113,20 +1120,20 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
                        "Metadata size:%#"PRIx64" not aligned to metadata size:%#x\n",
                        (uint64_t)cfg.metadata_size, meta_size);
                errno = EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.prinfo > 0xf) {
                fprintf(stderr, "Invalid value for prinfo:%#x\n", cfg.prinfo);
                errno = EINVAL;
-               goto close_fd;
+               goto close_dev;
        }
 
        if (cfg.data) {
                dfd = open(cfg.data, O_RDONLY);
                if (dfd < 0) {
                        perror(cfg.data);
-                       goto close_fd;
+                       goto close_dev;
                }
        }
 
@@ -1179,7 +1186,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
 
        struct nvme_zns_append_args args = {
                .args_size      = sizeof(args),
-               .fd             = fd,
+               .fd             = dev->fd,
                .nsid           = cfg.namespace_id,
                .zslba          = cfg.zslba,
                .nlb            = nblocks,
@@ -1219,8 +1226,8 @@ free_data:
 close_dfd:
        if (cfg.data)
                close(dfd);
-close_fd:
-       close(fd);
+close_dev:
+       dev_close(dev);
        return err;
 }
 
@@ -1231,7 +1238,8 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct
 
        struct nvme_zns_changed_zone_log log;
        enum nvme_print_flags flags;
-       int fd, err = -1;
+       struct nvme_dev *dev;
+       int err = -1;
 
        struct config {
                char *output_format;
@@ -1250,8 +1258,8 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct
                OPT_END()
        };
 
-       fd = parse_and_open(argc, argv, desc, opts);
-       if (fd < 0)
+       err = parse_and_open(&dev, argc, argv, desc, opts);
+       if (err < 0)
                return errno;
 
        flags = validate_output_format(cfg.output_format);
@@ -1259,14 +1267,15 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct
                goto close_fd;
 
        if (!cfg.namespace_id) {
-               err = nvme_get_nsid(fd, &cfg.namespace_id);
+               err = nvme_get_nsid(dev->fd, &cfg.namespace_id);
                if (err < 0) {
                        perror("get-namespace-id");
                        goto close_fd;
                }
        }
 
-       err = nvme_get_log_zns_changed_zones(fd, cfg.namespace_id, cfg.rae, &log);
+       err = nvme_get_log_zns_changed_zones(dev->fd, cfg.namespace_id,
+                                            cfg.rae, &log);
        if (!err)
                nvme_show_zns_changed(&log, flags);
        else if (err > 0)
@@ -1275,6 +1284,6 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct
                perror("zns changed-zone-list");
 
 close_fd:
-       close(fd);
+       dev_close(dev);
        return err;
 }