Skip to content

Commit a1369c8

Browse files
authored
Merge pull request #330 from hreinecke/filter-ns
Update nvme_scan_filter_t
2 parents 008a2da + a98edd0 commit a1369c8

4 files changed

Lines changed: 88 additions & 49 deletions

File tree

src/libnvme.map

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ LIBNVME_1_0 {
1212
nvme_ctrl_first_ns;
1313
nvme_ctrl_first_path;
1414
nvme_ctrl_get_address;
15-
nvme_ctrl_get_ana_state;
1615
nvme_ctrl_get_dhchap_key;
1716
nvme_ctrl_get_discovery_ctrl;
1817
nvme_ctrl_get_fd;
@@ -185,6 +184,8 @@ LIBNVME_1_0 {
185184
nvme_namespace_attach_ctrls;
186185
nvme_namespace_detach_ctrls;
187186
nvme_namespace_filter;
187+
nvme_namespace_first_path;
188+
nvme_namespace_next_path;
188189
nvme_next_host;
189190
nvme_next_subsystem;
190191
nvme_ns_attach;

src/nvme/tree.c

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@ static struct nvme_host *default_host;
3939
static void __nvme_free_host(nvme_host_t h);
4040
static void __nvme_free_ctrl(nvme_ctrl_t c);
4141
static int nvme_subsystem_scan_namespace(nvme_root_t r,
42-
struct nvme_subsystem *s, char *name);
42+
struct nvme_subsystem *s, char *name,
43+
nvme_scan_filter_t f, void *f_args);
4344
static int nvme_init_subsystem(nvme_subsystem_t s, const char *name);
4445
static int nvme_scan_subsystem(nvme_root_t r, const char *name,
45-
nvme_scan_filter_t f);
46+
nvme_scan_filter_t f, void *f_args);
4647
static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c,
4748
char *name);
4849
static int nvme_ctrl_scan_path(nvme_root_t r, struct nvme_ctrl *c, char *name);
@@ -75,7 +76,7 @@ nvme_host_t nvme_default_host(nvme_root_t r)
7576
return h;
7677
}
7778

