On 5/13/26 11:32 PM, Chen Pei wrote:
> 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]>
Reviewed-by: Dave Jiang <[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;
> + }
> }
> }
>