Reproducer of bug17764.
In order to hit the assertion the lustre file has to be open twice
from lustre clients, and once from nfs mount. Then unlink and close
opened lustre file and read the file opened on nfs.
Bugzilla: 17764
Author: Elena Gryanova <elena.gryaznova@oracle.com>
Signed-off-by: Elena Gryanova <elena.gryaznova@oracle.com>
Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
Change-Id: I05d8f04a2bd7c64864e1b82a07ef26a170887714
Reviewed-on: http://review.whamcloud.com/1895
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Johann Lombardi <johann@whamcloud.com>
rm -rf $testdir
cleanup_statahead $clients $mntpt_root $num_mntpts
}
-
run_test statahead "statahead test, multiple clients"
+# bug 17764 accessing files via nfs, ASSERTION(!mds_inode_is_orphan(dchild->d_inode)) failed
+test_nfsread_orphan_file() {
+ if [ ! "$NFSCLIENT" ]; then
+ skip "not NFSCLIENT mode, skipped"
+ return
+ fi
+
+ # copy file to lustre server
+ local nfsserver=$(nfs_server $MOUNT)
+ do_nodev $nfsserver cp /etc/passwd $DIR/$tfile
+ zconf_mount $nfsserver $MOUNT2
+
+ # open, wait, unlink and close
+ rmultiop_start --uniq unlink $nfsserver $DIR/$tfile o_uc
+ echo "1. unlinker on NFS server $nfsserver opened the file $DIR/$tfile"
+ sleep 1
+
+ # open $DIR2/$tfile and wait
+ rmultiop_start --uniq open $nfsserver $DIR2/$tfile o_c
+ echo "2. open on NFS server $nfsserver opened the file $DIR2/$tfile"
+ sleep 1
+
+ # open $DIR/$tfile on nfs client, wait, read
+ multiop_bg_pause $DIR/$tfile o_r10c
+ NFSREADPID=$!
+ echo "3. NFS client readder opened the file $DIR/$tfile"
+ sleep 1
+
+ # let unlink to go
+ rmultiop_stop --uniq unlink $nfsserver
+ echo "4. unlink, close completed"
+ sleep 1
+
+ # let nfs read to go
+ kill -USR1 $NFSREADPID
+ echo "5. NFS client read completed"
+
+ wait $NFSREADPID
+
+ rmultiop_stop --uniq open $nfsserver
+ zconf_umount $nfsserver $MOUNT2
+}
+run_test nfsread_orphan_file "accessing files via nfs, bug 17764"
+
complete $(basename $0) $SECONDS
check_and_cleanup_lustre
exit_status
[ "$DAEMONFILE" ] && $LCTL debug_daemon start $DAEMONFILE $DAEMONSIZE
-rmultiop_start() {
- local client=$1
- local file=$2
- local cmds=$3
-
- # We need to run do_node in bg, because pdsh does not exit
- # if child process of run script exists.
- # I.e. pdsh does not exit when runmultiop_bg_pause exited,
- # because of multiop_bg_pause -> $MULTIOP_PROG &
- # By the same reason we need sleep a bit after do_nodes starts
- # to let runmultiop_bg_pause start muliop and
- # update /tmp/multiop_bg.pid ;
- # The rm /tmp/multiop_bg.pid guarantees here that
- # we have the updated by runmultiop_bg_pause
- # /tmp/multiop_bg.pid file
-
- local pid_file=$TMP/multiop_bg.pid.$$
- do_node $client "rm -f $pid_file && MULTIOP_PID_FILE=$pid_file LUSTRE= runmultiop_bg_pause $file $cmds" &
- local pid=$!
- sleep 3
- local multiop_pid
- multiop_pid=$(do_node $client cat $pid_file)
- [ -n "$multiop_pid" ] || error "$client : Can not get multiop_pid from $pid_file "
- eval export $(node_var_name $client)_multiop_pid=$multiop_pid
- eval export $(node_var_name $client)_do_node_pid=$pid
- local var=$(node_var_name $client)_multiop_pid
- echo client $client multiop_bg started multiop_pid=${!var}
- return $?
-}
-
-rmultiop_stop() {
- local client=$1
- local multiop_pid=$(node_var_name $client)_multiop_pid
- local do_node_pid=$(node_var_name $client)_do_node_pid
-
- echo "Stopping multiop_pid=${!multiop_pid} (kill ${!multiop_pid} on $client)"
- do_node $client kill -USR1 ${!multiop_pid}
-
- wait ${!do_node_pid}
-}
-
get_version() {
local client=$1
local file=$2
local clients=$CLIENTS
[ -z $clients ] && clients=$(hostname)
- # FIXME: remove hostname when 19215 fixed
- do_nodes $clients "echo \\\$(hostname); grep ' '$MOUNT' ' /proc/mounts"
+ do_nodesv $clients "grep ' '$MOUNT' ' /proc/mounts"
declare -a nfsexport=(`grep ' '$MOUNT' ' /proc/mounts | awk '{print $1}' | awk -F: '{print $1 " " $2}'`)
if [[ ${#nfsexport[@]} -eq 0 ]]; then
error_exit NFSCLIENT=$NFSCLIENT mode, but no NFS export found!
fi
- do_nodes ${nfsexport[0]} "echo \\\$(hostname); df -T ${nfsexport[1]}"
+ do_nodesv ${nfsexport[0]} "df -T ${nfsexport[1]}"
return
fi
return 1
rm -f $file
}
-setstripe_nfsserver () {
+nfs_server () {
local dir=$1
local nfsserver=$(awk '"'$dir'" ~ $2 && $3 ~ "nfs" && $2 != "/" \
- { print $1 }' /proc/mounts | cut -f 1 -d : | head -1)
+ { print $1 }' /proc/mounts | cut -f 1 -d : | head -1)
+ echo $nfsserver
+}
+
+setstripe_nfsserver () {
+ local dir=$1
+ local nfsserver=$(nfs_server $dir)
[ -z $nfsserver ] && echo "$dir is not nfs mounted" && return 1
return 0
}
+rmultiop_start() {
+ local uniq=$$
+ if [ x$1 = x--uniq ]; then
+ shift
+ uniq=${uniq}_$1
+ shift
+ fi
+
+ local client=$1
+ local file=$2
+ local cmds=$3
+
+ # We need to run do_node in bg, because pdsh does not exit
+ # if child process of run script exists.
+ # I.e. pdsh does not exit when runmultiop_bg_pause exited,
+ # because of multiop_bg_pause -> $MULTIOP_PROG &
+ # By the same reason we need sleep a bit after do_nodes starts
+ # to let runmultiop_bg_pause start muliop and
+ # update /tmp/multiop_bg.pid ;
+ # The rm /tmp/multiop_bg.pid guarantees here that
+ # we have the updated by runmultiop_bg_pause
+ # /tmp/multiop_bg.pid file
+
+ local pid_file=$TMP/multiop_bg.pid.$uniq
+ do_node $client "rm -f $pid_file && MULTIOP_PID_FILE=$pid_file LUSTRE= runmultiop_bg_pause $file $cmds" &
+ local pid=$!
+ sleep 3
+ local multiop_pid
+ multiop_pid=$(do_node $client cat $pid_file)
+ [ -n "$multiop_pid" ] || error "$client : Can not get multiop_pid from $pid_file "
+ eval export $(node_var_name $client)_multiop_pid$uniq=$multiop_pid
+ eval export $(node_var_name $client)_do_node_pid$uniq=$pid
+ local var=$(node_var_name $client)_multiop_pid$uniq
+ echo node $client multiop_bg started multiop_pid=${!var}
+ return $?
+}
+
+rmultiop_stop() {
+ local uniq=$$
+ if [ x$1 = x--uniq ]; then
+ shift
+ uniq=${uniq}_$1
+ shift
+ fi
+
+ local client=$1
+ local multiop_pid=$(node_var_name $client)_multiop_pid$uniq
+ local do_node_pid=$(node_var_name $client)_do_node_pid$uniq
+
+ echo "Stopping multiop_pid=${!multiop_pid} (kill ${!multiop_pid} on $client)"
+ do_node $client kill -USR1 ${!multiop_pid}
+
+ wait ${!do_node_pid}
+}
+
do_and_time () {
local cmd=$1
local rc