const char *install_commands; /* owned by kmod_config */
const char *remove_commands; /* owned by kmod_config */
char *alias; /* only set if this module was created from an alias */
+ struct kmod_file *file;
int n_dep;
int refcount;
struct {
kmod_pool_del_module(mod->ctx, mod, mod->hashkey);
kmod_module_unref_list(mod->dep);
+
+ if (mod->file)
+ kmod_file_unref(mod->file);
+
kmod_unref(mod->ctx);
free(mod->options);
free(mod->path);
}
}
+static struct kmod_elf *kmod_module_get_elf(const struct kmod_module *mod)
+{
+ if (mod->file == NULL) {
+ const char *path = kmod_module_get_path(mod);
+
+ if (path == NULL) {
+ errno = ENOENT;
+ return NULL;
+ }
+
+ ((struct kmod_module *)mod)->file = kmod_file_open(mod->ctx,
+ path);
+ if (mod->file == NULL)
+ return NULL;
+ }
+
+ return kmod_file_get_elf(mod->file);
+}
+
struct kmod_module_info {
char *key;
char value[];
*/
KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_list **list)
{
- struct kmod_file *file;
struct kmod_elf *elf;
- const char *path;
- const void *mem;
char **strings;
- size_t size;
int i, count, ret = 0;
if (mod == NULL || list == NULL)
assert(*list == NULL);
- path = kmod_module_get_path(mod);
- if (path == NULL)
- return -ENOENT;
-
- file = kmod_file_open(mod->ctx, path);
- if (file == NULL)
+ elf = kmod_module_get_elf(mod);
+ if (elf == NULL)
return -errno;
- size = kmod_file_get_size(file);
- mem = kmod_file_get_contents(file);
-
- elf = kmod_elf_new(mem, size);
- if (elf == NULL) {
- ret = -errno;
- goto elf_open_error;
- }
-
count = kmod_elf_get_strings(elf, ".modinfo", &strings);
- if (count < 0) {
- ret = count;
- goto get_strings_error;
- }
+ if (count < 0)
+ return count;
for (i = 0; i < count; i++) {
struct kmod_module_info *info;
list_error:
free(strings);
-get_strings_error:
- kmod_elf_unref(elf);
-elf_open_error:
- kmod_file_unref(file);
-
return ret;
}
*/
KMOD_EXPORT int kmod_module_get_versions(const struct kmod_module *mod, struct kmod_list **list)
{
- struct kmod_file *file;
struct kmod_elf *elf;
- const char *path;
- const void *mem;
struct kmod_modversion *versions;
- size_t size;
int i, count, ret = 0;
if (mod == NULL || list == NULL)
assert(*list == NULL);
- path = kmod_module_get_path(mod);
- if (path == NULL)
- return -ENOENT;
-
- file = kmod_file_open(mod->ctx, path);
- if (file == NULL)
+ elf = kmod_module_get_elf(mod);
+ if (elf == NULL)
return -errno;
- size = kmod_file_get_size(file);
- mem = kmod_file_get_contents(file);
-
- elf = kmod_elf_new(mem, size);
- if (elf == NULL) {
- ret = -errno;
- goto elf_open_error;
- }
-
count = kmod_elf_get_modversions(elf, &versions);
- if (count < 0) {
- ret = count;
- goto get_strings_error;
- }
+ if (count < 0)
+ return count;
for (i = 0; i < count; i++) {
struct kmod_module_version *mv;
list_error:
free(versions);
-get_strings_error:
- kmod_elf_unref(elf);
-elf_open_error:
- kmod_file_unref(file);
-
return ret;
}
*/
KMOD_EXPORT int kmod_module_get_symbols(const struct kmod_module *mod, struct kmod_list **list)
{
- struct kmod_file *file;
struct kmod_elf *elf;
- const char *path;
- const void *mem;
struct kmod_modversion *symbols;
- size_t size;
int i, count, ret = 0;
if (mod == NULL || list == NULL)
assert(*list == NULL);
- path = kmod_module_get_path(mod);
- if (path == NULL)
- return -ENOENT;
-
- file = kmod_file_open(mod->ctx, path);
- if (file == NULL)
+ elf = kmod_module_get_elf(mod);
+ if (elf == NULL)
return -errno;
- size = kmod_file_get_size(file);
- mem = kmod_file_get_contents(file);
-
- elf = kmod_elf_new(mem, size);
- if (elf == NULL) {
- ret = -errno;
- goto elf_open_error;
- }
-
count = kmod_elf_get_symbols(elf, &symbols);
- if (count < 0) {
- ret = count;
- goto get_strings_error;
- }
+ if (count < 0)
+ return count;
for (i = 0; i < count; i++) {
struct kmod_module_symbol *mv;
list_error:
free(symbols);
-get_strings_error:
- kmod_elf_unref(elf);
-elf_open_error:
- kmod_file_unref(file);
-
return ret;
}
*/
KMOD_EXPORT int kmod_module_get_dependency_symbols(const struct kmod_module *mod, struct kmod_list **list)
{
- struct kmod_file *file;
struct kmod_elf *elf;
- const char *path;
- const void *mem;
struct kmod_modversion *symbols;
- size_t size;
int i, count, ret = 0;
if (mod == NULL || list == NULL)
assert(*list == NULL);
- path = kmod_module_get_path(mod);
- if (path == NULL)
- return -ENOENT;
-
- file = kmod_file_open(mod->ctx, path);
- if (file == NULL)
+ elf = kmod_module_get_elf(mod);
+ if (elf == NULL)
return -errno;
- size = kmod_file_get_size(file);
- mem = kmod_file_get_contents(file);
-
- elf = kmod_elf_new(mem, size);
- if (elf == NULL) {
- ret = -errno;
- goto elf_open_error;
- }
-
count = kmod_elf_get_dependency_symbols(elf, &symbols);
- if (count < 0) {
- ret = count;
- goto get_strings_error;
- }
+ if (count < 0)
+ return count;
for (i = 0; i < count; i++) {
struct kmod_module_dependency_symbol *mv;
list_error:
free(symbols);
-get_strings_error:
- kmod_elf_unref(elf);
-elf_open_error:
- kmod_file_unref(file);
-
return ret;
}