]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
kmod-modprobe: migrate to kmod_module_probe_insert_module()
authorLucas De Marchi <lucas.demarchi@profusion.mobi>
Mon, 30 Jan 2012 21:01:24 +0000 (19:01 -0200)
committerLucas De Marchi <lucas.demarchi@profusion.mobi>
Tue, 31 Jan 2012 16:08:57 +0000 (14:08 -0200)
tools/kmod-modprobe.c

index 1de75990f380bf36aad1d4bab1b6b54fb8272522..af64b725504c571db3be687b7a03b175751f0696 100644 (file)
@@ -495,212 +495,6 @@ static int rmmod_all(struct kmod_ctx *ctx, char **args, int nargs)
        return err;
 }
 
-#define INSMOD_RECURSION_STEP 15
-
-static int concat_options(const char *conf_opts, const char *extra_opts,
-                                                               char **opts)
-{
-       if (conf_opts == NULL && extra_opts == NULL)
-               *opts = NULL;
-       else if (conf_opts == NULL)
-               *opts = strdup(extra_opts);
-       else if (extra_opts == NULL)
-               *opts = strdup(conf_opts);
-       else if (asprintf(opts, "%s %s", conf_opts, extra_opts) < 0)
-               return -ENOMEM;
-
-       return 0;
-}
-
-static int insmod_do_insert_module(struct kmod_module *mod, const char *opts)
-{
-       int flags = 0, err;
-
-       SHOW("insmod %s %s\n", kmod_module_get_path(mod), opts ? opts : "");
-
-       if (dry_run)
-               return 0;
-
-       if (strip_modversion || force)
-               flags |= KMOD_INSERT_FORCE_MODVERSION;
-       if (strip_vermagic || force)
-               flags |= KMOD_INSERT_FORCE_VERMAGIC;
-
-       err = kmod_module_insert_module(mod, flags, opts);
-       switch (err) {
-       case -EEXIST:
-               /*
-                * We checked for EEXIST with an earlier call to
-                * retrieve the initstate, but to avoid a race
-                * condition, we don't make any assumptions and handle
-                * the error again here
-                */
-               if (!first_time)
-                       err = 0;
-               else
-                       ERR("Module %s already in kernel.\n",
-                                       kmod_module_get_name(mod));
-               break;
-       case -EPERM:
-               ERR("could not insert '%s': %s\n", kmod_module_get_name(mod),
-                               strerror(-err));
-               break;
-       }
-
-       return err;
-
-}
-
-static bool insmod_recursion_has_loop(struct kmod_module *mod,
-                                               struct array *recursion)
-{
-       unsigned int i;
-
-       /*
-        * Don't check every time to not impact normal use cases. If the
-        * recursion hits INSMOD_RECURSION_STEP, then search loop in
-        * @recursion.
-        */
-       if ((recursion->count + 1) % INSMOD_RECURSION_STEP != 0)
-               return false;
-
-       for (i = 0; i < recursion->count; i++) {
-               if (recursion->array[i] != mod)
-                       continue;
-
-               ERR("Dependency loop detected while inserting '%s'. Operation aborted.\n",
-                                               kmod_module_get_name(mod));
-
-               for (; i < recursion->count; i++)
-                       ERR("\t%s\n", kmod_module_get_name(recursion->array[i]));
-
-               return true;
-       }
-
-       return false;
-}
-
-static int insmod_do_module(struct kmod_module *mod, const char *extra_opts,
-                               bool do_dependencies, struct array *recursion);
-
-static int insmod_do_deps_list(struct kmod_list *list,
-                               bool stop_on_errors, struct array *recursion)
-{
-       struct kmod_list *l;
-       struct kmod_module *m;
-       int r;
-
-       if (list == NULL)
-               return 0;
-
-       m = kmod_module_get_module(list);
-       r = insmod_recursion_has_loop(m, recursion);
-       kmod_module_unref(m);
-
-       if (r)
-               return -ELOOP;
-
-       kmod_list_foreach(l, list) {
-               m = kmod_module_get_module(l);
-               array_append(recursion, m);
-               r = insmod_do_module(m, NULL, false, recursion);
-               kmod_module_unref(m);
-               array_pop(recursion);
-
-               if (r == -ELOOP)
-                       return r;
-
-               if (r < 0 && stop_on_errors)
-                       return r;
-       }
-
-       return 0;
-}
-
-static int insmod_do_module(struct kmod_module *mod, const char *extra_opts,
-                               bool do_dependencies, struct array *recursion)
-{
-       const char *modname = kmod_module_get_name(mod);
-       const char *conf_opts = kmod_module_get_options(mod);
-       struct kmod_list *pre = NULL, *post = NULL;
-       const char *cmd = NULL;
-       char *opts = NULL;
-       int err;
-
-       if (!ignore_commands) {
-               err = kmod_module_get_softdeps(mod, &pre, &post);
-               if (err < 0) {
-                       WRN("could not get softdeps of '%s': %s\n",
-                                               modname, strerror(-err));
-                       return err;
-               }
-
-               cmd = kmod_module_get_install_commands(mod);
-       }
-
-       if (cmd == NULL && !ignore_loaded) {
-               int state = kmod_module_get_initstate(mod);
-
-               if (state == KMOD_MODULE_BUILTIN) {
-                       if (first_time) {
-                               err = -EEXIST;
-                               LOG("Module %s already in kernel (builtin).\n",
-                                                               modname);
-                       } else
-                               err = 0;
-
-                       goto error;
-               } else if (state == KMOD_MODULE_LIVE) {
-                       if (first_time) {
-                               err = -EEXIST;
-                               LOG("Module %s already in kernel.\n", modname);
-
-                       } else
-                               err = 0;
-
-                       goto error;
-               }
-       }
-
-       if (cmd == NULL && kmod_module_get_path(mod) == NULL) {
-               err = -ENOENT;
-               LOG("Module %s not found.\n", modname);
-               goto error;
-       }
-
-       err = insmod_do_deps_list(pre, false, recursion);
-       if (err == -ELOOP)
-               goto error;
-
-       if (do_dependencies) {
-               struct kmod_list *deps = kmod_module_get_dependencies(mod);
-
-               err = insmod_do_deps_list(deps, true, recursion);
-               if (err < 0)
-                       goto error;
-       }
-
-       if ((err = concat_options(conf_opts, extra_opts, &opts)) < 0)
-               goto error;
-
-       if (cmd == NULL)
-               err = insmod_do_insert_module(mod, opts);
-       else
-               err = command_do(mod, "install", cmd, NULL);
-
-       if (err < 0)
-               goto error;
-
-       err = insmod_do_deps_list(post, false, recursion);
-
-error:
-       kmod_module_unref_list(pre);
-       kmod_module_unref_list(post);
-       free(opts);
-
-       return err;
-}
-
 static int handle_failed_lookup(struct kmod_ctx *ctx, const char *alias)
 {
        struct kmod_module *mod;
@@ -729,11 +523,24 @@ static int handle_failed_lookup(struct kmod_ctx *ctx, const char *alias)
        return 0;
 }
 
