]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
libkmod: Extract finit_module vs init_module paths
authorLucas De Marchi <lucas.de.marchi@gmail.com>
Thu, 1 Jun 2023 22:39:58 +0000 (15:39 -0700)
committerLucas De Marchi <lucas.de.marchi@gmail.com>
Fri, 9 Jun 2023 17:45:55 +0000 (10:45 -0700)
Extract 2 functions to handle finit_module vs init_modules differences,
with a fallback from the former to the latter.

Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
libkmod/libkmod-module.c

index f352fe12dcf1c0a7b6d160e30f4c2bacbdb6975c..6ed5ad4278e0a5c40c3584df0eedd528643d06c6 100644 (file)
@@ -861,6 +861,73 @@ KMOD_EXPORT int kmod_module_remove_module(struct kmod_module *mod,
 
 extern long init_module(const void *mem, unsigned long len, const char *args);
 
+static int do_finit_module(struct kmod_module *mod, unsigned int flags,
+                          const char *args)
+{
+       unsigned int kernel_flags = 0;
+       int err;
+
+       /*
+        * Re-use ENOSYS, returned when there is no such syscall, so the
+        * fallback to init_module applies
+        */
+       if (!kmod_file_get_direct(mod->file))
+               return -ENOSYS;
+
+       if (flags & KMOD_INSERT_FORCE_VERMAGIC)
+               kernel_flags |= MODULE_INIT_IGNORE_VERMAGIC;
+       if (flags & KMOD_INSERT_FORCE_MODVERSION)
+               kernel_flags |= MODULE_INIT_IGNORE_MODVERSIONS;
+
+       err = finit_module(kmod_file_get_fd(mod->file), args, kernel_flags);
+       if (err < 0)
+               err = -errno;
+
+       return err;
+}
+
+static int do_init_module(struct kmod_module *mod, unsigned int flags,
+                         const char *args)
+{
+       struct kmod_elf *elf;
+       const void *mem;
+       off_t size;
+       int err;
+
+       kmod_file_load_contents(mod->file);
+
+       if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) {
+               elf = kmod_file_get_elf(mod->file);
+               if (elf == NULL) {
+                       err = -errno;
+                       return err;
+               }
+
+               if (flags & KMOD_INSERT_FORCE_MODVERSION) {
+                       err = kmod_elf_strip_section(elf, "__versions");
+                       if (err < 0)
+                               INFO(mod->ctx, "Failed to strip modversion: %s\n", strerror(-err));
+               }
+
+               if (flags & KMOD_INSERT_FORCE_VERMAGIC) {
+                       err = kmod_elf_strip_vermagic(elf);
+                       if (err < 0)
+                               INFO(mod->ctx, "Failed to strip vermagic: %s\n", strerror(-err));
+               }
+
+               mem = kmod_elf_get_memory(elf);
+       } else {
+               mem = kmod_file_get_contents(mod->file);
+       }
+       size = kmod_file_get_size(mod->file);
+
+       err = init_module(mem, size, args);
+       if (err < 0)
+               err = -errno;
+
+       return err;
+}
+
 /**
  * kmod_module_insert_module:
  * @mod: kmod module
@@ -881,9 +948,6 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
                                                        const char *options)
 {
        int err;
-       const void *mem;
-       off_t size;
-       struct kmod_elf *elf;
        const char *path;
        const char *args = options ? options : "";
 
@@ -904,52 +968,14 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
                }
        }
 
-       if (kmod_file_get_direct(mod->file)) {
-               unsigned int kernel_flags = 0;
-
-               if (flags & KMOD_INSERT_FORCE_VERMAGIC)
-                       kernel_flags |= MODULE_INIT_IGNORE_VERMAGIC;
-               if (flags & KMOD_INSERT_FORCE_MODVERSION)
-                       kernel_flags |= MODULE_INIT_IGNORE_MODVERSIONS;
-
-               err = finit_module(kmod_file_get_fd(mod->file), args, kernel_flags);
-               if (err == 0 || errno != ENOSYS)
-                       goto init_finished;
-       }
-
-       kmod_file_load_contents(mod->file);
-
-       if (flags & (KMOD_INSERT_FORCE_VERMAGIC | KMOD_INSERT_FORCE_MODVERSION)) {
-               elf = kmod_file_get_elf(mod->file);
-               if (elf == NULL) {
-                       err = -errno;
-                       return err;
-               }
+       err = do_finit_module(mod, flags, args);
+       if (err == -ENOSYS)
+               err = do_init_module(mod, flags, args);
 
-               if (flags & KMOD_INSERT_FORCE_MODVERSION) {
-                       err = kmod_elf_strip_section(elf, "__versions");
-                       if (err < 0)
-                               INFO(mod->ctx, "Failed to strip modversion: %s\n", strerror(-err));
-               }
-
-               if (flags & KMOD_INSERT_FORCE_VERMAGIC) {
-                       err = kmod_elf_strip_vermagic(elf);
-                       if (err < 0)
-                               INFO(mod->ctx, "Failed to strip vermagic: %s\n", strerror(-err));
-               }
-
-               mem = kmod_elf_get_memory(elf);
-       } else {
-               mem = kmod_file_get_contents(mod->file);
-       }
-       size = kmod_file_get_size(mod->file);
+       if (err < 0)
+               INFO(mod->ctx, "Failed to insert module '%s': %s\n",
+                    path, strerror(-err));
 
-       err = init_module(mem, size, args);
-init_finished:
-       if (err < 0) {
-               err = -errno;
-               INFO(mod->ctx, "Failed to insert module '%s': %m\n", path);
-       }
        return err;
 }