Skip to content

Commit 42a8824

Browse files
authored
Merge pull request #396 from CodeConstruct/mi+scan
MI: Add endpoint iterators, and allow scanning from MCTP endpoints on dbus
2 parents 2ed61af + 6de50e5 commit 42a8824

12 files changed

Lines changed: 630 additions & 42 deletions

File tree

doc/mi.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,17 @@ each have a unique ``unsigned int`` as their ID.
2727

2828
The default Network ID is 1; unless you have configured otherwise, MCTP
2929
endpoints will appear on this network.
30+
31+
If compiled with D-Bus support, ``libnvme-mi`` can query the system MCTP daemon
32+
("``mctpd``") to find attached NVMe devices, via the ``nvme_mi_scan_mctp()``
33+
function. Calling this will establish a ``nvme_root_t`` object, populated
34+
with the results of that scan. Use the ``nvme_mi_for_each_endpoint`` macro
35+
to iterate through the scanned endpoints.
36+
37+
Note that the MCTP daemon is provided separately, as part of the MCTP userspace
38+
tools, at https://github.com/CodeConstruct/mctp . ``mctpd`` is responsible for
39+
discovery and enumeration for MCTP endpoints on the system, and will query
40+
each for its protocol capabilities during enumeration. Consequently, NVMe-MI
41+
endpoints will need to report support for NVMe-MI-over-MCTP (protocol 0x4) in
42+
their supported protocols list (ie., as returned by the MCTP Get Message Type
43+
Support command) in order to be discovered.

doc/mi.rst.in

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,17 @@ each have a unique ``unsigned int`` as their ID.
2727

2828
The default Network ID is 1; unless you have configured otherwise, MCTP
2929
endpoints will appear on this network.
30+
31+
If compiled with D-Bus support, ``libnvme-mi`` can query the system MCTP daemon
32+
("``mctpd``") to find attached NVMe devices, via the ``nvme_mi_scan_mctp()``
33+
function. Calling this will establish a ``nvme_root_t`` object, populated
34+
with the results of that scan. Use the ``nvme_mi_for_each_endpoint`` macro
35+
to iterate through the scanned endpoints.
36+
37+
Note that the MCTP daemon is provided separately, as part of the MCTP userspace
38+
tools, at https://github.com/CodeConstruct/mctp . ``mctpd`` is responsible for
39+
discovery and enumeration for MCTP endpoints on the system, and will query
40+
each for its protocol capabilities during enumeration. Consequently, NVMe-MI
41+
endpoints will need to report support for NVMe-MI-over-MCTP (protocol 0x4) in
42+
their supported protocols list (ie., as returned by the MCTP Get Message Type
43+
Support command) in order to be discovered.

examples/mi-mctp.c

Lines changed: 77 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -517,34 +517,73 @@ enum action {
517517
ACTION_SECURITY_INFO,
518518
};
519519

520+
static int do_action_endpoint(enum action action, nvme_mi_ep_t ep, int argc, char** argv)
521+
{
522+
int rc;
523+
524+
switch (action) {
525+
case ACTION_INFO:
526+
rc = do_info(ep);
527+
break;
528+
case ACTION_CONTROLLERS:
529+
rc = do_controllers(ep);
530+
break;
531+
case ACTION_IDENTIFY:
532+
rc = do_identify(ep, argc, argv);
533+
break;
534+
case ACTION_GET_LOG_PAGE:
535+
rc = do_get_log_page(ep, argc, argv);
536+
break;
537+
case ACTION_ADMIN_RAW:
538+
rc = do_admin_raw(ep, argc, argv);
539+
break;
540+
case ACTION_SECURITY_INFO:
541+
rc = do_security_info(ep, argc, argv);
542+
break;
543+
}
544+
return rc;
545+
}
546+
520547
int main(int argc, char **argv)
521548
{
522549
enum action action;
523550
nvme_root_t root;
524551
nvme_mi_ep_t ep;
552+
bool dbus = false, usage = true;
525553
uint8_t eid;
526-
int rc, net;
527-
528-
if (argc < 3) {
554+
int rc = 0, net;
555+
556+
if (argc >= 2 && strcmp(argv[1], "dbus") == 0) {
557+
usage = false;
558+
dbus= true;
559+
argv += 1;
560+
argc -= 1;
561+
} else if (argc >= 3) {
562+
usage = false;
563+
net = atoi(argv[1]);
564+
eid = atoi(argv[2]) & 0xff;
565+
argv += 2;
566+
argc -= 2;
567+
}
568+
569+
if (usage) {
529570
fprintf(stderr,
530-
"usage: %s <net> <eid> [action] [action args]\n",
531-
argv[0]);
571+
"usage: %s <net> <eid> [action] [action args]\n"
572+
" %s 'dbus' [action] [action args]\n",
573+
argv[0], argv[0]);
532574
fprintf(stderr, "where action is:\n"
533575
" info\n"
534576
" controllers\n"
535577
" identify <controller-id> [--partial]\n"
536578
" get-log-page <controller-id> [<log-id>]\n"
537579
" admin <controller-id> <opcode> [<cdw10>, <cdw11>, ...]\n"
538580
" security-info <controller-id>\n"
581+
"\n"
582+
" 'dbus' target will query D-Bus for known MCTP endpoints\n"
539583
);
540584
return EXIT_FAILURE;
541585
}
542586

543-
net = atoi(argv[1]);
544-
eid = atoi(argv[2]) & 0xff;
545-
argv += 2;
546-
argc -= 2;
547-
548587
if (argc == 1) {
549588
action = ACTION_INFO;
550589
} else {
@@ -569,40 +608,37 @@ int main(int argc, char **argv)
569608
return EXIT_FAILURE;
570609
}
571610
}
611+
if (dbus) {
612+
nvme_root_t root;
613+
int i = 0;
614+
615+
root = nvme_mi_scan_mctp();
616+
if (!root)
617+
errx(EXIT_FAILURE, "can't scan D-Bus entries");
618+
619+
nvme_mi_for_each_endpoint(root, ep) i++;
620+
printf("Found %d endpoints in D-Bus:\n", i);
621+
nvme_mi_for_each_endpoint(root, ep) {
622+
char *desc = nvme_mi_endpoint_desc(ep);
623+
printf("%s\n", desc);
624+
rc = do_action_endpoint(action, ep, argc, argv);
625+
printf("---\n");
626+
free(desc);
627+
}
628+
nvme_mi_free_root(root);
629+
} else {
630+
root = nvme_mi_create_root(stderr, DEFAULT_LOGLEVEL);
631+
if (!root)
632+
err(EXIT_FAILURE, "can't create NVMe root");
572633

573-
root = nvme_mi_create_root(stderr, DEFAULT_LOGLEVEL);
574-
if (!root)
575-
err(EXIT_FAILURE, "can't create NVMe root");
576-
577-
ep = nvme_mi_open_mctp(root, net, eid);
578-
if (!ep)
579-
err(EXIT_FAILURE, "can't open MCTP endpoint %d:%d", net, eid);
580-
581-
switch (action) {
582-
case ACTION_INFO:
583-
rc = do_info(ep);
584-
break;
585-
case ACTION_CONTROLLERS:
586-
rc = do_controllers(ep);
587-
break;
588-
case ACTION_IDENTIFY:
589-
rc = do_identify(ep, argc, argv);
590-
break;
591-
case ACTION_GET_LOG_PAGE:
592-
rc = do_get_log_page(ep, argc, argv);
593-
break;
594-
case ACTION_ADMIN_RAW:
595-
rc = do_admin_raw(ep, argc, argv);
596-
break;
597-
case ACTION_SECURITY_INFO:
598-
rc = do_security_info(ep, argc, argv);
599-
break;
634+
ep = nvme_mi_open_mctp(root, net, eid);
635+
if (!ep)
636+
errx(EXIT_FAILURE, "can't open MCTP endpoint %d:%d", net, eid);
637+
rc = do_action_endpoint(action, ep, argc, argv);
638+
nvme_mi_close(ep);
639+
nvme_mi_free_root(root);
600640
}
601641

602-
nvme_mi_close(ep);
603-
604-
nvme_mi_free_root(root);
605-
606642
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
607643
}
608644

meson.build

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ if openssl_dep.found()
7878
description: 'OpenSSL version 3.x')
7979
endif
8080

81+
# Check for libsystemd availability. Optional, only required for MCTP dbus scan
82+
libsystemd_dep = dependency('libsystemd', required: false)
83+
conf.set('CONFIG_LIBSYSTEMD', libsystemd_dep.found(), description: 'Is libsystemd available?')
84+
8185
# local (cross-compilable) implementations of ccan configure steps
8286
conf.set10(
8387
'HAVE_BUILTIN_TYPES_COMPATIBLE_P',

src/libnvme-mi.map

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ LIBNVME_MI_1_1 {
1515
nvme_mi_admin_xfer;
1616
nvme_mi_admin_security_send;
1717
nvme_mi_admin_security_recv;
18+
nvme_mi_endpoint_desc;
19+
nvme_mi_root_close;
20+
nvme_mi_first_endpoint;
21+
nvme_mi_next_endpoint;
1822
nvme_mi_open_mctp;
23+
nvme_mi_scan_mctp;
1924
local:
2025
*;
2126
};

src/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ deps = [
3535

3636
mi_deps = [
3737
libuuid_dep,
38+
libsystemd_dep,
3839
]
3940

4041
source_dir = meson.current_source_dir()

0 commit comments

Comments
 (0)