Whamcloud - gitweb
- added test_3b which emulates recursive mount. Does not pass yet.
[fs/lustre-release.git] / lustre / tests / sanity-gns.sh
index c540b91..b55312a 100644 (file)
@@ -97,7 +97,7 @@ check_kernel_version() {
 }
 
 run_one() {
-       if ! mount | grep -q $DIR; then
+       if ! cat /proc/mounts | grep -q $DIR; then
                $START
        fi
        echo $PTLDEBUG >/proc/sys/portals/debug 
@@ -189,7 +189,7 @@ rm -rf $DIR/[Rdfs][1-9]*
 build_test_filter
 
 echo preparing for tests involving mounts
-EXT2_DEV=${EXT2_DEV:-/tmp/SANITY.LOOP}
+EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
 touch $EXT2_DEV
 mke2fs -j -F $EXT2_DEV 8000 >/dev/null 2>&1
 
@@ -245,11 +245,11 @@ setup_upcall() {
     local LOG=$3
     local BG=$4
     
-    test "x$BG" = "xBACKGROUND" && 
+    test "x$BG" = "xBG" && 
        BG="&" || BG=""
     
-    test "x$MODE" = "xDEADLOCK" &&
-       INJECTION="touch \$MNTPATH/file"
+#    test "x$MODE" = "xDEADLOCK" &&
+#      INJECTION="touch \$MNTPATH/file"
     
     cat > $UPCALL <<- EOF
 #!/bin/sh
@@ -286,8 +286,24 @@ show_log() {
     }
 }
 
+check_mnt()
+{
+    local OBJECT=$1
+    local mnt=""
+    local p=""
+    
+    mnt="`cat /proc/mounts | grep $OBJECT | awk '{print \$2}'`"
+    test -z "$mnt" && return 1
+    
+    for p in $mnt; do
+       test "x$p" = "x$OBJECT" || return 1
+    done
+    
+    return 0
+}
+
 check_gns() {
-    local LOG="/tmp/gns-log"
+    local LOG="$TMP/gns-log"
     local UPCALL_PATH=""
     
     local UPCALL=$1
@@ -297,9 +313,10 @@ check_gns() {
     local TICK=$5
     local MODE=$6
     local BG=$7
+    local OP=$8
     
     rm -fr $LOG >/dev/null 2>&1
-    UPCALL_PATH="/tmp/gns-upcall-$UPCALL.sh"
+    UPCALL_PATH="$TMP/gns-upcall-$UPCALL.sh"
     
     echo "generating upcall $UPCALL_PATH"
     setup_upcall $UPCALL_PATH $UPCALL $LOG $BG || return $rc
@@ -311,18 +328,46 @@ check_gns() {
     echo "$UPCALL_PATH" > /proc/fs/lustre/llite/fs0/gns_upcall || return $?
     echo "upcall:  $(cat /proc/fs/lustre/llite/fs0/gns_upcall)"
 
+    echo -n "mount on $OP: "
+
+    local OLD_PWD=$(pwd)
+    
     case "$MODE" in
        GENERIC)
-           echo -n "mount on open $OBJECT1/test_file1 (generic): "
-           echo -n "test data" > $OBJECT1/test_file1 >/dev/null 2>&1 || return $?
+           case "$OP" in
+               OPEN)
+                   echo -n "test data" > $OBJECT1/test_file1 >/dev/null 2>&1
+                   ;;
+               LIST)
+                   ls -la $OBJECT1/
+                   ;;
+               CHDIR)
+                   cd $OBJECT1 || return $?
+                   ;;
+               *)
+                   echo "invalid testing operation $OP"
+                   return 1
+           esac
            ;;
        CONCUR1)
            local i=1
            local nr=20
        
-           echo -n "mount on open $OBJECT1/test_file1 ($nr threads): "
            for ((;i<=$nr;i++)); do 
-               echo -n "test data" > $OBJECT1/test_file$i >/dev/null 2>&1 &
+               case "$OP" in
+                   OPEN)
+                       echo -n "test data" > $OBJECT1/test_file$i >/dev/null 2>&1 &
+                       ;;
+                   LIST)
+                       ls -la $OBJECT1/
+                       ;;
+                   CHDIR)
+                       cd $OBJECT1 >/dev/null 2>&1 &
+                       ;;
+                   *)
+                       echo "invalid testing operation $OP"
+                       return 1
+               esac
            done
        
            wait
