All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] common: add support for the "local" file system type
@ 2018-05-03  3:43 Theodore Y. Ts'o
  2018-05-03  9:22 ` Amir Goldstein
                   ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Theodore Y. Ts'o @ 2018-05-03  3:43 UTC (permalink / raw)
  To: fstests

About a year and half ago, I sent the patch attached below to add
support for a "local" file system type where the file system could not
be mounted or dismounted, but where writes to TEST_DIR and SCRATCH_MNT
would be testing the file system in question.  At the time, I couldn't
describe the use case in any greater detail than what I had in the
commit description, and Dave Chinner at the time rejected the patch
since he didn't like xfstests being used to test a proprietary file
system for which I was not able to explain the details of what we were
trying to do.

Not a big deal, I just kept the patch in my private fork[1] of
xfstests on github.

[1] https://github.com/tytso/xfstests

However, happily, we can now talk a lot more about what the "local"
file system type in xfstests was used to test.  Earlier today, Google
announced gVisor[2], and published it as open source on github[3].
gVisor works much like User Mode Linux, and I suspect much like the
Windows Subsystem for Linux in that it uses the x86_64's hardware
virtualization extensions (so it has the security fencing much like a
VM) but instead of emulating hardware, instead the emulation layer is
done at the system call level (so it's more efficient than a VM, since
there is no guest kernel).

[2] https://cloudplatform.googleblog.com/2018/05/Open-sourcing-gVisor-a-sandboxed-container-runtime.html
[3] https://github.com/google/gvisor

File systems can be implemented using Gophers[4] in a separate
process, where the communication between the gVisor sandbox and the
Gopher is via the 9P2000.L protocol.  This means that if you want to
try to exploit a buffer overflow in the userspace file system, first
you have to get past the system call validation checks done by the
gVisor Sentry process (which is written in Go which makes this rather
more difficult, especially since the Sentry process itself is
protected using seccomp[5]).  Then the buffer overflow attack has to
make it past the 9P protocol encoding/decoding, and then survive the
9P protocol validation checks in the Gopher.  The Gopher process
provides an emulated file system service using the Cloud Provider's
internal cluster storage services, much like in GCE, the Persistent
Disk service provides an emulated block device service.

[4] https://news.ycombinator.com/item?id=16979126
[5] https://news.ycombinator.com/item?id=16976557

This whole system was designed with security first and foremost.  Of
course, we also want it to pass the file system checks, which is why
were using xfstests.

The way we actually tested the gVisor file system was via a Docker
container (the Dockerfile[6] is in the xfstests-bld git repo) which
would then get consumed by gVisor's Docker/Kubernetes integration
layer.

[6] https://github.com/tytso/xfstests-bld/blob/master/Dockerfile

Anyway, back in September, 2016, Dave Chinner was peeved that I
couldn't give this full description, and I'm glad to say, now we can
finally rectify that gap.  :-)

Could this commit therefore please be considered for inclusion in
xfstests upstream?

Many thanks!

						- Ted


>From 8b40b28866dca119d0c807c31ae48f153ec2dc53 Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Sat, 17 Sep 2016 19:08:18 -0400
Subject: [PATCH] common: add support for the "local" file system type

It is sometimes useful to be able to test the local file system
provided in a restricted execution environment (such as that which is
provided by Docker, for example) where it is not possible to mount and
unmount the file system under test.

To support this test case, add support for a new file system type
called "local".  The TEST_DEV and SCRATCH_DEV should be have a
non-block device format (e.g., local:/test or local:/scratch), and the
TEST_DIR and SCRATCH_MNT directories should be pre-existing
directories provided by the execution environment.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
 common/rc | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 70 insertions(+), 3 deletions(-)

diff --git a/common/rc b/common/rc
index 9ffab7fd..d5cb0fe4 100644
--- a/common/rc
+++ b/common/rc
@@ -351,6 +351,18 @@ _supports_filetype()
 	esac
 }
 
+_local_validate_mount_opt()
+{
+    case "$*" in
+	ro|ro,*|*,ro) _notrun "ro mount option not supported" ;;
+	*nosuid*) _notrun "nosuid mount option not supported" ;;
+	*noatime*) _notrun "noatime mount option not supported" ;;
+	*relatime*) _notrun "relatime mount option not supported" ;;
+	*diratime*) _notrun "diratime mount option not supported" ;;
+	*strictatime*) _notrun "strictatime mount option not supported" ;;
+    esac
+}
+
 # mount scratch device with given options but don't check mount status
 _try_scratch_mount()
 {
@@ -376,6 +388,9 @@ _scratch_unmount()
 	btrfs)
 		$UMOUNT_PROG $SCRATCH_MNT
 		;;
+	local)
+                rm -rf $SCRATCH_MNT/*
+                ;;
 	*)
 		$UMOUNT_PROG $SCRATCH_DEV
 		;;
@@ -386,6 +401,10 @@ _scratch_remount()
 {
     local opts="$1"
 
+    if [ "$FSTYP" = "local" ]; then
+	_local_validate_mount_opt "$*"
+	return 0;
+    fi
     if test -n "$opts"; then
 	mount -o "remount,$opts" $SCRATCH_MNT
     fi
@@ -395,7 +414,7 @@ _scratch_cycle_mount()
 {
     local opts="$1"
 
-    if [ "$FSTYP" = tmpfs ]; then
+    if [ "$FSTYP" = "tmpfs" -o "$FSTYP" = "local" ] ; then
 	_scratch_remount "$opts"
 	return
     fi
@@ -429,6 +448,10 @@ _test_mount()
         _overlay_test_mount $*
         return $?
     fi
+    if [ "$FSTYP" == "local" ]; then
+        mkdir -p $TEST_DIR
+	return $?
+    fi
     _test_options mount
     _mount -t $FSTYP $TEST_OPTIONS $TEST_FS_MOUNT_OPTS $SELINUX_MOUNT_OPTIONS $* $TEST_DEV $TEST_DIR
 }
@@ -437,7 +460,7 @@ _test_unmount()
 {
 	if [ "$FSTYP" == "overlay" ]; then
 		_overlay_test_unmount
-	else
+	elif [ "$FSTYP" != "local" ]; then
 		$UMOUNT_PROG $TEST_DEV
 	fi
 }
@@ -723,7 +746,7 @@ _scratch_mkfs()
 	local mkfs_status
 
 	case $FSTYP in
-	nfs*|cifs|ceph|overlay|glusterfs|pvfs2|9p)
+	nfs*|cifs|ceph|overlay|glusterfs|pvfs2|9p|local)
 		# unable to re-create this fstyp, just remove all files in
 		# $SCRATCH_MNT to avoid EEXIST caused by the leftover files
 		# created in previous runs
@@ -1465,6 +1488,10 @@ _check_mounted_on()
 	local mnt=$4
 	local type=$5
 
+	if [ "$FSTYP" == "local" ]; then
+		return 0
+	fi
+
 	# find $dev as the source, and print result in "$dev $mnt" format
 	local mount_rec=`findmnt -rncv -S $dev -o SOURCE,TARGET`
 	[ -n "$mount_rec" ] || return 1 # 1 = not mounted
@@ -1562,6 +1589,13 @@ _require_scratch_nocheck()
 			_notrun "this test requires a valid \$SCRATCH_MNT"
 		fi
 		;;
+	local)
+		if [ -z "$SCRATCH_DEV" -o ! -d "$SCRATCH_MNT" ];
+		then
+		    _notrun "this test requires a valid \$SCRATCH_MNT and unique $SCRATCH_DEV"
+		fi
+		return 0
+		;;
 	*)
 		 if [ -z "$SCRATCH_DEV" -o "`_is_block_dev "$SCRATCH_DEV"`" = "" ]
 		 then
@@ -1683,6 +1717,13 @@ _require_test()
 			_notrun "this test requires a valid \$TEST_DIR"
 		fi
 		;;
+	local)
+		if [ -z "$TEST_DEV" -o ! -d "$TEST_DIR" ];
+		then
+		    _notrun "this test requires a valid \$TEST_DIR and unique $TEST_DEV"
+		fi
+		return 0
+		;;
 	*)
 		 if [ -z "$TEST_DEV" ] || [ "`_is_block_dev "$TEST_DEV"`" = "" ]
 		 then
@@ -2438,6 +2479,10 @@ _remount()
     local device=$1
     local mode=$2
 
+    if [ "$FSTYP" == "local" ] ; then
+       return 0
+    fi
+
     if ! mount -o remount,$mode $device
     then
         echo "_remount: failed to remount filesystem on $device as $mode"
@@ -2483,6 +2528,10 @@ _mount_or_remount_rw()
 	local device=$2
 	local mountpoint=$3
 
+	if [ "$FSTYP" == "local" ] ; then
+	    return 0
+	fi
+
 	if [ $USE_REMOUNT -eq 0 ]; then
 		if [ "$FSTYP" != "overlay" ]; then
 			_mount -t $FSTYP $mount_opts $device $mountpoint
@@ -2636,6 +2685,9 @@ _check_test_fs()
     ubifs)
 	# there is no fsck program for ubifs yet
 	;;
+    local)
+	# no way to check consistency for local
+	;;
     *)
 	_check_generic_filesystem $TEST_DEV
 	;;
@@ -2691,6 +2743,9 @@ _check_scratch_fs()
     ubifs)
 	# there is no fsck program for ubifs yet
 	;;
+    local)
+	# no way to check consistency for local
+	;;
     *)
 	_check_generic_filesystem $device
 	;;
@@ -3003,6 +3058,9 @@ _require_fio()
 # Does freeze work on this fs?
 _require_freeze()
 {
+	if [ "$FSTYP" == "local" ]; then
+		_notrun "local does not support freeze"
+	fi
 	xfs_freeze -f "$TEST_DIR" >/dev/null 2>&1
 	local result=$?
 	xfs_freeze -u "$TEST_DIR" >/dev/null 2>&1
@@ -3024,6 +3082,9 @@ _require_scratch_shutdown()
 {
 	[ -x src/godown ] || _notrun "src/godown executable not found"
 
+	if [ "$FSTYP" == "local" ]; then
+		_notrun "local does not support shutdown"
+	fi
 	_scratch_mkfs > /dev/null 2>&1 || _notrun "_scratch_mkfs failed on $SCRATCH_DEV"
 	_scratch_mount
 
@@ -3049,6 +3110,9 @@ _require_scratch_shutdown()
 # Does dax mount option work on this dev/fs?
 _require_scratch_dax()
 {
+	if [ "$FSTYP" == "local" ]; then
+		_notrun "local does not support dax"
+	fi
 	_require_scratch
 	_scratch_mkfs > /dev/null 2>&1
 	_try_scratch_mount -o dax || \
@@ -3063,6 +3127,9 @@ _require_scratch_dax()
 # Does norecovery support by this fs?
 _require_norecovery()
 {
+	if [ "$FSTYP" == "local" ]; then
+		_notrun "local does not support norecovery"
+	fi
 	_try_scratch_mount -o ro,norecovery || \
 		_notrun "$FSTYP does not support norecovery"
 	_scratch_unmount
-- 
2.16.1.72.g5be1f00a9a


^ permalink raw reply related	[flat|nested] 21+ messages in thread
* [PATCH] common: add support for the "local" file system type
@ 2016-09-23 20:05 Theodore Ts'o
  2016-09-26 13:25 ` Eryu Guan
                   ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Theodore Ts'o @ 2016-09-23 20:05 UTC (permalink / raw)
  To: fstests; +Cc: Theodore Ts'o

