]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
depmod: Postpone creation of module array
authorJan Alexander Steffens (heftig) <jan.steffens@gmail.com>
Wed, 11 Jan 2012 22:17:38 +0000 (23:17 +0100)
committerLucas De Marchi <lucas.demarchi@profusion.mobi>
Wed, 11 Jan 2012 22:35:18 +0000 (20:35 -0200)
Deleting modules (we have found replacements) invalidates the indices
because the array collapses removed elements, hitting the assertion.

Since we don't make use of the array until the sorting step, build it from
the modules_by_name hash instead.

tools/kmod-depmod.c

index 0d12d5b37e9485be16cb1376ff49c40b8cd9d629..b964963c0ddec8d4797b5d27fdba5041044adcf5 100644 (file)
@@ -1141,16 +1141,9 @@ static int depmod_module_add(struct depmod *depmod, struct kmod_module *kmod)
        else
                mod->relpath = NULL;
 
-       err = array_append(&depmod->modules, mod);
-       if (err < 0) {
-               free(mod);
-               return err;
-       }
-
        err = hash_add_unique(depmod->modules_by_name, mod->modname, mod);
        if (err < 0) {
                ERR("hash_add_unique %s: %s\n", mod->modname, strerror(-err));
-               array_pop(&depmod->modules);
                free(mod);
                return err;
        }
@@ -1162,7 +1155,6 @@ static int depmod_module_add(struct depmod *depmod, struct kmod_module *kmod)
                        ERR("hash_add_unique %s: %s\n",
                            mod->relpath, strerror(-err));
                        hash_del(depmod->modules_by_name, mod->modname);
-                       array_pop(&depmod->modules);
                        free(mod);
                        return err;
                }
@@ -1182,9 +1174,6 @@ static int depmod_module_del(struct depmod *depmod, struct mod *mod)
 
        hash_del(depmod->modules_by_name, mod->modname);
 
-       assert(depmod->modules.array[mod->idx] == mod);
-       array_remove_at(&depmod->modules, mod->idx);
-
        mod_free(mod);
        return 0;
 }
@@ -1428,6 +1417,22 @@ static int mod_cmp(const void *pa, const void *pb) {
        return a->sort_idx - b->sort_idx;
 }
 
+static int depmod_modules_build_array(struct depmod *depmod)
+{
+       struct hash_iter module_iter;
+       const void *mod;
+       int err;
+
+       hash_iter_init(depmod->modules_by_name, &module_iter);
+       while (hash_iter_next(&module_iter, NULL, &mod)) {
+               err = array_append(&depmod->modules, mod);
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
+}
+
 static void depmod_modules_sort(struct depmod *depmod)
 {
        char order_file[PATH_MAX], line[PATH_MAX];
@@ -2711,6 +2716,13 @@ static int do_depmod(int argc, char *argv[])
                }
        }
 
+       err = depmod_modules_build_array(&depmod);
+       if (err < 0) {
+               CRIT("could not build module array: %s\n",
+                    strerror(-err));
+               goto cmdline_modules_failed;
+       }
+
        depmod_modules_sort(&depmod);
        err = depmod_load(&depmod);
        if (err < 0)