From: Lucas De Marchi <lucas.de.marchi@gmail.com>
To: linux-modules@vger.kernel.org
Cc: Luis Chamberlain <mcgrof@kernel.org>,
Lucas De Marchi <lucas.de.marchi@gmail.com>
Subject: [PATCH v2] libkmod: Do not inititialize file->memory on open
Date: Thu, 15 Jun 2023 22:00:41 -0700 [thread overview]
Message-ID: <20230616050041.99712-1-lucas.de.marchi@gmail.com> (raw)
Add a separate function to load the file contents when it's needed.
When it's not needed on the path of loading modules via finit_module(),
there is no need to mmap the file. This will help support loading
modules with the in-kernel compression support.
This is done differently than the lazy initialization for
kmod_file_get_elf() because on the contents case there is also the
file->size to be updated. It would be a weird API to return the pointer
and have the size changed as a side-effect.
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
---
v2: change kmod_file_load_contents() to void since the return is
actually checked on the file struct
libkmod/libkmod-elf.c | 5 +++++
libkmod/libkmod-file.c | 21 ++++++++++++++++++---
libkmod/libkmod-internal.h | 3 ++-
libkmod/libkmod-module.c | 2 ++
4 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/libkmod/libkmod-elf.c b/libkmod/libkmod-elf.c
index fb2e3d9..933825b 100644
--- a/libkmod/libkmod-elf.c
+++ b/libkmod/libkmod-elf.c
@@ -281,6 +281,11 @@ struct kmod_elf *kmod_elf_new(const void *memory, off_t size)
assert_cc(sizeof(uint32_t) == sizeof(Elf32_Word));
assert_cc(sizeof(uint32_t) == sizeof(Elf64_Word));
+ if (!memory) {
+ errno = -EINVAL;
+ return NULL;
+ }
+
class = elf_identify(memory, size);
if (class < 0) {
errno = -class;
diff --git a/libkmod/libkmod-file.c b/libkmod/libkmod-file.c
index b6a8cc9..08adea9 100644
--- a/libkmod/libkmod-file.c
+++ b/libkmod/libkmod-file.c
@@ -421,6 +421,7 @@ struct kmod_elf *kmod_file_get_elf(struct kmod_file *file)
if (file->elf)
return file->elf;
+ kmod_file_load_contents(file);
file->elf = kmod_elf_new(file->memory, file->size);
return file->elf;
}
@@ -431,7 +432,7 @@ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx,
struct kmod_file *file = calloc(1, sizeof(struct kmod_file));
const struct comp_type *itr;
size_t magic_size_max = 0;
- int err;
+ int err = 0;
if (file == NULL)
return NULL;
@@ -477,8 +478,8 @@ struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx,
if (file->ops == NULL)
file->ops = ®_ops;
- err = file->ops->load(file);
file->ctx = ctx;
+
error:
if (err < 0) {
if (file->fd >= 0)
@@ -491,6 +492,18 @@ error:
return file;
}
+/*
+ * Callers should just check file->memory got updated
+ */
+void kmod_file_load_contents(struct kmod_file *file)
+{
+ if (file->memory)
+ return;
+
+ /* The load functions already log possible errors. */
+ file->ops->load(file);
+}
+
void *kmod_file_get_contents(const struct kmod_file *file)
{
return file->memory;
@@ -516,7 +529,9 @@ void kmod_file_unref(struct kmod_file *file)
if (file->elf)
kmod_elf_unref(file->elf);
- file->ops->unload(file);
+ if (file->memory)
+ file->ops->unload(file);
+
if (file->fd >= 0)
close(file->fd);
free(file);
diff --git a/libkmod/libkmod-internal.h b/libkmod/libkmod-internal.h
index 4a4af58..3275bc5 100644
--- a/libkmod/libkmod-internal.h
+++ b/libkmod/libkmod-internal.h
@@ -152,6 +152,7 @@ bool kmod_module_is_builtin(struct kmod_module *mod) __attribute__((nonnull(1)))
/* libkmod-file.c */
struct kmod_file *kmod_file_open(const struct kmod_ctx *ctx, const char *filename) _must_check_ __attribute__((nonnull(1,2)));
struct kmod_elf *kmod_file_get_elf(struct kmod_file *file) __attribute__((nonnull(1)));
+void kmod_file_load_contents(struct kmod_file *file) __attribute__((nonnull(1)));
void *kmod_file_get_contents(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1)));
off_t kmod_file_get_size(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1)));
bool kmod_file_get_direct(const struct kmod_file *file) _must_check_ __attribute__((nonnull(1)));
@@ -166,7 +167,7 @@ struct kmod_modversion {
char *symbol;
};
-struct kmod_elf *kmod_elf_new(const void *memory, off_t size) _must_check_ __attribute__((nonnull(1)));
+struct kmod_elf *kmod_elf_new(const void *memory, off_t size) _must_check_;
void kmod_elf_unref(struct kmod_elf *elf) __attribute__((nonnull(1)));
const void *kmod_elf_get_memory(const struct kmod_elf *elf) _must_check_ __attribute__((nonnull(1)));
int kmod_elf_get_strings(const struct kmod_elf *elf, const char *section, char ***array) _must_check_ __attribute__((nonnull(1,2,3)));
diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
index 7736b7e..f352fe1 100644
--- a/libkmod/libkmod-module.c
+++ b/libkmod/libkmod-module.c
@@ -917,6 +917,8 @@ KMOD_EXPORT int kmod_module_insert_module(struct kmod_module *mod,
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) {
--
2.40.1
next reply other threads:[~2023-06-16 5:01 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-16 5:00 Lucas De Marchi [this message]
2023-07-24 13:29 ` [PATCH v2] libkmod: Do not inititialize file->memory on open Lucas De Marchi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230616050041.99712-1-lucas.de.marchi@gmail.com \
--to=lucas.de.marchi@gmail.com \
--cc=linux-modules@vger.kernel.org \
--cc=mcgrof@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).