Re: [PATCH] common: add support for the "local" file system type

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



On Wed, May 02, 2018 at 11:43:40PM -0400, Theodore Y. Ts'o wrote:
> 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?

I still think it's useful, and thanks for resending with such detailed
information! And I'm fine with the 'local' file system type. But I may
need some time to do careful testing and go into the details. Just some
random comments inline.

> 
> Many thanks!
> 
> 						- Ted
> 
> 
> From 8b40b28866dca119d0c807c31ae48f153ec2dc53 Mon Sep 17 00:00:00 2001
> From: Theodore Ts'o <tytso@xxxxxxx>
> 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

Does it require a non-block device format in this version of the patch?
I don't think so, as we have the new 'local' FSTYP introduced now.

> TEST_DIR and SCRATCH_MNT directories should be pre-existing
> directories provided by the execution environment.
> 
> Signed-off-by: Theodore Ts'o <tytso@xxxxxxx>
> ---
>  common/rc | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---

We really need some documentation added in README :)

>  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
> +}

Would be good to have some comments on why these mount options are not
supported for 'local'.

> +
>  # 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/*
> +                ;;

We do this in _scratch_mkfs by calling _scratch_cleanup_files. I noticed
that you already did this in _scratch_mkfs, just return here for
'local'?

>  	*)
>  		$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_DIR is guaranteed to be there (in common/config at initialization
time and in _require_test ). Perhaps we can just return in the 'local'
case?

>      _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
> +		;;

It seems $SCRATCH_DEV and $TEST_DEV are not important for 'local' type,
as long as we have SCRATCH_MNT and/or TEST_DIR defined as directories.

Thanks,
Eryu

>  	*)
>  		 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
> 
> --
> To unsubscribe from this list: send the line "unsubscribe fstests" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe fstests" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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