Skip to content

Commit 0d1f8a1

Browse files
authored
Merge pull request #324 from hreinecke/subsystem-rework
Rework nvme_scan_subsystem()
2 parents 851f186 + 1fe56b7 commit 0d1f8a1

1 file changed

Lines changed: 68 additions & 59 deletions

File tree

src/nvme/tree.c

Lines changed: 68 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ 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,
4242
struct nvme_subsystem *s, char *name);
43+
static int nvme_init_subsystem(nvme_subsystem_t s, const char *name);
4344
static int nvme_scan_subsystem(nvme_root_t r, const char *name,
4445
nvme_scan_filter_t f);
4546
static int nvme_ctrl_scan_namespace(nvme_root_t r, struct nvme_ctrl *c,
@@ -370,26 +371,20 @@ void nvme_free_subsystem(nvme_subsystem_t s)
370371
{
371372
}
372373

373-
struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h,
374-
const char *name,
375-
const char *subsysnqn)
374+
struct nvme_subsystem *nvme_alloc_subsystem(struct nvme_host *h,
375+
const char *name,
376+
const char *subsysnqn)
376377
{
377378
struct nvme_subsystem *s;
378379

379-
nvme_for_each_subsystem(h, s) {
380-
if (strcmp(s->subsysnqn, subsysnqn))
381-
continue;
382-
if (name && s->name &&
383-
strcmp(s->name, name))
384-
continue;
385-
return s;
386-
}
387380
s = calloc(1, sizeof(*s));
388381
if (!s)
389382
return NULL;
390383

391384
s->h = h;
392385
s->subsysnqn = strdup(subsysnqn);
386+
if (name)
387+
nvme_init_subsystem(s, name);
393388
list_head_init(&s->ctrls);
394389
list_head_init(&s->namespaces);
395390
list_node_init(&s->entry);
@@ -398,6 +393,23 @@ struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h,
398393
return s;
399394
}
400395

