Whamcloud - gitweb
LU-5319 tests: testcases for multiple modify RPCs feature 61/14861/17
authorGregoire Pichon <gregoire.pichon@bull.net>
Thu, 30 Jul 2015 06:27:34 +0000 (23:27 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 26 Aug 2015 15:49:01 +0000 (15:49 +0000)
This patch creates new testcases in the Auster test suite to
test the support of multiple modify RPCs in flight feature.

Two new OBD_FAIL codes are added to allow several failure occurences
of the reint requests or replies. This is needed because the current
fail checks impose the OBD_FAIL_ONCE flag.

Added testcases are :
- sanity         245
- conf-sanity    90a 90b 90c 90d
- replay-single  102a 102b 102c 102d

This patch also removes replay-single tests 53a and 53b
from the ALWAYS_EXCEPT list.

Signed-off-by: Gregoire Pichon <gregoire.pichon@bull.net>
Change-Id: I3cd233d5ef67a696e830c77b154dcc01520bb3d2
Reviewed-on: http://review.whamcloud.com/14861
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Jian Yu <jian.yu@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
lustre/include/obd_support.h
lustre/ldlm/ldlm_lib.c
lustre/target/tgt_handler.c
lustre/tests/conf-sanity.sh
lustre/tests/replay-single.sh
lustre/tests/sanity.sh

index 4534d13..e6d6741 100644 (file)
@@ -245,6 +245,8 @@ extern char obd_jobid_var[];
 #define OBD_FAIL_MDS_RENAME4             0x156
 #define OBD_FAIL_MDS_LDLM_REPLY_NET     0x157
 #define OBD_FAIL_MDS_STALE_DIR_LAYOUT   0x158
+#define OBD_FAIL_MDS_REINT_MULTI_NET     0x159
+#define OBD_FAIL_MDS_REINT_MULTI_NET_REP 0x15a
 
 /* layout lock */
 #define OBD_FAIL_MDS_NO_LL_GETATTR      0x170
index 0074148..f56b452 100644 (file)
@@ -2757,20 +2757,23 @@ int target_pack_pool_reply(struct ptlrpc_request *req)
 static int target_send_reply_msg(struct ptlrpc_request *req,
                                 int rc, int fail_id)
 {
-        if (OBD_FAIL_CHECK_ORSET(fail_id & ~OBD_FAIL_ONCE, OBD_FAIL_ONCE)) {
-                DEBUG_REQ(D_ERROR, req, "dropping reply");
-                return (-ECOMM);
-        }
+       if (OBD_FAIL_CHECK_ORSET(fail_id & ~OBD_FAIL_ONCE, OBD_FAIL_ONCE)) {
+               DEBUG_REQ(D_ERROR, req, "dropping reply");
+               return -ECOMM;
+       }
+       if (unlikely(lustre_msg_get_opc(req->rq_reqmsg) == MDS_REINT &&
+                    OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_MULTI_NET_REP)))
+               return -ECOMM;
 
-        if (unlikely(rc)) {
-                DEBUG_REQ(D_NET, req, "processing error (%d)", rc);
-                req->rq_status = rc;
-                return (ptlrpc_send_error(req, 1));
-        } else {
-                DEBUG_REQ(D_NET, req, "sending reply");
-        }
+       if (unlikely(rc)) {
+               DEBUG_REQ(D_NET, req, "processing error (%d)", rc);
+               req->rq_status = rc;
+               return ptlrpc_send_error(req, 1);
+       } else {
+               DEBUG_REQ(D_NET, req, "sending reply");
+       }
 
-        return (ptlrpc_send_reply(req, PTLRPC_REPLY_MAYBE_DIFFICULT));
+       return ptlrpc_send_reply(req, PTLRPC_REPLY_MAYBE_DIFFICULT);
 }
 
 void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id)
