Commit 6cb66eca authored by Ilya Leoshkevich's avatar Ilya Leoshkevich Committed by Alexei Starovoitov
Browse files

selftests/bpf: Unmount the cgroup2 work directory



test_progs -t bind_perm,bpf_obj_pinning/mounted-str-rel fails when
the selftests directory is mounted under /mnt, which is a reasonable
thing to do when sharing the selftests residing on the host with a
virtual machine, e.g., using 9p.

The reason is that cgroup2 is mounted at /mnt and not unmounted,
causing subsequent tests that need to access the selftests directory
to fail.

Fix by unmounting it. The kernel maintains a mount stack, so this
reveals what was mounted there before. Introduce cgroup_workdir_mounted
in order to maintain idempotency. Make it thread-local in order to
support test_progs -j.

Signed-off-by: default avatarIlya Leoshkevich <iii@linux.ibm.com>
Link: https://lore.kernel.org/r/20230919101336.2223655-3-iii@linux.ibm.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 577c06af
Loading
Loading
Loading
Loading
+26 −7
Original line number Diff line number Diff line
@@ -49,6 +49,10 @@
	snprintf(buf, sizeof(buf), "%s%s", NETCLS_MOUNT_PATH,	\
		 CGROUP_WORK_DIR)

static __thread bool cgroup_workdir_mounted;

static void __cleanup_cgroup_environment(void);

static int __enable_controllers(const char *cgroup_path, const char *controllers)
{
	char path[PATH_MAX + 1];
@@ -209,9 +213,10 @@ int setup_cgroup_environment(void)
		log_err("mount cgroup2");
		return 1;
	}
	cgroup_workdir_mounted = true;

	/* Cleanup existing failed runs, now that the environment is setup */
	cleanup_cgroup_environment();
	__cleanup_cgroup_environment();

	if (mkdir(cgroup_workdir, 0777) && errno != EEXIST) {
		log_err("mkdir cgroup work dir");
@@ -305,11 +310,26 @@ int join_parent_cgroup(const char *relative_path)
	return join_cgroup_from_top(cgroup_path);
}

/**
 * __cleanup_cgroup_environment() - Delete temporary cgroups
 *
 * This is a helper for cleanup_cgroup_environment() that is responsible for
 * deletion of all temporary cgroups that have been created during the test.
 */
static void __cleanup_cgroup_environment(void)
{
	char cgroup_workdir[PATH_MAX + 1];

	format_cgroup_path(cgroup_workdir, "");
	join_cgroup_from_top(CGROUP_MOUNT_PATH);
	nftw(cgroup_workdir, nftwfunc, WALK_FD_LIMIT, FTW_DEPTH | FTW_MOUNT);
}

/**
 * cleanup_cgroup_environment() - Cleanup Cgroup Testing Environment
 *
 * This is an idempotent function to delete all temporary cgroups that
 * have been created during the test, including the cgroup testing work
 * have been created during the test and unmount the cgroup testing work
 * directory.
 *
 * At call time, it moves the calling process to the root cgroup, and then
@@ -320,11 +340,10 @@ int join_parent_cgroup(const char *relative_path)
 */
void cleanup_cgroup_environment(void)
{
	char cgroup_workdir[PATH_MAX + 1];

	format_cgroup_path(cgroup_workdir, "");
	join_cgroup_from_top(CGROUP_MOUNT_PATH);
	nftw(cgroup_workdir, nftwfunc, WALK_FD_LIMIT, FTW_DEPTH | FTW_MOUNT);
	__cleanup_cgroup_environment();
	if (cgroup_workdir_mounted && umount(CGROUP_MOUNT_PATH))
		log_err("umount cgroup2");
	cgroup_workdir_mounted = false;
}

/**