return -EEXIST;
}
- *mod = kmod_module_ref(m);
- return 0;
- }
+ kmod_module_ref(m);
+ } else {
+ err = kmod_module_new(ctx, name, name, namelen, NULL, 0, &m);
+ if (err < 0) {
+ free(abspath);
+ return err;
+ }
- err = kmod_module_new(ctx, name, name, namelen, NULL, 0, &m);
- if (err < 0) {
- free(abspath);
- return err;
+ m->path = abspath;
}
- m->path = abspath;
+ m->builtin = KMOD_MODULE_BUILTIN_NO;
*mod = m;
return 0;
err = kmod_lookup_alias_from_aliases_file(ctx, alias, list);
CHECK_ERR_AND_FINISH(err, fail, list, finish);
- DBG(ctx, "lookup modules.builtin %s\n", alias);
- err = kmod_lookup_alias_from_builtin_file(ctx, alias, list);
+ DBG(ctx, "lookup modules.builtin.modinfo %s\n", alias);
+ err = kmod_lookup_alias_from_kernel_builtin_file(ctx, alias, list);
+ if (err == -ENOSYS) {
+ /* Optional index missing, try the old one */
+ DBG(ctx, "lookup modules.builtin %s\n", alias);
+ err = kmod_lookup_alias_from_builtin_file(ctx, alias, list);
+ }
CHECK_ERR_AND_FINISH(err, fail, list, finish);
+
finish:
DBG(ctx, "lookup %s=%d, list=%p\n", alias, err, *list);
return err;
err = system(cmd);
unsetenv("MODPROBE_MODULE");
- if (err == -1 || WEXITSTATUS(err)) {
- ERR(mod->ctx, "Error running %s command for %s\n",
- type, modname);
- if (err != -1)
- err = -WEXITSTATUS(err);
+ if (err == -1) {
+ ERR(mod->ctx, "Could not run %s command '%s' for module %s: %m\n",
+ type, cmd, modname);
+ return -EINVAL;
}
- return err;
+ if (WEXITSTATUS(err)) {
+ ERR(mod->ctx, "Error running %s command '%s' for module %s: retcode %d\n",
+ type, cmd, modname, WEXITSTATUS(err));
+ return -EINVAL;
+ }
+
+ return 0;
}
struct probe_insert_cb {
*
* After use, free the @list by calling kmod_module_info_free_list().
*
- * Returns: 0 on success or < 0 otherwise.
+ * Returns: number of entries in @list on success or < 0 otherwise.
*/
KMOD_EXPORT int kmod_module_get_info(const struct kmod_module *mod, struct kmod_list **list)
{
struct kmod_elf *elf;
char **strings;
int i, count, ret = -ENOMEM;
- struct kmod_signature_info sig_info;
+ struct kmod_signature_info sig_info = {};
if (mod == NULL || list == NULL)
return -ENOENT;
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;
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"),
ret = count;
list_error:
+ /* aux structures freed in normal case also */
+ kmod_module_signature_info_free(&sig_info);
+
if (ret < 0) {
kmod_module_info_free_list(*list);
*list = NULL;
list = kmod_list_remove(list);
}
}
+
+/**
+ * kmod_module_get_builtin:
+ * @ctx: kmod library context
+ * @list: where to save the builtin module list
+ *
+ * Returns: 0 on success or < 0 otherwise.
+ */
+int kmod_module_get_builtin(struct kmod_ctx *ctx, struct kmod_list **list)
+{
+ struct kmod_builtin_iter *iter;
+ int err = 0;
+
+ iter = kmod_builtin_iter_new(ctx);
+ if (!iter)
+ return -errno;
+
+ while (kmod_builtin_iter_next(iter)) {
+ struct kmod_module *mod = NULL;
+ char modname[PATH_MAX];
+
+ if (!kmod_builtin_iter_get_modname(iter, modname)) {
+ err = -errno;
+ goto fail;
+ }
+
+ err = kmod_module_new_from_name(ctx, modname, &mod);
+ if (err < 0)
+ goto fail;
+
+ kmod_module_set_builtin(mod, true);
+
+ *list = kmod_list_append(*list, mod);
+ }
+
+ kmod_builtin_iter_free(iter);
+ return err;
+fail:
+ kmod_builtin_iter_free(iter);
+ kmod_module_unref_list(*list);
+ *list = NULL;
+ return err;
+}