On 10/24/23 13:18, Manu Bretelle wrote:
Currently this tests tries to umount /sys/kernel/debug (TDIR) but the
system it is running on may have mounts below.
For example, danobi/vmtest [0] VMs have
mount -t tracefs tracefs /sys/kernel/debug/tracing
as part of their init.
This change list mounts and will umount any mounts below TDIR before
umounting TDIR itself.
Note that it is not umounting recursively, so in the case of a sub-mount
of TDIR having another sub-mount, this will fail as mtab is ordered.
Should we move TID to a random path likes "/sys/kernel/debug-<pid>/"?
Test:
Originally:
$ vmtest -k $KERNEL_REPO/arch/x86_64/boot/bzImage "./test_progs -vv -a test_bpffs"
=> bzImage
===> Booting
===> Setting up VM
===> Running command
[ 2.138818] bpf_testmod: loading out-of-tree module taints kernel.
[ 2.140913] bpf_testmod: module verification failed: signature and/or required key missing - tainting kernel
bpf_testmod.ko is already unloaded.
Loading bpf_testmod.ko...
Successfully loaded bpf_testmod.ko.
test_test_bpffs:PASS:clone 0 nsec
fn:PASS:unshare 0 nsec
fn:PASS:mount / 0 nsec
fn:FAIL:umount /sys/kernel/debug unexpected error: -1 (errno 16)
bpf_testmod.ko is already unloaded.
Loading bpf_testmod.ko...
Successfully loaded bpf_testmod.ko.
test_test_bpffs:PASS:clone 0 nsec
test_test_bpffs:PASS:waitpid 0 nsec
test_test_bpffs:FAIL:bpffs test failed 255#282 test_bpffs:FAIL
Summary: 0/0 PASSED, 0 SKIPPED, 1 FAILED
Successfully unloaded bpf_testmod.ko.
Command failed with exit code: 1
After this change:
$ vmtest -k $KERNEL_REPO/arch/x86_64/boot/bzImage "./test_progs -vv -a test_bpffs"
=> bzImage
===> Booting
===> Setting up VM
===> Running command
[ 2.035210] bpf_testmod: loading out-of-tree module taints kernel.
[ 2.036510] bpf_testmod: module verification failed: signature and/or required key missing - tainting kernel
bpf_testmod.ko is already unloaded.
Loading bpf_testmod.ko...
Successfully loaded bpf_testmod.ko.
test_test_bpffs:PASS:clone 0 nsec
fn:PASS:unshare 0 nsec
fn:PASS:mount / 0 nsec
fn:PASS:accessing /etc/mtab 0 nsec
fn:PASS:umount /sys/kernel/debug/tracing 0 nsec
fn:PASS:umount /sys/kernel/debug 0 nsec
fn:PASS:mount tmpfs 0 nsec
fn:PASS:mkdir /sys/kernel/debug/fs1 0 nsec
fn:PASS:mkdir /sys/kernel/debug/fs2 0 nsec
fn:PASS:mount bpffs /sys/kernel/debug/fs1 0 nsec
fn:PASS:mount bpffs /sys/kernel/debug/fs2 0 nsec
fn:PASS:reading /sys/kernel/debug/fs1/maps.debug 0 nsec
fn:PASS:reading /sys/kernel/debug/fs2/progs.debug 0 nsec
fn:PASS:creating /sys/kernel/debug/fs1/a 0 nsec
fn:PASS:creating /sys/kernel/debug/fs1/a/1 0 nsec
fn:PASS:creating /sys/kernel/debug/fs1/b 0 nsec
fn:PASS:create_map(ARRAY) 0 nsec
fn:PASS:pin map 0 nsec
fn:PASS:stat(/sys/kernel/debug/fs1/a) 0 nsec
fn:PASS:renameat2(/fs1/a, /fs1/b, RENAME_EXCHANGE) 0 nsec
fn:PASS:stat(/sys/kernel/debug/fs1/b) 0 nsec
fn:PASS:b should have a's inode 0 nsec
fn:PASS:access(/sys/kernel/debug/fs1/b/1) 0 nsec
fn:PASS:stat(/sys/kernel/debug/fs1/map) 0 nsec
fn:PASS:renameat2(/fs1/c, /fs1/b, RENAME_EXCHANGE) 0 nsec
fn:PASS:stat(/sys/kernel/debug/fs1/b) 0 nsec
fn:PASS:b should have c's inode 0 nsec
fn:PASS:access(/sys/kernel/debug/fs1/c/1) 0 nsec
fn:PASS:renameat2(RENAME_NOREPLACE) 0 nsec
fn:PASS:access(/sys/kernel/debug/fs1/b) 0 nsec
bpf_testmod.ko is already unloaded.
Loading bpf_testmod.ko...
Successfully loaded bpf_testmod.ko.
test_test_bpffs:PASS:clone 0 nsec
test_test_bpffs:PASS:waitpid 0 nsec
test_test_bpffs:PASS:bpffs test 0 nsec
#282 test_bpffs:OK
Summary: 1/0 PASSED, 0 SKIPPED, 0 FAILED
Successfully unloaded bpf_testmod.ko.
[0] https://github.com/danobi/vmtest
Signed-off-by: Manu Bretelle <chantr4@xxxxxxxxx>
---
.../selftests/bpf/prog_tests/test_bpffs.c | 28 +++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/test_bpffs.c b/tools/testing/selftests/bpf/prog_tests/test_bpffs.c
index 214d9f4a94a5..001bf694c269 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_bpffs.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_bpffs.c
@@ -3,12 +3,14 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <sched.h>
+#include <mntent.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <test_progs.h>
#define TDIR "/sys/kernel/debug"
+#define MTAB "/etc/mtab"
static int read_iter(char *file)
{
@@ -32,6 +34,8 @@ static int read_iter(char *file)
static int fn(void)
{
+ /* A buffer to store logging messages */
+ char buf[1024];
struct stat a, b, c;
int err, map;
@@ -43,6 +47,30 @@ static int fn(void)
if (!ASSERT_OK(err, "mount /"))
goto out;
+ /* TDIR may have mounts below. unount them first */
+ FILE *mtab = setmntent(MTAB, "r");
+
+ if (!ASSERT_TRUE(mtab != NULL, "accessing " MTAB)) {
+ err = errno;
+ goto out;
+ }
+
+ struct mntent *mnt = NULL;
+
+ while ((mnt = getmntent(mtab)) != NULL) {
+ if (strlen(mnt->mnt_dir) > strlen(TDIR) &&
+ strncmp(TDIR, mnt->mnt_dir, strlen(TDIR)) == 0) {
+ snprintf(buf, sizeof(buf) - 1, "umount %s", mnt->mnt_dir);
+ err = umount(mnt->mnt_dir);
+ if (!ASSERT_OK(err, buf)) {
+ endmntent(mtab);
+ goto out;
+ }
+ }
+ }
+ // Ignore any error here
+ endmntent(mtab);
+
err = umount(TDIR);
if (!ASSERT_OK(err, "umount " TDIR))
goto out;