selftests: add FSMOUNT_NAMESPACE tests

Add selftests for FSMOUNT_NAMESPACE which creates a new mount namespace
with the newly created filesystem mounted onto a copy of the real
rootfs.

Link: https://patch.msgid.link/20260122-work-fsmount-namespace-v1-6-5ef0a886e646@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Christian Brauner
2026-01-22 11:48:51 +01:00
parent be1ca3ee8f
commit 3ac7ea91f3
5 changed files with 1156 additions and 30 deletions
@@ -0,0 +1 @@
fsmount_ns_test
@@ -0,0 +1,10 @@
# SPDX-License-Identifier: GPL-2.0
TEST_GEN_PROGS := fsmount_ns_test
CFLAGS += -Wall -O0 -g $(KHDR_INCLUDES) $(TOOLS_INCLUDES)
LDLIBS := -lcap
include ../../lib.mk
$(OUTPUT)/fsmount_ns_test: fsmount_ns_test.c ../utils.c
$(CC) $(CFLAGS) -o $@ $^ $(LDLIBS)
File diff suppressed because it is too large Load Diff
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
TEST_GEN_PROGS := open_tree_ns_test
CFLAGS := -Wall -Werror -g $(KHDR_INCLUDES)
CFLAGS += -Wall -O0 -g $(KHDR_INCLUDES) $(TOOLS_INCLUDES)
LDLIBS := -lcap
include ../../lib.mk
@@ -1,5 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2026 Christian Brauner <brauner@kernel.org>
*
* Test for OPEN_TREE_NAMESPACE flag.
*
* Test that open_tree() with OPEN_TREE_NAMESPACE creates a new mount
@@ -50,31 +52,6 @@ static int get_mnt_ns_id_from_path(const char *path, uint64_t *mnt_ns_id)
return ret;
}
#define STATMOUNT_BUFSIZE (1 << 15)
static struct statmount *statmount_alloc(uint64_t mnt_id, uint64_t mnt_ns_id, uint64_t mask)
{
struct statmount *buf;
size_t bufsize = STATMOUNT_BUFSIZE;
int ret;
for (;;) {
buf = malloc(bufsize);
if (!buf)
return NULL;
ret = statmount(mnt_id, mnt_ns_id, mask, buf, bufsize, 0);
if (ret == 0)
return buf;
free(buf);
if (errno != EOVERFLOW)
return NULL;
bufsize <<= 1;
}
}
static void log_mount(struct __test_metadata *_metadata, struct statmount *sm)
{
const char *fs_type = "";
@@ -221,7 +198,7 @@ FIXTURE_SETUP(open_tree_ns)
SKIP(return, "open_tree() syscall not supported");
/* Check if statmount/listmount are supported */
ret = statmount(0, 0, 0, NULL, 0, 0);
ret = statmount(0, 0, 0, 0, NULL, 0, 0);
if (ret == -1 && errno == ENOSYS)
SKIP(return, "statmount() syscall not supported");
@@ -340,7 +317,7 @@ TEST_F(open_tree_ns, verify_mount_properties)
ASSERT_GE(nr_mounts, 1);
/* Get info about the root mount (the bind mount, rootfs is hidden) */
ret = statmount(list[0], new_ns_id, STATMOUNT_MNT_BASIC, &sm, sizeof(sm), 0);
ret = statmount(list[0], new_ns_id, 0, STATMOUNT_MNT_BASIC, &sm, sizeof(sm), 0);
ASSERT_EQ(ret, 0);
ASSERT_NE(sm.mnt_id, sm.mnt_parent_id);
@@ -452,7 +429,7 @@ FIXTURE_SETUP(open_tree_ns_userns)
SKIP(return, "open_tree() syscall not supported");
/* Check if statmount/listmount are supported */
ret = statmount(0, 0, 0, NULL, 0, 0);
ret = statmount(0, 0, 0, 0, NULL, 0, 0);
if (ret == -1 && errno == ENOSYS)
SKIP(return, "statmount() syscall not supported");
}
@@ -904,7 +881,7 @@ TEST_F(open_tree_ns_userns, umount_succeeds)
ASSERT_FALSE(true) TH_LOG("setns into new namespace failed");
break;
case 7:
ASSERT_FALSE(true) TH_LOG("umount succeeded but should have failed with EINVAL");
ASSERT_FALSE(true) TH_LOG("umount failed but should have succeeded");
break;
case 9:
ASSERT_FALSE(true) TH_LOG("listmount failed");