@@ -275,7 +275,7 @@ ssize_t kmod_builtin_get_modinfo(struct kmod_ctx *ctx, const char *modname,
struct kmod_builtin_iter *iter = kmod_builtin_iter_new(ctx);
if (!iter)
- return -1;
+ return -errno;
while (!name && kmod_builtin_iter_next(iter)) {
if (!kmod_builtin_iter_get_modname(iter, buf)) {
@@ -2286,13 +2286,22 @@ KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_
assert(*list == NULL);
- elf = kmod_module_get_elf(mod);
- if (elf == NULL)
- return -errno;
+ /* remove const: this can only change internal state */
+ if (kmod_module_is_builtin((struct kmod_module *)mod)) {
+ count = kmod_builtin_get_modinfo(mod->ctx,
+ kmod_module_get_name(mod),
+ &strings);
+ if (count < 0)
+ return count;
+ } else {
+ elf = kmod_module_get_elf(mod);
+ if (elf == NULL)
+ return -errno;
- count = kmod_elf_get_strings(elf, ".modinfo", &strings);
- if (count < 0)
- return count;
+ count = kmod_elf_get_strings(elf, ".modinfo", &strings);
+ if (count < 0)
+ return count;
+ }
for (i = 0; i < count; i++) {
struct kmod_list *n;
@@ -2316,7 +2325,7 @@ KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_
goto list_error;
}
- if (kmod_module_signature_info(mod->file, &sig_info)) {
+ if (mod->file && kmod_module_signature_info(mod->file, &sig_info)) {
struct kmod_list *n;
n = kmod_module_info_append(list, "sig_id", strlen("sig_id"),
@@ -172,18 +172,33 @@ static int modinfo_do(struct kmod_module *mod)
{
struct kmod_list *l, *list = NULL;
struct param *params = NULL;
- int err;
+ int err, is_builtin;
+ const char *filename = kmod_module_get_path(mod);
+
+ is_builtin = (filename == NULL);
+
+ if (is_builtin) {
+ printf("%-16s%s%c", "name:", kmod_module_get_name(mod), separator);
+ filename = "(builtin)";
+ }
if (field != NULL && streq(field, "filename")) {
- printf("%s%c", kmod_module_get_path(mod), separator);
+ printf("%s%c", filename, separator);
return 0;
} else if (field == NULL) {
printf("%-16s%s%c", "filename:",
- kmod_module_get_path(mod), separator);
+ filename, separator);
}
err = kmod_module_get_info(mod, &list);
if (err < 0) {
+ if (is_builtin && err == -ENOENT) {
+ /*
+ * This is an old kernel that does not have a file
+ * with information about built-in modules.
+ */
+ return 0;
+ }
ERR("could not get modinfo from '%s': %s\n",
kmod_module_get_name(mod), strerror(-err));
return err;
@@ -276,7 +291,7 @@ static int modinfo_path_do(struct kmod_ctx *ctx, const char *path)
static int modinfo_alias_do(struct kmod_ctx *ctx, const char *alias)
{
- struct kmod_list *l, *filtered, *list = NULL;
+ struct kmod_list *l, *list = NULL;
int err = kmod_module_new_from_lookup(ctx, alias, &list);
if (err < 0) {
ERR("Module alias %s not found.\n", alias);
@@ -288,26 +303,14 @@ static int modinfo_alias_do(struct kmod_ctx *ctx, const char *alias)
return -ENOENT;
}
- err = kmod_module_apply_filter(ctx, KMOD_FILTER_BUILTIN, list, &filtered);
- kmod_module_unref_list(list);
- if (err < 0) {
- ERR("Failed to filter list: %m\n");
- return err;
- }
-
- if (filtered == NULL) {
- ERR("Module %s not found.\n", alias);
- return -ENOENT;
- }
-
- kmod_list_foreach(l, filtered) {
+ kmod_list_foreach(l, list) {
struct kmod_module *mod = kmod_module_get_module(l);
int r = modinfo_do(mod);
kmod_module_unref(mod);
if (r < 0)
err = r;
}
- kmod_module_unref_list(filtered);
+ kmod_module_unref_list(list);
return err;
}
Signed-off-by: Alexey Gladkov <gladkov.alexey@gmail.com> --- libkmod/libkmod-builtin.c | 2 +- libkmod/libkmod-module.c | 23 ++++++++++++++++------- tools/modinfo.c | 39 +++++++++++++++++++++------------------ 3 files changed, 38 insertions(+), 26 deletions(-)