diff mbox series

[bpf-next] selftests/bpf: umount children of TDIR in test_bpffs

Message ID 20231024201852.1512720-1-chantr4@gmail.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series [bpf-next] selftests/bpf: umount children of TDIR in test_bpffs | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for bpf-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 9 this patch: 9
netdev/cc_maintainers warning 1 maintainers not CCed: linux-kselftest@vger.kernel.org
netdev/build_clang success Errors and warnings before: 9 this patch: 9
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 9 this patch: 9
netdev/checkpatch warning CHECK: Alignment should match open parenthesis CHECK: Comparison to NULL could be written "mtab" WARNING: Possible repeated word: 'tracefs' WARNING: line length of 82 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-PR fail PR summary
bpf/vmtest-bpf-next-VM_Test-0 pending Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-5 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-1 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-2 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-6 success Logs for test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-8 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-12 fail Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-10 fail Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 fail Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 fail Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-16 fail Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-17 fail Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-21 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-28 success Logs for veristat
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-15 fail Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-11 fail Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-7 success Logs for test_maps on s390x with gcc

Commit Message

Manu Bretelle Oct. 24, 2023, 8:18 p.m. UTC
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.

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@gmail.com>
---
 .../selftests/bpf/prog_tests/test_bpffs.c     | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

Comments

Kui-Feng Lee Oct. 24, 2023, 9:29 p.m. UTC | #1
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@gmail.com>
> ---
>   .../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;
Manu Bretelle Oct. 25, 2023, 5:41 a.m. UTC | #2
On Tue, Oct 24, 2023 at 02:29:19PM -0700, Kui-Feng Lee wrote:
> 
> 
> 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>/"?
> 

Fair point, I suppose we would want to keep TDIR a defined string as it does
simplify the gymnastic involved through the rest of the script, but yeah
looking at the original commit:
edb65ee5aa25 (selftests/bpf: Add bpffs preload test)

I don't see any reason to use an alternate directory and rather mkdir it vs
umounting the original one.
so something like

    #define TDIR "/sys/kernel/test_bpffs"

Would probably do.

Alexei could confirm his original intent probably.

> > 
> > 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@gmail.com>
> > ---
> >   .../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;
Alexei Starovoitov Oct. 26, 2023, 9:35 p.m. UTC | #3
On Tue, Oct 24, 2023 at 10:42 PM Manu Bretelle <chantr4@gmail.com> wrote:
>
> On Tue, Oct 24, 2023 at 02:29:19PM -0700, Kui-Feng Lee wrote:
> >
> >
> > 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>/"?
> >
>
> Fair point, I suppose we would want to keep TDIR a defined string as it does
> simplify the gymnastic involved through the rest of the script, but yeah
> looking at the original commit:
> edb65ee5aa25 (selftests/bpf: Add bpffs preload test)
>
> I don't see any reason to use an alternate directory and rather mkdir it vs
> umounting the original one.
> so something like
>
>     #define TDIR "/sys/kernel/test_bpffs"
>
> Would probably do.
>
> Alexei could confirm his original intent probably.

I don't remember why I picked /sys/kernel/debug back then.
I suspect TDIR /tmp/foo and mkdir would work the same way.
Yonghong Song Oct. 27, 2023, 6:08 a.m. UTC | #4
On 10/24/23 10:41 PM, Manu Bretelle wrote:
> On Tue, Oct 24, 2023 at 02:29:19PM -0700, Kui-Feng Lee wrote:
>>
>> 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>/"?
>>
> Fair point, I suppose we would want to keep TDIR a defined string as it does
> simplify the gymnastic involved through the rest of the script, but yeah
> looking at the original commit:
> edb65ee5aa25 (selftests/bpf: Add bpffs preload test)
>
> I don't see any reason to use an alternate directory and rather mkdir it vs
> umounting the original one.
> so something like
>
>      #define TDIR "/sys/kernel/test_bpffs"
>
> Would probably do.
>
> Alexei could confirm his original intent probably.


Maybe/sys/kernel/tracing should work too? Not sure whether it is universally 
available or not.


>
>>> 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@gmail.com>
>>> ---
>>>    .../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;
Manu Bretelle Oct. 27, 2023, 9:09 p.m. UTC | #5
On Thu, Oct 26, 2023 at 11:08:35PM -0700, Yonghong Song wrote:
> 
> On 10/24/23 10:41 PM, Manu Bretelle wrote:
> > On Tue, Oct 24, 2023 at 02:29:19PM -0700, Kui-Feng Lee wrote:
> > > 
> > > 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>/"?
> > > 
> > Fair point, I suppose we would want to keep TDIR a defined string as it does
> > simplify the gymnastic involved through the rest of the script, but yeah
> > looking at the original commit:
> > edb65ee5aa25 (selftests/bpf: Add bpffs preload test)
> > 
> > I don't see any reason to use an alternate directory and rather mkdir it vs
> > umounting the original one.
> > so something like
> > 
> >      #define TDIR "/sys/kernel/test_bpffs"
> > 
> > Would probably do.
> > 
> > Alexei could confirm his original intent probably.
> 
> 
> Maybe/sys/kernel/tracing should work too? Not sure whether it is universally
> available or not.
> 
> 

I think we just need an existing directory (whichever) to mount tmpfs on, and Alexei previous
comment seems to confirm that. But importantly, nothing that has sub-mounts
if we don't want to get into the business of recursively umounting sub-mounts.

I will just pick up a name which is random enough to not realistically exist on
a system, mkdir it instead of the existing umount(TDIR) and we should be good.


> > 
> > > > 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@gmail.com>
> > > > ---
> > > >    .../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;
Manu Bretelle Oct. 28, 2023, 12:56 a.m. UTC | #6
On Thu, Oct 26, 2023 at 02:35:11PM -0700, Alexei Starovoitov wrote:
> On Tue, Oct 24, 2023 at 10:42 PM Manu Bretelle <chantr4@gmail.com> wrote:
> >
> > On Tue, Oct 24, 2023 at 02:29:19PM -0700, Kui-Feng Lee wrote:
> > >
> > >
> > > 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>/"?
> > >
> >
> > Fair point, I suppose we would want to keep TDIR a defined string as it does
> > simplify the gymnastic involved through the rest of the script, but yeah
> > looking at the original commit:
> > edb65ee5aa25 (selftests/bpf: Add bpffs preload test)
> >
> > I don't see any reason to use an alternate directory and rather mkdir it vs
> > umounting the original one.
> > so something like
> >
> >     #define TDIR "/sys/kernel/test_bpffs"
> >
> > Would probably do.
> >
> > Alexei could confirm his original intent probably.
> 
> I don't remember why I picked /sys/kernel/debug back then.
> I suspect TDIR /tmp/foo and mkdir would work the same way.

Yeah. I suspect the reason you used an existing directory is that
/sys/kernel is not mutable from userspace.
I ended up picking a random name under /tmp and mkdir.
diff mbox series

Patch

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;