It is sometimes useful to be able to test the local file system
provided in a restricted execution environment (such as that which is
provided by Docker, for example) where it is not possible to mount and
unmount the file system under test.

To support this test case, add support for a new file system type
called "local".  The TEST_DEV and SCRATCH_DEV should be have a
non-block device format (e.g., local:/test or local:/scratch), and the
TEST_DIR and SCRATCH_MNT directories should be pre-existing
directories provided by the execution environment.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
 common/rc         | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
 tests/generic/027 |  2 +-
 2 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/common/rc b/common/rc
index 70d79c9..c03b132 100644
--- a/common/rc
+++ b/common/rc
@@ -330,12 +330,29 @@ _overlay_scratch_unmount()
 	$UMOUNT_PROG $SCRATCH_MNT
 }
 
+_local_validate_mount_opt()
+{
+    case "$*" in
+	ro|ro,*|*,ro) _notrun "ro mount option not supported" ;;
+	*nosuid*) _notrun "nosuid mount option not supported" ;;
+	*noatime*) _notrun "noatime mount option not supported" ;;
+	*relatime*) _notrun "relatime mount option not supported" ;;
+	*diratime*) _notrun "diratime mount option not supported" ;;
+	*strictatime*) _notrun "strictatime mount option not supported" ;;
+    esac
+}
+
 _scratch_mount()
 {
     if [ "$FSTYP" == "overlay" ]; then
         _overlay_scratch_mount $*
         return $?
     fi
+    if [ "$FSTYP" == "local" ]; then
+	_local_validate_mount_opt "$*"
+        mkdir -p $SCRATCH_MNT
+	return $?
+    fi
     _mount -t $FSTYP `_scratch_mount_options $*`
 }
 
