Skip to content

Commit c53a114

Browse files
Martin Belangerclaude
andcommitted
nvmf: replace nvmf_get_discovery_log() with opaque-args API
Introduce struct nvmf_discovery_args as an ABI-stable opaque object with auto-generated setter/getter accessors (nvmf-accessors.{h,c,ld}). The mandatory controller argument moves to the function signature; optional parameters (timeout, max_retries, lsp) are set via accessors. Remove nvmf_get_discovery_wargs() entirely. Split the accessor generator output into a common NVMe triplet (accessors.{h,c,ld}) and an NVMe-oF-specific triplet (nvmf-accessors.{h,c,ld}) so that PCIe/embedded builds can exclude all fabrics code. The generator script is made generic; two meson targets (update-common-accessors, update-fabrics-accessors) are exposed under the update-accessors alias. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Martin Belanger <[email protected]>
1 parent a1115a7 commit c53a114

14 files changed

Lines changed: 441 additions & 161 deletions

File tree

libnvme/examples/discover-loop.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static void print_discover_log(struct nvmf_discovery_log *log)
5151

5252
int main()
5353
{
54-
struct nvmf_discovery_log *log;
54+
struct nvmf_discovery_log *log = NULL;
5555
struct libnvme_global_ctx *ctx;
5656
libnvme_host_t h;
5757
libnvme_ctrl_t c;
@@ -86,7 +86,16 @@ int main()
8686
return 1;
8787
}
8888

89-
ret = nvmf_get_discovery_log(c, &log, 4);
89+
{
90+
struct nvmf_discovery_args *dargs;
91+
92+
ret = nvmf_discovery_args_create(&dargs);
93+
if (!ret) {
94+
nvmf_discovery_args_set_max_retries(dargs, 4);
95+
ret = nvmf_get_discovery_log(c, dargs, &log);
96+
nvmf_discovery_args_free(dargs);
97+
}
98+
}
9099
libnvme_disconnect_ctrl(c);
91100
libnvme_free_ctrl(c);
92101

