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;
> +                     }
>               }
>       }
>  


Reply via email to