nvme_strerror(errno));
return -errno;
}
- ret = nvme_scan_topology(r, NULL);
+ ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "Failed to scan topoplogy: %s\n",
nvme_strerror(errno));
nvme_strerror(errno));
return -errno;
}
- ret = nvme_scan_topology(r, NULL);
+ ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "Failed to scan topoplogy: %s\n",
nvme_strerror(errno));
nvme_strerror(errno));
return -errno;
}
- ret = nvme_scan_topology(r, NULL);
+ ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "Failed to scan topoplogy: %s\n",
nvme_strerror(errno));
nvme_strerror(errno));
return -errno;
}
- ret = nvme_scan_topology(r, NULL);
+ ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "Failed to scan topoplogy: %s\n",
nvme_strerror(errno));
return -errno;
}
if (scan_tree) {
- ret = nvme_scan_topology(r, NULL);
+ ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "Failed to scan topoplogy: %s\n",
nvme_strerror(errno));
nvme_strerror(errno));
return -errno;
}
- ret = nvme_scan_topology(r, NULL);
+ ret = nvme_scan_topology(r, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "Failed to scan topoplogy: %s\n",
nvme_strerror(errno));
}
}
-static void nvme_show_subsystem(nvme_root_t r, unsigned int nsid)
+static unsigned int nvme_show_subsystem_multipath(nvme_subsystem_t s)
+{
+ nvme_ns_t n;
+ unsigned int i = 0;
+
+ nvme_subsystem_for_each_ns(s, n) {
+ nvme_path_t p;
+
+ nvme_namespace_for_each_path(n, p) {
+ nvme_ctrl_t c = nvme_path_get_ctrl(p);
+
+ printf(" +- %s %s %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c),
+ nvme_ctrl_get_state(c),
+ nvme_path_get_ana_state(p));
+ i++;
+ }
+ }
+
+ return i;
+}
+
+static void nvme_show_subsystem_ctrls(nvme_subsystem_t s)
+{
+ nvme_ctrl_t c;
+
+ nvme_subsystem_for_each_ctrl(s, c) {
+ printf(" +- %s %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c),
+ nvme_ctrl_get_state(c));
+ }
+}
+
+static void nvme_show_subsystem(nvme_root_t r)
{
nvme_host_t h;
nvme_subsystem_t s;
nvme_for_each_subsystem(h, s) {
- nvme_ctrl_t c;
-
printf("%s - NQN=%s\n", nvme_subsystem_get_name(s),
nvme_subsystem_get_nqn(s));
printf("\\\n");
- nvme_subsystem_for_each_ctrl(s, c) {
- const char *ana_state =
- nvme_ctrl_get_ana_state(c, nsid);
- printf(" +- %s %s %s %s %s\n",
- nvme_ctrl_get_name(c),
- nvme_ctrl_get_transport(c),
- nvme_ctrl_get_address(c),
- nvme_ctrl_get_state(c),
- ana_state ? : "");
- }
+ if (!nvme_show_subsystem_multipath(s))
+ nvme_show_subsystem_ctrls(s);
+ }
+ }
+}
+
+static unsigned int json_print_nvme_subsystem_multipath(nvme_subsystem_t s,
+ json_object *paths)
+{
+ nvme_ns_t n;
+ unsigned int i = 0;
+
+ nvme_subsystem_for_each_ns(s, n) {
+ nvme_path_t p;
+
+ nvme_namespace_for_each_path(n, p) {
+ struct json_object *path_attrs;
+ nvme_ctrl_t c = nvme_path_get_ctrl(p);
+
+ path_attrs = json_create_object();
+ json_object_add_value_string(path_attrs, "Name",
+ nvme_ctrl_get_name(c));
+ json_object_add_value_string(path_attrs, "Transport",
+ nvme_ctrl_get_transport(c));
+ json_object_add_value_string(path_attrs, "Address",
+ nvme_ctrl_get_address(c));
+ json_object_add_value_string(path_attrs, "State",
+ nvme_ctrl_get_state(c));
+ json_object_add_value_string(path_attrs, "ANAState",
+ nvme_path_get_ana_state(p));
+ json_array_add_value_object(paths, path_attrs);
+ i++;
}
}
+
+ return i;
+}
+
+static void json_print_nvme_subsystem_ctrls(nvme_subsystem_t s,
+ json_object *paths)
+{
+ nvme_ctrl_t c;
+
+ nvme_subsystem_for_each_ctrl(s, c) {
+ struct json_object *path_attrs;
+
+ path_attrs = json_create_object();
+ json_object_add_value_string(path_attrs, "Name",
+ nvme_ctrl_get_name(c));
+ json_object_add_value_string(path_attrs, "Transport",
+ nvme_ctrl_get_transport(c));
+ json_object_add_value_string(path_attrs, "Address",
+ nvme_ctrl_get_address(c));
+ json_object_add_value_string(path_attrs, "State",
+ nvme_ctrl_get_state(c));
+ json_array_add_value_object(paths, path_attrs);
+ }
}
-static void json_print_nvme_subsystem_list(nvme_root_t r, unsigned int nsid)
+static void json_print_nvme_subsystem_list(nvme_root_t r)
{
- struct json_object *host_attrs, *subsystem_attrs, *path_attrs;
+ struct json_object *host_attrs, *subsystem_attrs;
struct json_object *subsystems, *paths;
struct json_object *root;
nvme_host_t h;
nvme_host_get_hostid(h));
subsystems = json_create_array();
nvme_for_each_subsystem(h, s) {
- nvme_ctrl_t c;
-
subsystem_attrs = json_create_object();
json_object_add_value_string(subsystem_attrs, "Name",
nvme_subsystem_get_name(s));
json_array_add_value_object(subsystems, subsystem_attrs);
paths = json_create_array();
- nvme_subsystem_for_each_ctrl(s, c) {
- path_attrs = json_create_object();
- json_object_add_value_string(path_attrs, "Name",
- nvme_ctrl_get_name(c));
- json_object_add_value_string(path_attrs, "Transport",
- nvme_ctrl_get_transport(c));
- json_object_add_value_string(path_attrs, "Address",
- nvme_ctrl_get_address(c));
- json_object_add_value_string(path_attrs, "State",
- nvme_ctrl_get_state(c));
- if (nsid != NVME_NSID_ALL) {
- const char *ana_state =
- nvme_ctrl_get_ana_state(c, nsid);
- if (ana_state)
- json_object_add_value_string(path_attrs,
- "ANAState", ana_state);
- }
- json_array_add_value_object(paths, path_attrs);
- }
+ if (!json_print_nvme_subsystem_multipath(s, paths))
+ json_print_nvme_subsystem_ctrls(s, paths);
+
json_object_add_value_array(subsystem_attrs, "Paths",
paths);
}
json_free_object(root);
}
-void nvme_show_subsystem_list(nvme_root_t r, unsigned int nsid,
- enum nvme_print_flags flags)
+void nvme_show_subsystem_list(nvme_root_t r, enum nvme_print_flags flags)
{
if (flags & JSON)
- return json_print_nvme_subsystem_list(r, nsid);
- nvme_show_subsystem(r, nsid);
+ return json_print_nvme_subsystem_list(r);
+ nvme_show_subsystem(r);
}
static void nvme_show_registers_cap(struct nvme_bar_cap *cap)
return err;
}
-static bool nvme_match_device_filter(nvme_subsystem_t s)
+static bool nvme_match_device_filter(nvme_subsystem_t s,
+ nvme_ctrl_t c, nvme_ns_t ns, void *f_args)
{
- nvme_ctrl_t c;
- nvme_ns_t n;
+ int ret, instance, nsid, s_num;
+ char *devname = f_args;
- if (!devicename || !strlen(devicename))
+ if (!devname || !strlen(devname))
return true;
- nvme_subsystem_for_each_ctrl(s, c) {
- if (!strncmp(devicename, nvme_ctrl_get_name(c),
- strlen(nvme_ctrl_get_name(c))))
+ ret = sscanf(devname, "nvme%dn%d", &instance, &nsid);
+ if (ret != 2)
+ return true;
+
+ if (s) {
+ ret = sscanf(nvme_subsystem_get_name(s), "nvme-subsys%d",
+ &s_num);
+ if (ret == 1 && s_num == instance)
return true;
}
+ if (c) {
+ s = nvme_ctrl_get_subsystem(c);
- nvme_subsystem_for_each_ns(s, n) {
- if (!strcmp(devicename, nvme_ns_get_name(n)))
+ ret = sscanf(nvme_subsystem_get_name(s), "nvme-subsys%d",
+ &s_num);
+ if (ret == 1 && s_num == instance)
+ return true;
+ }
+ if (ns) {
+ if (!strcmp(devname, nvme_ns_get_name(ns)))
return true;
}
const char *desc = "Retrieve information for subsystems";
const char *verbose = "Increase output verbosity";
nvme_scan_filter_t filter = NULL;
- __u32 nsid = NVME_NSID_ALL;
int err;
struct config {
}
if (devicename) {
- int subsys_num;
+ int subsys_num, nsid;
if (sscanf(devicename,"nvme%dn%d",
&subsys_num, &nsid) != 2) {
filter = nvme_match_device_filter;
}
- err = nvme_scan_topology(r, filter);
+ err = nvme_scan_topology(r, filter, (void *)devicename);
if (err) {
fprintf(stderr, "Failed to scan topology: %s\n",
nvme_strerror(errno));
goto ret;
}
- nvme_show_subsystem_list(r, nsid, flags);
+ nvme_show_subsystem_list(r, flags);
+
ret:
if (r)
nvme_free_tree(r);
nvme_strerror(errno));
return -errno;
}
- err = nvme_scan_topology(r, NULL);
+ err = nvme_scan_topology(r, NULL, NULL);
if (err < 0) {
fprintf(stderr, "Failed to scan topoplogy: %s\n",
nvme_strerror(errno));