Skip to content

Commit

Permalink
testsuite: add tests for weak dependencies
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jtornosm authored and lucasdemarchi committed Jun 14, 2024
1 parent a0ed4f8 commit d06712b
Show file tree
Hide file tree
Showing 36 changed files with 309 additions and 10 deletions.
4 changes: 3 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions testsuite/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
/test-modprobe
/test-hash
/test-list
/test-user
/rootfs
/stamp-rootfs
/test-scratchbuf.log
Expand Down Expand Up @@ -52,3 +53,5 @@
/test-testsuite.trs
/test-list.log
/test-list.trs
/test-user.log
/test-user.trs
2 changes: 2 additions & 0 deletions testsuite/module-playground/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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),)
Expand Down
19 changes: 19 additions & 0 deletions testsuite/module-playground/mod-weakdep.c
Original file line number Diff line number Diff line change
@@ -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");
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Weak dependencies extracted from modules themselves.
weakdep mod_weakdep mod-simple
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
weakdep mod-loop-b mod-loop-a mod-simple
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Aliases extracted from modules themselves.
Binary file not shown.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kernel/mod-loop-b.ko:
kernel/mod-loop-a.ko:
kernel/mod-simple.ko:
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Device nodes to trigger on-demand module loading.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Soft dependencies extracted from modules themselves.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Aliases for symbols, used by symbol_request().
alias symbol:printB mod_loop_b
alias symbol:printA mod_loop_a
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Weak dependencies extracted from modules themselves.
2 changes: 2 additions & 0 deletions testsuite/rootfs-pristine/test-user/correct-weakdep.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod-loop-b: mod_loop_a mod_simple
mod-weakdep: mod_simple
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
weakdep mod-loop-b mod-loop-a mod-simple
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Aliases extracted from modules themselves.
Binary file not shown.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -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
Binary file not shown.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Soft dependencies extracted from modules themselves.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Aliases for symbols, used by symbol_request().
alias symbol:printB mod_loop_b
alias symbol:printA mod_loop_a
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Weak dependencies extracted from modules themselves.
weakdep mod_weakdep mod-simple
9 changes: 9 additions & 0 deletions testsuite/setup-rootfs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand All @@ -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=(
Expand Down
27 changes: 27 additions & 0 deletions testsuite/test-depmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
23 changes: 23 additions & 0 deletions testsuite/test-modprobe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
110 changes: 110 additions & 0 deletions testsuite/test-user.c
Original file line number Diff line number Diff line change
@@ -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();
Loading

0 comments on commit d06712b

Please sign in to comment.