396+
struct nvme_subsystem *nvme_lookup_subsystem(struct nvme_host *h,
397+
const char *name,
398+
const char *subsysnqn)
399+
{
400+
struct nvme_subsystem *s;
401+
402+
nvme_for_each_subsystem(h, s) {
403+
if (strcmp(s->subsysnqn, subsysnqn))
404+
continue;
405+
if (name && s->name &&
406+
strcmp(s->name, name))
407+
continue;
408+
return s;
409+
}
410+
return nvme_alloc_subsystem(h, name, subsysnqn);
411+
}
412+
401413
static void __nvme_free_host(struct nvme_host *h)
402414
{
403415
struct nvme_subsystem *s, *_s;
@@ -504,9 +516,8 @@ static int nvme_init_subsystem(nvme_subsystem_t s, const char *name)
504516
static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
505517
nvme_scan_filter_t f)
506518
{
507-
struct nvme_subsystem *s;
519+
struct nvme_subsystem *s = NULL, *_s;
508520
char *path, *subsysnqn;
509-
char *hostnqn, *hostid = NULL;
510521
nvme_host_t h = NULL;
511522
int ret;
512523

@@ -515,47 +526,49 @@ static int nvme_scan_subsystem(struct nvme_root *r, const char *name,
515526
if (ret < 0)
516527
return ret;
517528

518-
hostnqn = nvme_get_attr(path, "hostnqn");
519-
if (hostnqn) {
520-
hostid = nvme_get_attr(path, "hostid");
521-
h = nvme_lookup_host(r, hostnqn, hostid);
522-
free(hostnqn);
523-
if (hostid)
524-
free(hostid);
525-
if (h) {
526-
if (h->dhchap_key)
527-
free(h->dhchap_key);
528-
h->dhchap_key = nvme_get_attr(path, "dhchap_secret");
529-
if (h->dhchap_key && !strcmp(h->dhchap_key, "none")) {
530-
free(h->dhchap_key);
531-
h->dhchap_key = NULL;
532-
}
533-
}
534-
}
535-
if (!h)
536-
h = nvme_default_host(r);
537-
if (!h) {
538-
free(path);
539-
errno = ENOMEM;
540-
return -1;
541-
}
542529
subsysnqn = nvme_get_attr(path, "subsysnqn");
543530
free(path);
544531
if (!subsysnqn) {
545532
errno = ENODEV;
546533
return -1;
547534
}
548-
s = nvme_lookup_subsystem(h, name, subsysnqn);
549-
free(subsysnqn);
535+
nvme_for_each_host(r, h) {
536+
nvme_for_each_subsystem(h, _s) {
537+
/*
538+
* We are always called after nvme_scan_ctrl(),
539+
* so any subsystem we're interested at _must_
540+
* have a name.
541+
*/
542+
if (!_s->name)
543+
continue;
544+
if (strcmp(_s->name, name))
545+
continue;
546+
s = _s;
547+
}
548+
}
550549
if (!s) {
551-
errno = ENOMEM;
550+
/*
551+
* Subsystem with non-matching controller. odd.
552+
* Create a subsystem with the default host
553+
* and hope for the best.
554+
*/
555+
nvme_msg(r, LOG_DEBUG, "creating detached subsystem '%s'\n",
556+
name);
557+
h = nvme_default_host(r);
558+
s = nvme_alloc_subsystem(h, name, subsysnqn);
559+
if (!s) {
560+
errno = ENOMEM;
561+
}
562+
} else if (strcmp(s->subsysnqn, subsysnqn)) {
563+
nvme_msg(r, LOG_WARNING, "NQN mismatch for subsystem '%s'\n",
564+
name);
565+
s = NULL;
566+
errno = EINVAL;
552567
return -1;
553568
}
554-
if (!s->name) {
555-
ret = nvme_init_subsystem(s, name);
556-
if (ret < 0)
557-
return -1;
558-
}
569+
free(subsysnqn);
570+
if (!s)
571+
return -1;
559572

560573
nvme_subsystem_scan_namespaces(r, s);
561574

@@ -1199,14 +1212,6 @@ int nvme_init_ctrl(nvme_host_t h, nvme_ctrl_t c, int instance)
11991212
ret = -1;
12001213
goto out_free_subsys;
12011214
}
1202-
if (!s->name) {
1203-
ret = nvme_init_subsystem(s, subsys_name);
1204-
if (ret < 0) {
1205-
nvme_msg(h->r, LOG_ERR, "Failed to init subsystem %s\n",
1206-
subsys_name);
1207-
goto out_free_subsys;
1208-
}
1209-
}
12101215
if (s->subsystype && !strcmp(s->subsystype, "discovery"))
12111216
c->discovery_ctrl = true;
12121217
c->s = s;
@@ -1369,15 +1374,19 @@ nvme_ctrl_t nvme_scan_ctrl(nvme_root_t r, const char *name)
13691374
return NULL;
13701375
}
13711376
subsysname = nvme_ctrl_lookup_subsystem_name(r, name);
1372-
/* subsysname might be NULL here */
1377+
if (!subsysname) {
1378+
nvme_msg(r, LOG_ERR,
1379+
"failed to lookup subsystem for controller %s\n",
1380+
name);
1381+
free(path);
1382+
errno = ENXIO;
1383+
return NULL;
1384+
}
13731385
s = nvme_lookup_subsystem(h, subsysname, subsysnqn);
13741386
free(subsysnqn);
1375-
1376-
ret = 0;
1377-
if (s && !s->name && subsysname)
1378-
ret = nvme_init_subsystem(s, subsysname);
13791387
free(subsysname);
1380-
if (!s || ret < 0) {
1388+
1389+
if (!s) {
13811390
free(path);
13821391
errno = ENOMEM;
13831392
return NULL;

0 commit comments

Comments
 (0)