index d28c242..6b32fca 100644 (file)
@@ -405,6 +405,9 @@ static int tgt_handle_request0(struct tgt_session_info *tsi,
         */
        if (OBD_FAIL_CHECK_ORSET(h->th_fail_id, OBD_FAIL_ONCE))
                RETURN(0);
+       if (unlikely(lustre_msg_get_opc(req->rq_reqmsg) == MDS_REINT &&
+                    OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_MULTI_NET)))
+               RETURN(0);
 
        rc = tgt_request_preprocess(tsi, h, req);
        /* pack reply if reply format is fixed */
index 617f016..4c2aa80 100644 (file)
@@ -5574,6 +5574,292 @@ test_87() { #LU-6544
 }
 run_test 87 "check if MDT inode can hold EAs with N stripes properly"
 
+# $1 test directory
+# $2 (optional) value of max_mod_rpcs_in_flight to set
+check_max_mod_rpcs_in_flight() {
+       local dir="$1"
+       local mmr="$2"
+       local idx
+       local facet
+       local tmp
+       local i
+
+       idx=$(printf "%04x" $($LFS getdirstripe -i $dir))
+       facet="mds$((0x$idx + 1))"
+
+       if [ -z "$mmr" ]; then
+               # get value of max_mod_rcps_in_flight
+               mmr=$($LCTL get_param -n \
+                       mdc.$FSNAME-MDT$idx-mdc-*.max_mod_rpcs_in_flight) ||
+                       error "Unable to get max_mod_rpcs_in_flight"
+               echo "max_mod_rcps_in_flight is $mmr"
+       else
+               # set value of max_mod_rpcs_in_flight
+               $LCTL set_param \
+                   mdc.$FSNAME-MDT$idx-mdc-*.max_mod_rpcs_in_flight=$mmr ||
+                       error "Unable to set max_mod_rpcs_in_flight to $mmr"
+               echo "max_mod_rpcs_in_flight set to $mmr"
+       fi
+
+       # create mmr+1 files
+       echo "creating $((mmr + 1)) files ..."
+       umask 0022
+       for i in $(seq $((mmr + 1))); do
+               touch $dir/file-$i
+       done
+
+       ### part 1 ###
+
+       # consumes mmr-1 modify RPC slots
+       #define OBD_FAIL_MDS_REINT_MULTI_NET     0x159
+       # drop requests on MDT so that RPC slots are consumed
+       # during all the request resend interval
+       do_facet $facet "$LCTL set_param fail_loc=0x159"
+       echo "launch $((mmr - 1)) chmod in parallel ..."
+       for i in $(seq $((mmr - 1))); do
+               chmod 0600 $dir/file-$i &
+       done
+
+       # send one additional modify RPC
+       do_facet $facet "$LCTL set_param fail_loc=0"
+       echo "launch 1 additional chmod in parallel ..."
+       chmod 0600 $dir/file-$mmr &
+       sleep 1
+
+       # check this additional modify RPC get a modify RPC slot
+       # and succeed its operation
+       checkstat -vp 0600 $dir/file-$mmr ||
+               error "Unable to send $mmr modify RPCs in parallel"
+       wait
+
+       ### part 2 ###
+
+       # consumes mmr modify RPC slots
+       #define OBD_FAIL_MDS_REINT_MULTI_NET     0x159
+       # drop requests on MDT so that RPC slots are consumed
+       # during all the request resend interval
+       do_facet $facet "$LCTL set_param fail_loc=0x159"
+       echo "launch $mmr chmod in parallel ..."
+       for i in $(seq $mmr); do
+               chmod 0666 $dir/file-$i &
+       done
+
+       # send one additional modify RPC
+       do_facet $facet "$LCTL set_param fail_loc=0"
+       echo "launch 1 additional chmod in parallel ..."
+       chmod 0666 $dir/file-$((mmr + 1)) &
+       sleep 1
+
+       # check this additional modify RPC blocked getting a modify RPC slot
+       checkstat -vp 0644 $dir/file-$((mmr + 1)) ||
+               error "Unexpectedly send $mmr modify RPCs in parallel"
+       wait
+}
+
+test_90a() {
+       reformat
+       if ! combined_mgs_mds ; then
+               start_mgs
+       fi
+       setup
+
+       [[ $($LCTL get_param mdc.*.import |
+            grep "connect_flags:.*multi_mod_rpc") ]] ||
+               { skip "Need MDC with 'multi_mod_rpcs' feature"; return 0; }
+
+       # check default value
+       $LFS mkdir -c1 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
+       check_max_mod_rpcs_in_flight $DIR/$tdir
+
+       cleanup
+}
+run_test 90a "check max_mod_rpcs_in_flight is enforced"
+
+test_90b() {
+       local idx
+       local facet
+       local tmp
+       local mmrpc
+
+       setup
+
+       [[ $($LCTL get_param mdc.*.import |
+            grep "connect_flags:.*multi_mod_rpc") ]] ||
+               { skip "Need MDC with 'multi_mod_rpcs' feature"; return 0; }
+
+       ### test 1.
+       # update max_mod_rpcs_in_flight
+       $LFS mkdir -c1 $DIR/${tdir}1 || error "mkdir $DIR/${tdir}1 failed"
+       check_max_mod_rpcs_in_flight $DIR/${tdir}1 1
+
+       ### test 2.
+       # check client is able to send multiple modify RPCs in paralell
+       tmp=$($LCTL get_param -n mdc.$FSNAME-MDT*-mdc-*.import |
+               grep -c "multi_mod_rpcs")
+       if [ "$tmp" -ne $MDSCOUNT ]; then
+               echo "Client not able to send multiple modify RPCs in parallel"
+               cleanup
+               return
+       fi
+
+       # update max_mod_rpcs_in_flight
+       $LFS mkdir -c1 $DIR/${tdir}2 || error "mkdir $DIR/${tdir}2 failed"
+       check_max_mod_rpcs_in_flight $DIR/${tdir}2 5
+
+       ### test 3.
+       $LFS mkdir -c1 $DIR/${tdir}3 || error "mkdir $DIR/${tdir}3 failed"
+       idx=$(printf "%04x" $($LFS getdirstripe -i $DIR/${tdir}3))
+       facet="mds$((0x$idx + 1))"
+
+       # save MDT max_mod_rpcs_per_client
+       mmrpc=$(do_facet $facet \
+                   cat /sys/module/mdt/parameters/max_mod_rpcs_per_client)
+
+       # update max_mod_rpcs_in_flight
+       umount_client $MOUNT
+       do_facet $facet \
+               "echo 16 > /sys/module/mdt/parameters/max_mod_rpcs_per_client"
+       mount_client $MOUNT
+       $LCTL set_param mdc.$FSNAME-MDT$idx-mdc-*.max_rpcs_in_flight=17
+       check_max_mod_rpcs_in_flight $DIR/${tdir}3 16
+
+       # restore MDT max_mod_rpcs_per_client initial value
+       do_facet $facet \
+               "echo $mmrpc > /sys/module/mdt/parameters/max_mod_rpcs_per_client"
+
+       rm -rf $DIR/${tdir}?
+       cleanup
+}
+run_test 90b "check max_mod_rpcs_in_flight is enforced after update"
+
+test_90c() {
+       local tmp
+       local mrif
+       local mmrpc
+
+       setup
+
+       [[ $($LCTL get_param mdc.*.import |
+            grep "connect_flags:.*multi_mod_rpc") ]] ||
+               { skip "Need MDC with 'multi_mod_rpcs' feature"; return 0; }
+
+       # check client is able to send multiple modify RPCs in paralell
+       tmp=$($LCTL get_param -n mdc.$FSNAME-MDT*-mdc-*.import |
+               grep -c "multi_mod_rpcs")
+       if [ "$tmp" -ne $MDSCOUNT ]; then
+               skip "Client not able to send multiple modify RPCs in parallel"
+               cleanup
+               return
+       fi
+
+       # get max_rpcs_in_flight value
+       mrif=$($LCTL get_param -n mdc.$FSNAME-MDT0000-mdc-*.max_rpcs_in_flight)
+       echo "max_rpcs_in_flight is $mrif"
+
+       # get MDT max_mod_rpcs_per_client
+       mmrpc=$(do_facet mds1 \
+                   cat /sys/module/mdt/parameters/max_mod_rpcs_per_client)
+       echo "max_mod_rpcs_per_client is $mmrpc"
+
+       # testcase 1
+       # attempt to set max_mod_rpcs_in_flight to max_rpcs_in_flight value
+       # prerequisite: set max_mod_rpcs_per_client to max_rpcs_in_flight value
+       umount_client $MOUNT
+       do_facet mds1 \
+               "echo $mrif > /sys/module/mdt/parameters/max_mod_rpcs_per_client"
+       mount_client $MOUNT
+
+       $LCTL set_param \
+           mdc.$FSNAME-MDT0000-mdc-*.max_mod_rpcs_in_flight=$mrif &&
+           error "set max_mod_rpcs_in_flight to $mrif should fail"
+
+       umount_client $MOUNT
+       do_facet mds1 \
+               "echo $mmrpc > /sys/module/mdt/parameters/max_mod_rpcs_per_client"
+       mount_client $MOUNT
+
+       # testcase 2
+       # attempt to set max_mod_rpcs_in_flight to max_mod_rpcs_per_client+1
+       # prerequisite: set max_rpcs_in_flight to max_mod_rpcs_per_client+2
+       $LCTL set_param \
+           mdc.$FSNAME-MDT0000-mdc-*.max_rpcs_in_flight=$((mmrpc + 2))
+
+       $LCTL set_param \
+           mdc.$FSNAME-MDT0000-mdc-*.max_mod_rpcs_in_flight=$((mmrpc + 1)) &&
+           error "set max_mod_rpcs_in_flight to $((mmrpc + 1)) should fail"
+
+       cleanup
+}
+run_test 90c "check max_mod_rpcs_in_flight update limits"
+
+test_90d() {
+       local idx
+       local facet
+       local mmr
+       local i
+       local pid
+
+       setup
+
+       [[ $($LCTL get_param mdc.*.import |
+            grep "connect_flags:.*multi_mod_rpc") ]] ||
+               { skip "Need MDC with 'multi_mod_rpcs' feature"; return 0; }
+
+       $LFS mkdir -c1 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
+       idx=$(printf "%04x" $($LFS getdirstripe -i $DIR/$tdir))
+       facet="mds$((0x$idx + 1))"
+
+       # check client version supports multislots
+       tmp=$($LCTL get_param -N \
+               mdc.$FSNAME-MDT$idx-mdc-*.max_mod_rpcs_in_flight)
+       if [ -z "$tmp" ]; then
+               skip "Client does not support multiple modify RPCs in flight"
+               cleanup
+               return
+       fi
+
+       # get current value of max_mod_rcps_in_flight
+       mmr=$($LCTL get_param -n \
+               mdc.$FSNAME-MDT$idx-mdc-*.max_mod_rpcs_in_flight)
+       echo "max_mod_rcps_in_flight is $mmr"
+
+       # create mmr files
+       echo "creating $mmr files ..."
+       umask 0022
+       for i in $(seq $mmr); do
+               touch $DIR/$tdir/file-$i
+       done
+
+       # prepare for close RPC
+       multiop_bg_pause $DIR/$tdir/file-close O_c
+       pid=$!
+
+       # consumes mmr modify RPC slots
+       #define OBD_FAIL_MDS_REINT_MULTI_NET     0x159
+       # drop requests on MDT so that RPC slots are consumed
+       # during all the request resend interval
+       do_facet $facet "$LCTL set_param fail_loc=0x159"
+       echo "launch $mmr chmod in parallel ..."
+       for i in $(seq $mmr); do
+               chmod 0600 $DIR/$tdir/file-$i &
+       done
+
+       # send one additional close RPC
+       do_facet $facet "$LCTL set_param fail_loc=0"
+       echo "launch 1 additional close in parallel ..."
+       kill -USR1 $pid
+       cancel_lru_locks mdc
+       sleep 1
+
+       # check this additional close RPC get a modify RPC slot
+       # and multiop process completed
+       [ -d /proc/$pid ] &&
+               error "Unable to send the additional close RPC in parallel"
+       wait
+       rm -rf $DIR/$tdir
+       cleanup
+}
+run_test 90d "check one close RPC is allowed above max_mod_rpcs_in_flight"
 
 if ! combined_mgs_mds ; then
        stop mgs