libnvme/libnvme/nvme.i

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -777,25 +777,22 @@ struct libnvme_ns {
777777

778778
%newobject discover;
779779
struct nvmf_discovery_log *discover(int lsp = 0, int max_retries = 6) {
780-
const char *dev;
781780
struct nvmf_discovery_log *logp = NULL;
782-
struct libnvme_get_discovery_args args = {
783-
.c = $self,
784-
.args_size = sizeof(args),
785-
.max_retries = max_retries,
786-
.result = NULL,
787-
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
788-
.lsp = lsp,
789-
};
781+
struct nvmf_discovery_args *args = NULL;
790782

791-
dev = libnvme_ctrl_get_name($self);
792-
if (!dev) {
783+
if (!libnvme_ctrl_get_name($self)) {
793784
discover_err = 1;
794785
return NULL;
795786
}
787+
discover_err = nvmf_discovery_args_create(&args);
788+
if (discover_err)
789+
return NULL;
790+
nvmf_discovery_args_set_lsp(args, lsp);
791+
nvmf_discovery_args_set_max_retries(args, max_retries);
796792
Py_BEGIN_ALLOW_THREADS /* Release Python GIL */
797-
discover_err = nvmf_get_discovery_wargs(&args, &logp);
793+
discover_err = nvmf_get_discovery_log($self, args, &logp);
798794
Py_END_ALLOW_THREADS /* Reacquire Python GIL */
795+
nvmf_discovery_args_free(args);
799796

800797
if (logp == NULL) discover_err = 2;
801798
return logp;

libnvme/src/libnvmf.ld

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ LIBNVMF_3 {
2828
nvmf_exat_ptr_next;
2929
nvmf_free_uri;
3030
nvmf_get_default_trsvcid;
31+
nvmf_discovery_args_create;
32+
nvmf_discovery_args_free;
3133
nvmf_get_discovery_log;
32-
nvmf_get_discovery_wargs;
3334
nvmf_is_registration_supported;
3435
nvmf_nbft_free;
3536
nvmf_nbft_read_files;

libnvme/src/meson.build

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,12 @@ if want_fabrics
4545
sources += [
4646
'nvme/fabrics.c',
4747
'nvme/nbft.c',
48+
'nvme/nvmf-accessors.c',
4849
]
4950
headers += [
5051
'nvme/fabrics.h',
5152
'nvme/nbft.h',
53+
'nvme/nvmf-accessors.h',
5254
]
5355
endif
5456

@@ -85,6 +87,7 @@ endif
8587
nvme_ld = meson.current_source_dir() / 'libnvme.ld'
8688
nvmf_ld = meson.current_source_dir() / 'libnvmf.ld'
8789
accessors_ld = meson.current_source_dir() / 'accessors.ld'
90+
nvmf_accessors_ld = meson.current_source_dir() / 'nvmf-accessors.ld'
8891

8992
link_args = [
9093
'-Wl,--version-script=@0@'.format(nvme_ld),
@@ -93,9 +96,12 @@ link_args = [
9396

9497
libconf = configuration_data()
9598
if want_fabrics
96-
link_args += '-Wl,--version-script=@0@'.format(nvmf_ld)
99+
link_args += [
100+
'-Wl,--version-script=@0@'.format(nvmf_ld),
101+
'-Wl,--version-script=@0@'.format(nvmf_accessors_ld),
102+
]
97103
libconf.set('FABRICS_INCLUDE',
98-
'#include <nvme/fabrics.h>\n#include <nvme/nbft.h>')
104+
'#include <nvme/fabrics.h>\n#include <nvme/nbft.h>\n#include <nvme/nvmf-accessors.h>')
99105
else
100106
libconf.set('FABRICS_INCLUDE', '')
101107
endif

libnvme/src/nvme/fabrics.c

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
#include "cleanup.h"
3838
#include "private.h"
39+
#include "private-fabrics.h"
3940
#include "compiler_attributes.h"
4041

4142
const char *nvmf_dev = "/dev/nvme-fabrics";
@@ -1297,16 +1298,19 @@ static int nvmf_connect_disc_entry(libnvme_host_t h,
12971298
*/
12981299
#define DISCOVERY_HEADER_LEN 20
12991300

1300-
static int nvme_discovery_log(const struct libnvme_get_discovery_args *args,
1301+
static int nvme_discovery_log(libnvme_ctrl_t ctrl,
1302+
const struct nvmf_discovery_args *args,
13011303
struct nvmf_discovery_log **logp)
13021304
{
1303-
struct libnvme_global_ctx *ctx = args->c->ctx;
1305+
struct libnvme_global_ctx *ctx = ctrl->ctx;
13041306
struct nvmf_discovery_log *log;
13051307
int retries = 0;
13061308
int err;
1307-
const char *name = libnvme_ctrl_get_name(args->c);
1309+
const char *name = libnvme_ctrl_get_name(ctrl);
13081310
uint64_t genctr, numrec;
1309-
struct libnvme_transport_handle *hdl = libnvme_ctrl_get_transport_handle(args->c);
1311+
struct libnvme_transport_handle *hdl;
1312+
1313+
hdl = libnvme_ctrl_get_transport_handle(ctrl);
13101314
struct libnvme_passthru_cmd cmd;
13111315

13121316
log = __libnvme_alloc(sizeof(*log));
@@ -1417,27 +1421,38 @@ static void sanitize_discovery_log_entry(struct nvmf_disc_log_entry *e)
14171421
}
14181422
}
14191423

1420-
__public int nvmf_get_discovery_log(libnvme_ctrl_t c, struct nvmf_discovery_log **logp,
1421-
int max_retries)
1424+
__public int nvmf_discovery_args_create(struct nvmf_discovery_args **argsp)
14221425
{
1423-
struct libnvme_get_discovery_args args = {
1424-
.c = c,
1425-
.max_retries = max_retries,
1426-
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
1427-
.lsp = NVMF_LOG_DISC_LSP_NONE,
1428-
};
1426+
struct nvmf_discovery_args *args;
14291427

1428+
if (!argsp)
1429+
return -EINVAL;
1430+
1431+
args = calloc(1, sizeof(*args));
1432+
if (!args)
1433+
return -ENOMEM;
14301434

1431-
return nvmf_get_discovery_wargs(&args, logp);
1435+
args->max_retries = 6;
1436+
args->timeout = NVME_DEFAULT_IOCTL_TIMEOUT;
1437+
args->lsp = NVMF_LOG_DISC_LSP_NONE;
1438+
1439+
*argsp = args;
1440+
return 0;
1441+
}
1442+
1443+
__public void nvmf_discovery_args_free(struct nvmf_discovery_args *args)
1444+
{
1445+
free(args);
14321446
}
14331447

1434-
__public int nvmf_get_discovery_wargs(struct libnvme_get_discovery_args *args,
1435-
struct nvmf_discovery_log **logp)
1448+
__public int nvmf_get_discovery_log(libnvme_ctrl_t ctrl,
1449+
struct nvmf_discovery_args *args,
1450+
struct nvmf_discovery_log **logp)
14361451
{
14371452
struct nvmf_discovery_log *log;
14381453
int err;
14391454

1440-
err = nvme_discovery_log(args, &log);
1455+
err = nvme_discovery_log(ctrl, args, &log);
14411456
if (err)
14421457
return err;
14431458

@@ -1448,6 +1463,7 @@ __public int nvmf_get_discovery_wargs(struct libnvme_get_discovery_args *args,
14481463
return 0;
14491464
}
14501465

1466+
14511467
/**
14521468
* nvmf_get_tel() - Calculate the amount of memory needed for a DIE.
14531469
* @hostsymname: Symbolic name (may be NULL)
@@ -1981,15 +1997,13 @@ static int _nvmf_discovery(struct libnvme_global_ctx *ctx,
19811997
uint64_t numrec;
19821998
int err;
19831999

1984-
struct libnvme_get_discovery_args args = {
1985-
.c = c,
1986-
.args_size = sizeof(args),
2000+
struct nvmf_discovery_args args = {
19872001
.max_retries = fctx->default_max_discovery_retries,
19882002
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
19892003
.lsp = NVMF_LOG_DISC_LSP_NONE,
19902004
};
19912005

1992-
err = nvmf_get_discovery_wargs(&args, &log);
2006+
err = nvme_discovery_log(c, &args, &log);
19932007
if (err) {
19942008
libnvme_msg(ctx, LOG_ERR, "failed to get discovery log: %s\n",
19952009
libnvme_strerror(err));
@@ -2664,15 +2678,13 @@ static int nbft_discovery(struct libnvme_global_ctx *ctx,
26642678
int ret;
26652679
int i;
26662680

2667-
struct libnvme_get_discovery_args args = {
2668-
.c = c,
2669-
.args_size = sizeof(args),
2681+
struct nvmf_discovery_args args = {
26702682
.max_retries = 10 /* MAX_DISC_RETRIES */,
26712683
.timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
26722684
.lsp = NVMF_LOG_DISC_LSP_NONE,
26732685
};
26742686

2675-
ret = nvmf_get_discovery_wargs(&args, &log);
2687+
ret = nvme_discovery_log(c, &args, &log);
26762688
if (ret) {
26772689
libnvme_msg(ctx, LOG_ERR,
26782690
"Discovery Descriptor %d: failed to get discovery log: %s\n",

libnvme/src/nvme/fabrics.h

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -232,57 +232,47 @@ int nvmf_add_ctrl(libnvme_host_t h, libnvme_ctrl_t c,
232232
*/
233233
int nvmf_connect_ctrl(libnvme_ctrl_t c);
234234

235-
/**
236-
* nvmf_get_discovery_log() - Return the discovery log page
237-
* @c: Discovery controller to use
238-
* @logp: Log page object to return
239-
* @max_retries: Number of retries in case of failure
235+
/*
236+
* struct nvmf_discovery_args - Opaque arguments for nvmf_get_discovery_log()
240237
*
241-
* The memory allocated for the log page and returned in @logp
242-
* must be freed by the caller using free().
238+
* Allocate with nvmf_discovery_args_create() and release with
239+
* nvmf_discovery_args_free(). Use the setter/getter accessors to configure
240+
* fields; do not access members directly.
241+
*/
242+
struct nvmf_discovery_args;
243+
244+
/**
245+
* nvmf_discovery_args_create() - Allocate a discovery args object
246+
* @argsp: On success, set to the newly allocated object
243247
*
244-
* Note: Consider using nvmf_get_discovery_wargs() instead.
248+
* Allocates and initialises a &struct nvmf_discovery_args with sensible
249+
* defaults. The caller must release it with nvmf_discovery_args_free().
245250
*
246-
* Return: 0 on success, or an error code on failure.
251+
* Return: 0 on success, or a negative error code on failure.
247252
*/
248-
int nvmf_get_discovery_log(libnvme_ctrl_t c, struct nvmf_discovery_log **logp,
249-
int max_retries);
250-
251-
/**
252-
* struct libnvme_get_discovery_args - Arguments for nvmf_get_discovery_wargs()
253-
* @c: Discovery controller
254-
* @args_size: Length of the structure
255-
* @max_retries: Number of retries in case of failure
256-
* @result: The command completion result from CQE dword0
257-
* @timeout: Timeout in ms (default: NVME_DEFAULT_IOCTL_TIMEOUT)
258-
* @lsp: Log specific field (See enum nvmf_log_discovery_lsp)
259-
*/
260-
struct libnvme_get_discovery_args {
261-
libnvme_ctrl_t c;
262-
int args_size;
263-
int max_retries;
264-
__u32 *result;
265-
__u32 timeout;
266-
__u8 lsp;
267-
};
253+
int nvmf_discovery_args_create(struct nvmf_discovery_args **argsp);
268254

269255
/**
270-
* nvmf_get_discovery_wargs() - Get the discovery log page with args
271-
* @args: Argument structure
272-
* @log: Discovery log page object to return
273-
*
274-
* This function is similar to nvmf_get_discovery_log(), but
275-
* takes an extensible @args parameter. @args provides more
276-
* options than nvmf_get_discovery_log().
256+
* nvmf_discovery_args_free() - Release a discovery args object
257+
* @args: Object previously returned by nvmf_discovery_args_create()
258+
*/
259+
void nvmf_discovery_args_free(struct nvmf_discovery_args *args);
260+
261+
/**
262+
* nvmf_get_discovery_log() - Fetch the NVMe-oF discovery log page
263+
* @ctrl: Discovery controller
264+
* @args: Optional arguments (pass NULL for defaults)
265+
* @logp: On success, set to the allocated log page (caller must free())
277266
*
278-
* This function performs a get discovery log page (DLP) command
279-
* and returns the DLP. The memory allocated for the returned
280-
* DLP must be freed by the caller using free().
267+
* Issues the three-phase Get Log Page protocol against @ctrl, validates
268+
* generation-counter atomicity, and normalises each log entry.
281269
*
282-
* Return: 0 on success, or an error code on failure.
270+
* Return: 0 on success, or a negative error code on failure.
283271
*/
284-
int nvmf_get_discovery_wargs(struct libnvme_get_discovery_args *args,
285-
struct nvmf_discovery_log **log);
272+
int nvmf_get_discovery_log(libnvme_ctrl_t ctrl,
273+
struct nvmf_discovery_args *args,
274+
struct nvmf_discovery_log **logp);
275+
286276

287277
/**
288278
* nvmf_is_registration_supported - check whether registration can be performed.

libnvme/src/nvme/nvmf-accessors.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// SPDX-License-Identifier: LGPL-2.1-or-later
2+
3+
/**
4+
* This file is part of libnvme.
5+
*
6+
* Copyright (c) 2025, Dell Technologies Inc. or its subsidiaries.
7+
* Authors: Martin Belanger <[email protected]>
8+
*
9+
* ____ _ _ ____ _
10+
* / ___| ___ _ __ ___ _ __ __ _| |_ ___ __| | / ___|___ __| | ___
11+
* | | _ / _ \ '_ \ / _ \ '__/ _` | __/ _ \/ _` | | | / _ \ / _` |/ _ \
12+
* | |_| | __/ | | | __/ | | (_| | || __/ (_| | | |__| (_) | (_| | __/
13+
* \____|\___|_| |_|\___|_| \__,_|\__\___|\__,_| \____\___/ \__,_|\___|
14+
*
15+
* Auto-generated struct member accessors (setter/getter)
16+
*
17+
* To update run: meson compile -C [BUILD-DIR] update-accessors
18+
* Or: make update-accessors
19+
*/
20+
#include <stdlib.h>
21+
#include <string.h>
22+
#include "nvmf-accessors.h"
23+
24+
#include "private-fabrics.h"
25+
#include "compiler_attributes.h"
26+
27+
/****************************************************************************
28+
* Accessors for: struct nvmf_discovery_args
29+
****************************************************************************/
30+
31+
__public void nvmf_discovery_args_set_max_retries(
32+
struct nvmf_discovery_args *p,
33+
int max_retries)
34+
{
35+
p->max_retries = max_retries;
36+
}
37+
38+
__public int nvmf_discovery_args_get_max_retries(
39+
const struct nvmf_discovery_args *p)
40+
{
41+
return p->max_retries;
42+
}
43+
44+
__public void nvmf_discovery_args_set_timeout(
45+
struct nvmf_discovery_args *p,
46+
__u32 timeout)
47+
{
48+
p->timeout = timeout;
49+
}
50+
51+
__public __u32 nvmf_discovery_args_get_timeout(
52+
const struct nvmf_discovery_args *p)
53+
{
54+
return p->timeout;
55+
}
56+
57+
__public void nvmf_discovery_args_set_lsp(
58+
struct nvmf_discovery_args *p,
59+
__u8 lsp)
60+
{
61+
p->lsp = lsp;
62+
}
63+
64+
__public __u8 nvmf_discovery_args_get_lsp(const struct nvmf_discovery_args *p)
65+
{
66+
return p->lsp;
67+
}
68+

0 commit comments

Comments
 (0)