Skip to content

Commit ee1a3a2

Browse files
committed
mi: make management interface support optional
The MI code depends on Linux-specific interfaces (networking), which makes porting to other platforms more difficult. Make it optional. This also helps reduce the footprint for minimal setups. Signed-off-by: Daniel Wagner <[email protected]>
1 parent 0b2bb53 commit ee1a3a2

13 files changed

Lines changed: 240 additions & 152 deletions

File tree

libnvme/examples/meson.build

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -47,46 +47,48 @@ if want_fabrics
4747
)
4848
endif
4949

50-
executable(
51-
'mi-mctp',
52-
['mi-mctp.c'],
53-
dependencies: [
54-
config_dep,
55-
ccan_dep,
56-
libnvme_dep,
57-
],
58-
)
59-
60-
executable(
61-
'mi-mctp-csi-test',
62-
['mi-mctp-csi-test.c'],
63-
dependencies: [
64-
config_dep,
65-
ccan_dep,
66-
libnvme_dep,
67-
threads_dep,
68-
],
69-
)
50+
if want_mi
51+
executable(
52+
'mi-mctp',
53+
['mi-mctp.c'],
54+
dependencies: [
55+
config_dep,
56+
ccan_dep,
57+
libnvme_dep,
58+
],
59+
)
7060

71-
executable(
72-
'mi-mctp-ae',
73-
['mi-mctp-ae.c'],
74-
dependencies: [
75-
config_dep,
76-
ccan_dep,
77-
libnvme_dep,
78-
],
79-
)
61+
executable(
62+
'mi-mctp-csi-test',
63+
['mi-mctp-csi-test.c'],
64+
dependencies: [
65+
config_dep,
66+
ccan_dep,
67+
libnvme_dep,
68+
threads_dep,
69+
],
70+
)
8071

81-
if libdbus_dep.found()
8272
executable(
83-
'mi-conf',
84-
['mi-conf.c'],
73+
'mi-mctp-ae',
74+
['mi-mctp-ae.c'],
8575
dependencies: [
8676
config_dep,
8777
ccan_dep,
8878
libnvme_dep,
89-
libdbus_dep,
9079
],
9180
)
81+
82+
if libdbus_dep.found()
83+
executable(
84+
'mi-conf',
85+
['mi-conf.c'],
86+
dependencies: [
87+
config_dep,
88+
ccan_dep,
89+
libnvme_dep,
90+
libdbus_dep,
91+
],
92+
)
93+
endif
9294
endif

libnvme/src/meson.build

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ else
1919
'nvme/lib.c',
2020
'nvme/linux.c',
2121
'nvme/log.c',
22-
'nvme/mi-mctp.c',
23-
'nvme/mi.c',
2422
'nvme/sysfs.c',
2523
'nvme/tree.c',
2624
'nvme/util.c',
@@ -34,8 +32,6 @@ headers = [
3432
'nvme/lib-types.h',
3533
'nvme/lib.h',
3634
'nvme/linux.h',
37-
'nvme/mi-types.h',
38-
'nvme/mi.h',
3935
'nvme/tree.h',
4036
'nvme/types.h',
4137
'nvme/util.h',
@@ -54,6 +50,21 @@ if want_fabrics
5450
]
5551
endif
5652

53+
if want_mi
54+
sources += [
55+
'nvme/mi-mctp.c',
56+
'nvme/mi.c',
57+
]
58+
headers += [
59+
'nvme/mi-types.h',
60+
'nvme/mi.h',
61+
]
62+
else
63+
sources += [
64+
'nvme/no-mi.c'
65+
]
66+
endif
67+
5768
if liburing_dep.found()
5869
sources += 'nvme/uring.c'
5970
else
@@ -158,14 +169,17 @@ libnvme_test_dep = declare_dependency(
158169
)
159170

160171
mode = 'rw-r--r--'
161-
install_headers(
162-
[
163-
'libnvme-mi.h',
164-
],
165-
install_mode: mode,
166-
)
167172
install_headers(
168173
headers,
169174
subdir: 'nvme',
170175
install_mode: mode,
171176
)
177+
if want_mi
178+
install_headers(
179+
[
180+
'libnvme-mi.h',
181+
],
182+
install_mode: mode,
183+
)
184+
endif
185+