index 9998498..61d429b 100755 (executable)
@@ -22,9 +22,8 @@ require_dsh_mds || exit 0
 
 # Skip these tests
 # bug number for skipped tests:
-# b=17466/LU-472 : 61d
-# LU-5319 : 53a 53d
-ALWAYS_EXCEPT="61d 53a 53d $REPLAY_SINGLE_EXCEPT"
+#                                    b=17466/LU-472
+ALWAYS_EXCEPT="$REPLAY_SINGLE_EXCEPT 61d"
 # UPDATE THE COMMENT ABOVE WITH BUG NUMBERS WHEN CHANGING ALWAYS_EXCEPT!
 
 case "$(lsb_release -sr)" in   # only disable tests for el7
@@ -1186,6 +1185,10 @@ run_test 52 "time out lock replay (3764)"
 
 # bug 3462 - simultaneous MDC requests
 test_53a() {
+       [[ $(lctl get_param mdc.*.import |
+            grep "connect_flags:.*multi_mod_rpc") ]] ||
+               { skip "Need MDC with 'multi_mod_rpcs' feature"; return 0; }
+
        cancel_lru_locks mdc    # cleanup locks from former test cases
        mkdir $DIR/${tdir}-1 || error "mkdir $DIR/${tdir}-1 failed"
        mkdir $DIR/${tdir}-2 || error "mkdir $DIR/${tdir}-2 failed"
@@ -1290,6 +1293,10 @@ test_53c() {
 run_test 53c "|X| open request and close request while two MDC requests in flight"
 
 test_53d() {
+       [[ $(lctl get_param mdc.*.import |
+            grep "connect_flags:.*multi_mod_rpc") ]] ||
+               { skip "Need MDC with 'multi_mod_rpcs' feature"; return 0; }
+
        cancel_lru_locks mdc    # cleanup locks from former test cases
 
        mkdir $DIR/${tdir}-1 || error "mkdir $DIR/${tdir}-1 failed"
@@ -3088,6 +3095,224 @@ test_101() { #LU-5648
 }
 run_test 101 "Shouldn't reassign precreated objs to other files after recovery"
 
+test_102a() {
+       local idx
+       local facet
+       local num
+       local i
+       local pids pid
+
+       [[ $(lctl get_param mdc.*.import |
+            grep "connect_flags:.*multi_mod_rpc") ]] ||
+               { skip "Need MDC with 'multi_mod_rpcs' feature"; return 0; }
+
+       $LFS mkdir -c1 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
+       idx=$(printf "%04x" $($LFS getdirstripe -i $DIR/$tdir))
+       facet="mds$((0x$idx + 1))"
+
+       # get current value of max_mod_rcps_in_flight
+       num=$($LCTL get_param -n \
+               mdc.$FSNAME-MDT$idx-mdc-*.max_mod_rpcs_in_flight)
+       # set default value if client does not support multi mod RPCs
+       [ -z "$num" ] && num=1
+
+       echo "creating $num files ..."
+       umask 0022
+       for i in $(seq $num); do
+               touch $DIR/$tdir/file-$i
+       done
+
+       # drop request on MDT to force resend
+       #define OBD_FAIL_MDS_REINT_MULTI_NET 0x159
+       do_facet $facet "$LCTL set_param fail_loc=0x159"
+       echo "launch $num chmod in parallel ($(date +%H:%M:%S)) ..."
+       for i in $(seq $num); do
+               chmod 0600 $DIR/$tdir/file-$i &
+               pids="$pids $!"
+       done
+       sleep 1
+       do_facet $facet "$LCTL set_param fail_loc=0"
+       for pid in $pids; do
+               wait $pid || error "chmod failed"
+       done
+       echo "done ($(date +%H:%M:%S))"
+
+       # check chmod succeed
+       for i in $(seq $num); do
+               checkstat -vp 0600 $DIR/$tdir/file-$i
+       done
+
+       rm -rf $DIR/$tdir
+}
+run_test 102a "check resend (request lost) with multiple modify RPCs in flight"
+
+test_102b() {
+       local idx
+       local facet
+       local num
+       local i
+       local pids pid
+
+       [[ $(lctl get_param mdc.*.import |
+            grep "connect_flags:.*multi_mod_rpc") ]] ||
+               { skip "Need MDC with 'multi_mod_rpcs' feature"; return 0; }
+
+       $LFS mkdir -c1 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
+       idx=$(printf "%04x" $($LFS getdirstripe -i $DIR/$tdir))
+       facet="mds$((0x$idx + 1))"
+
+       # get current value of max_mod_rcps_in_flight
+       num=$($LCTL get_param -n \
+               mdc.$FSNAME-MDT$idx-mdc-*.max_mod_rpcs_in_flight)
+       # set default value if client does not support multi mod RPCs
+       [ -z "$num" ] && num=1
+
+       echo "creating $num files ..."
+       umask 0022
+       for i in $(seq $num); do
+               touch $DIR/$tdir/file-$i
+       done
+
+       # drop reply on MDT to force reconstruction
+       #define OBD_FAIL_MDS_REINT_MULTI_NET_REP 0x15a
+       do_facet $facet "$LCTL set_param fail_loc=0x15a"
+       echo "launch $num chmod in parallel ($(date +%H:%M:%S)) ..."
+       for i in $(seq $num); do
+               chmod 0600 $DIR/$tdir/file-$i &
+               pids="$pids $!"
+       done
+       sleep 1
+       do_facet $facet "$LCTL set_param fail_loc=0"
+       for pid in $pids; do
+               wait $pid || error "chmod failed"
+       done
+       echo "done ($(date +%H:%M:%S))"
+
+       # check chmod succeed
+       for i in $(seq $num); do
+               checkstat -vp 0600 $DIR/$tdir/file-$i
+       done
+
+       rm -rf $DIR/$tdir
+}
+run_test 102b "check resend (reply lost) with multiple modify RPCs in flight"
+
+test_102c() {
+       local idx
+       local facet
+       local num
+       local i
+       local pids pid
+
+       [[ $(lctl get_param mdc.*.import |
+            grep "connect_flags:.*multi_mod_rpc") ]] ||
+               { skip "Need MDC with 'multi_mod_rpcs' feature"; return 0; }
+
+       $LFS mkdir -c1 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
+       idx=$(printf "%04x" $($LFS getdirstripe -i $DIR/$tdir))
+       facet="mds$((0x$idx + 1))"
+
+       # get current value of max_mod_rcps_in_flight
+       num=$($LCTL get_param -n \
+               mdc.$FSNAME-MDT$idx-mdc-*.max_mod_rpcs_in_flight)
+       # set default value if client does not support multi mod RPCs
+       [ -z "$num" ] && num=1
+
+       echo "creating $num files ..."
+       umask 0022
+       for i in $(seq $num); do
+               touch $DIR/$tdir/file-$i
+       done
+
+       replay_barrier $facet
+
+       # drop reply on MDT
+       #define OBD_FAIL_MDS_REINT_MULTI_NET_REP 0x15a
+       do_facet $facet "$LCTL set_param fail_loc=0x15a"
+       echo "launch $num chmod in parallel ($(date +%H:%M:%S)) ..."
+       for i in $(seq $num); do
+               chmod 0600 $DIR/$tdir/file-$i &
+               pids="$pids $!"
+       done
+       sleep 1
+       do_facet $facet "$LCTL set_param fail_loc=0"
+
+       # fail MDT
+       fail $facet
+
+       for pid in $pids; do
+               wait $pid || error "chmod failed"
+       done
+       echo "done ($(date +%H:%M:%S))"
+
+       # check chmod succeed
+       for i in $(seq $num); do
+               checkstat -vp 0600 $DIR/$tdir/file-$i
+       done
+
+       rm -rf $DIR/$tdir
+}
+run_test 102c "check replay w/o reconstruction with multiple mod RPCs in flight"
+
+test_102d() {
+       local idx
+       local facet
+       local num
+       local i
+       local pids pid
+
+       [[ $(lctl get_param mdc.*.import |
+            grep "connect_flags:.*multi_mod_rpc") ]] ||
+               { skip "Need MDC with 'multi_mod_rpcs' feature"; return 0; }
+
+       $LFS mkdir -c1 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
+       idx=$(printf "%04x" $($LFS getdirstripe -i $DIR/$tdir))
+       facet="mds$((0x$idx + 1))"
+
+       # get current value of max_mod_rcps_in_flight
+       num=$($LCTL get_param -n \
+               mdc.$FSNAME-MDT$idx-mdc-*.max_mod_rpcs_in_flight)
+       # set default value if client does not support multi mod RPCs
+       [ -z "$num" ] && num=1
+
+       echo "creating $num files ..."
+       umask 0022
+       for i in $(seq $num); do
+               touch $DIR/$tdir/file-$i
+       done
+
+       # drop reply on MDT
+       #define OBD_FAIL_MDS_REINT_MULTI_NET_REP 0x15a
+       do_facet $facet "$LCTL set_param fail_loc=0x15a"
+       echo "launch $num chmod in parallel ($(date +%H:%M:%S)) ..."
+       for i in $(seq $num); do
+               chmod 0600 $DIR/$tdir/file-$i &
+               pids="$pids $!"
+       done
+       sleep 1
+
+       # write MDT transactions to disk
+       do_facet $facet "sync; sync; sync"
+
+       do_facet $facet "$LCTL set_param fail_loc=0"
+
+       # fail MDT
+       fail $facet
+
+       for pid in $pids; do
+               wait $pid || error "chmod failed"
+       done
+       echo "done ($(date +%H:%M:%S))"
+
+       # check chmod succeed
+       for i in $(seq $num); do
+               checkstat -vp 0600 $DIR/$tdir/file-$i
+       done
+
+       rm -rf $DIR/$tdir
+}
+run_test 102d "check replay & reconstruction with multiple mod RPCs in flight"
+
 check_striped_dir_110()
 {
        $CHECKSTAT -t dir $DIR/$tdir/striped_dir ||
index cc0166c..fdb74d4 100644 (file)
@@ -13113,6 +13113,31 @@ test_244()
 }
 run_test 244 "sendfile with group lock tests"
 
+test_245() {
+       local flagname="multi_mod_rpcs"
+       local connect_data_name="max_mod_rpcs"
+       local out
+
+       # check if multiple modify RPCs flag is set
+       out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
+               grep "connect_flags:")
+       echo "$out"
+
+       echo "$out" | grep -qw $flagname
+       if [ $? -ne 0 ]; then
+               echo "connect flag $flagname is not set"
+               return
+       fi
+
+       # check if multiple modify RPCs data is set
+       out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
+       echo "$out"
+
+       echo "$out" | grep -qw $connect_data_name ||
+               error "import should have connect data $connect_data_name"
+}
+run_test 245 "check mdc connection flag/data: multiple modify RPCs"
+
 test_250() {
        [ "$(facet_fstype ost$(($($GETSTRIPE -i $DIR/$tfile) + 1)))" = "zfs" ] \
         && skip "no 16TB file size limit on ZFS" && return