diff mbox series

[2/5] libkmod: Extract finit_module vs init_module paths

Message ID 20230601224001.23397-3-lucas.de.marchi@gmail.com (mailing list archive)
State New, archived
Headers show
Series libkmod: Use kernel decompression support | expand

Commit Message

Lucas De Marchi June 1, 2023, 10:39 p.m. UTC
Extract 2 functions to handle finit_module vs init_modules differences,
with a fallback from the former to the latter.

Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
---
 libkmod/libkmod-module.c | 120 ++++++++++++++++++++++++---------------
 1 file changed, 73 insertions(+), 47 deletions(-)

Comments

Luis Chamberlain June 6, 2023, 6:27 p.m. UTC | #1
On Thu, Jun 01, 2023 at 03:39:58PM -0700, Lucas De Marchi wrote:
> Extract 2 functions to handle finit_module vs init_modules differences,
> with a fallback from the former to the latter.
> 
> Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>

Other than not checking for the error for kmod_file_load_contents()
looks good to me.

Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>

  Luis
diff mbox series

Patch

diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
index f352fe1..6ed5ad4 100644
--- a/libkmod/libkmod-module.c
+++ b/libkmod/libkmod-module.c
@@ -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;
 }