From 4baf173b3e98a1b9742cb9fc236f7bc7770d3459 Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Wed, 8 Apr 2026 17:49:01 +0200 Subject: [PATCH] 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 --- README.md | 1 + fabrics.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ meson.build | 10 +++++++++ meson_options.txt | 6 ++++++ 4 files changed, 69 insertions(+) diff --git a/README.md b/README.md index 1a587ab57f..dd698194f3 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ built as part of nvme-cli. |---------|------------|-------| | libnvme, libnvme-mi | integrated | No external dependency, included in nvme-cli | | json-c | optional | Recommended; without it, all plugins are disabled and json-c output format is disabled | +| libkmod | optional | Without it, nvme-cli won't be able to load the nvme-fabrics module when needed | ### Build with meson diff --git a/fabrics.c b/fabrics.c index 34a71a30cd..efd5508bdd 100644 --- a/fabrics.c +++ b/fabrics.c @@ -41,6 +41,10 @@ #include +#ifdef HAVE_LIBKMOD +#include +#endif + #include "common.h" #include "nvme.h" #include "nvme-print.h" @@ -472,6 +476,50 @@ static int nvme_read_config_checked(struct libnvme_global_ctx *ctx, return libnvme_read_config(ctx, filename); } +static void load_nvme_fabrics_module(void) +{ +#ifdef HAVE_LIBKMOD + struct kmod_ctx *ctx; + struct kmod_module *mod; + int err, state; + int timeout = 20; /* 2 seconds */ + + ctx = kmod_new(NULL, NULL); + if (!ctx) + return; + + err = kmod_module_new_from_name(ctx, "nvme-fabrics", &mod); + if (err) + goto unref; + + state = kmod_module_get_initstate(mod); + if (state != KMOD_MODULE_LIVE && state != KMOD_MODULE_BUILTIN) { + err = kmod_module_probe_insert_module(mod, + KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL); + if (err) + goto mod_unref; + + while (timeout--) { + state = kmod_module_get_initstate(mod); + if (state == KMOD_MODULE_LIVE) + goto mod_unref; + + /* 100 ms */ + usleep(100 * 1000); + } + err = -ENOENT; + } + +mod_unref: + kmod_module_unref(mod); +unref: + kmod_unref(ctx); + + if (err) + fprintf(stderr, "Couldn't load the nvme-fabrics module\n"); +#endif +} + #define NBFT_SYSFS_PATH "/sys/firmware/acpi/tables" 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) nvmf_default_config(&cfg); + load_nvme_fabrics_module(); + ret = argconfig_parse(argc, argv, desc, opts); if (ret) return ret; @@ -606,6 +656,8 @@ int fabrics_connect(const char *desc, int argc, char **argv) nvmf_default_config(&cfg); + load_nvme_fabrics_module(); + ret = argconfig_parse(argc, argv, desc, opts); if (ret) return ret; diff --git a/meson.build b/meson.build index d04bf26c85..1db2c44890 100644 --- a/meson.build +++ b/meson.build @@ -54,6 +54,7 @@ want_nvme = get_option('nvme').disabled() == false want_libnvme = get_option('libnvme').disabled() == false want_fabrics = get_option('fabrics').disabled() == false and host_system != 'windows' want_json_c = get_option('json-c').disabled() == false and host_system != 'windows' +want_libkmod = get_option('libkmod').disabled() == false and host_system != 'windows' want_tests = get_option('tests') and host_system != 'windows' want_examples = get_option('examples') and host_system != 'windows' want_docs = get_option('docs') @@ -300,6 +301,13 @@ else endif conf.set('CONFIG_LIBURING', liburing_dep.found(), description: 'Is liburing available?') +if not want_libkmod + libkmod_dep = dependency('', required: false) +else + libkmod_dep = dependency('libkmod', required: get_option('libkmod')) +endif +conf.set('HAVE_LIBKMOD', libkmod_dep.found(), description: 'Is libkmod available?') + if not want_fabrics or get_option('openssl').disabled() openssl_dep = dependency('', required: false) else @@ -524,6 +532,7 @@ if want_nvme ccan_dep, libnvme_dep, json_c_dep, + libkmod_dep, ] if host_system == 'windows' @@ -678,6 +687,7 @@ dep_dict = { 'libdbus': libdbus_dep.found(), 'python3': py3_dep.found(), 'liburing': liburing_dep.found(), + 'libkmod': libkmod_dep.found(), } if host_system == 'windows' dep_dict += { diff --git a/meson_options.txt b/meson_options.txt index 88c8f364cb..d125f95ae2 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -59,6 +59,12 @@ option( value: 'auto', description: 'JSON suppport' ) +option( + 'libkmod', + type: 'feature', + value: 'auto', + description: 'libkmod support' +) option( 'nvme-tests', type : 'boolean',