| #! /bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # Copyright (c) 2016 Red Hat Inc. All Rights Reserved. |
| # |
| # FS QA Test 409 |
| # |
| # Test mount shared subtrees, verify the bind semantics: |
| # |
| # --------------------------------------------------------------------------- |
| # | BIND MOUNT OPERATION | |
| # |************************************************************************** |
| # |source(A)->| shared | private | slave | unbindable | |
| # | dest(B) | | | | | |
| # | | | | | | | |
| # | v | | | | | |
| # |************************************************************************** |
| # | shared | shared | shared | shared & slave | invalid | |
| # | | | | | | |
| # |non-shared| shared | private | slave | invalid | |
| # *************************************************************************** |
| # |
| . ./common/preamble |
| _begin_fstest auto quick mount |
| |
| # Override the default cleanup function. |
| _cleanup() |
| { |
| _kill_fsstress |
| _clear_mount_stack |
| # make sure there's no bug cause dentry isn't be freed |
| rm -rf $MNTHEAD |
| cd / |
| rm -f $tmp.* |
| } |
| |
| # Import common functions. |
| . ./common/filter |
| |
| _require_test |
| _require_scratch |
| _require_local_device $SCRATCH_DEV |
| |
| fs_stress() |
| { |
| local target=$1 |
| |
| _run_fsstress -z -n 50 -p 3 \ |
| -f creat=5 \ |
| -f mkdir=5 \ |
| -f link=2 \ |
| -f rename=1 \ |
| -f rmdir=2 \ |
| -f unlink=1 \ |
| -f symlink=1 \ |
| -f write=1 \ |
| -f read=1 \ |
| -f chown=1 \ |
| -f getdents=1 \ |
| -f fiemap=1 \ |
| -d $target |
| _sync_fs $target |
| } |
| |
| # prepare some mountpoint dir |
| MNTHEAD=$TEST_DIR/$seq |
| rm -rf $MNTHEAD |
| mkdir $MNTHEAD 2>>$seqres.full |
| mpA=$MNTHEAD/"$$"_mpA |
| mpB=$MNTHEAD/"$$"_mpB |
| mpC=$MNTHEAD/"$$"_mpC |
| mpD=$MNTHEAD/"$$"_mpD |
| |
| find_mnt() |
| { |
| echo "------" |
| findmnt -n -o TARGET,SOURCE $SCRATCH_DEV | \ |
| sed -e "s;$mpA;mpA;g" \ |
| -e "s;$mpB;mpB;g" \ |
| -e "s;$mpC;mpC;g" \ |
| -e "s;$mpD;mpD;g" | \ |
| _filter_spaces | _filter_testdir_and_scratch | sort |
| echo "======" |
| } |
| |
| start_test() |
| { |
| local type=$1 |
| |
| _scratch_mkfs >$seqres.full 2>&1 |
| _get_mount -t $FSTYP $SCRATCH_DEV $MNTHEAD |
| $MOUNT_PROG --make-"${type}" $MNTHEAD |
| mkdir $mpA $mpB $mpC $mpD |
| } |
| |
| end_test() |
| { |
| _clear_mount_stack |
| rm -rf $mpA $mpB $mpC $mpD |
| } |
| |
| bind_run() |
| { |
| local source=$1 |
| local dest=$2 |
| |
| start_test $dest |
| |
| echo "bind $source on $dest" |
| _get_mount -t $FSTYP $SCRATCH_DEV $mpA |
| mkdir -p $mpA/dir 2>/dev/null |
| $MOUNT_PROG --make-shared $mpA |
| _get_mount --bind $mpA $mpB |
| $MOUNT_PROG --make-"$source" $mpB |
| # maybe unbindable at here |
| _get_mount --bind $mpB $mpC 2>/dev/null |
| if [ $? -ne 0 ]; then |
| find_mnt |
| end_test |
| return 0 |
| fi |
| _get_mount --bind $mpC $mpD |
| for m in $mpA $mpB $mpC $mpD; do |
| _get_mount -t $FSTYP $SCRATCH_DEV $m/dir |
| fs_stress $m/dir |
| find_mnt |
| _put_mount |
| done |
| |
| end_test |
| } |
| |
| bind_test() |
| { |
| # source dest |
| bind_run shared shared |
| bind_run slave shared |
| bind_run private shared |
| bind_run unbindable shared |
| |
| bind_run shared slave |
| bind_run slave slave |
| bind_run private slave |
| bind_run unbindable slave |
| |
| bind_run shared private |
| bind_run slave private |
| bind_run private private |
| bind_run unbindable private |
| } |
| |
| bind_test |
| |
| # success, all done |
| status=0 |
| exit |