libnvme/src/nvme/lib.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "cleanup.h"
2525
#include "cleanup-linux.h"
2626
#include "private.h"
27+
#include "private-mi.h"
2728
#include "compiler-attributes.h"
2829

2930
static bool libnvme_mi_probe_enabled_default(void)
@@ -73,7 +74,9 @@ __public struct libnvme_global_ctx *libnvme_create_global_ctx(FILE *fp, int log_
7374
__public void libnvme_free_global_ctx(struct libnvme_global_ctx *ctx)
7475
{
7576
struct libnvme_host *h, *_h;
77+
#ifdef CONFIG_MI
7678
libnvme_mi_ep_t ep, tmp;
79+
#endif
7780

7881
if (!ctx)
7982
return;
@@ -86,8 +89,10 @@ __public void libnvme_free_global_ctx(struct libnvme_global_ctx *ctx)
8689

8790
libnvme_for_each_host_safe(ctx, h, _h)
8891
__libnvme_free_host(h);
92+
#ifdef CONFIG_MI
8993
libnvme_mi_for_each_endpoint_safe(ctx, ep, tmp)
9094
libnvme_mi_close(ep);
95+
#endif
9196
free(ctx->config_file);
9297
free(ctx->application);
9398
libnvme_close_uring(ctx);

libnvme/src/nvme/mi-mctp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
#include <ccan/endian/endian.h>
2929

30+
#include "private-mi.h"
31+
3032
#ifdef CONFIG_DBUS
3133
#include <dbus/dbus.h>
3234

libnvme/src/nvme/mi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <libnvme-mi.h>
2121

2222
#include "private.h"
23+
#include "private-mi.h"
2324
#include "compiler-attributes.h"
2425

2526
#define NUM_ENABLES (256u)

libnvme/src/nvme/no-mi.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// SPDX-License-Identifier: LGPL-2.1-or-later
2+
/*
3+
* This file is part of libnvme.
4+
* Copyright (c) 2026 SUSE Software Solutions
5+
*
6+
* Authors: Daniel Wagner <[email protected]>
7+
*/
8+
9+
#include <errno.h>
10+
11+
#include <libnvme.h>
12+
13+
const char *libnvme_mi_status_to_string(int status)
14+
{
15+
return "MI support disabled";
16+
}
17+
18+
int __libnvme_transport_handle_open_mi(struct libnvme_transport_handle *hdl,
19+
const char *devname)
20+
{
21+
return -ENOTSUP;
22+
}
23+
24+
int __libnvme_transport_handle_init_mi(struct libnvme_transport_handle *hdl)
25+
{
26+
return -ENOTSUP;
27+
}
28+
29+
void __libnvme_transport_handle_close_mi(struct libnvme_transport_handle *hdl)
30+
{
31+
}
32+
33+
int libnvme_mi_admin_admin_passthru(struct libnvme_transport_handle *hdl,
34+
struct libnvme_passthru_cmd *cmd)
35+
{
36+
return -ENOTSUP;
37+
}

libnvme/src/nvme/private-mi.h

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// SPDX-License-Identifier: LGPL-2.1-or-later
2+
/*
3+
* This file is part of libnvme.
4+
* Copyright (c) 2021 Code Construct Pty Ltd
5+
*
6+
* Authors: Jeremy Kerr <[email protected]>
7+
*/
8+
9+
#pragma once
10+
11+
#include <poll.h>
12+
#include <stdbool.h>
13+
#include <stddef.h>
14+
#include <time.h>
15+
16+
#include <sys/socket.h>
17+
18+
#include <ccan/list/list.h>
19+
20+
#include <nvme/mi.h>
21+
22+
/* internal transport API */
23+
struct libnvme_mi_req {
24+
struct nvme_mi_msg_hdr *hdr;
25+
size_t hdr_len;
26+
void *data;
27+
size_t data_len;
28+
__u32 mic;
29+
};
30+
31+
struct libnvme_mi_resp {
32+
struct nvme_mi_msg_hdr *hdr;
33+
size_t hdr_len;
34+
void *data;
35+
size_t data_len;
36+
__u32 mic;
37+
};
38+
39+
struct libnvme_mi_aem_ctx {
40+
struct nvme_mi_aem_occ_list_hdr *occ_header;
41+
struct nvme_mi_aem_occ_data *list_start;
42+
struct nvme_mi_aem_occ_data *list_current;
43+
int list_current_index;
44+
struct libnvme_mi_aem_config callbacks;
45+
int last_generation_num;
46+
struct libnvme_mi_event event;
47+
};
48+
49+
struct libnvme_mi_ep {
50+
struct libnvme_global_ctx *ctx;
51+
const struct libnvme_mi_transport *transport;
52+
void *transport_data;
53+
struct list_node root_entry;
54+
struct list_head controllers;
55+
bool quirks_probed;
56+
bool controllers_scanned;
57+
unsigned int timeout;
58+
unsigned int mprt_max;
59+
unsigned long quirks;
60+
61+
__u8 csi;
62+
63+
/* inter-command delay, for LIBNVME_QUIRK_MIN_INTER_COMMAND_TIME */
64+
unsigned int inter_command_us;
65+
struct timespec last_resp_time;
66+
bool last_resp_time_valid;
67+
68+
struct libnvme_mi_aem_ctx *aem_ctx;
69+
};
70+
71+
struct libnvme_mi_transport {
72+
const char *name;
73+
bool mic_enabled;
74+
int (*submit)(struct libnvme_mi_ep *ep,
75+
struct libnvme_mi_req *req,
76+
struct libnvme_mi_resp *resp);
77+
void (*close)(struct libnvme_mi_ep *ep);
78+
int (*desc_ep)(struct libnvme_mi_ep *ep, char *buf, size_t len);
79+
int (*check_timeout)(struct libnvme_mi_ep *ep, unsigned int timeout);
80+
int (*aem_fd)(struct libnvme_mi_ep *ep);
81+
int (*aem_read)(struct libnvme_mi_ep *ep,
82+
struct libnvme_mi_resp *resp);
83+
int (*aem_purge)(struct libnvme_mi_ep *ep);
84+
};
85+
86+
struct libnvme_mi_ep *libnvme_mi_init_ep(struct libnvme_global_ctx *ctx);
87+
void libnvme_mi_ep_probe(struct libnvme_mi_ep *ep);
88+
89+
/* for tests, we need to calculate the correct MICs */
90+
__u32 libnvme_mi_crc32_update(__u32 crc, void *data, size_t len);
91+
92+
/* we have a facility to mock MCTP socket operations in the mi-mctp transport,
93+
* using this ops type. This should only be used for test, and isn't exposed
94+
* in the shared lib */;
95+
struct mctp_ioc_tag_ctl;
96+
struct __mi_mctp_socket_ops {
97+
int (*msg_socket)(void);
98+
int (*aem_socket)(__u8 eid, unsigned int network);
99+
ssize_t (*sendmsg)(int, const struct msghdr *, int);
100+
ssize_t (*recvmsg)(int, struct msghdr *, int);
101+
int (*poll)(struct pollfd *, nfds_t, int);
102+
int (*ioctl_tag)(int, unsigned long, struct mctp_ioc_tag_ctl *);
103+
};
104+
void __libnvme_mi_mctp_set_ops(const struct __mi_mctp_socket_ops *newops);
105+
106+
/* quirks */
107+
108+
/* Set a minimum time between receiving a response from one command and
109+
* sending the next request. Some devices may ignore new commands sent too soon
110+
* after the previous request, so manually insert a delay
111+
*/
112+
#define LIBNVME_QUIRK_MIN_INTER_COMMAND_TIME (1 << 0)
113+
114+
/* Some devices may not support using CSI 1. Attempting to set an
115+
* endpoint to use this with these devices should return an error
116+
*/
117+
#define LIBNVME_QUIRK_CSI_1_NOT_SUPPORTED (1 << 1)
118+
119+
int __libnvme_transport_handle_open_mi(struct libnvme_transport_handle *hdl,
120+
const char *devname);
121+
int __libnvme_transport_handle_init_mi(struct libnvme_transport_handle *hdl);
122+
void __libnvme_transport_handle_close_mi(struct libnvme_transport_handle *hdl);

0 commit comments

Comments
 (0)