78-
int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f)
79+
int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f, void *f_args)
7980
{
8081
struct dirent **subsys, **ctrls;
8182
int i, num_subsys, num_ctrls, ret;
@@ -97,7 +98,7 @@ int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f)
9798
ctrls[i]->d_name, strerror(errno));
9899
continue;
99100
}
100-
if ((f) && !f(c->s)) {
101+
if ((f) && !f(NULL, c, NULL, f_args)) {
101102
nvme_msg(r, LOG_DEBUG, "filter out controller %s\n",
102103
ctrls[i]->d_name);
103104
nvme_free_ctrl(c);
@@ -114,7 +115,7 @@ int nvme_scan_topology(struct nvme_root *r, nvme_scan_filter_t f)
114115
}
115116

116117
for (i = 0; i < num_subsys; i++) {
117-
ret = nvme_scan_subsystem(r, subsys[i]->d_name, f);
118+
ret = nvme_scan_subsystem(r, subsys[i]->d_name, f, f_args);
118119
if (ret < 0) {
119120
nvme_msg(r, LOG_DEBUG,
120121
"failed to scan subsystem %s: %s\n",
@@ -172,7 +173,7 @@ nvme_root_t nvme_scan(const char *config_file)
172173
{
173174
nvme_root_t r = nvme_create_root(NULL, DEFAULT_LOGLEVEL);
174175

175-
nvme_scan_topology(r, NULL);
176+
nvme_scan_topology(r, NULL, NULL);
176177
nvme_read_config(r, config_file);
177178
return r;
178179
}
@@ -266,7 +267,7 @@ void nvme_refresh_topology(nvme_root_t r)
266267

267268
nvme_for_each_host_safe(r, h, _h)
268269
__nvme_free_host(h);
269-
nvme_scan_topology(r, NULL);
270+
nvme_scan_topology(r, NULL, NULL);
270271
}
271272

272273
void nvme_free_tree(nvme_root_t r)
@@ -325,6 +326,16 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n)
325326
return n ? list_next(&s->namespaces, n, entry) : NULL;
326327
}
327328

329+
nvme_path_t nvme_namespace_first_path(nvme_ns_t ns)
330+
{
331+
return list_top(&ns->paths, struct nvme_path, nentry);
332+
}
333+
334+
nvme_path_t nvme_namespace_next_path(nvme_ns_t ns, nvme_path_t p)
335+
{
336+
return p ? list_next(&ns->paths, p, nentry) : NULL;
337+
}
338+
328339
static void __nvme_free_ns(struct nvme_ns *n)
329340
{
330341
list_del_init(&n->entry);
@@ -465,7 +476,8 @@ struct nvme_host *nvme_lookup_host(nvme_root_t r, const char *hostnqn,
465476
return h;
466477
}
467478

468-
static int nvme_subsystem_scan_namespaces(nvme_root_t r, nvme_subsystem_t s)
479+
static int nvme_subsystem_scan_namespaces(nvme_root_t r, nvme_subsystem_t s,
480+
nvme_scan_filter_t f, void *f_args)
469481
{
470482
struct dirent **namespaces;
471483
int i, num_ns, ret;
@@ -480,7 +492,7 @@ static int nvme_subsystem_scan_namespaces(nvme_root_t r, nvme_subsystem_t s)
480492

481493
for (i = 0; i < num_ns; i++) {
482494
ret = nvme_subsystem_scan_namespace(r, s,
483-
namespaces[i]->d_name);
495+
namespaces[i]->d_name, f, f_args);
484496
if (ret < 0)
485497
nvme_msg(r, LOG_DEBUG,
486498
"failed to scan namespace %s: %s\n",
@@ -517,7 +529,7 @@ static int nvme_init_subsystem(nvme_subsystem_t s, const char *name)
517529
}
518530

519531
static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
520-
nvme_scan_filter_t f)
532+
nvme_scan_filter_t f, void *f_args)
521533
{
522534
struct nvme_subsystem *s = NULL, *_s;
523535
char *path, *subsysnqn;
@@ -573,13 +585,14 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
573585
if (!s)
574586
return -1;
575587

576-
nvme_subsystem_scan_namespaces(r, s);
577-
578-
if (f && !f(s)) {
588+
if (f && !f(s, NULL, NULL, f_args)) {
579589
nvme_msg(r, LOG_DEBUG, "filter out subsystem %s\n", name);
580590
__nvme_free_subsystem(s);
591+
return 0;
581592
}
582593

594+
nvme_subsystem_scan_namespaces(r, s, f, f_args);
595+
583596
return 0;
584597
}
585598

@@ -789,19 +802,6 @@ const char *nvme_ctrl_get_host_iface(nvme_ctrl_t c)
789802
return c->cfg.host_iface;
790803
}
791804

792-
const char *nvme_ctrl_get_ana_state(nvme_ctrl_t c, __u32 nsid)
793-
{
794-
if (nsid != NVME_NSID_ALL) {
795-
nvme_path_t p;
796-
797-
nvme_ctrl_for_each_path(c, p) {
798-
if (p->n && p->n->nsid == nsid)
799-
return p->ana_state;
800-
}
801-
}
802-
return NULL;
803-
}
804-
805805
struct nvme_fabrics_config *nvme_ctrl_get_config(nvme_ctrl_t c)
806806
{
807807
return &c->cfg;
@@ -1411,9 +1411,9 @@ void nvme_rescan_ctrl(struct nvme_ctrl *c)
14111411
nvme_root_t r = c->s && c->s->h ? c->s->h->r : NULL;
14121412
if (!c->s)
14131413
return;
1414-
nvme_subsystem_scan_namespaces(r, c->s);
14151414
nvme_ctrl_scan_namespaces(r, c);
14161415
nvme_ctrl_scan_paths(r, c);
1416+
nvme_subsystem_scan_namespaces(r, c->s, NULL, NULL);
14171417
}
14181418

14191419
static int nvme_bytes_to_lba(nvme_ns_t n, off_t offset, size_t count,
@@ -1884,7 +1884,7 @@ static void nvme_subsystem_set_ns_path(nvme_subsystem_t s, nvme_ns_t n)
18841884
}
18851885

18861886
static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s,
1887-
char *name)
1887+
char *name, nvme_scan_filter_t f, void *f_args)
18881888
{
18891889
struct nvme_ns *n;
18901890

@@ -1895,7 +1895,11 @@ static int nvme_subsystem_scan_namespace(nvme_root_t r, nvme_subsystem_t s,
18951895
nvme_msg(r, LOG_DEBUG, "failed to scan namespace %s\n", name);
18961896
return -1;
18971897
}
1898-
1898+
if (f && !f(NULL, NULL, n, f_args)) {
1899+
nvme_msg(r, LOG_DEBUG, "filter out namespace %s\n", name);
1900+
__nvme_free_ns(n);
1901+
return 0;
1902+
}
18991903
n->s = s;
19001904
list_add(&s->namespaces, &n->entry);
19011905
nvme_subsystem_set_ns_path(s, n);

src/nvme/tree.h

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ typedef struct nvme_subsystem *nvme_subsystem_t;
3333
typedef struct nvme_host *nvme_host_t;
3434
typedef struct nvme_root *nvme_root_t;
3535

36-
typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t);
36+
typedef bool (*nvme_scan_filter_t)(nvme_subsystem_t, nvme_ctrl_t,
37+
nvme_ns_t, void *);
3738

3839
/**
3940
* nvme_create_root() - Initialize root object
@@ -216,6 +217,23 @@ nvme_ctrl_t nvme_subsystem_first_ctrl(nvme_subsystem_t s);
216217
*/
217218
nvme_ctrl_t nvme_subsystem_next_ctrl(nvme_subsystem_t s, nvme_ctrl_t c);
218219

