Skip to content

Commit 6d68ddc

Browse files
maurizio-lombardiigaw
authored andcommitted
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 09dce4c commit 6d68ddc

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
@@ -54,6 +54,7 @@ built as part of nvme-cli.
5454
|---------|------------|-------|
5555
| libnvme, libnvme-mi | integrated | No external dependency, included in nvme-cli |
5656
| json-c | optional | Recommended; without it, all plugins are disabled and json-c output format is disabled |
57+
| libkmod | optional | Without it, nvme-cli won't be able to load the nvme-fabrics module when needed |
5758

5859
### Optional feature dependencies
5960

fabrics.c

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

3939
#include <libnvme.h>
4040

41+
#ifdef HAVE_LIBKMOD
42+
#include <libkmod.h>
43+
#endif
44+
4145
#include "common.h"
4246
#include "nvme.h"
4347
#include "nvme-print.h"
@@ -469,6 +473,50 @@ static int nvme_read_config_checked(struct libnvme_global_ctx *ctx,
469473
return libnvme_read_config(ctx, filename);
470474
}
471475

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

474522
int fabrics_discovery(const char *desc, int argc, char **argv, bool connect)
@@ -502,6 +550,8 @@ int fabrics_discovery(const char *desc, int argc, char **argv, bool connect)
502550

503551
libnvmf_default_config(&cfg);
504552

553+
load_nvme_fabrics_module();
554+
505555
ret = argconfig_parse(argc, argv, desc, opts);
506556
if (ret)
507557
return ret;
@@ -603,6 +653,8 @@ int fabrics_connect(const char *desc, int argc, char **argv)
603653

604654
libnvmf_default_config(&cfg);
605655

656+
load_nvme_fabrics_module();
657+
606658
ret = argconfig_parse(argc, argv, desc, opts);
607659
if (ret)
608660
return ret;

meson.build

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ want_libnvme = get_option('libnvme').disabled() == false
5555
want_fabrics = get_option('fabrics').disabled() == false and host_system != 'windows'
5656
want_mi = get_option('mi').disabled() == false and host_system != 'windows'
5757
want_json_c = get_option('json-c').disabled() == false and host_system != 'windows'
58+
want_libkmod = get_option('libkmod').disabled() == false and host_system != 'windows'
5859
want_tests = get_option('tests') and host_system != 'windows'
5960
want_examples = get_option('examples') and host_system != 'windows'
6061
want_docs = get_option('docs')
@@ -302,6 +303,13 @@ else
302303
endif
303304
conf.set('CONFIG_LIBURING', liburing_dep.found(), description: 'Is liburing available?')
304305

306+
if not want_libkmod
307+
libkmod_dep = dependency('', required: false)
308+
else
309+
libkmod_dep = dependency('libkmod', required: get_option('libkmod'))
310+
endif
311+
conf.set('HAVE_LIBKMOD', libkmod_dep.found(), description: 'Is libkmod available?')
312+
305313
if not want_fabrics or get_option('openssl').disabled()
306314
openssl_dep = dependency('', required: false)
307315
else
@@ -526,6 +534,7 @@ if want_nvme
526534
ccan_dep,
527535
libnvme_dep,
528536
json_c_dep,
537+
libkmod_dep,
529538
]
530539

531540
if host_system == 'windows'
@@ -680,6 +689,7 @@ dep_dict = {
680689
'libdbus': libdbus_dep.found(),
681690
'python3': py3_dep.found(),
682691
'liburing': liburing_dep.found(),
692+
'libkmod': libkmod_dep.found(),
683693
}
684694
if host_system == 'windows'
685695
dep_dict += {

meson_options.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ option(
6565
value: 'auto',
6666
description: 'JSON suppport'
6767
)
68+
option(
69+
'libkmod',
70+
type: 'feature',
71+
value: 'auto',
72+
description: 'libkmod support'
73+
)
6874
option(
6975
'nvme-tests',
7076
type : 'boolean',

0 commit comments

Comments
 (0)