+static void print_action(struct kmod_module *m, bool install,
+                                                       const char *options)
+{
+       if (install)
+               printf("install %s %s\n", kmod_module_get_install_commands(m),
+                                                               options);
+       else
+               printf("insmod %s %s\n", kmod_module_get_path(m), options);
+}
+
 static int insmod(struct kmod_ctx *ctx, const char *alias,
                                                const char *extra_options)
 {
        struct kmod_list *l, *list = NULL;
-       int err;
+       int err, flags = 0;
+
+       void (*show)(struct kmod_module *m, bool install,
+                                               const char *options) = NULL;
 
        err = kmod_module_new_from_lookup(ctx, alias, &list);
        if (err < 0)
@@ -742,17 +549,24 @@ static int insmod(struct kmod_ctx *ctx, const char *alias,
        if (list == NULL)
                return handle_failed_lookup(ctx, alias);
 
-       if (use_blacklist) {
-               struct kmod_list *filtered = NULL;
-               err = kmod_module_get_filtered_blacklist(ctx, list, &filtered);
-               DBG("using blacklist: input %p, output=%p\n", list, filtered);
-               kmod_module_unref_list(list);
-               if (err < 0) {
-                       LOG("could not filter alias list!\n");
-                       return err;
-               }
-               list = filtered;
-       }
+       if (strip_modversion || force)
+               flags |= KMOD_PROBE_FORCE_MODVERSION;
+       if (strip_vermagic || force)
+               flags |= KMOD_PROBE_FORCE_VERMAGIC;
+       if (ignore_commands)
+               flags |= KMOD_PROBE_IGNORE_COMMAND;
+       if (ignore_loaded)
+               flags |= KMOD_PROBE_IGNORE_LOADED;
+       if (dry_run)
+               flags |= KMOD_PROBE_DRY_RUN;
+       if (do_show || verbose > DEFAULT_VERBOSE)
+               show = &print_action;
+
+
+       if (use_blacklist)
+               flags |= KMOD_PROBE_APPLY_BLACKLIST;
+       if (first_time)
+               flags |= KMOD_PROBE_STOP_ON_ALREADY_LOADED;
 
        kmod_list_foreach(l, list) {
                struct kmod_module *mod = kmod_module_get_module(l);
@@ -760,15 +574,18 @@ static int insmod(struct kmod_ctx *ctx, const char *alias,
                if (lookup_only)
                        printf("%s\n", kmod_module_get_name(mod));
                else {
-                       struct array recursion;
+                       err = kmod_module_probe_insert_module(mod, flags,
+                                       extra_options, NULL, NULL, show);
+               }
 
-                       array_init(&recursion, INSMOD_RECURSION_STEP);
-                       err = insmod_do_module(mod, extra_options, true,
-                                                               &recursion);
-                       array_free_array(&recursion);
+               if (err == KMOD_PROBE_STOP_ON_ALREADY_LOADED) {
+                       ERR("Module %s already in kernel.\n",
+                                               kmod_module_get_name(mod));
+                       err = -EEXIST;
                }
+
                kmod_module_unref(mod);
-               if (err < 0)
+               if (err != 0)
                        break;
        }