summaryrefslogtreecommitdiff
path: root/testing/kmod
diff options
context:
space:
mode:
authorroot <root@rshg054.dnsready.net>2012-02-05 23:15:10 +0000
committerroot <root@rshg054.dnsready.net>2012-02-05 23:15:10 +0000
commitbdb5b3e66f6afa586ea147f69af5e4ba388f7615 (patch)
tree4374282e7b40f1decf8ecb78f004114498208361 /testing/kmod
parent359d940358dec836dd0acfe9d9caf0b1ff0a97fe (diff)
Sun Feb 5 23:15:10 UTC 2012
Diffstat (limited to 'testing/kmod')
-rw-r--r--testing/kmod/0001-partially-fix-parsing-of-alias-with-dots.patch34
-rw-r--r--testing/kmod/0002-libkmod-module-used-shared-code-in-module-creation.patch196
-rw-r--r--testing/kmod/0003-modprobe-handle-all-error-returns-from-init_module.patch34
-rw-r--r--testing/kmod/0004-modprobe-remove-0-refcnt-deps.patch52
-rw-r--r--testing/kmod/0005-continue-after-module-insert-fail.patch25
-rw-r--r--testing/kmod/0006-modprobe-remove-support-for-path-based-loading.patch79
-rw-r--r--testing/kmod/0007-modinfo-handle-arguments-more-carefully.patch86
-rw-r--r--testing/kmod/0008-Use-realpath-to-canonicalize-provided-paths.patch163
-rw-r--r--testing/kmod/PKGBUILD80
-rw-r--r--testing/kmod/depmod-search.conf5
10 files changed, 754 insertions, 0 deletions
diff --git a/testing/kmod/0001-partially-fix-parsing-of-alias-with-dots.patch b/testing/kmod/0001-partially-fix-parsing-of-alias-with-dots.patch
new file mode 100644
index 000000000..73ed7801b
--- /dev/null
+++ b/testing/kmod/0001-partially-fix-parsing-of-alias-with-dots.patch
@@ -0,0 +1,34 @@
+From 7b67a2c080e77acef0344d5a7518c07dbac830f1 Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner@archlinux.org>
+Date: Tue, 31 Jan 2012 00:12:32 -0500
+Subject: [PATCH 1/8] partially fix parsing of alias with dots
+
+---
+ libkmod/libkmod-util.c | 4 +---
+ 1 files changed, 1 insertions(+), 3 deletions(-)
+
+diff --git a/libkmod/libkmod-util.c b/libkmod/libkmod-util.c
+index 7c2611b..6a9f697 100644
+--- a/libkmod/libkmod-util.c
++++ b/libkmod/libkmod-util.c
+@@ -134,8 +134,7 @@ inline int alias_normalize(const char *alias, char buf[PATH_MAX], size_t *len)
+ case ']':
+ return -EINVAL;
+ case '[':
+- while (alias[s] != ']' &&
+- alias[s] != '.' && alias[s] != '\0')
++ while (alias[s] != ']' && alias[s] != '\0')
+ s++;
+
+ if (alias[s] != ']')
+@@ -144,7 +143,6 @@ inline int alias_normalize(const char *alias, char buf[PATH_MAX], size_t *len)
+ s++;
+ break;
+ case '\0':
+- case '.':
+ goto finish;
+ default:
+ buf[s] = c;
+--
+1.7.9
+
diff --git a/testing/kmod/0002-libkmod-module-used-shared-code-in-module-creation.patch b/testing/kmod/0002-libkmod-module-used-shared-code-in-module-creation.patch
new file mode 100644
index 000000000..7019e5132
--- /dev/null
+++ b/testing/kmod/0002-libkmod-module-used-shared-code-in-module-creation.patch
@@ -0,0 +1,196 @@
+From 133132b6129f86c1f0aabdf3e807f56ea0190f8a Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner@archlinux.org>
+Date: Tue, 31 Jan 2012 00:13:43 -0500
+Subject: [PATCH 2/8] libkmod-module: used shared code in module creation
+
+---
+ libkmod/libkmod-module.c | 135 ++++++++++++++++++++++++++-------------------
+ 1 files changed, 78 insertions(+), 57 deletions(-)
+
+diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
+index 47b1709..48e4aa1 100644
+--- a/libkmod/libkmod-module.c
++++ b/libkmod/libkmod-module.c
+@@ -162,6 +162,76 @@ fail:
+ return err;
+ }
+
++/*
++ * Memory layout with alias:
++ *
++ * struct kmod_module {
++ * hashkey -----.
++ * alias -----. |
++ * name ----. | |
++ * } | | |
++ * name <----------' | |
++ * alias <-----------' |
++ * name\alias <--------'
++ *
++ * Memory layout without alias:
++ *
++ * struct kmod_module {
++ * hashkey ---.
++ * alias -----|----> NULL
++ * name ----. |
++ * } | |
++ * name <----------'-'
++ *
++ * @key is "name\alias" or "name" (in which case alias == NULL)
++ */
++static int kmod_module_new(struct kmod_ctx *ctx, const char *key,
++ const char *name, size_t namelen,
++ const char *alias, size_t aliaslen,
++ struct kmod_module **mod)
++{
++ struct kmod_module *m;
++ size_t keylen;
++
++ m = kmod_pool_get_module(ctx, key);
++ if (m != NULL) {
++ *mod = kmod_module_ref(m);
++ return 0;
++ }
++
++ if (alias == NULL)
++ keylen = namelen;
++ else
++ keylen = namelen + aliaslen + 1;
++
++ m = malloc(sizeof(*m) + (alias == NULL ? 1 : 2) * (keylen + 1));
++ if (m == NULL) {
++ free(m);
++ return -ENOMEM;
++ }
++
++ memset(m, 0, sizeof(*m));
++
++ m->ctx = kmod_ref(ctx);
++ m->name = (char *)m + sizeof(*m);
++ memcpy(m->name, key, keylen + 1);
++ if (alias == NULL) {
++ m->hashkey = m->name;
++ m->alias = NULL;
++ } else {
++ m->name[namelen] = '\0';
++ m->alias = m->name + namelen + 1;
++ m->hashkey = m->name + keylen + 1;
++ memcpy(m->hashkey, key, keylen + 1);
++ }
++
++ m->refcount = 1;
++ kmod_pool_add_module(ctx, m, m->hashkey);
++ *mod = m;
++
++ return 0;
++}
++
+ /**
+ * kmod_module_new_from_name:
+ * @ctx: kmod library context
+@@ -188,54 +258,15 @@ KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx,
+ const char *name,
+ struct kmod_module **mod)
+ {
+- struct kmod_module *m;
+ size_t namelen;
+ char name_norm[PATH_MAX];
+- char *namesep;
+
+ if (ctx == NULL || name == NULL || mod == NULL)
+ return -ENOENT;
+
+- if (alias_normalize(name, name_norm, &namelen) < 0) {
+- DBG(ctx, "invalid alias: %s\n", name);
+- return -EINVAL;
+- }
++ modname_normalize(name, name_norm, &namelen);
+
+- m = kmod_pool_get_module(ctx, name_norm);
+- if (m != NULL) {
+- *mod = kmod_module_ref(m);
+- return 0;
+- }
+-
+- namesep = strchr(name_norm, '/');
+- m = malloc(sizeof(*m) + (namesep == NULL ? 1 : 2) * namelen + 2);
+- if (m == NULL) {
+- free(m);
+- return -ENOMEM;
+- }
+-
+- memset(m, 0, sizeof(*m));
+-
+- m->ctx = kmod_ref(ctx);
+- m->name = (char *)m + sizeof(*m);
+- memcpy(m->name, name_norm, namelen + 1);
+-
+- if (namesep) {
+- size_t len = namesep - name_norm;
+-
+- m->name[len] = '\0';
+- m->alias = m->name + len + 1;
+- m->hashkey = m->name + namelen + 1;
+- memcpy(m->hashkey, name_norm, namelen + 1);
+- } else {
+- m->hashkey = m->name;
+- }
+-
+- m->refcount = 1;
+- kmod_pool_add_module(ctx, m, m->hashkey);
+- *mod = m;
+-
+- return 0;
++ return kmod_module_new(ctx, name_norm, name_norm, namelen, NULL, 0, mod);
+ }
+
+ int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias,
+@@ -251,9 +282,9 @@ int kmod_module_new_from_alias(struct kmod_ctx *ctx, const char *alias,
+
+ memcpy(key, name, namelen);
+ memcpy(key + namelen + 1, alias, aliaslen + 1);
+- key[namelen] = '/';
++ key[namelen] = '\\';
+
+- err = kmod_module_new_from_name(ctx, key, mod);
++ err = kmod_module_new(ctx, key, name, namelen, alias, aliaslen, mod);
+ if (err < 0)
+ return err;
+
+@@ -323,7 +354,7 @@ KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx,
+ free(abspath);
+ else {
+ ERR(ctx, "kmod_module '%s' already exists with different path: new-path='%s' old-path='%s'\n",
+- name, abspath, m->path);
++ name, abspath, m->path);
+ free(abspath);
+ return -EEXIST;
+ }
+@@ -332,21 +363,11 @@ KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx,
+ return 0;
+ }
+
+- m = malloc(sizeof(*m) + namelen + 1);
+- if (m == NULL)
+- return -errno;
+-
+- memset(m, 0, sizeof(*m));
++ err = kmod_module_new(ctx, name, name, namelen, NULL, 0, &m);
++ if (err < 0)
++ return err;
+
+- m->ctx = kmod_ref(ctx);
+- m->name = (char *)m + sizeof(*m);
+- memcpy(m->name, name, namelen + 1);
+ m->path = abspath;
+- m->hashkey = m->name;
+- m->refcount = 1;
+-
+- kmod_pool_add_module(ctx, m, m->hashkey);
+-
+ *mod = m;
+
+ return 0;
+--
+1.7.9
+
diff --git a/testing/kmod/0003-modprobe-handle-all-error-returns-from-init_module.patch b/testing/kmod/0003-modprobe-handle-all-error-returns-from-init_module.patch
new file mode 100644
index 000000000..f4754c5a7
--- /dev/null
+++ b/testing/kmod/0003-modprobe-handle-all-error-returns-from-init_module.patch
@@ -0,0 +1,34 @@
+From 2e42e3b3af219575dc855971f08d8bed226ebfa8 Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner@archlinux.org>
+Date: Mon, 30 Jan 2012 23:05:26 -0500
+Subject: [PATCH 3/8] modprobe: handle all error returns from init_module
+
+---
+ tools/kmod-modprobe.c | 4 +++-
+ 1 files changed, 3 insertions(+), 1 deletions(-)
+
+diff --git a/tools/kmod-modprobe.c b/tools/kmod-modprobe.c
+index 3e51506..c882856 100644
+--- a/tools/kmod-modprobe.c
++++ b/tools/kmod-modprobe.c
+@@ -551,6 +551,8 @@ static int insmod_do_insert_module(struct kmod_module *mod, const char *opts)
+
+ err = kmod_module_insert_module(mod, flags, opts);
+ switch (err) {
++ case 0:
++ break;
+ case -EEXIST:
+ /*
+ * We checked for EEXIST with an earlier call to
+@@ -564,7 +566,7 @@ static int insmod_do_insert_module(struct kmod_module *mod, const char *opts)
+ ERR("Module %s already in kernel.\n",
+ kmod_module_get_name(mod));
+ break;
+- case -EPERM:
++ default:
+ ERR("could not insert '%s': %s\n", kmod_module_get_name(mod),
+ strerror(-err));
+ break;
+--
+1.7.9
+
diff --git a/testing/kmod/0004-modprobe-remove-0-refcnt-deps.patch b/testing/kmod/0004-modprobe-remove-0-refcnt-deps.patch
new file mode 100644
index 000000000..a76b609b8
--- /dev/null
+++ b/testing/kmod/0004-modprobe-remove-0-refcnt-deps.patch
@@ -0,0 +1,52 @@
+From f169a0c3737b8ac69499240fca8314a2bd67a0a1 Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner@archlinux.org>
+Date: Mon, 30 Jan 2012 23:39:30 -0500
+Subject: [PATCH 4/8] modprobe: remove 0 refcnt deps
+
+---
+ tools/kmod-modprobe.c | 15 +++++++++++++--
+ 1 files changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/tools/kmod-modprobe.c b/tools/kmod-modprobe.c
+index c882856..bd991a5 100644
+--- a/tools/kmod-modprobe.c
++++ b/tools/kmod-modprobe.c
+@@ -381,7 +381,7 @@ static int rmmod_do_deps_list(struct kmod_list *list, bool stop_on_errors)
+ static int rmmod_do_module(struct kmod_module *mod, bool do_dependencies)
+ {
+ const char *modname = kmod_module_get_name(mod);
+- struct kmod_list *pre = NULL, *post = NULL;
++ struct kmod_list *pre = NULL, *post = NULL, *deps, *itr;
+ const char *cmd = NULL;
+ int err;
+
+@@ -422,7 +422,7 @@ static int rmmod_do_module(struct kmod_module *mod, bool do_dependencies)
+ rmmod_do_deps_list(post, false);
+
+ if (do_dependencies && remove_dependencies) {
+- struct kmod_list *deps = kmod_module_get_dependencies(mod);
++ deps = kmod_module_get_dependencies(mod);
+
+ err = rmmod_do_deps_list(deps, true);
+ if (err < 0)
+@@ -451,6 +451,17 @@ static int rmmod_do_module(struct kmod_module *mod, bool do_dependencies)
+
+ rmmod_do_deps_list(pre, false);
+
++ deps = kmod_module_get_dependencies(mod);
++ if (deps != NULL) {
++ kmod_list_foreach_reverse(itr, deps) {
++ struct kmod_module *dep = kmod_module_get_module(itr);
++ if (kmod_module_get_refcnt(dep) == 0)
++ rmmod_do_remove_module(dep);
++ kmod_module_unref(dep);
++ }
++ kmod_module_unref_list(deps);
++ }
++
+ error:
+ kmod_module_unref_list(pre);
+ kmod_module_unref_list(post);
+--
+1.7.9
+
diff --git a/testing/kmod/0005-continue-after-module-insert-fail.patch b/testing/kmod/0005-continue-after-module-insert-fail.patch
new file mode 100644
index 000000000..cdc0c87c5
--- /dev/null
+++ b/testing/kmod/0005-continue-after-module-insert-fail.patch
@@ -0,0 +1,25 @@
+From 1f386a0e357a8916713fe26acd96206be2159157 Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner@archlinux.org>
+Date: Wed, 1 Feb 2012 20:09:27 -0500
+Subject: [PATCH 5/8] continue after module insert fail
+
+---
+ tools/kmod-modprobe.c | 2 --
+ 1 files changed, 0 insertions(+), 2 deletions(-)
+
+diff --git a/tools/kmod-modprobe.c b/tools/kmod-modprobe.c
+index bd991a5..e70bf3d 100644
+--- a/tools/kmod-modprobe.c
++++ b/tools/kmod-modprobe.c
+@@ -825,8 +825,6 @@ static int insmod_alias(struct kmod_ctx *ctx, const char *alias,
+ array_free_array(&recursion);
+ }
+ kmod_module_unref(mod);
+- if (err < 0)
+- break;
+ }
+
+ kmod_module_unref_list(list);
+--
+1.7.9
+
diff --git a/testing/kmod/0006-modprobe-remove-support-for-path-based-loading.patch b/testing/kmod/0006-modprobe-remove-support-for-path-based-loading.patch
new file mode 100644
index 000000000..b694413fb
--- /dev/null
+++ b/testing/kmod/0006-modprobe-remove-support-for-path-based-loading.patch
@@ -0,0 +1,79 @@
+From 658e2cafc2b88d1ab88f20b6183daabc113d3714 Mon Sep 17 00:00:00 2001
+From: Dave Reisner <dreisner@archlinux.org>
+Date: Sat, 4 Feb 2012 16:08:34 -0500
+Subject: [PATCH 6/8] modprobe: remove support for path based loading
+
+m-i-t doesn't support this, and it causes serious problems with local
+files clashing with alias names.
+---
+ tools/kmod-modprobe.c | 35 ++---------------------------------
+ 1 files changed, 2 insertions(+), 33 deletions(-)
+
+diff --git a/tools/kmod-modprobe.c b/tools/kmod-modprobe.c
+index e70bf3d..b9943da 100644
+--- a/tools/kmod-modprobe.c
++++ b/tools/kmod-modprobe.c
+@@ -737,27 +737,6 @@ error:
+ return err;
+ }
+
+-static int insmod_path(struct kmod_ctx *ctx, const char *path,
+- const char *extra_options)
+-{
+- struct kmod_module *mod;
+- struct array recursion;
+- int err;
+-
+- err = kmod_module_new_from_path(ctx, path, &mod);
+- if (err < 0) {
+- LOG("Module %s not found.\n", path);
+- return err;
+- }
+-
+- array_init(&recursion, INSMOD_RECURSION_STEP);
+- err = insmod_do_module(mod, extra_options, true, &recursion);
+- kmod_module_unref(mod);
+- array_free_array(&recursion);
+-
+- return err;
+-}
+-
+ static int handle_failed_lookup(struct kmod_ctx *ctx, const char *alias)
+ {
+ struct kmod_module *mod;
+@@ -831,22 +810,12 @@ static int insmod_alias(struct kmod_ctx *ctx, const char *alias,
+ return err;
+ }
+
+-static int insmod(struct kmod_ctx *ctx, const char *name,
+- const char *extra_options)
+-{
+- struct stat st;
+- if (stat(name, &st) == 0)
+- return insmod_path(ctx, name, extra_options);
+- else
+- return insmod_alias(ctx, name, extra_options);
+-}
+-
+ static int insmod_all(struct kmod_ctx *ctx, char **args, int nargs)
+ {
+ int i, err = 0;
+
+ for (i = 0; i < nargs; i++) {
+- int r = insmod(ctx, args[i], NULL);
++ int r = insmod_alias(ctx, args[i], NULL);
+ if (r < 0)
+ err = r;
+ }
+@@ -1232,7 +1201,7 @@ static int do_modprobe(int argc, char **orig_argv)
+ char *opts;
+ err = options_from_array(args, nargs, &opts);
+ if (err == 0) {
+- err = insmod(ctx, args[0], opts);
++ err = insmod_alias(ctx, args[0], opts);
+ free(opts);
+ }
+ }
+--
+1.7.9
+
diff --git a/testing/kmod/0007-modinfo-handle-arguments-more-carefully.patch b/testing/kmod/0007-modinfo-handle-arguments-more-carefully.patch
new file mode 100644
index 000000000..389008414
--- /dev/null
+++ b/testing/kmod/0007-modinfo-handle-arguments-more-carefully.patch
@@ -0,0 +1,86 @@
+From 2b77a48833818feb8cf35ffac3adcba8de503aec Mon Sep 17 00:00:00 2001
+From: Dan McGee <dan@archlinux.org>
+Date: Fri, 3 Feb 2012 20:20:21 -0600
+Subject: [PATCH 7/8] modinfo: handle arguments more carefully
+
+A simple case of breakage before this commit:
+
+ $ touch aes
+ $ modinfo aes
+ filename: /tmp/aes
+ ERROR: could not get modinfo from 'aes': Invalid argument
+
+Add a new is_module_filename() function that attempts to do more than
+just check if the passed argument is a regular file. We look at the name
+for a '.ko' string, and if that is found, ensure it is either at the end
+of the string or followed by another '.' (for .gz and .xz modules, for
+instance). We don't make this second option conditional on the way the
+tools are built with compression support; the file is a module file
+regardless and should always be treated that way.
+
+When doing this, and noticed in the test suite output, we open the
+system modules index unconditionally, even if it is never going to be
+used during the modinfo call, which is the case when passing module
+filenames directly. Delay the opening of the index file until we get an
+argument that is not a module filename.
+
+With-help-from: Dave Reisner <dreisner@archlinux.org>
+Signed-off-by: Dan McGee <dan@archlinux.org>
+---
+ tools/kmod-modinfo.c | 20 +++++++++++++++++---
+ 1 files changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/tools/kmod-modinfo.c b/tools/kmod-modinfo.c
+index 87483a5..ace5d3f 100644
+--- a/tools/kmod-modinfo.c
++++ b/tools/kmod-modinfo.c
+@@ -19,6 +19,7 @@
+
+ #include <stdio.h>
+ #include <stdlib.h>
++#include <stdbool.h>
+ #include <getopt.h>
+ #include <errno.h>
+ #include <string.h>
+@@ -332,6 +333,21 @@ static void help(const char *progname)
+ progname);
+ }
+
++static bool is_module_filename(const char *name)
++{
++ struct stat st;
++ const char *ptr;
++ if (stat(name, &st) == 0 && S_ISREG(st.st_mode) &&
++ (ptr = strstr(name, ".ko")) != NULL) {
++ /* we screened for .ko; make sure this is either at the end of the name
++ * or followed by another '.' (e.g. gz or xz modules) */
++ if(ptr[3] != '\0' && ptr[3] != '.')
++ return false;
++ return true;
++ }
++ return false;
++}
++
+ static int do_modinfo(int argc, char *argv[])
+ {
+ struct kmod_ctx *ctx;
+@@ -418,15 +434,13 @@ static int do_modinfo(int argc, char *argv[])
+ fputs("Error: kmod_new() failed!\n", stderr);
+ return EXIT_FAILURE;
+ }
+- kmod_load_resources(ctx);
+
+ err = 0;
+ for (i = optind; i < argc; i++) {
+ const char *name = argv[i];
+- struct stat st;
+ int r;
+
+- if (stat(name, &st) == 0 && S_ISREG(st.st_mode))
++ if (is_module_filename(name))
+ r = modinfo_path_do(ctx, name);
+ else
+ r = modinfo_alias_do(ctx, name);
+--
+1.7.9
+
diff --git a/testing/kmod/0008-Use-realpath-to-canonicalize-provided-paths.patch b/testing/kmod/0008-Use-realpath-to-canonicalize-provided-paths.patch
new file mode 100644
index 000000000..652d2e854
--- /dev/null
+++ b/testing/kmod/0008-Use-realpath-to-canonicalize-provided-paths.patch
@@ -0,0 +1,163 @@
+From 4148d50c980e20a71b5e284e93863b4f36f4fbe4 Mon Sep 17 00:00:00 2001
+From: Dan McGee <dan@archlinux.org>
+Date: Fri, 3 Feb 2012 15:01:34 -0600
+Subject: [PATCH 8/8] Use realpath() to canonicalize provided paths
+
+The existing function choked in several corner cases:
+* '/tmp/../tmp' was seen as absolute, so not cleaned up.
+* '/tmp/' and '/tmp' were not equal, causing depmod to act differently
+ when called with the -b option for the two paths.
+
+Don't reinvent the wheel; just use the standard library function.
+
+Signed-off-by: Dan McGee <dan@archlinux.org>
+---
+ libkmod/libkmod-module.c | 6 +++---
+ libkmod/libkmod-util.c | 36 ------------------------------------
+ libkmod/libkmod-util.h | 2 --
+ libkmod/libkmod.c | 13 +++++++++----
+ tools/kmod-depmod.c | 8 ++++++--
+ 5 files changed, 18 insertions(+), 47 deletions(-)
+
+diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c
+index 48e4aa1..48e7286 100644
+--- a/libkmod/libkmod-module.c
++++ b/libkmod/libkmod-module.c
+@@ -326,10 +326,10 @@ KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx,
+ if (ctx == NULL || path == NULL || mod == NULL)
+ return -ENOENT;
+
+- abspath = path_make_absolute_cwd(path);
++ abspath = canonicalize_file_name(path);
+ if (abspath == NULL) {
+- DBG(ctx, "no absolute path for %s\n", path);
+- return -ENOMEM;
++ DBG(ctx, "no canonical filename returned for %s\n", path);
++ return -errno;
+ }
+
+ err = stat(abspath, &st);
+diff --git a/libkmod/libkmod-util.c b/libkmod/libkmod-util.c
+index 6a9f697..02b7f63 100644
+--- a/libkmod/libkmod-util.c
++++ b/libkmod/libkmod-util.c
+@@ -301,42 +301,6 @@ char *strchr_replace(char *s, int c, char r)
+ return s;
+ }
+
+-bool path_is_absolute(const char *p)
+-{
+- assert(p != NULL);
+-
+- return p[0] == '/';
+-}
+-
+-char *path_make_absolute_cwd(const char *p)
+-{
+- char *cwd, *r;
+- size_t plen;
+- size_t cwdlen;
+-
+- if (path_is_absolute(p))
+- return strdup(p);
+-
+- cwd = get_current_dir_name();
+- if (cwd == NULL)
+- return NULL;
+-
+- plen = strlen(p);
+- cwdlen = strlen(cwd);
+-
+- /* cwd + '/' + p + '\0' */
+- r = realloc(cwd, cwdlen + 1 + plen + 1);
+- if (r == NULL) {
+- free(cwd);
+- return NULL;
+- }
+-
+- r[cwdlen] = '/';
+- memcpy(&r[cwdlen + 1], p, plen + 1);
+-
+- return r;
+-}
+-
+ #define USEC_PER_SEC 1000000ULL
+ #define NSEC_PER_USEC 1000ULL
+ unsigned long long ts_usec(const struct timespec *ts)
+diff --git a/libkmod/libkmod-util.h b/libkmod/libkmod-util.h
+index c9a1a21..63c348f 100644
+--- a/libkmod/libkmod-util.h
++++ b/libkmod/libkmod-util.h
+@@ -19,8 +19,6 @@ ssize_t write_str_safe(int fd, const char *buf, size_t buflen) __attribute__((no
+ int read_str_long(int fd, long *value, int base) __must_check __attribute__((nonnull(2)));
+ int read_str_ulong(int fd, unsigned long *value, int base) __must_check __attribute__((nonnull(2)));
+ char *strchr_replace(char *s, int c, char r);
+-bool path_is_absolute(const char *p) __must_check __attribute__((nonnull(1)));
+-char *path_make_absolute_cwd(const char *p) __must_check __attribute__((nonnull(1)));
+ int alias_normalize(const char *alias, char buf[PATH_MAX], size_t *len) __must_check __attribute__((nonnull(1,2)));
+ char *modname_normalize(const char *modname, char buf[PATH_MAX], size_t *len) __attribute__((nonnull(1, 2)));
+ char *path_to_modname(const char *path, char buf[PATH_MAX], size_t *len) __attribute__((nonnull(2)));
+diff --git a/libkmod/libkmod.c b/libkmod/libkmod.c
+index 800a178..c578afb 100644
+--- a/libkmod/libkmod.c
++++ b/libkmod/libkmod.c
+@@ -160,13 +160,18 @@ static int log_priority(const char *priority)
+
+ static const char *dirname_default_prefix = ROOTPREFIX "/lib/modules";
+
+-static char *get_kernel_release(const char *dirname)
++static char *get_kernel_release(struct kmod_ctx *ctx, const char *dirname)
+ {
+ struct utsname u;
+ char *p;
+
+- if (dirname != NULL)
+- return path_make_absolute_cwd(dirname);
++ if (dirname != NULL) {
++ p = canonicalize_file_name(dirname);
++ if (p)
++ return p;
++ INFO(ctx, "could not canonicalize directory %s: %m\n", dirname);
++ return strdup(dirname);
++ }
+
+ if (uname(&u) < 0)
+ return NULL;
+@@ -215,7 +220,7 @@ KMOD_EXPORT struct kmod_ctx *kmod_new(const char *dirname,
+ ctx->log_data = stderr;
+ ctx->log_priority = LOG_ERR;
+
+- ctx->dirname = get_kernel_release(dirname);
++ ctx->dirname = get_kernel_release(ctx, dirname);
+
+ /* environment overwrites config */
+ env = getenv("KMOD_LOG");
+diff --git a/tools/kmod-depmod.c b/tools/kmod-depmod.c
+index 0cf28f6..72180ef 100644
+--- a/tools/kmod-depmod.c
++++ b/tools/kmod-depmod.c
+@@ -1160,7 +1160,7 @@ static int depmod_module_add(struct depmod *depmod, struct kmod_module *kmod)
+ }
+ }
+
+- DBG("add %p kmod=%p, path=%s\n", mod, kmod, mod->path);
++ DBG("add %p kmod=%p, path=%s, relpath=%s\n", mod, kmod, mod->path, mod->relpath);
+
+ return 0;
+ }
+@@ -2547,7 +2547,11 @@ static int do_depmod(int argc, char *argv[])
+ maybe_all = 1;
+ break;
+ case 'b':
+- root = path_make_absolute_cwd(optarg);
++ root = canonicalize_file_name(optarg);
++ if (!root) {
++ CRIT("could not resolve path %s\n", optarg);
++ goto cmdline_failed;
++ }
+ break;
+ case 'C': {
+ size_t bytes = sizeof(char *) * (n_config_paths + 2);
+--
+1.7.9
+
diff --git a/testing/kmod/PKGBUILD b/testing/kmod/PKGBUILD
new file mode 100644
index 000000000..01f07eaaf
--- /dev/null
+++ b/testing/kmod/PKGBUILD
@@ -0,0 +1,80 @@
+# $Id: PKGBUILD 148640 2012-02-04 21:40:08Z dreisner $
+# Maintainer: Dave Reisner <dreisner@archlinux.org>
+
+pkgname=kmod
+pkgver=4
+pkgrel=3
+pkgdesc="Linux kernel module handling"
+arch=('i686' 'x86_64')
+url="http://git.profusion.mobi/cgit.cgi/kmod.git"
+license=('GPL2')
+depends=('glibc' 'zlib')
+options=('!libtool')
+provides=('module-init-tools=3.16')
+conflicts=('module-init-tools')
+replaces=('module-init-tools')
+source=("http://packages.profusion.mobi/$pkgname/$pkgname-$pkgver.tar.xz"
+ "0001-partially-fix-parsing-of-alias-with-dots.patch"
+ "0002-libkmod-module-used-shared-code-in-module-creation.patch"
+ "0003-modprobe-handle-all-error-returns-from-init_module.patch"
+ "0004-modprobe-remove-0-refcnt-deps.patch"
+ "0005-continue-after-module-insert-fail.patch"
+ "0006-modprobe-remove-support-for-path-based-loading.patch"
+ "0007-modinfo-handle-arguments-more-carefully.patch"
+ "0008-Use-realpath-to-canonicalize-provided-paths.patch"
+ "depmod-search.conf")
+md5sums=('e14450a066a48accd0af1995b3c0232d'
+ 'f5fad0e48a76abe1b1f4c7289c546f32'
+ '1b68167a077354419e5aa763f03f3c66'
+ '8836228a7ebb60b147cfba7ead75b484'
+ '92376505d9493d263fd288a403385192'
+ '90eef7d134a4ec4b5fa055c9a4d03dc8'
+ '204c1ddb3a9f95f6ce9b72cb5ac9358d'
+ 'd6edcea814f18e5233b2fdfe14ae33a3'
+ '825f550884d8dc13b760898ea5d14aed'
+ '4b8cbcbc54b9029c99fd730e257d4436')
+
+build() {
+ cd "$pkgname-$pkgver"
+
+ patch -Np1 <"$srcdir/0001-partially-fix-parsing-of-alias-with-dots.patch"
+ patch -Np1 <"$srcdir/0002-libkmod-module-used-shared-code-in-module-creation.patch"
+ patch -Np1 <"$srcdir/0003-modprobe-handle-all-error-returns-from-init_module.patch"
+ patch -Np1 <"$srcdir/0004-modprobe-remove-0-refcnt-deps.patch"
+ patch -Np1 <"$srcdir/0005-continue-after-module-insert-fail.patch"
+ patch -Np1 <"$srcdir/0006-modprobe-remove-support-for-path-based-loading.patch"
+ patch -Np1 <"$srcdir/0007-modinfo-handle-arguments-more-carefully.patch"
+ patch -Np1 <"$srcdir/0008-Use-realpath-to-canonicalize-provided-paths.patch"
+
+ ./configure \
+ --sysconfdir=/etc \
+ --with-rootprefix= \
+ --with-zlib
+
+ make
+}
+
+check() {
+ make -C "$pkgname-$pkgver" check
+}
+
+package() {
+ make -C "$pkgname-$pkgver" DESTDIR="$pkgdir" install
+
+ # binary directories
+ install -dm755 "$pkgdir"/{,s}bin
+
+ # configuration directories
+ install -dm755 "$pkgdir"/{etc,lib}/{depmod,modprobe}.d
+
+ # add symlinks to kmod
+ ln -s /usr/bin/kmod "$pkgdir/bin/lsmod"
+ for tool in {ins,rm,dep}mod mod{info,probe}; do
+ ln -s ../usr/bin/kmod "$pkgdir/sbin/$tool"
+ done
+
+ # install depmod.d file for search/ dir
+ install -Dm644 "$srcdir/depmod-search.conf" "$pkgdir/lib/depmod.d/search.conf"
+}
+
+# vim: ft=sh syn=sh et
diff --git a/testing/kmod/depmod-search.conf b/testing/kmod/depmod-search.conf
new file mode 100644
index 000000000..3feb67b05
--- /dev/null
+++ b/testing/kmod/depmod-search.conf
@@ -0,0 +1,5 @@
+#
+# /etc/depmod.d/depmod.conf
+#
+
+search updates extramodules built-in