return S_ISBLK(dev->direct.stat.st_mode);
}
-static int open_dev_direct(struct nvme_dev **devp, char *devstr, int flags)
+static bool is_nvme_dev(char *dev)
+{
+ int instance;
+ int head_instance;
+
+ return sscanf(basename(dev), "nvme%dn%d", &instance, &head_instance) == 1;
+}
+
+static __u32 get_nsid(struct argconfig_commandline_options *opts)
+{
+ __u32 *nsid = argconfig_get_value(opts, "namespace-id");
+
+ if (nsid && *nsid != NVME_NSID_ALL)
+ return *nsid;
+
+ return NVME_NSID_NONE;
+}
+
+static int open_blkdev_direct(char *dev, int flags, __u32 nsid)
+{
+ _cleanup_free_ char *blkdev = NULL;
+ int fd = -1;
+
+ if (is_nvme_dev(dev) && nsid) {
+ if (asprintf(&blkdev, "%sn%d", dev, nsid) < 0)
+ blkdev = NULL;
+ }
+
+ if (blkdev) {
+ fd = open(blkdev, flags);
+ print_info("blkdev: %s, fd: %d\n", blkdev, fd);
+ }
+
+ if (fd < 0) {
+ fd = open(dev, flags);
+ print_info("dev: %s, fd: %d\n", dev, fd);
+ }
+
+ return fd;
+}
+
+static int open_dev_direct(struct nvme_dev **devp, char *devstr, int flags, __u32 nsid)
{
struct nvme_dev *dev;
int err;
dev->type = NVME_DEV_DIRECT;
dev->name = basename(devstr);
- err = open(devstr, flags);
+ err = open_blkdev_direct(devstr, flags, nsid);
if (err < 0) {
nvme_show_perror(devstr);
goto err_free;
return 0;
}
-static int get_dev(struct nvme_dev **dev, int argc, char **argv, int flags)
+static int get_dev(struct nvme_dev **dev, int argc, char **argv, int flags,
+ struct argconfig_commandline_options *opts)
{
char *devname;
int ret;
+ __u32 nsid = get_nsid(opts);
ret = check_arg_dev(argc, argv);
if (ret)
if (!strncmp(devname, "mctp:", strlen("mctp:")))
ret = open_dev_mi_mctp(dev, devname);
else
- ret = open_dev_direct(dev, devname, flags);
+ ret = open_dev_direct(dev, devname, flags, nsid);
return ret ? -errno : 0;
}
if (ret)
return ret;
- ret = get_dev(dev, argc, argv, O_RDONLY);
+ ret = get_dev(dev, argc, argv, O_RDONLY, opts);
if (ret < 0)
argconfig_print_help(desc, opts);
}
int open_exclusive(struct nvme_dev **dev, int argc, char **argv,
- int ignore_exclusive)
+ int ignore_exclusive, struct argconfig_commandline_options *opts)
{
int flags = O_RDONLY;
if (!ignore_exclusive)
flags |= O_EXCL;
- return get_dev(dev, argc, argv, flags);
+ return get_dev(dev, argc, argv, flags, opts);
}
int validate_output_format(const char *format, nvme_print_flags_t *flags)
if (err)
return err;
- err = open_exclusive(&dev, argc, argv, cfg.force);
+ err = open_exclusive(&dev, argc, argv, cfg.force, opts);
if (err) {
if (errno == EBUSY) {
fprintf(stderr, "Failed to open %s.\n", basename(argv[optind]));
err = parse_args(argc, argv, desc, opts);
if (err)
return err;
- err = open_exclusive(&dev, argc, argv, cfg.force);
+ err = open_exclusive(&dev, argc, argv, cfg.force, opts);
if (err) {
if (errno == EBUSY) {
fprintf(stderr, "Failed to open %s.\n", basename(argv[optind]));