blob: ac1b14ad60f7233be4efa781db79d15beb77272d [file] [log] [blame]
#! /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