Re: [PATCH v4 9/9] vfs: Add tmpfs tests for idmap mounts

[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]



On Tue, Mar 14, 2023 at 12:45:11PM +0100, Rodrigo Campos wrote:
> This patch calls all tests in the suite s_idmapped_mounts, but with a
> tmpfs directory mounted inside a userns. This directory is setup as the
> mount point for the test that runs nested.
> 
> This excercises that tmpfs mounted inside a userns works as expected
> regarding idmap mounts.
> 
> Signed-off-by: Rodrigo Campos <rodrigo@xxxxxxxxxxx>
> ---

This verion looks good to me, so ...
Reviewed-by: Zorro Lang <zlang@xxxxxxxxxx>

Just curious, did you use "--no-prefix" option or use some similar configuration
to generate this patchset. I have to use "-p0" to merge this patchset :)

Thanks,
Zorro

>  src/vfs/Makefile                |   4 +-
>  src/vfs/tmpfs-idmapped-mounts.c | 305 ++++++++++++++++++++++++++++++++
>  src/vfs/tmpfs-idmapped-mounts.h |  14 ++
>  src/vfs/utils.h                 |   2 +
>  src/vfs/vfstest.c               |  13 +-
>  tests/tmpfs/001                 |  27 +++
>  tests/tmpfs/001.out             |   2 +
>  tests/tmpfs/Makefile            |  24 +++
>  8 files changed, 388 insertions(+), 3 deletions(-)
>  create mode 100644 src/vfs/tmpfs-idmapped-mounts.c
>  create mode 100644 src/vfs/tmpfs-idmapped-mounts.h
>  create mode 100755 tests/tmpfs/001
>  create mode 100644 tests/tmpfs/001.out
>  create mode 100644 tests/tmpfs/Makefile
> 
> diff --git src/vfs/Makefile src/vfs/Makefile
> index 1b0b364b..4841da12 100644
> --- src/vfs/Makefile
> +++ src/vfs/Makefile
> @@ -4,10 +4,10 @@ TOPDIR = ../..
>  include $(TOPDIR)/include/builddefs
>  
>  TARGETS = vfstest mount-idmapped
> -CFILES_VFSTEST = vfstest.c btrfs-idmapped-mounts.c idmapped-mounts.c utils.c
> +CFILES_VFSTEST = vfstest.c btrfs-idmapped-mounts.c idmapped-mounts.c utils.c tmpfs-idmapped-mounts.c
>  CFILES_MOUNT_IDMAPPED = mount-idmapped.c utils.c
>  
> -HFILES = missing.h utils.h btrfs-idmapped-mounts.h idmapped-mounts.h
> +HFILES = missing.h utils.h btrfs-idmapped-mounts.h idmapped-mounts.h tmpfs-idmapped-mounts.h
>  LLDLIBS += -pthread
>  LDIRT = $(TARGETS)
>  
> diff --git src/vfs/tmpfs-idmapped-mounts.c src/vfs/tmpfs-idmapped-mounts.c
> new file mode 100644
> index 00000000..0899aed9
> --- /dev/null
> +++ src/vfs/tmpfs-idmapped-mounts.c
> @@ -0,0 +1,305 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#ifndef _GNU_SOURCE
> +#define _GNU_SOURCE
> +#endif
> +
> +#include "../global.h"
> +
> +#include <dirent.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <getopt.h>
> +#include <grp.h>
> +#include <limits.h>
> +#include <linux/limits.h>
> +#include <linux/types.h>
> +#include <pthread.h>
> +#include <pwd.h>
> +#include <sched.h>
> +#include <stdbool.h>
> +#include <sys/fsuid.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
> +#include <sys/xattr.h>
> +#include <unistd.h>
> +
> +#include "missing.h"
> +#include "utils.h"
> +#include "vfstest.h"
> +#include "idmapped-mounts.h"
> +
> +static int tmpfs_nested_mount_setup(const struct vfstest_info *info, int (*test)(const struct vfstest_info *info))
> +{
> +	char path[PATH_MAX];
> +	int fret = -1;
> +	struct vfstest_info nested_test_info = *info;
> +
> +	/* Create mapping for userns
> +	 * Make the mapping quite long, so all nested userns that are created by
> +	 * any test we call is contained here (otherwise userns creation fails).
> +	 */
> +	struct mount_attr attr = {
> +		.attr_set	= MOUNT_ATTR_IDMAP,
> +		.userns_fd	= -EBADF,
> +	};
> +	attr.userns_fd = get_userns_fd(0, 10000, 200000);
> +	if (attr.userns_fd < 0) {
> +		log_stderr("failure: get_userns_fd");
> +		goto out_close;
> +	}
> +
> +	if (!switch_userns(attr.userns_fd, 0, 0, false)) {
> +		log_stderr("failure: switch_userns");
> +		goto out_close;
> +	}
> +
> +	/* create separate mount namespace */
> +	if (unshare(CLONE_NEWNS)) {
> +		log_stderr("failure: create new mount namespace");
> +		goto out_close;
> +	}
> +
> +	/* We don't want this mount in the parent mount ns */
> +	if (sys_mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0)) {
> +		log_stderr("failure: mount");
> +		goto out_close;
> +	}
> +
> +	/* Create DIR0 to mount there */
> +	if (mkdirat(info->t_mnt_fd, DIR0, 0777)) {
> +		log_stderr("failure: mkdirat");
> +		goto out_close;
> +	}
> +	if (fchmodat(info->t_mnt_fd, DIR0, 0777, 0)) {
> +		log_stderr("failure: fchmodat");
> +		goto out_rm;
> +	}
> +
> +	snprintf(path, sizeof(path), "%s/%s", info->t_mountpoint, DIR0);
> +	if (sys_mount("tmpfs", path, "tmpfs", 0, NULL)) {
> +		log_stderr("failure: mount");
> +		goto out_rm;
> +	}
> +
> +	// Create a new info to use for the test we will call.
> +	nested_test_info = *info;
> +	nested_test_info.t_mountpoint = strdup(path);
> +	if (!nested_test_info.t_mountpoint) {
> +		log_stderr("failure: strdup");
> +		goto out;
> +	}
> +	nested_test_info.t_mnt_fd = openat(-EBADF, nested_test_info.t_mountpoint, O_CLOEXEC | O_DIRECTORY);
> +	if (nested_test_info.t_mnt_fd < 0) {
> +		log_stderr("failure: openat");
> +		goto out;
> +	}
> +
> +	test_setup(&nested_test_info);
> +
> +	// Run the test.
> +	if ((*test)(&nested_test_info)) {
> +		log_stderr("failure: calling test");
> +		goto out;
> +	}
> +
> +	test_cleanup(&nested_test_info);
> +
> +	fret = 0;
> +	log_debug("Ran test");
> +out:
> +	snprintf(path, sizeof(path), "%s/" DIR0, info->t_mountpoint);
> +	sys_umount2(path, MNT_DETACH);
> +out_rm:
> +	if (rm_r(info->t_mnt_fd, DIR0))
> +		log_stderr("failure: rm_r");
> +out_close:
> +	safe_close(attr.userns_fd);
> +	return fret;
> +}
> +
> +static int tmpfs_acls(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_acls);
> +}
> +static int tmpfs_create_in_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_create_in_userns);
> +}
> +static int tmpfs_device_node_in_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_device_node_in_userns);
> +}
> +static int tmpfs_fsids_mapped(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_fsids_mapped);
> +}
> +static int tmpfs_fsids_unmapped(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_fsids_unmapped);
> +}
> +static int tmpfs_expected_uid_gid_idmapped_mounts(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_expected_uid_gid_idmapped_mounts);
> +}
> +static int tmpfs_fscaps_idmapped_mounts(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_fscaps_idmapped_mounts);
> +}
> +static int tmpfs_fscaps_idmapped_mounts_in_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_fscaps_idmapped_mounts_in_userns);
> +}
> +static int tmpfs_fscaps_idmapped_mounts_in_userns_separate_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_fscaps_idmapped_mounts_in_userns_separate_userns);
> +}
> +
> +static int tmpfs_hardlink_crossing_idmapped_mounts(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_hardlink_crossing_idmapped_mounts);
> +}
> +static int tmpfs_hardlink_from_idmapped_mount(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_hardlink_from_idmapped_mount);
> +}
> +static int tmpfs_hardlink_from_idmapped_mount_in_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_hardlink_from_idmapped_mount_in_userns);
> +}
> +
> +#ifdef HAVE_LIBURING_H
> +static int tmpfs_io_uring_idmapped(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_io_uring_idmapped);
> +}
> +static int tmpfs_io_uring_idmapped_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_io_uring_idmapped_userns);
> +}
> +static int tmpfs_io_uring_idmapped_unmapped(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_io_uring_idmapped_unmapped);
> +}
> +static int tmpfs_io_uring_idmapped_unmapped_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_io_uring_idmapped_unmapped_userns);
> +}
> +#endif /* HAVE_LIBURING_H */
> +
> +static int tmpfs_protected_symlinks_idmapped_mounts(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_protected_symlinks_idmapped_mounts);
> +}
> +static int tmpfs_protected_symlinks_idmapped_mounts_in_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_protected_symlinks_idmapped_mounts_in_userns);
> +}
> +static int tmpfs_rename_crossing_idmapped_mounts(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_rename_crossing_idmapped_mounts);
> +}
> +static int tmpfs_rename_from_idmapped_mount(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_rename_from_idmapped_mount);
> +}
> +static int tmpfs_rename_from_idmapped_mount_in_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_rename_from_idmapped_mount_in_userns);
> +}
> +static int tmpfs_setattr_truncate_idmapped(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_setattr_truncate_idmapped);
> +}
> +static int tmpfs_setattr_truncate_idmapped_in_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_setattr_truncate_idmapped_in_userns);
> +}
> +static int tmpfs_setgid_create_idmapped(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_setgid_create_idmapped);
> +}
> +static int tmpfs_setgid_create_idmapped_in_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_setgid_create_idmapped_in_userns);
> +}
> +static int tmpfs_setid_binaries_idmapped_mounts(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_setid_binaries_idmapped_mounts);
> +}
> +static int tmpfs_setid_binaries_idmapped_mounts_in_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_setid_binaries_idmapped_mounts_in_userns);
> +}
> +static int tmpfs_setid_binaries_idmapped_mounts_in_userns_separate_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_setid_binaries_idmapped_mounts_in_userns_separate_userns);
> +}
> +static int tmpfs_sticky_bit_unlink_idmapped_mounts(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_sticky_bit_unlink_idmapped_mounts);
> +}
> +static int tmpfs_sticky_bit_unlink_idmapped_mounts_in_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_sticky_bit_unlink_idmapped_mounts_in_userns);
> +}
> +static int tmpfs_sticky_bit_rename_idmapped_mounts(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_sticky_bit_rename_idmapped_mounts);
> +}
> +static int tmpfs_sticky_bit_rename_idmapped_mounts_in_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_sticky_bit_rename_idmapped_mounts_in_userns);
> +}
> +static int tmpfs_symlink_idmapped_mounts(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_symlink_idmapped_mounts);
> +}
> +static int tmpfs_symlink_idmapped_mounts_in_userns(const struct vfstest_info *info)
> +{
> +	return tmpfs_nested_mount_setup(info, tcore_symlink_idmapped_mounts_in_userns);
> +}
> +
> +static const struct test_struct t_tmpfs[] = {
> +	{ tmpfs_acls,						T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs create operations in user namespace",							      },
> +	{ tmpfs_create_in_userns,						T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs create operations in user namespace",							      },
> +	{ tmpfs_device_node_in_userns,						T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs device node in user namespace",								      },
> +	{ tmpfs_expected_uid_gid_idmapped_mounts,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs expected ownership on idmapped mounts",							},
> +	{ tmpfs_fscaps_idmapped_mounts,						T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs fscaps on idmapped mounts",									},
> +	{ tmpfs_fscaps_idmapped_mounts_in_userns,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs fscaps on idmapped mounts in user namespace",							},
> +	{ tmpfs_fscaps_idmapped_mounts_in_userns_separate_userns,		T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs fscaps on idmapped mounts in user namespace with different id mappings",			},
> +	{ tmpfs_fsids_mapped,							T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs mapped fsids",										      },
> +	{ tmpfs_fsids_unmapped,							T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs unmapped fsids",										      },
> +	{ tmpfs_hardlink_crossing_idmapped_mounts,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs cross idmapped mount hardlink",								},
> +	{ tmpfs_hardlink_from_idmapped_mount,					T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs hardlinks from idmapped mounts",								},
> +	{ tmpfs_hardlink_from_idmapped_mount_in_userns,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs hardlinks from idmapped mounts in user namespace",						},
> +#ifdef HAVE_LIBURING_H
> +	{ tmpfs_io_uring_idmapped,						T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs io_uring from idmapped mounts",								      },
> +	{ tmpfs_io_uring_idmapped_userns,					T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs io_uring from idmapped mounts in user namespace",					      },
> +	{ tmpfs_io_uring_idmapped_unmapped,					T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs io_uring from idmapped mounts with unmapped ids",					      },
> +	{ tmpfs_io_uring_idmapped_unmapped_userns,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs io_uring from idmapped mounts with unmapped ids in user namespace",			      },
> +#endif
> +	{ tmpfs_protected_symlinks_idmapped_mounts,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs following protected symlinks on idmapped mounts",						},
> +	{ tmpfs_protected_symlinks_idmapped_mounts_in_userns,			T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs following protected symlinks on idmapped mounts in user namespace",				},
> +	{ tmpfs_rename_crossing_idmapped_mounts,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs cross idmapped mount rename",									},
> +	{ tmpfs_rename_from_idmapped_mount,					T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs rename from idmapped mounts",									},
> +	{ tmpfs_rename_from_idmapped_mount_in_userns,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs rename from idmapped mounts in user namespace",						},
> +	{ tmpfs_setattr_truncate_idmapped,					T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs setattr truncate on idmapped mounts",								},
> +	{ tmpfs_setattr_truncate_idmapped_in_userns,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs setattr truncate on idmapped mounts in user namespace",					},
> +	{ tmpfs_setgid_create_idmapped,						T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs create operations in directories with setgid bit set on idmapped mounts",			},
> +	{ tmpfs_setgid_create_idmapped_in_userns,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs create operations in directories with setgid bit set on idmapped mounts in user namespace",	},
> +	{ tmpfs_setid_binaries_idmapped_mounts,					T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs setid binaries on idmapped mounts",								},
> +	{ tmpfs_setid_binaries_idmapped_mounts_in_userns,			T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs setid binaries on idmapped mounts in user namespace",						},
> +	{ tmpfs_setid_binaries_idmapped_mounts_in_userns_separate_userns,	T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs setid binaries on idmapped mounts in user namespace with different id mappings",		},
> +	{ tmpfs_sticky_bit_unlink_idmapped_mounts,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs sticky bit unlink operations on idmapped mounts",						},
> +	{ tmpfs_sticky_bit_unlink_idmapped_mounts_in_userns,			T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs sticky bit unlink operations on idmapped mounts in user namespace",				},
> +	{ tmpfs_sticky_bit_rename_idmapped_mounts,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs sticky bit rename operations on idmapped mounts",						},
> +	{ tmpfs_sticky_bit_rename_idmapped_mounts_in_userns,			T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs sticky bit rename operations on idmapped mounts in user namespace",				},
> +	{ tmpfs_symlink_idmapped_mounts,					T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs symlink from idmapped mounts",									},
> +	{ tmpfs_symlink_idmapped_mounts_in_userns,				T_REQUIRE_USERNS | T_REQUIRE_IDMAPPED_MOUNTS,	"tmpfs symlink from idmapped mounts in user namespace",						},
> +};
> +
> +
> +const struct test_suite s_tmpfs_idmapped_mounts = {
> +	.tests = t_tmpfs,
> +	.nr_tests = ARRAY_SIZE(t_tmpfs),
> +};
> diff --git src/vfs/tmpfs-idmapped-mounts.h src/vfs/tmpfs-idmapped-mounts.h
> new file mode 100644
> index 00000000..ed24651f
> --- /dev/null
> +++ src/vfs/tmpfs-idmapped-mounts.h
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef __TMPFS_IDMAPPED_MOUNTS_H
> +#define __TMPFS_IDMAPPED_MOUNTS_H
> +
> +#ifndef _GNU_SOURCE
> +#define _GNU_SOURCE
> +#endif
> +
> +#include "utils.h"
> +
> +extern const struct test_suite s_tmpfs_idmapped_mounts;
> +
> +#endif /* __TMPFS_IDMAPPED_MOUNTS_H */
> diff --git src/vfs/utils.h src/vfs/utils.h
> index f1681737..872fd96f 100644
> --- src/vfs/utils.h
> +++ src/vfs/utils.h
> @@ -45,6 +45,8 @@
>  #define DIR2 "dir2"
>  #define DIR3 "dir3"
>  #define DIR1_RENAME "dir1_rename"
> +// This directory may be used by tests that call another test.
> +#define DIR0 "dir0"
>  #define HARDLINK1 "hardlink1"
>  #define SYMLINK1 "symlink1"
>  #define SYMLINK_USER1 "symlink_user1"
> diff --git src/vfs/vfstest.c src/vfs/vfstest.c
> index 325f04a1..f842117d 100644
> --- src/vfs/vfstest.c
> +++ src/vfs/vfstest.c
> @@ -23,6 +23,7 @@
>  #include <unistd.h>
>  
>  #include "btrfs-idmapped-mounts.h"
> +#include "tmpfs-idmapped-mounts.h"
>  #include "idmapped-mounts.h"
>  #include "missing.h"
>  #include "utils.h"
> @@ -2316,6 +2317,7 @@ static void usage(void)
>  	fprintf(stderr, "--test-fscaps-regression            Run fscap regression tests\n");
>  	fprintf(stderr, "--test-nested-userns                Run nested userns idmapped mount testsuite\n");
>  	fprintf(stderr, "--test-btrfs                        Run btrfs specific idmapped mount testsuite\n");
> +	fprintf(stderr, "--test-tmpfs                        Run tmpfs specific idmapped mount testsuite\n");
>  	fprintf(stderr, "--test-setattr-fix-968219708108     Run setattr regression tests\n");
>  	fprintf(stderr, "--test-setxattr-fix-705191b03d50    Run setxattr regression tests\n");
>  	fprintf(stderr, "--test-setgid-create-umask          Run setgid with umask tests\n");
> @@ -2340,6 +2342,7 @@ static const struct option longopts[] = {
>  	{"test-setxattr-fix-705191b03d50",	no_argument,		0,	'j'},
>  	{"test-setgid-create-umask",		no_argument,		0,	'u'},
>  	{"test-setgid-create-acl",		no_argument,		0,	'l'},
> +	{"test-tmpfs",				no_argument,		0,	't'},
>  	{NULL,					0,			0,	  0},
>  };
>  
> @@ -2480,7 +2483,7 @@ int main(int argc, char *argv[])
>  	bool idmapped_mounts_supported = false, test_btrfs = false,
>  	     test_core = false, test_fscaps_regression = false,
>  	     test_nested_userns = false, test_setattr_fix_968219708108 = false,
> -	     test_setxattr_fix_705191b03d50 = false,
> +	     test_setxattr_fix_705191b03d50 = false, test_tmpfs = false,
>  	     test_setgid_create_umask = false, test_setgid_create_acl = false;
>  
>  	init_vfstest_info(&info);
> @@ -2529,6 +2532,9 @@ int main(int argc, char *argv[])
>  		case 'l':
>  			test_setgid_create_acl = true;
>  			break;
> +		case 't':
> +			test_tmpfs = true;
> +			break;
>  		case 'h':
>  			/* fallthrough */
>  		default:
> @@ -2622,6 +2628,11 @@ int main(int argc, char *argv[])
>  			goto out;
>  	}
>  
> +	if (test_tmpfs) {
> +		if (!run_suite(&info, &s_tmpfs_idmapped_mounts))
> +			goto out;
> +	}
> +
>  	fret = EXIT_SUCCESS;
>  
>  out:
> diff --git tests/tmpfs/001 tests/tmpfs/001
> new file mode 100755
> index 00000000..37ef0b18
> --- /dev/null
> +++ tests/tmpfs/001
> @@ -0,0 +1,27 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2023 Rodrigo Campos Catelin (Microsoft). All Rights Reserved.
> +#
> +# FS QA Test 001
> +#
> +# Test that idmapped mounts behave correctly with tmpfs filesystem.
> +#
> +. ./common/preamble
> +_begin_fstest auto quick idmapped
> +
> +# get standard environment, filters and checks
> +. ./common/filter
> +
> +# real QA test starts here
> +
> +_supported_fs tmpfs
> +_require_idmapped_mounts
> +_require_test
> +
> +echo "Silence is golden"
> +
> +$here/src/vfs/vfstest --test-tmpfs --device "$TEST_DEV" \
> +	        --mount "$TEST_DIR" --fstype "$FSTYP"
> +
> +status=$?
> +exit
> diff --git tests/tmpfs/001.out tests/tmpfs/001.out
> new file mode 100644
> index 00000000..88678b8e
> --- /dev/null
> +++ tests/tmpfs/001.out
> @@ -0,0 +1,2 @@
> +QA output created by 001
> +Silence is golden
> diff --git tests/tmpfs/Makefile tests/tmpfs/Makefile
> new file mode 100644
> index 00000000..46544313
> --- /dev/null
> +++ tests/tmpfs/Makefile
> @@ -0,0 +1,24 @@
> +#
> +# Copyright (c) 2023 Rodrigo Campos Catelin (Microsoft). All Rights Reserved.
> +#
> +
> +TOPDIR = ../..
> +include $(TOPDIR)/include/builddefs
> +include $(TOPDIR)/include/buildgrouplist
> +
> +TMPFS_DIR = tmpfs
> +TARGET_DIR = $(PKG_LIB_DIR)/$(TESTS_DIR)/$(TMPFS_DIR)
> +DIRT = group.list
> +
> +default: $(DIRT)
> +
> +include $(BUILDRULES)
> +
> +install:
> +	$(INSTALL) -m 755 -d $(TARGET_DIR)
> +	$(INSTALL) -m 755 $(TESTS) $(TARGET_DIR)
> +	$(INSTALL) -m 644 group.list $(TARGET_DIR)
> +	$(INSTALL) -m 644 $(OUTFILES) $(TARGET_DIR)
> +
> +# Nothing.
> +install-dev install-lib:
> -- 
> 2.39.2
> 




[Index of Archives]     [Linux Filesystems Development]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux