kmod_module_probe_insert_module() is supposed to return 0 for builtin modules, but only when libkmod can locate the modules.builtin index. If the index is missing or out of sync, libkmod falls through to the real init_module() syscall and returns an error such as -ENOENT, producing a spurious "insert failure" even though the driver is already part of the running kernel.
Pre-check kmod_module_get_initstate() and short-circuit when the module is KMOD_MODULE_BUILTIN or KMOD_MODULE_LIVE, matching the pattern used by ndctl's own test/core.c. For builtin modules the local kmod reference is dropped because builtin drivers cannot be unloaded; for live modules the reference is retained in dev->module, matching the post-probe-success behavior. Signed-off-by: Chen Pei <[email protected]> --- daxctl/lib/libdaxctl.c | 18 ++++++++++++++++-- util/sysfs.c | 17 +++++++++++------ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c index ffc81eb..42bfc39 100644 --- a/daxctl/lib/libdaxctl.c +++ b/daxctl/lib/libdaxctl.c @@ -910,7 +910,7 @@ static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev, const char *devname = daxctl_dev_get_devname(dev); struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev); struct kmod_module *kmod; - int rc; + int state, rc; rc = kmod_module_new_from_name(ctx->kmod_ctx, mod_name, &kmod); if (rc < 0) { @@ -919,7 +919,21 @@ static int daxctl_insert_kmod_for_mode(struct daxctl_dev *dev, return rc; } - /* if the driver is builtin, this Just Works */ + /* If the driver is builtin or already live, skip probe-insert. */ + state = kmod_module_get_initstate(kmod); + if (state == KMOD_MODULE_BUILTIN) { + dbg(ctx, "%s: module %s is builtin\n", devname, + kmod_module_get_name(kmod)); + kmod_module_unref(kmod); + return 0; + } + if (state == KMOD_MODULE_LIVE) { + dbg(ctx, "%s: module %s already loaded\n", devname, + kmod_module_get_name(kmod)); + dev->module = kmod; + return 0; + } + dbg(ctx, "%s inserting module: %s\n", devname, kmod_module_get_name(kmod)); rc = kmod_module_probe_insert_module(kmod, diff --git a/util/sysfs.c b/util/sysfs.c index e027e38..641b86d 100644 --- a/util/sysfs.c +++ b/util/sysfs.c @@ -183,12 +183,17 @@ int __util_bind(const char *devname, struct kmod_module *module, } if (module) { - rc = kmod_module_probe_insert_module(module, - KMOD_PROBE_APPLY_BLACKLIST, - NULL, NULL, NULL, NULL); - if (rc < 0) { - log_err(ctx, "%s: insert failure: %d\n", __func__, rc); - return rc; + /* Skip probe-insert when the module is already builtin or live. */ + int state = kmod_module_get_initstate(module); + + if (state != KMOD_MODULE_BUILTIN && state != KMOD_MODULE_LIVE) { + rc = kmod_module_probe_insert_module(module, + KMOD_PROBE_APPLY_BLACKLIST, + NULL, NULL, NULL, NULL); + if (rc < 0) { + log_err(ctx, "%s: insert failure: %d\n", __func__, rc); + return rc; + } } } -- 2.43.0