220+
/**
221+
* nvme_namespace_first_path() - Start path iterator
222+
* @ns: Namespace instance
223+
*
224+
* Return: First &nvme_path_t object of an @ns iterator
225+
*/
226+
nvme_path_t nvme_namespace_first_path(nvme_ns_t ns);
227+
228+
/**
229+
* nvme_namespace_next_path() - Next path iterator
230+
* @ns: Namespace instance
231+
* @p: Previous &nvme_path_t object of an @ns iterator
232+
*
233+
* Return: Next &nvme_path_t object of an @ns iterator
234+
*/
235+
nvme_path_t nvme_namespace_next_path(nvme_ns_t c, nvme_path_t p);
236+
219237
/**
220238
* nvme_lookup_ctrl() - Lookup nvme_ctrl_t object
221239
* @s: &nvme_subsystem_t object
@@ -403,6 +421,27 @@ nvme_ns_t nvme_subsystem_next_ns(nvme_subsystem_t s, nvme_ns_t n);
403421
for (n = nvme_subsystem_first_ns(s); n != NULL; \
404422
n = nvme_subsystem_next_ns(s, n))
405423

424+
/**
425+
* nvme_namespace_for_each_path_safe() - Traverse paths
426+
* @ns: Namespace instance
427+
* @p: &nvme_path_t object
428+
* @_p: A &nvme_path_t_node to use as temporary storage
429+
*/
430+
#define nvme_namespace_for_each_path_safe(n, p, _p) \
431+
for (p = nvme_namespace_first_path(n), \
432+
_p = nvme_namespace_next_path(n, p); \
433+
p != NULL; \
434+
p = _p, _p = nvme_namespace_next_path(n, p))
435+
436+
/**
437+
* nvme_namespace_for_each_path() - Traverse paths
438+
* @ns: Namespace instance
439+
* @p: &nvme_path_t object
440+
*/
441+
#define nvme_namespace_for_each_path(c, p) \
442+
for (p = nvme_namespace_first_path(c); p != NULL; \
443+
p = nvme_namespace_next_path(c, p))
444+
406445
/**
407446
* nvme_ns_get_fd() - Get associated filedescriptor
408447
* @n: Namespace instance
@@ -836,15 +875,6 @@ const char *nvme_ctrl_get_host_traddr(nvme_ctrl_t c);
836875
*/
837876
const char *nvme_ctrl_get_host_iface(nvme_ctrl_t c);
838877

839-
/**
840-
* nvme_ctrl_get_ana_state() - ANA state of a controller path
841-
* @c: Constroller instance
842-
* @nsid: Namespace ID to evaluate
843-
*
844-
* Return: ANA state of the namespace @nsid on controller @c.
845-
*/
846-
const char *nvme_ctrl_get_ana_state(nvme_ctrl_t c, __u32 nsid);
847-
848878
/**
849879
* nvme_ctrl_get_dhchap_key() - Return controller key
850880
* @c: Controller for which the key should be set
@@ -1021,15 +1051,16 @@ const char *nvme_subsystem_get_type(nvme_subsystem_t s);
10211051

10221052
/**
10231053
* nvme_scan_topology() - Scan NVMe topology and apply filter
1024-
* @r: nvme_root_t object
1025-
* @f: filter to apply
1054+
* @r: nvme_root_t object
1055+
* @f: filter to apply
1056+
* @f_args: user-specified argument to @f
10261057
*
10271058
* Scans the NVMe topology and filters out the resulting elements
10281059
* by applying @f.
10291060
*
10301061
* Return: Number of elements scanned
10311062
*/
1032-
int nvme_scan_topology(nvme_root_t r, nvme_scan_filter_t f);
1063+
int nvme_scan_topology(nvme_root_t r, nvme_scan_filter_t f, void *f_args);
10331064

10341065
/**
10351066
* nvme_host_get_hostnqn() - Host NQN of an nvme_host_t object

test/test.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,14 @@
2424

2525
#include <ccan/endian/endian.h>
2626

27-
static char *nqn_match;
28-
29-
static bool nvme_match_subsysnqn_filter(nvme_subsystem_t s)
27+
static bool nvme_match_subsysnqn_filter(nvme_subsystem_t s,
28+
nvme_ctrl_t c, nvme_ns_t ns, void *f_args)
3029
{
31-
return strcmp(nvme_subsystem_get_nqn(s), nqn_match) == 0;
30+
char *nqn_match = f_args;
31+
32+
if (s)
33+
return strcmp(nvme_subsystem_get_nqn(s), nqn_match) == 0;
34+
return true;
3235
}
3336

3437
static int test_ctrl(nvme_ctrl_t c)
@@ -321,13 +324,13 @@ int main(int argc, char **argv)
321324
nvme_path_t p;
322325
nvme_ns_t n;
323326
const char *ctrl = "nvme4";
327+
const char *nqn_match = "testnqn";
324328

325329
printf("Test filter for common loop back target\n");
326-
nqn_match = "testnqn";
327330
r = nvme_create_root(NULL, DEFAULT_LOGLEVEL);
328331
if (!r)
329332
return 1;
330-
nvme_scan_topology(r, nvme_match_subsysnqn_filter);
333+
nvme_scan_topology(r, nvme_match_subsysnqn_filter, (void *)nqn_match);
331334
nvme_for_each_host(r, h) {
332335
nvme_for_each_subsystem(h, s) {
333336
printf("%s - NQN=%s\n", nvme_subsystem_get_name(s),

0 commit comments

Comments
 (0)