Skip to content

Commit 4baf173

Browse files
Add nvme_fabrics module loading function
Introduce a new function to check and load the nvme_fabrics module when performing a connect/discover command, if it is not already loaded. It uses the libkmod library. Signed-off-by: Maurizio Lombardi <[email protected]>
1 parent e401e98 commit 4baf173

4 files changed

Lines changed: 69 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ built as part of nvme-cli.
4343
|---------|------------|-------|
4444
| libnvme, libnvme-mi | integrated | No external dependency, included in nvme-cli |
4545
| json-c | optional | Recommended; without it, all plugins are disabled and json-c output format is disabled |
46+
| libkmod | optional | Without it, nvme-cli won't be able to load the nvme-fabrics module when needed |
4647

4748

4849
### Build with meson

fabrics.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141

4242
#include <libnvme.h>
4343

44+
#ifdef HAVE_LIBKMOD
45+
#include <libkmod.h>
46+
#endif
47+
4448
#include "common.h"
4549
#include "nvme.h"
4650
#include "nvme-print.h"
@@ -472,6 +476,50 @@ static int nvme_read_config_checked(struct libnvme_global_ctx *ctx,
472476
return libnvme_read_config(ctx, filename);
473477
}
474478

479+
static void load_nvme_fabrics_module(void)
480+
{
481+
#ifdef HAVE_LIBKMOD
482+
struct kmod_ctx *ctx;
483+
struct kmod_module *mod;
484+
int err, state;
485+
int timeout = 20; /* 2 seconds */
486+
487+
ctx = kmod_new(NULL, NULL);
488+
if (!ctx)
489+
return;
490+
491+
err = kmod_module_new_from_name(ctx, "nvme-fabrics", &mod);
492+
if (err)
493+
goto unref;
494+
495+
state = kmod_module_get_initstate(mod);
496+
if (state != KMOD_MODULE_LIVE && state != KMOD_MODULE_BUILTIN) {
497+
err = kmod_module_probe_insert_module(mod,
498+
KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
499+
if (err)
500+
goto mod_unref;
501+
502+
while (timeout--) {
503+
state = kmod_module_get_initstate(mod);
504+
if (state == KMOD_MODULE_LIVE)
505+
goto mod_unref;
506+
507+
/* 100 ms */
508+
usleep(100 * 1000);
509+
}
510+
err = -ENOENT;
511+
}
512+
513+
mod_unref:
514+
kmod_module_unref(mod);
515+
unref:
516+
kmod_unref(ctx);
517+
518+
if (err)
519+
fprintf(stderr, "Couldn't load the nvme-fabrics module\n");
520+
#endif
521+
}
522+
475523
#define NBFT_SYSFS_PATH "/sys/firmware/acpi/tables"
476524

477525
int fabrics_discovery(const char *desc, int argc, char **argv, bool connect)
@@ -505,6 +553,8 @@ int fabrics_discovery(const char *desc, int argc, char **argv, bool connect)
505553

506554
nvmf_default_config(&cfg);
507555

556+
load_nvme_fabrics_module();
557+
508558
ret = argconfig_parse(argc, argv, desc, opts);
509559
if (ret)
510560
return ret;
@@ -606,6 +656,8 @@ int fabrics_connect(const char *desc, int argc, char **argv)
606656

607657
nvmf_default_config(&cfg);
608658

659+
load_nvme_fabrics_module();
660+
609661
ret = argconfig_parse(argc, argv, desc, opts);
610662
if (ret)
611663
return ret;

meson.build

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ want_nvme = get_option('nvme').disabled() == false
5454
want_libnvme = get_option('libnvme').disabled() == false
5555
want_fabrics = get_option('fabrics').disabled() == false and host_system != 'windows'
5656
want_json_c = get_option('json-c').disabled() == false and host_system != 'windows'
57+
want_libkmod = get_option('libkmod').disabled() == false and host_system != 'windows'
5758
want_tests = get_option('tests') and host_system != 'windows'
5859
want_examples = get_option('examples') and host_system != 'windows'
5960
want_docs = get_option('docs')
@@ -300,6 +301,13 @@ else
300301
endif
301302
conf.set('CONFIG_LIBURING', liburing_dep.found(), description: 'Is liburing available?')
302303

304+
if not want_libkmod
305+
libkmod_dep = dependency('', required: false)
306+
else
307+
libkmod_dep = dependency('libkmod', required: get_option('libkmod'))
308+
endif
309+
conf.set('HAVE_LIBKMOD', libkmod_dep.found(), description: 'Is libkmod available?')
310+
303311
if not want_fabrics or get_option('openssl').disabled()
304312
openssl_dep = dependency('', required: false)
305313
else
@@ -524,6 +532,7 @@ if want_nvme
524532
ccan_dep,
525533
libnvme_dep,
526534
json_c_dep,
535+
libkmod_dep,
527536
]
528537

529538
if host_system == 'windows'
@@ -678,6 +687,7 @@ dep_dict = {
678687
'libdbus': libdbus_dep.found(),
679688
'python3': py3_dep.found(),
680689
'liburing': liburing_dep.found(),
690+
'libkmod': libkmod_dep.found(),
681691
}
682692
if host_system == 'windows'
683693
dep_dict += {

meson_options.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ option(
5959
value: 'auto',
6060
description: 'JSON suppport'
6161
)
62+
option(
63+
'libkmod',
64+
type: 'feature',
65+
value: 'auto',
66+
description: 'libkmod support'
67+
)
6268
option(
6369
'nvme-tests',
6470
type : 'boolean',

0 commit comments

Comments
 (0)