]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
testsuite: add tests for weak dependencies
authorJose Ignacio Tornos Martinez <jtornosm@redhat.com>
Thu, 30 May 2024 07:08:27 +0000 (09:08 +0200)
committerLucas De Marchi <lucas.de.marchi@gmail.com>
Fri, 14 Jun 2024 19:16:17 +0000 (14:16 -0500)
The following tests to verify weak dependencies have been implemented:
1) modprobe test to check that related weakdep modules are not loaded
   due to being a weakdep.
2) depmod test to check weakdep output.
3) user test to check that configuration files with weakdep are parsed
   correctly and related weakdep modules can be read correctly from user
   applications.

Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
Link: https://lore.kernel.org/r/20240530070836.9438-1-jtornosm@redhat.com
[ Minor whitespace issues and define MODULE_WEAKDEP if it's not defined
  already ]
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
36 files changed:
Makefile.am
testsuite/.gitignore
testsuite/module-playground/Makefile
testsuite/module-playground/mod-weakdep.c [new file with mode: 0644]
testsuite/rootfs-pristine/test-depmod/check-weakdep/lib/modules/4.4.4/correct-modules.weakdep [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/weakdep-loop/etc/modprobe.d/dumb-weakdep.conf [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.alias [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.alias.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.builtin.alias.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.builtin.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.dep [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.dep.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.devname [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.softdep [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.symbols [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.symbols.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.weakdep [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/correct-weakdep.txt [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/etc/modprobe.d/dumb-weakdep.conf [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.alias [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.alias.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.builtin.alias.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.builtin.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.dep [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.dep.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.devname [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.softdep [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.symbols [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.symbols.bin [new file with mode: 0644]
testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.weakdep [new file with mode: 0644]
testsuite/setup-rootfs.sh
testsuite/test-depmod.c
testsuite/test-modprobe.c
testsuite/test-user.c [new file with mode: 0644]
testsuite/testsuite.c
testsuite/testsuite.h

index e2e2411188cf261d7cfb796b5b58aa3909e8ec7a..4b67ee28db9f19039bf6a059a9bb6f2f3431547c 100644 (file)
@@ -262,7 +262,7 @@ TESTSUITE = \
        testsuite/test-modinfo testsuite/test-util testsuite/test-new-module \
        testsuite/test-modprobe testsuite/test-blacklist \
        testsuite/test-dependencies testsuite/test-depmod \
-       testsuite/test-list
+       testsuite/test-list testsuite/test-user
 
 check_PROGRAMS = $(TESTSUITE)
 TESTS = $(TESTSUITE)
@@ -305,6 +305,8 @@ testsuite_test_depmod_LDADD = $(TESTSUITE_LDADD)
 testsuite_test_depmod_CPPFLAGS = $(TESTSUITE_CPPFLAGS)
 testsuite_test_list_LDADD = $(TESTSUITE_LDADD)
 testsuite_test_list_CPPFLAGS = $(TESTSUITE_CPPFLAGS)
+testsuite_test_user_LDADD = $(TESTSUITE_LDADD)
+testsuite_test_user_CPPFLAGS = $(TESTSUITE_CPPFLAGS)
 
 testsuite-distclean:
        $(RM) -r $(ROOTFS)
index 5465b1a0cf4126b088b522b6165a8b15fef22998..56d628e0a46c5a73751ba052cc436b47e700e28c 100644 (file)
@@ -18,6 +18,7 @@
 /test-modprobe
 /test-hash
 /test-list
+/test-user
 /rootfs
 /stamp-rootfs
 /test-scratchbuf.log
@@ -52,3 +53,5 @@
 /test-testsuite.trs
 /test-list.log
 /test-list.trs
+/test-user.log
+/test-user.trs
index a7ab09bea2bfa5ccaca5e2c0642301c115c82d24..42c750b30bd83dfb9f81bdec86a70fae3532202a 100644 (file)
@@ -37,6 +37,8 @@ obj-m += mod-fake-hpsa.o
 obj-m += mod-fake-scsi-mod.o
 obj-m += mod-fake-cciss.o
 
+obj-m += mod-weakdep.o
+
 else
 # only build ARCH-specific module
 ifeq ($(ARCH),)
diff --git a/testsuite/module-playground/mod-weakdep.c b/testsuite/module-playground/mod-weakdep.c
new file mode 100644 (file)
index 0000000..7eca7cf
--- /dev/null
@@ -0,0 +1,19 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+#ifndef MODULE_WEAKDEP
+#define MODULE_WEAKDEP(_weakdep) MODULE_INFO(weakdep, _weakdep)
+#endif
+
+static int __init weakdep_init(void)
+{
+       return 0;
+}
+
+module_init(weakdep_init);
+
+MODULE_AUTHOR("Jose Ignacio Tornos Martinez <jtornosm@redhat.com>");
+MODULE_LICENSE("LGPL");
+MODULE_WEAKDEP("mod-simple");
diff --git a/testsuite/rootfs-pristine/test-depmod/check-weakdep/lib/modules/4.4.4/correct-modules.weakdep b/testsuite/rootfs-pristine/test-depmod/check-weakdep/lib/modules/4.4.4/correct-modules.weakdep
new file mode 100644 (file)
index 0000000..00777b8
--- /dev/null
@@ -0,0 +1,2 @@
+# Weak dependencies extracted from modules themselves.
+weakdep mod_weakdep mod-simple
diff --git a/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/etc/modprobe.d/dumb-weakdep.conf b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/etc/modprobe.d/dumb-weakdep.conf
new file mode 100644 (file)
index 0000000..181714a
--- /dev/null
@@ -0,0 +1 @@
+weakdep mod-loop-b mod-loop-a mod-simple
diff --git a/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.alias b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.alias
new file mode 100644 (file)
index 0000000..ba76e18
--- /dev/null
@@ -0,0 +1 @@
+# Aliases extracted from modules themselves.
diff --git a/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.alias.bin b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.alias.bin
new file mode 100644 (file)
index 0000000..7075435
Binary files /dev/null and b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.alias.bin differ
diff --git a/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.builtin.alias.bin b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.builtin.alias.bin
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.builtin.bin b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.builtin.bin
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.dep b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.dep
new file mode 100644 (file)
index 0000000..9207182
--- /dev/null
@@ -0,0 +1,3 @@
+kernel/mod-loop-b.ko:
+kernel/mod-loop-a.ko:
+kernel/mod-simple.ko:
diff --git a/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.dep.bin b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.dep.bin
new file mode 100644 (file)
index 0000000..418d583
Binary files /dev/null and b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.dep.bin differ
diff --git a/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.devname b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.devname
new file mode 100644 (file)
index 0000000..58f6d6d
--- /dev/null
@@ -0,0 +1 @@
+# Device nodes to trigger on-demand module loading.
diff --git a/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.softdep b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.softdep
new file mode 100644 (file)
index 0000000..5554ccc
--- /dev/null
@@ -0,0 +1 @@
+# Soft dependencies extracted from modules themselves.
diff --git a/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.symbols b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.symbols
new file mode 100644 (file)
index 0000000..6c53580
--- /dev/null
@@ -0,0 +1,3 @@
+# Aliases for symbols, used by symbol_request().
+alias symbol:printB mod_loop_b
+alias symbol:printA mod_loop_a
diff --git a/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.symbols.bin b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.symbols.bin
new file mode 100644 (file)
index 0000000..27c5f43
Binary files /dev/null and b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.symbols.bin differ
diff --git a/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.weakdep b/testsuite/rootfs-pristine/test-modprobe/weakdep-loop/lib/modules/4.4.4/modules.weakdep
new file mode 100644 (file)
index 0000000..569696d
--- /dev/null
@@ -0,0 +1 @@
+# Weak dependencies extracted from modules themselves.
diff --git a/testsuite/rootfs-pristine/test-user/correct-weakdep.txt b/testsuite/rootfs-pristine/test-user/correct-weakdep.txt
new file mode 100644 (file)
index 0000000..ac09f8d
--- /dev/null
@@ -0,0 +1,2 @@
+mod-loop-b: mod_loop_a mod_simple
+mod-weakdep: mod_simple
diff --git a/testsuite/rootfs-pristine/test-user/etc/modprobe.d/dumb-weakdep.conf b/testsuite/rootfs-pristine/test-user/etc/modprobe.d/dumb-weakdep.conf
new file mode 100644 (file)
index 0000000..181714a
--- /dev/null
@@ -0,0 +1 @@
+weakdep mod-loop-b mod-loop-a mod-simple
diff --git a/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.alias b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.alias
new file mode 100644 (file)
index 0000000..ba76e18
--- /dev/null
@@ -0,0 +1 @@
+# Aliases extracted from modules themselves.
diff --git a/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.alias.bin b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.alias.bin
new file mode 100644 (file)
index 0000000..7075435
Binary files /dev/null and b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.alias.bin differ
diff --git a/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.builtin.alias.bin b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.builtin.alias.bin
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.builtin.bin b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.builtin.bin
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.dep b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.dep
new file mode 100644 (file)
index 0000000..3ffbd6b
--- /dev/null
@@ -0,0 +1,4 @@
+kernel/mod-weakdep.ko:
+kernel/mod-simple.ko:
+kernel/mod-loop-b.ko:
+kernel/mod-loop-a.ko: kernel/mod-loop-b.ko
diff --git a/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.dep.bin b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.dep.bin
new file mode 100644 (file)
index 0000000..70a6e76
Binary files /dev/null and b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.dep.bin differ
diff --git a/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.devname b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.devname
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.softdep b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.softdep
new file mode 100644 (file)
index 0000000..5554ccc
--- /dev/null
@@ -0,0 +1 @@
+# Soft dependencies extracted from modules themselves.
diff --git a/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.symbols b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.symbols
new file mode 100644 (file)
index 0000000..6c53580
--- /dev/null
@@ -0,0 +1,3 @@
+# Aliases for symbols, used by symbol_request().
+alias symbol:printB mod_loop_b
+alias symbol:printA mod_loop_a
diff --git a/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.symbols.bin b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.symbols.bin
new file mode 100644 (file)
index 0000000..8683b6c
Binary files /dev/null and b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.symbols.bin differ
diff --git a/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.weakdep b/testsuite/rootfs-pristine/test-user/lib/modules/4.4.4/modules.weakdep
new file mode 100644 (file)
index 0000000..00777b8
--- /dev/null
@@ -0,0 +1,2 @@
+# Weak dependencies extracted from modules themselves.
+weakdep mod_weakdep mod-simple
index 5477c692942bf73a431933506b44ef50dce56216..f57ef19766ac50c841b30a44fceb00f1016d6bf3 100755 (executable)
@@ -68,6 +68,8 @@ map=(
     ["test-depmod/search-order-external-last/lib/modules/external/"]="mod-simple.ko"
     ["test-depmod/search-order-override$MODULE_DIRECTORY/4.4.4/foo/"]="mod-simple.ko"
     ["test-depmod/search-order-override$MODULE_DIRECTORY/4.4.4/override/"]="mod-simple.ko"
+    ["test-depmod/check-weakdep$MODULE_DIRECTORY/4.4.4/kernel/mod-weakdep.ko"]="mod-weakdep.ko"
+    ["test-depmod/check-weakdep$MODULE_DIRECTORY/4.4.4/kernel/mod-simple.ko"]="mod-simple.ko"
     ["test-dependencies$MODULE_DIRECTORY/4.0.20-kmod/kernel/fs/foo/"]="mod-foo-b.ko"
     ["test-dependencies$MODULE_DIRECTORY/4.0.20-kmod/kernel/"]="mod-foo-c.ko"
     ["test-dependencies$MODULE_DIRECTORY/4.0.20-kmod/kernel/lib/"]="mod-foo-a.ko"
@@ -80,6 +82,9 @@ map=(
     ["test-modprobe/show-exports/mod-loop-a.ko"]="mod-loop-a.ko"
     ["test-modprobe/softdep-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-a.ko"]="mod-loop-a.ko"
     ["test-modprobe/softdep-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-b.ko"]="mod-loop-b.ko"
+    ["test-modprobe/weakdep-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-a.ko"]="mod-loop-a.ko"
+    ["test-modprobe/weakdep-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-b.ko"]="mod-loop-b.ko"
+    ["test-modprobe/weakdep-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-simple.ko"]="mod-simple.ko"
     ["test-modprobe/install-cmd-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-a.ko"]="mod-loop-a.ko"
     ["test-modprobe/install-cmd-loop$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-b.ko"]="mod-loop-b.ko"
     ["test-modprobe/force$MODULE_DIRECTORY/4.4.4/kernel/"]="mod-simple.ko"
@@ -103,6 +108,10 @@ map=(
     ["test-modinfo/mod-simple-sha256.ko"]="mod-simple.ko"
     ["test-modinfo/mod-simple-pkcs7.ko"]="mod-simple.ko"
     ["test-modinfo/external/lib/modules/external/mod-simple.ko"]="mod-simple.ko"
+    ["test-user$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-a.ko"]="mod-loop-a.ko"
+    ["test-user$MODULE_DIRECTORY/4.4.4/kernel/mod-loop-b.ko"]="mod-loop-b.ko"
+    ["test-user$MODULE_DIRECTORY/4.4.4/kernel/mod-simple.ko"]="mod-simple.ko"
+    ["test-user$MODULE_DIRECTORY/4.4.4/kernel/mod-weakdep.ko"]="mod-weakdep.ko"
 )
 
 gzip_array=(
index c96dbf0a62bef7251605c6fb4d4a8a59e988f1ee..eaa5b1a0040d92feb40f9541f6e595cb217b4500 100644 (file)
@@ -244,4 +244,31 @@ DEFINE_TEST(depmod_search_order_override,
                },
        });
 
+#define CHECK_WEAKDEP_ROOTFS TESTSUITE_ROOTFS "test-depmod/check-weakdep"
+#define CHECK_WEAKDEP_LIB_MODULES CHECK_WEAKDEP_ROOTFS MODULE_DIRECTORY "/" MODULES_UNAME
+static noreturn int depmod_check_weakdep(const struct test *t)
+{
+       const char *progname = ABS_TOP_BUILDDIR "/tools/depmod";
+       const char *const args[] = {
+               progname,
+               NULL,
+       };
+
+       test_spawn_prog(progname, args);
+       exit(EXIT_FAILURE);
+}
+DEFINE_TEST(depmod_check_weakdep,
+       .description = "check weakdep output",
+       .config = {
+               [TC_UNAME_R] = MODULES_UNAME,
+               [TC_ROOTFS] = CHECK_WEAKDEP_ROOTFS,
+       },
+       .output = {
+               .files = (const struct keyval[]) {
+                       { CHECK_WEAKDEP_LIB_MODULES "/correct-modules.weakdep",
+                         CHECK_WEAKDEP_LIB_MODULES "/modules.weakdep" },
+                       { }
+               },
+       });
+
 TESTSUITE_MAIN();
index 309f3e34c5fc84f3c874d68280916c66b8721ceb..6a824c9f61d533cdc87af8f895e38fb07f94ea67 100644 (file)
@@ -181,6 +181,29 @@ DEFINE_TEST(modprobe_softdep_loop,
        .modules_loaded = "mod-loop-a,mod-loop-b",
        );
 
+static noreturn int modprobe_weakdep_loop(const struct test *t)
+{
+       const char *progname = ABS_TOP_BUILDDIR "/tools/modprobe";
+       const char *const args[] = {
+               progname,
+               "mod-loop-b",
+               NULL,
+       };
+
+       test_spawn_prog(progname, args);
+       exit(EXIT_FAILURE);
+}
+DEFINE_TEST(modprobe_weakdep_loop,
+       .description = "check if modprobe breaks weakdep loop",
+       .config = {
+               [TC_UNAME_R] = "4.4.4",
+               [TC_ROOTFS] = TESTSUITE_ROOTFS "test-modprobe/weakdep-loop",
+               [TC_INIT_MODULE_RETCODES] = "",
+       },
+       .modules_loaded = "mod-loop-b",
+       .modules_not_loaded = "mod-loop-a,mod-simple-c",
+       );
+
 static noreturn int modprobe_install_cmd_loop(const struct test *t)
 {
        const char *progname = ABS_TOP_BUILDDIR "/tools/modprobe";
diff --git a/testsuite/test-user.c b/testsuite/test-user.c
new file mode 100644 (file)
index 0000000..c37c9a0
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <libkmod/libkmod.h>
+
+#include "testsuite.h"
+
+#define TEST_USER_ROOTFS TESTSUITE_ROOTFS "test-user/"
+#define TEST_USER_KERNEL_DIR TEST_USER_ROOTFS "lib/modules/4.4.4/"
+
+static const char *const test_user_config_paths[] = {
+       TEST_USER_ROOTFS "etc/modprobe.d",
+       NULL
+};
+
+static const char *const mod_name[] = {
+       "mod-loop-b",
+       "mod-weakdep",
+       NULL
+};
+
+static int test_user_weakdep(const struct test *t)
+{
+       struct kmod_ctx *ctx;
+       int mod_name_index = 0;
+       int err;
+
+       ctx = kmod_new(TEST_USER_KERNEL_DIR, test_user_config_paths);
+       if (ctx == NULL)
+               exit(EXIT_FAILURE);
+
+       while (mod_name[mod_name_index]) {
+               struct kmod_list *list = NULL;
+               struct kmod_module *mod = NULL;
+               struct kmod_list *mod_list = NULL;
+               struct kmod_list *itr = NULL;
+
+               printf("%s:", mod_name[mod_name_index]);
+               err = kmod_module_new_from_lookup(ctx, mod_name[mod_name_index], &list);
+               if (list == NULL || err < 0) {
+                       fprintf(stderr, "module %s not found in directory %s\n",
+                               mod_name[mod_name_index],
+                               ctx ? kmod_get_dirname(ctx) : "(missing)");
+                       exit(EXIT_FAILURE);
+               }
+
+               mod = kmod_module_get_module(list);
+
+               err = kmod_module_get_weakdeps(mod, &mod_list);
+               if (err) {
+                       fprintf(stderr, "weak dependencies can not be read for %s (%d)\n",
+                               mod_name[mod_name_index], err);
+                       exit(EXIT_FAILURE);
+               }
+
+               kmod_list_foreach(itr, mod_list) {
+                       struct kmod_module *weakdep_mod = kmod_module_get_module(itr);
+                       const char *weakdep_name = kmod_module_get_name(weakdep_mod);
+
+                       printf(" %s", weakdep_name);
+                       kmod_module_unref(weakdep_mod);
+               }
+               printf("\n");
+
+               kmod_module_unref_list(mod_list);
+               kmod_module_unref(mod);
+               kmod_module_unref_list(list);
+
+               mod_name_index++;
+       }
+
+       kmod_unref(ctx);
+
+       return EXIT_SUCCESS;
+}
+DEFINE_TEST(test_user_weakdep,
+       .description = "check if modprobe breaks weakdep2",
+       .config = {
+               [TC_UNAME_R] = "4.4.4",
+               [TC_ROOTFS] = TESTSUITE_ROOTFS "test-user",
+               [TC_INIT_MODULE_RETCODES] = "",
+       },
+       .need_spawn = true,
+       .output = {
+               .out = TESTSUITE_ROOTFS "test-user/correct-weakdep.txt",
+       });
+
+TESTSUITE_MAIN();
index f4280be2ab12d65d6020bfcd1806ab3041ded941..6602aaf1d8e7282cf10a5f973a9628d6982bd074 100644 (file)
@@ -773,10 +773,10 @@ static int cmp_modnames(const void *m1, const void *m2)
 }
 
 /*
- * Store the expected module names in buf and return a list of pointers to
- * them.
+ * Auxiliary function to store the module names in buf and return a list
+ * of pointers to them.
  */
-static const char **read_expected_modules(const struct test *t,
+static const char **read_modules(const char* modules,
                char **buf, int *count)
 {
        const char **res;
@@ -784,12 +784,8 @@ static const char **read_expected_modules(const struct test *t,
        int i;
        char *p;
 
-       if (t->modules_loaded[0] == '\0') {
-               *count = 0;
-               *buf = NULL;
-               return NULL;
-       }
-       *buf = strdup(t->modules_loaded);
+
+       *buf = strdup(modules);
        if (!*buf) {
                *count = -1;
                return NULL;
@@ -817,6 +813,36 @@ static const char **read_expected_modules(const struct test *t,
        return res;
 }
 
+/*
+ * Store the expected module names in buf and return a list of pointers to
+ * them.
+ */
+static const char **read_expected_modules(const struct test *t,
+               char **buf, int *count)
+{
+       if (t->modules_loaded[0] == '\0') {
+               *count = 0;
+               *buf = NULL;
+               return NULL;
+       }
+       return read_modules(t->modules_loaded, buf, count);
+}
+
+/*
+ * Store the unexpected module names in buf and return a list of pointers to
+ * them.
+ */
+static const char **read_unexpected_modules(const struct test *t,
+               char **buf, int *count)
+{
+       if (t->modules_not_loaded[0] == '\0') {
+               *count = 0;
+               *buf = NULL;
+               return NULL;
+       }
+       return read_modules(t->modules_not_loaded, buf, count);
+}
+
 static char **read_loaded_modules(const struct test *t, char **buf, int *count)
 {
        char dirname[PATH_MAX];
@@ -931,6 +957,54 @@ out_a1:
        return err;
 }
 
+static int check_not_loaded_modules(const struct test *t)
+{
+       int l1, l2, i1, i2;
+       const char **a1;
+       char **a2;
+       char *buf1, *buf2;
+       int err = false;
+
+       a1 = read_unexpected_modules(t, &buf1, &l1);
+       if (l1 < 0)
+               return err;
+       a2 = read_loaded_modules(t, &buf2, &l2);
+       if (l2 < 0)
+               goto out_a1;
+       qsort(a1, l1, sizeof(char *), cmp_modnames);
+       qsort(a2, l2, sizeof(char *), cmp_modnames);
+       i1 = i2 = 0;
+       err = true;
+       while (i1 < l1 || i2 < l2) {
+               int cmp;
+
+               if (i1 >= l1)
+                       cmp = 1;
+               else if (i2 >= l2)
+                       cmp = -1;
+               else
+                       cmp = cmp_modnames(&a1[i1], &a2[i2]);
+               if (cmp == 0) {
+                       err = false;
+                       ERR("module %s loaded\n", a1[i1]);
+                       i1++;
+               } else if (cmp < 0) {
+                       i1++;
+                       i2++;
+               } else  {
+                       err = false;
+                       ERR("module %s is loaded but should not be\n", a2[i2]);
+                       i2++;
+               }
+       }
+       free(a2);
+       free(buf2);
+out_a1:
+       free(a1);
+       free(buf1);
+       return err;
+}
+
 static inline int test_run_parent(const struct test *t, int fdout[2],
                                int fderr[2], int fdmonitor[2], pid_t child)
 {
@@ -995,6 +1069,8 @@ static inline int test_run_parent(const struct test *t, int fdout[2],
                match_modules = check_loaded_modules(t);
        else
                match_modules = true;
+       if (match_modules && t->modules_not_loaded)
+               match_modules = check_not_loaded_modules(t);
 
        if (t->expected_fail == false) {
                if (err == 0) {
index 44d17300d371c56199b6a871eb0bd891e55474f3..4b2565cd72169e8d99f999d38b66fa9f91e538b2 100644 (file)
@@ -103,6 +103,7 @@ struct test {
        } output;
        /* comma-separated list of loaded modules at the end of the test */
        const char *modules_loaded;
+       const char *modules_not_loaded;
        testfunc func;
        const char *config[_TC_LAST];
        const char *path;