This test checks two behaviour cases:

When a mount is propagated to a place which is already busy, the new
mount is inserted between parent and old mount.

When a mount that is being unmounted due to propagation has another
mount on top of it, it is replaced by the top mount.

Cc: Shuah Khan <sh...@kernel.org>
Signed-off-by: Andrei Vagin <ava...@openvz.org>
---
 tools/testing/selftests/mount/Makefile             | 19 +++--
 tools/testing/selftests/mount/test-reparent-mounts | 92 ++++++++++++++++++++++
 2 files changed, 105 insertions(+), 6 deletions(-)
 create mode 100755 tools/testing/selftests/mount/test-reparent-mounts

diff --git a/tools/testing/selftests/mount/Makefile 
b/tools/testing/selftests/mount/Makefile
index 9093d7f..5927230 100644
--- a/tools/testing/selftests/mount/Makefile
+++ b/tools/testing/selftests/mount/Makefile
@@ -6,11 +6,18 @@ TEST_GEN_PROGS := unprivileged-remount-test
 
 include ../lib.mk
 
-override RUN_TESTS := if [ -f /proc/self/uid_map ] ; \
-                     then      \
-                               ./unprivileged-remount-test ; \
-                     else      \
-                               echo "WARN: No /proc/self/uid_map exist, test 
skipped." ; \
-                     fi
+override define RUN_TESTS
+       if [ -f /proc/self/uid_map ] ; \
+       then    \
+               ./unprivileged-remount-test ; \
+       else    \
+               echo "WARN: No /proc/self/uid_map exist, test skipped." ; \
+       fi
+       unshare -Urm ./test-reparent-mounts
+       unshare -Urm ./test-reparent-mounts -c
+       unshare -Urm ./test-reparent-mounts -s
+       unshare -Urm ./test-reparent-mounts -s -S
+endef
+
 override EMIT_TESTS := echo "$(RUN_TESTS)"
 
diff --git a/tools/testing/selftests/mount/test-reparent-mounts 
b/tools/testing/selftests/mount/test-reparent-mounts
new file mode 100755
index 0000000..57ae300
--- /dev/null
+++ b/tools/testing/selftests/mount/test-reparent-mounts
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+# This test checks two following behaviour cases:
+#
+# When a mount is propagated to a place which is already busy, the new mount is
+# inserted between parent and old mount.
+#
+# When a mount that is being unmounted due to propagation has another mount on
+# top of it, it is replaced by the top mount.
+
+ITER=3
+
+set -e
+
+usage()
+{
+       echo " ./$0 [OPTIONS]
+This test checks a case when a mount has to be propagated under another mount.
+       -c - create a mount which is visible only from the second tree
+       -s - make a second tree as a slave to the first one
+       -S - create a sub-mount when the send tree is a slave to the first one
+       -i - how many times to call mount
+"
+}
+
+while getopts "csi:hS" opt; do
+   case $opt in
+   c )  with_child=1;;
+   s )  make_slave=1;;
+   S )  slave_child=1;;
+   i )  ITER=$OPTARG;;
+   h )  usage; exit 0 ;;
+   esac
+done
+
+shift $(($OPTIND - 1))
+
+if [ -n "$1" ]; then
+       usage
+       exit 1
+fi
+
+mount -t tmpfs test /mnt
+mkdir /mnt/main
+mkdir /mnt/second
+mount --bind /mnt/main /mnt/main
+mount --make-shared /mnt/main
+mount --bind /mnt/main /mnt/second
+mkdir -p /mnt/main/sub
+
+if [ -n "$make_slave" ]; then
+       mount --make-slave /mnt/second
+       if [ -n "slave_child" ]; then
+               mount -t tmpfs slave_child /mnt/second/sub/
+               touch /mnt/second/sub/slave_child
+       fi
+fi
+
+if [ -n "$make_slave" ]; then
+       mount --make-slave /mnt/second
+       if [ -n "$slave_child" ]; then
+               mount -t tmpfs test_slave /mnt/second/sub/
+               touch /mnt/second/sub/slave_child
+       fi
+fi
+
+for i in `seq $ITER`; do
+       mount --bind /mnt/main/sub /mnt/main/sub
+done
+
+if [ -n "$with_child" ]; then
+       mkdir /mnt/second/sub/child
+       mount --make-private /mnt/second/sub
+       mount --bind /mnt/second/sub/child /mnt/second/sub/child
+fi
+if [ -n "$slave_child" ]; then
+       test -f /mnt/second/sub/slave_child
+fi
+
+umount /mnt/main/sub
+
+if [ -n "$with_child" ]; then
+       umount /mnt/second/sub/child
+       umount /mnt/second/sub
+fi
+if [ -n "$slave_child" ]; then
+       test -f /mnt/second/sub/slave_child
+       umount /mnt/second/sub
+fi
+
+umount /mnt/second
+umount /mnt/main
-- 
2.9.3

Reply via email to