@@ -348,6 +365,9 @@ _scratch_unmount()
 	btrfs)
 		$UMOUNT_PROG $SCRATCH_MNT
 		;;
+	local)
+                rm -rf $SCRATCH_MNT/*
+                ;;
 	*)
 		$UMOUNT_PROG $SCRATCH_DEV
 		;;
@@ -358,6 +378,10 @@ _scratch_remount()
 {
     local opts="$1"
 
+    if [ "$FSTYP" = "local" ]; then
+	_local_validate_mount_opt "$*"
+	return 0;
+    fi
     if test -n "$opts"; then
 	mount -o "remount,$opts" $SCRATCH_MNT
     fi
@@ -367,7 +391,7 @@ _scratch_cycle_mount()
 {
     local opts="$1"
 
-    if [ "$FSTYP" = tmpfs ]; then
+    if [ "$FSTYP" = "tmpfs" -o "$FSTYP" = "local" ] ; then
 	_scratch_remount "$opts"
 	return
     fi
@@ -384,6 +408,10 @@ _test_mount()
         _overlay_test_mount $*
         return $?
     fi
+    if [ "$FSTYP" == "local" ]; then
+        mkdir -p $TEST_DIR
+	return $?
+    fi
     _test_options mount
     _mount -t $FSTYP $TEST_OPTIONS $TEST_FS_MOUNT_OPTS $SELINUX_MOUNT_OPTIONS $* $TEST_DEV $TEST_DIR
 }
@@ -392,7 +420,7 @@ _test_unmount()
 {
 	if [ "$FSTYP" == "overlay" ]; then
 		_overlay_test_unmount
-	else
+	elif [ "$FSTYP" != "local" ]; then
 		$UMOUNT_PROG $TEST_DEV
 	fi
 }
@@ -811,6 +839,9 @@ _scratch_mkfs()
     tmpfs)
 	# do nothing for tmpfs
 	;;
+    local)
+        _scratch_cleanup_files
+	;;
     f2fs)
         $MKFS_F2FS_PROG $MKFS_OPTIONS $* $SCRATCH_DEV > /dev/null
 	;;
@@ -1031,6 +1062,13 @@ _scratch_mkfs_sized()
 	fi
 	export MOUNT_OPTIONS="-o size=$fssize $TMPFS_MOUNT_OPTIONS"
 	;;
+    local)
+        _scratch_cleanup_files
+	free_space=$(_df_dir $SCRATCH_MNT | $AWK_PROG '{ print $5 }')
+	if [ "$(expr $free_space * 1024)" -lt "$fssize" ] ; then
+	   _notrun "Not enough space ($free_space) for local with $fssize bytes"
+	fi
+	;;
     *)
 	_notrun "Filesystem $FSTYP not supported in _scratch_mkfs_sized"
 	;;
@@ -1517,6 +1555,13 @@ _require_scratch_nocheck()
 		    _notrun "this test requires a valid \$SCRATCH_MNT and unique $SCRATCH_DEV"
 		fi
 		;;
+	local)
+		if [ -z "$SCRATCH_DEV" -o ! -d "$SCRATCH_MNT" ];
+		then
+		    _notrun "this test requires a valid \$SCRATCH_MNT and unique $SCRATCH_DEV"
+		fi
+		return 0
+		;;
 	*)
 		 if [ -z "$SCRATCH_DEV" -o "`_is_block_dev "$SCRATCH_DEV"`" = "" ]
 		 then
@@ -1602,6 +1647,13 @@ _require_test()
 		    _notrun "this test requires a valid \$TEST_DIR and unique $TEST_DEV"
 		fi
 		;;
+	local)
+		if [ -z "$TEST_DEV" -o ! -d "$TEST_DIR" ];
+		then
+		    _notrun "this test requires a valid \$TEST_DIR and unique $TEST_DEV"
+		fi
+		return 0
+		;;
 	*)
 		 if [ -z "$TEST_DEV" ] || [ "`_is_block_dev "$TEST_DEV"`" = "" ]
 		 then
@@ -2264,6 +2316,10 @@ _remount()
     device=$1
     mode=$2
 
+    if [ "$FSTYP" == "local" ] ; then
+       return 0
+    fi
+
     if ! mount -o remount,$mode $device
     then
         echo "_remount: failed to remount filesystem on $device as $mode"
@@ -2309,6 +2365,10 @@ _mount_or_remount_rw()
 	device=$2
 	mountpoint=$3
 
+	if [ "$FSTYP" == "local" ] ; then
+	    return 0
+	fi
+
 	if [ $USE_REMOUNT -eq 0 ]; then
 		if [ "$FSTYP" != "overlay" ]; then
 			_mount -t $FSTYP $mount_opts $device $mountpoint
@@ -2666,6 +2726,9 @@ _check_test_fs()
     tmpfs)
 	# no way to check consistency for tmpfs
 	;;
+    local)
+	# no way to check consistency for local
+	;;
     *)
 	_check_generic_filesystem $TEST_DEV
 	;;
@@ -2707,6 +2770,9 @@ _check_scratch_fs()
     tmpfs)
 	# no way to check consistency for tmpfs
 	;;
+    local)
+	# no way to check consistency for local
+	;;
     *)
 	_check_generic_filesystem $device
 	;;
@@ -3784,7 +3850,7 @@ init_rc()
 		fi
 	fi
 
-	if [ "`_fs_type $TEST_DEV`" != "$FSTYP" ]
+	if [ "$FSTYP" != "local" -a "`_fs_type $TEST_DEV`" != "$FSTYP" ]
 	then
 		echo "common/rc: Error: \$TEST_DEV ($TEST_DEV) is not a MOUNTED $FSTYP filesystem"
 		# raw $DF_PROG cannot handle NFS/CIFS/overlay correctly
diff --git a/tests/generic/027 b/tests/generic/027
index d2e59d6..73565fc 100755
--- a/tests/generic/027
+++ b/tests/generic/027
@@ -77,7 +77,7 @@ rm -f $SCRATCH_MNT/testfile
 
 loop=100
 # btrfs takes much longer time, reduce the loop count
-if [ "$FSTYP" == "btrfs" ]; then
+if [ "$FSTYP" == "btrfs" -o "$FSTYP" == "local" ]; then
 	loop=10
 fi
 
-- 
2.9.0.243.g5c589a7.dirty


^ permalink raw reply related	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2018-05-12  8:42 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-03  3:43 [PATCH] common: add support for the "local" file system type Theodore Y. Ts'o
2018-05-03  9:22 ` Amir Goldstein
2018-05-03 18:35   ` Theodore Y. Ts'o
2018-05-03 19:24     ` Amir Goldstein
2018-05-06  3:54 ` Eryu Guan
2018-05-12  8:42 ` Eryu Guan
  -- strict thread matches above, loose matches on Subject: below --
2016-09-23 20:05 Theodore Ts'o
2016-09-26 13:25 ` Eryu Guan
2016-09-26 15:14   ` Theodore Ts'o
2016-09-27  9:55     ` Eryu Guan
2016-09-29  0:01       ` Theodore Ts'o
2016-09-26 22:18 ` Dave Chinner
2016-09-28 23:57   ` Theodore Ts'o
2016-09-29  2:16     ` Dave Chinner
2016-09-29  3:56       ` Theodore Ts'o
2016-09-29  5:37         ` Dave Chinner
2016-09-29 13:05           ` Theodore Ts'o
2016-09-29 22:49             ` Dave Chinner
2016-09-30  3:43               ` Theodore Ts'o
2016-09-29 13:37         ` Eric Sandeen
2016-09-29 13:57 ` Eric Sandeen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.