@@ -337,10 +382,23 @@ check_gns() {
                echo "not defined object2 for concurrent2 testing"
                return 1
            }
-           echo -n "mount on open $OBJECT1/test_file1: "
-           echo -n "mount on open $OBJECT2/test_file1: "
-           echo -n "test data" > $OBJECT1/test_file1 >/dev/null 2>&1 &
-           echo -n "test data" > $OBJECT2/test_file1 >/dev/null 2>&1 &
+           case "$OP" in
+               OPEN)
+                   echo -n "test data" > $OBJECT1/test_file1 >/dev/null 2>&1 &
+                   echo -n "test data" > $OBJECT2/test_file1 >/dev/null 2>&1 &
+                   ;;
+               LIST)
+                   ls -la $OBJECT1/
+                   ls -la $OBJECT2/
+                   ;;
+               CHDIR)
+                   cd $OBJECT1 >/dev/null 2>&1 &
+                   cd $OBJECT2 >/dev/null 2>&1 &
+                   ;;
+               *)
+                   echo "invalid testing operation $OP"
+                   return 1
+           esac
            
            wait
            
@@ -350,15 +408,30 @@ check_gns() {
                return $RETVAL
            ;;
        CONCUR3)
-           echo -n "mount on open $OBJECT1/test_file1: "
-           
            local i=1
            local nr=20
            
            for ((;i<$nr;i++)); do
-               touch $OBJECT1/file$i &
-               echo -n "test data" > $OBJECT1/test_file$i >/dev/null 2>&1 &
-               mkdir $OBJECT1/dir$i &
+               case "$OP" in
+                   OPEN)
+                       touch $OBJECT1/file$i &
+                       echo -n "test data" > $OBJECT1/test_file$i >/dev/null 2>&1 &
+                       mkdir $OBJECT1/dir$i &
+                       ;;
+                   LIST)
+                       touch $OBJECT1/file &
+                       ls -la $OBJECT1/ &
+                       mkdir $OBJECT1/dir$i &
+                       ;;
+                   CHDIR)
+                       touch $OBJECT1/file$i &
+                       cd $OBJECT1 >/dev/null 2>&1 &
+                       mkdir $OBJECT1/dir$i &
+                       ;;
+                   *)
+                       echo "invalid testing operation $OP"
+                       return 1
+               esac
            done
 
            wait
