Accepting request 234279 from Base:System

(forwarded request 234278 from matwey)

OBS-URL: https://build.opensuse.org/request/show/234279
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/kmod?expand=0&rev=23
This commit is contained in:
Stephan Kulow 2014-05-18 04:49:15 +00:00 committed by Git OBS Bridge
commit 2aa462ce9f
4 changed files with 221 additions and 77 deletions

View File

@ -1,76 +0,0 @@
From 48d4d7ba1acbb5c0955f75c6bdda9cf0935240fd Mon Sep 17 00:00:00 2001
From: "Matwey V. Kornilov" <matwey.kornilov@gmail.com>
Date: Fri, 11 Apr 2014 19:43:18 +0400
Subject: [PATCH] Fix recursion loop in mod_count_all_dependencies() when
subgraph has a cycle.
When cycle is detected in mod_count_all_dependencies, use total count of
modules as an upper bound of needed memory. Correct number of nodes is determined by
subsequent call of mod_fill_all_unique_dependencies().
---
tools/depmod.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/tools/depmod.c b/tools/depmod.c
index 1aedaaf..c83dee1 100644
--- a/tools/depmod.c
+++ b/tools/depmod.c
@@ -1682,12 +1682,20 @@ static int depmod_load(struct depmod *depmod)
return 0;
}
-static size_t mod_count_all_dependencies(const struct mod *mod)
+static size_t mod_count_all_dependencies(const struct mod *mod, size_t upper_bound)
{
size_t i, count = 0;
+ /* cycle is detected */
+ if (mod->dep_loop)
+ return upper_bound;
+
for (i = 0; i < mod->deps.count; i++) {
const struct mod *d = mod->deps.array[i];
- count += 1 + mod_count_all_dependencies(d);
+ const size_t child = mod_count_all_dependencies(d, upper_bound);
+ if(child == upper_bound)
+ return child;
+
+ count += 1 + child;
}
return count;
}
@@ -1722,12 +1730,12 @@ static int mod_fill_all_unique_dependencies(const struct mod *mod, const struct
return err;
}
-static const struct mod **mod_get_all_sorted_dependencies(const struct mod *mod, size_t *n_deps)
+static const struct mod **mod_get_all_sorted_dependencies(const struct mod *mod, size_t *n_deps, size_t count)
{
const struct mod **deps;
size_t last = 0;
- *n_deps = mod_count_all_dependencies(mod);
+ *n_deps = mod_count_all_dependencies(mod, count);
if (*n_deps == 0)
return NULL;
@@ -1771,7 +1779,7 @@ static int output_deps(struct depmod *depmod, FILE *out)
if (mod->deps.count == 0)
goto end;
- deps = mod_get_all_sorted_dependencies(mod, &n_deps);
+ deps = mod_get_all_sorted_dependencies(mod, &n_deps, depmod->modules.count);
if (deps == NULL) {
ERR("could not get all sorted dependencies of %s\n", p);
goto end;
@@ -1819,7 +1827,7 @@ static int output_deps_bin(struct depmod *depmod, FILE *out)
continue;
}
- deps = mod_get_all_sorted_dependencies(mod, &n_deps);
+ deps = mod_get_all_sorted_dependencies(mod, &n_deps, depmod->modules.count);
if (deps == NULL && n_deps > 0) {
ERR("could not get all sorted dependencies of %s\n", p);
continue;
--
1.8.1.4

View File

@ -0,0 +1,214 @@
From c48b269d64e4c2e23194f0a7c20d27e7727cdf3d Mon Sep 17 00:00:00 2001
From: Lucas De Marchi <lucas.demarchi@intel.com>
Date: Fri, 9 May 2014 08:22:02 -0300
Subject: [PATCH] depmod: Make dependency loops be fatal
Since the beginning depmod just warned about dependency loops and upon
creation of modules.dep{,.bin} it skipped the modules that were part of
a loop. However just skipping the modules may come as a surprise to
kernel module developers: they will need to try to load the module (or
to pay attention to the log messages) to notice thavt the module has not
been put in the index. Also, differently from module-init-tools we were
not skipping modules that depend on modules with dependency loops,
leading to a segfault in depmod.
So this is a summary of the change in behavior with this patch:
Loop 1)
A -> B -> C -
^ |
'------------
Before:
depmod: WARNING: found 3 modules in dependency cycles!
depmod: WARNING: /tmp/test-kmod/lib/modules/3.14.2-1-ARCH/kernel/moduleB.ko in dependency cycle!
depmod: WARNING: /tmp/test-kmod/lib/modules/3.14.2-1-ARCH/kernel/moduleC.ko in dependency cycle!
depmod: WARNING: /tmp/test-kmod/lib/modules/3.14.2-1-ARCH/kernel/moduleA.ko in dependency cycle!
return code: 0
After:
depmod: ERROR: Found 3 modules in dependency cycles!
depmod: ERROR: /tmp/test-kmod/lib/modules/3.14.2-1-ARCH/kernel/moduleB.ko in dependency cycle!
depmod: ERROR: /tmp/test-kmod/lib/modules/3.14.2-1-ARCH/kernel/moduleC.ko in dependency cycle!
depmod: ERROR: /tmp/test-kmod/lib/modules/3.14.2-1-ARCH/kernel/moduleA.ko in dependency cycle!
return code: 2
Loop 2)
A -> B -> C -
^ |
'-------
Before:
depmod: WARNING: found 2 modules in dependency cycles!
depmod: WARNING: /tmp/test-kmod//lib/modules/3.14.2-1-ARCH/kernel/moduleB.ko in dependency cycle!
depmod: WARNING: /tmp/test-kmod//lib/modules/3.14.2-1-ARCH/kernel/moduleC.ko in dependency cycle!
Segmentation fault (core dumped)
After:
depmod: ERROR: Found 2 modules in dependency cycles!
depmod: ERROR: /tmp/test-kmod/lib/modules/3.14.2-1-ARCH/kernel/moduleB.ko in dependency cycle!
depmod: ERROR: /tmp/test-kmod/lib/modules/3.14.2-1-ARCH/kernel/moduleC.ko in dependency cycle!
return code: 2
The segfault above could be fixed, but let's just fail everything
because dependency cycles should be fixed in the modules rather than
just be skipped in the index.
---
tools/depmod.c | 55 +++++++++----------------------------------------------
1 file changed, 9 insertions(+), 46 deletions(-)
diff --git a/tools/depmod.c b/tools/depmod.c
index 1aedaaf..7ac1e26 100644
--- a/tools/depmod.c
+++ b/tools/depmod.c
@@ -927,7 +927,6 @@ struct mod {
int dep_sort_idx; /* topological sort index */
uint16_t idx; /* index in depmod->modules.array */
uint16_t users; /* how many modules depend on this one */
- uint8_t dep_loop : 1;
char modname[];
};
@@ -944,7 +943,6 @@ struct depmod {
struct hash *modules_by_uncrelpath;
struct hash *modules_by_name;
struct hash *symbols;
- unsigned int dep_loops;
};
static void mod_free(struct mod *mod)
@@ -1337,12 +1335,6 @@ static int depmod_modules_search(struct depmod *depmod)
static int mod_cmp(const void *pa, const void *pb) {
const struct mod *a = *(const struct mod **)pa;
const struct mod *b = *(const struct mod **)pb;
- if (a->dep_loop == b->dep_loop)
- return a->sort_idx - b->sort_idx;
- else if (a->dep_loop)
- return 1;
- else if (b->dep_loop)
- return -1;
return a->sort_idx - b->sort_idx;
}
@@ -1566,12 +1558,6 @@ static int dep_cmp(const void *pa, const void *pb)
{
const struct mod *a = *(const struct mod **)pa;
const struct mod *b = *(const struct mod **)pb;
- if (a->dep_loop == b->dep_loop)
- return a->dep_sort_idx - b->dep_sort_idx;
- else if (a->dep_loop)
- return 1;
- else if (b->dep_loop)
- return -1;
return a->dep_sort_idx - b->dep_sort_idx;
}
@@ -1592,6 +1578,7 @@ static int depmod_calculate_dependencies(struct depmod *depmod)
const struct mod **itrm;
uint16_t *users, *roots, *sorted;
uint16_t i, n_roots = 0, n_sorted = 0, n_mods = depmod->modules.count;
+ int ret = 0;
users = malloc(sizeof(uint16_t) * n_mods * 3);
if (users == NULL)
@@ -1640,27 +1627,26 @@ static int depmod_calculate_dependencies(struct depmod *depmod)
}
if (n_sorted < n_mods) {
- WRN("found %u modules in dependency cycles!\n",
+ ERR("Found %u modules in dependency cycles!\n",
n_mods - n_sorted);
+ ret = -EINVAL;
for (i = 0; i < n_mods; i++) {
struct mod *m;
if (users[i] == 0)
continue;
m = depmod->modules.array[i];
- WRN("%s in dependency cycle!\n", m->path);
- m->dep_loop = 1;
- m->dep_sort_idx = INT32_MAX;
- depmod->dep_loops++;
+ ERR("%s in dependency cycle!\n", m->path);
}
+ goto exit;
}
depmod_sort_dependencies(depmod);
- DBG("calculated dependencies and ordering (%u loops, %hu modules)\n",
- depmod->dep_loops, n_mods);
+ DBG("calculated dependencies and ordering (%hu modules)\n", n_mods);
+exit:
free(users);
- return 0;
+ return ret;
}
static int depmod_load(struct depmod *depmod)
@@ -1761,11 +1747,6 @@ static int output_deps(struct depmod *depmod, FILE *out)
const char *p = mod_get_compressed_path(mod);
size_t j, n_deps;
- if (mod->dep_loop) {
- DBG("Ignored %s due dependency loops\n", p);
- continue;
- }
-
fprintf(out, "%s:", p);
if (mod->deps.count == 0)
@@ -1779,12 +1760,6 @@ static int output_deps(struct depmod *depmod, FILE *out)
for (j = 0; j < n_deps; j++) {
const struct mod *d = deps[j];
- if (d->dep_loop) {
- DBG("Ignored %s (dependency of %s) "
- "due dependency loops\n",
- mod_get_compressed_path(d), p);
- continue;
- }
fprintf(out, " %s", mod_get_compressed_path(d));
}
free(deps);
@@ -1814,11 +1789,6 @@ static int output_deps_bin(struct depmod *depmod, FILE *out)
size_t j, n_deps, linepos, linelen, slen;
int duplicate;
- if (mod->dep_loop) {
- DBG("Ignored %s due dependency loops\n", p);
- continue;
- }
-
deps = mod_get_all_sorted_dependencies(mod, &n_deps);
if (deps == NULL && n_deps > 0) {
ERR("could not get all sorted dependencies of %s\n", p);
@@ -1828,12 +1798,6 @@ static int output_deps_bin(struct depmod *depmod, FILE *out)
linelen = strlen(p) + 1;
for (j = 0; j < n_deps; j++) {
const struct mod *d = deps[j];
- if (d->dep_loop) {
- DBG("Ignored %s (dependency of %s) "
- "due dependency loops\n",
- mod_get_compressed_path(d), p);
- continue;
- }
linelen += 1 + strlen(mod_get_compressed_path(d));
}
@@ -1854,8 +1818,7 @@ static int output_deps_bin(struct depmod *depmod, FILE *out)
for (j = 0; j < n_deps; j++) {
const struct mod *d = deps[j];
const char *dp;
- if (d->dep_loop)
- continue;
+
line[linepos] = ' ';
linepos++;
--
1.8.1.4

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Fri May 16 11:00:43 UTC 2014 - matwey.kornilov@gmail.com
- Remove 0001-Fix-recursion-loop-in-mod_count_all_dependencies-whe.patch
- Add 0001-depmod-Make-dependency-loops-be-fatal.patch (upstream fix for bnc#872715)
-------------------------------------------------------------------
Sat Apr 12 12:33:16 UTC 2014 - matwey.kornilov@gmail.com

View File

@ -30,7 +30,7 @@ Url: http://www.jonmasters.org/blog/2011/12/20/libkmod-replaces-modul
#Git-Clone: git://git.kernel.org/pub/scm/utils/kernel/kmod/kmod
Source: ftp://ftp.kernel.org/pub/linux/utils/kernel/kmod/%name-%version.tar.xz
Source2: ftp://ftp.kernel.org/pub/linux/utils/kernel/kmod/%name-%version.tar.sign
Patch1: 0001-Fix-recursion-loop-in-mod_count_all_dependencies-whe.patch
Patch1: 0001-depmod-Make-dependency-loops-be-fatal.patch
Patch2: 0002-modprobe-Recognize-allow-unsupported-modules-on-comm.patch
Patch3: 0003-libkmod-config-Recognize-allow_unsupported_modules-i.patch
Patch9: 0009-libkmod-Implement-filtering-of-unsupported-modules-o.patch