@@ -372,18 +445,17 @@ check_gns() {
            echo "invalid testing mode $MODE"
            return 1
     esac
+
+    test "x$OP" = "xCHDIR" && cd $OLD_PWD
     
-    local ENTRY1="`basename $OBJECT1`"
-    local ENTRY2="`basename $OBJECT2`"
-    
-    cat /proc/mounts | grep -q "$ENTRY1" || {
+    check_mnt $OBJECT1 || {
        echo "fail"
        show_log $LOG
        return 1
     }
     
     if test "x$MODE" = "xCONCUR2"; then
-       cat /proc/mounts | grep -q "$ENTRY2" || {
+       check_mnt $OBJECT2 || {
            echo "fail"
            show_log $LOG
            return 1
@@ -396,14 +468,14 @@ check_gns() {
     let sleep_time+=$TICK*2
     echo -n "waiting for umount ${sleep_time}s (timeout + tick*2): "
     sleep $sleep_time
-
-    cat /proc/mounts | grep -q "$ENTRY1" && {
+    
+    check_mnt $OBJECT1 && {
        echo "failed"
        return 2
     }
     
     if test "x$MODE" = "xCONCUR2"; then
-       cat /proc/mounts | grep -q "$ENTRY2" && {
+       check_mnt $OBJECT2 && {
            echo "failed"
            return 2
        }
@@ -427,14 +499,14 @@ setup_object() {
     echo ""
     echo "================================================================="
     
-    chmod u+s $OBJPATH -R
+    chmod u+s $OBJPATH
     return $?
 }
 
 cleanup_object() {
     local OBJPATH=$1
 
-    chmod u-s $OBJPATH -R
+    chmod u-s $OBJPATH
     umount $OBJPATH >/dev/null 2>&1
     rm -fr $OBJPATH >/dev/null 2>&1
 }
@@ -470,7 +542,7 @@ disable_gns()
 
 test_1a() {
     local LOOP_DEV=$(find_free_loop 2>/dev/null)
-    local LOOP_FILE="/tmp/gns_loop_1a"
+    local LOOP_FILE="$TMP/gns_loop_1a"
     local OBJECT=".mntinfo"
     local TIMOUT=5
     local TICK=1
@@ -494,8 +566,24 @@ test_1a() {
 
     echo ""
     echo "testing GNS with GENERIC upcall 3 times on the row"
+    
+    echo ""
+    echo "testing OPEN operation"
+    
     for ((i=0;i<3;i++)); do
-       check_gns GENERIC $DIR/gns_test_1a $DIR/gns_test_1a $TIMOUT $TICK GENERIC || {
+       check_gns GENERIC $DIR/gns_test_1a $DIR/gns_test_1a $TIMOUT $TICK GENERIC FG OPEN || {
+           disable_gns
+           cleanup_object $DIR/gns_test_1a
+           cleanup_loop $LOOP_DEV $LOOP_FILE
+           error
+       }
+    done
+    
+    echo ""
+    echo "testing CHDIR operation"
+    
+    for ((i=0;i<3;i++)); do
+       check_gns GENERIC $DIR/gns_test_1a $DIR/gns_test_1a $TIMOUT $TICK GENERIC FG CHDIR || {
            disable_gns
            cleanup_object $DIR/gns_test_1a
            cleanup_loop $LOOP_DEV $LOOP_FILE
@@ -507,13 +595,14 @@ test_1a() {
 
     cleanup_object $DIR/gns_test_1a
     cleanup_loop $LOOP_DEV $LOOP_FILE
+    return 0
 }
 
 run_test 1a " general GNS test - mount/umount (GENERIC) ================"
 
 test_1b() {
     local LOOP_DEV=$(find_free_loop 2>/dev/null)
-    local LOOP_FILE="/tmp/gns_loop_1b"
+    local LOOP_FILE="$TMP/gns_loop_1b"
     local OBJECT=".mntinfo"
     local TIMOUT=5
     local TICK=1
@@ -537,26 +626,23 @@ test_1b() {
 
     echo ""
     echo "testing GNS with DEADLOCK upcall 3 times on the row"
+    
     for ((i=0;i<3;i++)); do
-       check_gns DEADLOCK $DIR/gns_test_1b $DIR/gns_test_1b $TIMOUT $TICK GENERIC || {
-           disable_gns
-           cleanup_object $DIR/gns_test_1b
-           cleanup_loop $LOOP_DEV $LOOP_FILE
-           error
-       }
+       check_gns DEADLOCK $DIR/gns_test_1b $DIR/gns_test_1b $TIMOUT $TICK GENERIC FG OPEN
     done
     
     disable_gns
 
     cleanup_object $DIR/gns_test_1b
     cleanup_loop $LOOP_DEV $LOOP_FILE
+    return 0
 }
 
 run_test 1b " general GNS test - mount/umount (DEADLOCK) ==============="
 
 test_1c() {
     local LOOP_DEV=$(find_free_loop 2>/dev/null)
-    local LOOP_FILE="/tmp/gns_loop_1c"
+    local LOOP_FILE="$TMP/gns_loop_1c"
     local OBJECT=".mntinfo"
     local TIMOUT=5
     local TICK=1
@@ -579,33 +665,35 @@ test_1c() {
     enable_gns
 
     echo ""
-    echo "testing GNS with DEADLOCK upcall 4 times on the row"
+    echo "testing GNS with GENERIC/DEADLOCK upcall 4 times on the row in GENERIC mode"
     local i=0
     
     for ((;i<4;i++)); do
-       local MODE="GENERIC"
-       
-       test $(($i%2)) -eq 1 && MODE="DEADLOCK"
-       
-       check_gns $MODE $DIR/gns_test_1c $DIR/gns_test_1c $TIMOUT $TICK GENERIC || {
-           disable_gns
-           cleanup_object $DIR/gns_test_1c
-           cleanup_loop $LOOP_DEV $LOOP_FILE
-           error
+       test $(($i%2)) -eq 1 && {
+           check_gns DEADLOCK $DIR/gns_test_1c $DIR/gns_test_1c $TIMOUT $TICK GENERIC FG OPEN
+       } || {
+           check_gns GENERIC $DIR/gns_test_1c $DIR/gns_test_1c $TIMOUT $TICK GENERIC FG OPEN || {
+               disable_gns
+               cleanup_object $DIR/gns_test_1c
+               cleanup_loop $LOOP_DEV $LOOP_FILE
+               error "generic upcall does not work!"
+           }
        }
+       
     done
     
     disable_gns
 
     cleanup_object $DIR/gns_test_1c
     cleanup_loop $LOOP_DEV $LOOP_FILE
+    return 0
 }
 
 run_test 1c " general GNS test - mount/umount (GENERIC/DEADLOCK) ========"
 
 test_1d() {
     local LOOP_DEV=$(find_free_loop 2>/dev/null)
-    local LOOP_FILE="/tmp/gns_loop_1d"
+    local LOOP_FILE="$TMP/gns_loop_1d"
     local OBJECT=".mntinfo"
     local TIMOUT=5
     local TICK=1
@@ -628,15 +716,11 @@ test_1d() {
     enable_gns
 
     echo ""
-    echo "testing GNS with GENERIC/DEADLOCK upcall 4 times on the row in CONCUR1 mode"
+    echo "testing GNS with GENERIC upcall 4 times on the row in CONCUR1 mode"
     local i=0
     
     for ((;i<4;i++)); do
-       local MODE="GENERIC"
-       
-       test $(($i%2)) -eq 1 && MODE="DEADLOCK"
-       
-       check_gns $MODE $DIR/gns_test_1d $DIR/gns_test_1d $TIMOUT $TICK CONCUR1 || {
+       check_gns GENERIC $DIR/gns_test_1d $DIR/gns_test_1d $TIMOUT $TICK CONCUR1 FG OPEN || {
            disable_gns
            cleanup_object $DIR/gns_test_1d
            cleanup_loop $LOOP_DEV $LOOP_FILE
@@ -648,13 +732,14 @@ test_1d() {
 
     cleanup_object $DIR/gns_test_1d
     cleanup_loop $LOOP_DEV $LOOP_FILE
+    return 0
 }
 
 run_test 1d " general GNS test - concurrent mount ======================="
 
 test_1e() {
     local LOOP_DEV=$(find_free_loop 2>/dev/null)
-    local LOOP_FILE="/tmp/gns_loop_1e"
+    local LOOP_FILE="$TMP/gns_loop_1e"
     local OBJECT=".mntinfo"
     local TIMOUT=5
     local TICK=1
@@ -681,7 +766,8 @@ test_1e() {
 
     echo ""
     echo "testing GNS with GENERIC upcall in CONCUR2 mode"
-    check_gns GENERIC $DIR/gns_test_1e1 $DIR/gns_test_1e2 $TIMOUT $TICK CONCUR2 || {
+    
+    check_gns GENERIC $DIR/gns_test_1e1 $DIR/gns_test_1e2 $TIMOUT $TICK CONCUR2 FG OPEN || {
        disable_gns
         cleanup_object $DIR/gns_test_1e1
         cleanup_object $DIR/gns_test_1e2
@@ -694,6 +780,7 @@ test_1e() {
     cleanup_object $DIR/gns_test_1e1
     cleanup_object $DIR/gns_test_1e2
     cleanup_loop $LOOP_DEV $LOOP_FILE
+    return 0
 }
 
 run_test 1e " general GNS test - concurrent mount of 2 GNS mounts ======="
@@ -717,7 +804,8 @@ test_2a() {
 
     echo ""
     echo "testing GNS with GENERIC upcall"
-    check_gns GENERIC $DIR/gns_test_2a $DIR/gns_test_2a $TIMOUT $TICK GENERIC && {
+    
+    check_gns GENERIC $DIR/gns_test_2a $DIR/gns_test_2a $TIMOUT $TICK GENERIC FG OPEN && {
        disable_gns
        chmod u-s $DIR/gns_test_2a
        rm -fr $DIR/gns_test_2a
@@ -727,6 +815,7 @@ test_2a() {
     disable_gns
     chmod u-s $DIR/gns_test_2a
     rm -fr $DIR/gns_test_2a
+    return 0
 }
 
 run_test 2a " odd conditions (mount object is symlink) ============="
@@ -749,7 +838,8 @@ test_2b() {
     
     echo ""
     echo "testing GNS with GENERIC upcall"
-    check_gns GENERIC $DIR/gns_test_2b $DIR/gns_test_2b $TIMOUT $TICK GENERIC && {
+    
+    check_gns GENERIC $DIR/gns_test_2b $DIR/gns_test_2b $TIMOUT $TICK GENERIC FG OPEN && {
        disable_gns
        chmod u-s $DIR/gns_test_2b
        rm -fr $DIR/gns_test_2b
@@ -759,6 +849,7 @@ test_2b() {
     disable_gns
     chmod u-s $DIR/gns_test_2b
     rm -fr $DIR/gns_test_2b
+    return 0
 }
 
 run_test 2b " odd conditions (mount object is directory) ==========="
@@ -781,7 +872,8 @@ test_2c() {
     
     echo ""
     echo "testing GNS with GENERIC upcall"
-    check_gns GENERIC $DIR/gns_test_2c $DIR/gns_test_2c $TIMOUT $TICK GENERIC && {
+    
+    check_gns GENERIC $DIR/gns_test_2c $DIR/gns_test_2c $TIMOUT $TICK GENERIC FG OPEN && {
        disable_gns
        chmod u-s -R $DIR/gns_test_2c
        rm -fr $DIR/gns_test_2c
@@ -789,8 +881,9 @@ test_2c() {
     }
     
     disable_gns
-    chmod u-s $DIR/gns_test_2c
+    chmod u-s -R $DIR/gns_test_2c
     rm -fr $DIR/gns_test_2c
+    return 0
 }
 
 run_test 2c " odd conditions (mount object is recursive dir) ======="
@@ -813,7 +906,8 @@ test_2d() {
 
     echo ""
     echo "testing GNS with GENERIC upcall"
-    check_gns GENERIC $DIR/gns_test_2d $DIR/gns_test_2d $TIMOUT $TICK GENERIC && {
+    
+    check_gns GENERIC $DIR/gns_test_2d $DIR/gns_test_2d $TIMOUT $TICK GENERIC FG OPEN && {
        disable_gns
        chmod u-s $DIR/gns_test_2d
        rm -fr $DIR/gns_test_2d
@@ -823,6 +917,7 @@ test_2d() {
     disable_gns
     chmod u-s $DIR/gns_test_2d
     rm -fr $DIR/gns_test_2d
+    return 0
 }
 
 run_test 2d " odd conditions (mount object is absent) =============="
@@ -850,13 +945,14 @@ test_2e() {
     echo "..a" > /proc/fs/lustre/llite/fs0/gns_object_name
     test "x$(cat /proc/fs/lustre/llite/fs0/gns_object_name)" = "x..a" || 
        error "'..a' is not set as mount object name"
+    return 0
 }
 
 run_test 2e " odd conditions ('.' and '..' as mount object) ============="
 
 test_2f() {
     local LOOP_DEV=$(find_free_loop 2>/dev/null)
-    local LOOP_FILE="/tmp/gns_loop_2f"
+    local LOOP_FILE="$TMP/gns_loop_2f"
     local OBJECT=".mntinfo"
     local TIMOUT=5
     local TICK=1
@@ -879,28 +975,27 @@ test_2f() {
     enable_gns
 
     echo ""
-    echo "testing GNS with DEADLOCK upcall in CONCUR3 mode"
+    echo "testing GNS with GENERIC upcall in CONCUR3 mode"
     
-    local MODE="DEADLOCK"
-       
-    check_gns $MODE $DIR/gns_test_2f $DIR/gns_test_2f $TIMOUT $TICK CONCUR3 || {
+    check_gns GENERIC $DIR/gns_test_2f $DIR/gns_test_2f $TIMOUT $TICK CONCUR3 FG OPEN || {
         disable_gns
         cleanup_object $DIR/gns_test_2f
         cleanup_loop $LOOP_DEV $LOOP_FILE
-        error
+        error "mount during modifying mount point does not work"
     }
     
     disable_gns
 
     cleanup_object $DIR/gns_test_2f
     cleanup_loop $LOOP_DEV $LOOP_FILE
+    return 0
 }
 
 run_test 2f " odd conditions (mount point is modifying during mount) ===="
 
 test_2g() {
     local LOOP_DEV=$(find_free_loop 2>/dev/null)
-    local LOOP_FILE="/tmp/gns_loop_2g"
+    local LOOP_FILE="$TMP/gns_loop_2g"
     local OBJECT=".mntinfo"
     local TIMOUT=5
     local TICK=1
@@ -920,33 +1015,49 @@ test_2g() {
     echo "preparing mount object at $DIR/gns_test_2g/$OBJECT/$OBJECT/$OBJECT..."
     setup_object $DIR/gns_test_2g/$OBJECT/$OBJECT/$OBJECT \
 $OBJECT "-t ext2 $LOOP_DEV" || error
+    chmod u+s $DIR/gns_test_2g -R
 
     enable_gns
 
     echo ""
-    echo "testing GNS with DEADLOCK upcall in GENERIC mode"
+    echo "testing GNS with GENERIC upcall in GENERIC mode"
     
-    local MODE="DEADLOCK"
-       
-    check_gns $MODE $DIR/gns_test_2g/$OBJECT/$OBJECT/$OBJECT \
-$DIR/gns_test_2g/$OBJECT/$OBJECT/$OBJECT $TIMOUT $TICK GENERIC || {
+    check_gns GENERIC $DIR/gns_test_2g/$OBJECT/$OBJECT/$OBJECT \
+$DIR/gns_test_2g/$OBJECT/$OBJECT/$OBJECT $TIMOUT $TICK GENERIC FG OPEN || {
         disable_gns
         cleanup_object $DIR/gns_test_2g
         cleanup_loop $LOOP_DEV $LOOP_FILE
-        error
+        error "recursive mount point does not work"
     }
     
     disable_gns
 
+    echo ""
+    echo "turning SUID on $DIR/gns_test_2g/$OBJECT/$OBJECT/$OBJECT off"
+    chmod u-s $DIR/gns_test_2g/$OBJECT/$OBJECT/$OBJECT
+
+    enable_gns
+
+    check_gns GENERIC $DIR/gns_test_2g/$OBJECT/$OBJECT/$OBJECT \
+$DIR/gns_test_2g/$OBJECT/$OBJECT/$OBJECT $TIMOUT $TICK GENERIC FG OPEN && {
+        disable_gns
+        cleanup_object $DIR/gns_test_2g
+        cleanup_loop $LOOP_DEV $LOOP_FILE
+        error "GNS works whereas mount point is not SUID marked dir"
+    }
+
+    disable_gns
+
     cleanup_object $DIR/gns_test_2g
     cleanup_loop $LOOP_DEV $LOOP_FILE
+    return 0
 }
 
 run_test 2g " odd conditions (mount point is recursive marked SUID dir) ="
 
 test_2h() {
     local LOOP_DEV=$(find_free_loop 2>/dev/null)
-    local LOOP_FILE="/tmp/gns_loop_2h"
+    local LOOP_FILE="$TMP/gns_loop_2h"
     local OBJECT=".mntinfo"
     local TIMOUT=5
     local TICK=1
@@ -972,7 +1083,7 @@ test_2h() {
     echo "testing GNS with GENERIC upcall in GENERIC mode"
     
     check_gns GENERIC $DIR/gns_test_2h $DIR/gns_test_2h \
-$TIMOUT $TICK GENERIC BACKGROUND || {
+$TIMOUT $TICK GENERIC BG OPEN || {
         disable_gns
         cleanup_object $DIR/gns_test_2h
         cleanup_loop $LOOP_DEV $LOOP_FILE
@@ -983,10 +1094,181 @@ $TIMOUT $TICK GENERIC BACKGROUND || {
 
     cleanup_object $DIR/gns_test_2h
     cleanup_loop $LOOP_DEV $LOOP_FILE
+    return 0
 }
 
 run_test 2h " odd conditions (mounting in background) ==================="
 
+test_3a() {
+    local LOOP_DEV=$(find_free_loop 2>/dev/null)
+    local LOOP_FILE="$TMP/gns_loop_3a"
+    local OBJECT=".mntinfo"
+    local TIMOUT=5
+    local TICK=1
+
+    test "x$LOOP_DEV" != "x" && test -b $LOOP_DEV ||
+       error "can't find free loop device"
+
+    echo "preparing loop device $LOOP_DEV <-> $LOOP_FILE..."
+    cleanup_loop $LOOP_DEV $LOOP_FILE
+    setup_loop $LOOP_DEV $LOOP_FILE || error
+
+    echo "setting up GNS timeouts and mount object..."
+    setup_gns $OBJECT $TIMOUT $TICK || error
+
+    disable_gns
+
+    echo "preparing mount object at $DIR/gns_test_3a/$OBJECT..."
+    setup_object $DIR/gns_test_3a $OBJECT "-t ext2 $LOOP_DEV" || error
+
+    enable_gns
+
+    echo ""
+    echo "testing GNS with GENERIC upcall in GENERIC mode"
+    
+    check_gns GENERIC $DIR/gns_test_3a $DIR/gns_test_3a \
+$TIMOUT $TICK GENERIC FG OPEN || {
+        disable_gns
+        cleanup_object $DIR/gns_test_3a
+        cleanup_loop $LOOP_DEV $LOOP_FILE
+        error
+    }
+    
+    chmod u-s $DIR/gns_test_3a || {
+        disable_gns
+        cleanup_object $DIR/gns_test_3a
+        cleanup_loop $LOOP_DEV $LOOP_FILE
+       error "can't chmod u-s $DIR/gns_test_3a"
+    }
+    
+    check_mnt $DIR/gns_test_3a && {
+        disable_gns
+        cleanup_object $DIR/gns_test_3a
+        cleanup_loop $LOOP_DEV $LOOP_FILE
+       error "chmod u-s $DIR/gns_test_3a caused mounting"
+    }
+    
+    disable_gns
+    cleanup_object $DIR/gns_test_3a
+    cleanup_loop $LOOP_DEV $LOOP_FILE
+    return 0
+}
+
+run_test 3a " removing mnt by chmod u-s ================================="
+
+test_3b() {
+    local LOOP_FILE1="$TMP/gns_loop_3b1"
+    local LOOP_FILE2="$TMP/gns_loop_3b2"
+    local LOOP_FILE3="$TMP/gns_loop_3b3"
+    local OBJECT=".mntinfo"
+    local LOOP_DEV1=""
+    local LOOP_DEV2=""
+    local LOOP_DEV3=""
+    local TIMOUT=5
+    local TICK=1
+
+    disable_gns
+
+    LOOP_DEV1=$(find_free_loop 2>/dev/null)
+    test "x$LOOP_DEV1" != "x" && test -b $LOOP_DEV1 ||
+       error "can't find free loop device"
+
+    echo "preparing loop device $LOOP_DEV1 <-> $LOOP_FILE1..."
+    cleanup_loop $LOOP_DEV1 $LOOP_FILE1
+    setup_loop $LOOP_DEV1 $LOOP_FILE1 || error
+
+    LOOP_DEV2=$(find_free_loop 2>/dev/null)
+    test "x$LOOP_DEV2" != "x" && test -b $LOOP_DEV2 || {
+        cleanup_loop $LOOP_DEV2 $LOOP_FILE2
+       error "can't find free loop device"
+    }
+
+    echo "preparing loop device $LOOP_DEV2 <-> $LOOP_FILE2..."
+    cleanup_loop $LOOP_DEV2 $LOOP_FILE2
+    setup_loop $LOOP_DEV2 $LOOP_FILE2 || {
+        cleanup_loop $LOOP_DEV2 $LOOP_FILE2
+       error
+    }
+    
+    LOOP_DEV3=$(find_free_loop 2>/dev/null)
+    test "x$LOOP_DEV3" != "x" && test -b $LOOP_DEV3 || {
+        cleanup_loop $LOOP_DEV1 $LOOP_FILE1
+        cleanup_loop $LOOP_DEV2 $LOOP_FILE2
+       error "can't find free loop device"
+    }
+
+    echo "preparing loop device $LOOP_DEV3 <-> $LOOP_FILE3..."
+    cleanup_loop $LOOP_DEV3 $LOOP_FILE3
+    setup_loop $LOOP_DEV3 $LOOP_FILE3 || {
+        cleanup_loop $LOOP_DEV1 $LOOP_FILE1
+        cleanup_loop $LOOP_DEV2 $LOOP_FILE2
+       error
+    }
+
+    # prepare object1
+    echo "preparing mount object at $DIR/gns_test_3b1/$OBJECT..."
+    setup_object $DIR/gns_test_3b1 $OBJECT "-t ext2 $LOOP_DEV1" || {
+        cleanup_loop $LOOP_DEV1 $LOOP_FILE1
+        cleanup_loop $LOOP_DEV2 $LOOP_FILE2
+        cleanup_loop $LOOP_DEV3 $LOOP_FILE3
+       error
+    }
+    
+    # prepare object2
+    mkdir -p $TMP/mnt || error
+    mount -t ext2 $LOOP_DEV2 $TMP/mnt || {
+        cleanup_object $DIR/gns_test_3b1
+        cleanup_loop $LOOP_DEV1 $LOOP_FILE1
+        cleanup_loop $LOOP_DEV2 $LOOP_FILE2
+        cleanup_loop $LOOP_DEV3 $LOOP_FILE3
+       error "cannot mount $LOOP_DEV2"
+    }
+
+    echo "preparing mount object at $TMP/mnt/gns_test_3b2/$OBJECT..."
+    setup_object $TMP/mnt/gns_test_3b2 $OBJECT "-t ext2 $LOOP_DEV3" || {
+        cleanup_object $DIR/gns_test_3b1
+       umount $TMP/mnt
+        cleanup_loop $LOOP_DEV1 $LOOP_FILE1
+        cleanup_loop $LOOP_DEV2 $LOOP_FILE2
+        cleanup_loop $LOOP_DEV3 $LOOP_FILE3
+       error
+    }
+    umount $TMP/mnt || error
+
+    echo "setting up GNS timeouts and mount object..."
+    setup_gns $OBJECT $TIMOUT $TICK || {
+        cleanup_object $DIR/gns_test_3b1
+        cleanup_loop $LOOP_DEV1 $LOOP_FILE1
+        cleanup_loop $LOOP_DEV2 $LOOP_FILE2
+        cleanup_loop $LOOP_DEV3 $LOOP_FILE3
+       error
+    }
+
+    enable_gns
+
+    echo ""
+    echo "testing GNS with GENERIC upcall in CONCUR2 mode"
+    
+    check_gns GENERIC $DIR/gns_test_3b1/gns_test_3b2 $DIR/gns_test_3b1/gns_test_3b2 $TIMOUT $TICK GENERIC FG LIST || {
+       disable_gns
+        cleanup_object $DIR/gns_test_3b1
+        cleanup_loop $LOOP_DEV1 $LOOP_FILE1
+        cleanup_loop $LOOP_DEV2 $LOOP_FILE2
+        cleanup_loop $LOOP_DEV3 $LOOP_FILE3
+        error
+    }
+    
+    disable_gns
+
+    cleanup_object $DIR/gns_test_3b1
+    cleanup_loop $LOOP_DEV1 $LOOP_FILE1
+    cleanup_loop $LOOP_DEV2 $LOOP_FILE2
+    cleanup_loop $LOOP_DEV3 $LOOP_FILE3
+    return 0
+}
+
+run_test 3b " general GNS test - concurrent mount of 2 GNS mounts ======="
+
 TMPDIR=$OLDTMPDIR
 TMP=$OLDTMP
 HOME=$OLDHOME