Date: Wed, 24 Aug 2016 22:48:56 +0000 (UTC) From: Alan Somers <asomers@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r304776 - projects/zfsd/head/tests/sys/cddl/zfs/tests/cli_root/zpool_destroy Message-ID: <201608242248.u7OMmuYq053455@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: asomers Date: Wed Aug 24 22:48:55 2016 New Revision: 304776 URL: https://svnweb.freebsd.org/changeset/base/304776 Log: Fix intermittent failures in zpool_destroy_004_pos The test case has multiple zfs send/recv scenarios. The scenario that was commonly failing was as follows; 1.) zfs send poolA | zfs recv poolB 2.) wait 3.) destroy -f poolA 4.) declare an error if the exit status of the send/recv pipeline was success. Step 4 was attempting to assert that the destruction of poolA interrupted the zfs send. The problem is that the zfs send could complete before the zfs destroy -f poolA was issued. If this occured then the receive half of the pipeline would succeed and the exit code of the pipeline would be zero. It is not possible to manage this race from a shell script. Changed test to allow the scenario described above to not declare an error if the zfs receive succeeds. Submitted by: Dave Baukus Reviewed by: asomers Sponsored by: Spectra Logic Corp Modified: projects/zfsd/head/tests/sys/cddl/zfs/tests/cli_root/zpool_destroy/zpool_destroy_004_pos.ksh Modified: projects/zfsd/head/tests/sys/cddl/zfs/tests/cli_root/zpool_destroy/zpool_destroy_004_pos.ksh ============================================================================== --- projects/zfsd/head/tests/sys/cddl/zfs/tests/cli_root/zpool_destroy/zpool_destroy_004_pos.ksh Wed Aug 24 22:38:06 2016 (r304775) +++ projects/zfsd/head/tests/sys/cddl/zfs/tests/cli_root/zpool_destroy/zpool_destroy_004_pos.ksh Wed Aug 24 22:48:55 2016 (r304776) @@ -56,28 +56,77 @@ function create_sender_and_receiver create_pool "$TESTPOOL1" "$DISK1" } +function check_recv_status +{ + rcv_pid="$1" + rcv_status="$2" + destroyed="$3" + + if ((rcv_status != 0)) + then + log_note \ + "zfs receive interrupted by destruction of $destroyed as expected" + return 0 + fi + + log_note "zfs receive NOT interrupted by destruction of $destroyed" + case $destroyed + in + SAME_POOL|RECEIVER) + log_fail "expected zfs receive failure did not occur" + ;; + + SENDER) + log_note "zfs send completed before destruction of $destroyed" + ;; + + *) + log_fail "unknown parameter $destroyed" + ;; + esac + return 0 +} + function send_recv_destroy { sleeptime=$1 recv=$2 to_destroy=$3 + who_to_destroy="$4" + # The pid of this send/receive pipeline is that of zfs receive. + # We can not get the exit status of the zfs send. We can, however, + # infer the status of the send; see note below. + # ( $ZFS send -RP $TESTPOOL/$TESTFS@snap1 | $ZFS receive -Fu $recv/d1 ) & - sendrecvpid=$! + recvpid=$! + sndrcv_start=$(date '+%s') log_must sleep $sleeptime destroy_start=$(date '+%s') log_must $ZPOOL destroy -f $to_destroy destroy_end=$(date '+%s') - dtime=$(expr ${destroy_end} - ${destroy_start}) - log_note "Destroy took ${dtime} seconds." + dtime=$((destroy_end - destroy_start)) + log_note "Destroy of $who_to_destroy took ${dtime} seconds." - log_note "If this wait returns 0, it means send or receive succeeded." - log_mustnot wait $sendrecvpid + # NOTE: + # If the we have destroyed the send pool then the send/receive may + # succeed. + # 1.) If the destruction of the send pool interrupts the zfs + # send then this error will be detected by the receiver; + # the entire operation will fail. + # + # 2.) If the send completes before the destruction of the send + # pool then the receive will succeed. + # + wait $recvpid + rc=$? wait_end=$(date '+%s') - wtime=$(expr ${wait_end} - ${destroy_end}) - log_note "send|receive took ${wtime} seconds to finish." + log_note "$recvpid rc = $rc for destruction of $who_to_destroy" + check_recv_status $recvpid $rc $who_to_destroy + wtime=$((wait_end - sndrcv_start)) + log_note "send|receive took ${wtime} seconds to finish." log_mustnot $ZPOOL list $to_destroy } @@ -85,15 +134,15 @@ function run_tests { log_note "TEST: send|receive to the same pool" create_sender - send_recv_destroy $sleeptime $TESTPOOL $TESTPOOL + send_recv_destroy $sleeptime $TESTPOOL $TESTPOOL SAME_POOL log_note "TEST: send|receive to different pools, destroy sender" create_sender_and_receiver - send_recv_destroy $sleeptime $TESTPOOL1 $TESTPOOL + send_recv_destroy $sleeptime $TESTPOOL1 $TESTPOOL SENDER log_note "TEST: send|receive to different pools, destroy receiver" create_sender_and_receiver - send_recv_destroy $sleeptime $TESTPOOL1 $TESTPOOL1 + send_recv_destroy $sleeptime $TESTPOOL1 $TESTPOOL1 RECEIVER } log_assert "'zpool destroy -f <pool>' can force destroy active pool" @@ -112,7 +161,7 @@ done # time after the start of the run. arcmem=$(sysctl -n vfs.zfs.arc_max) # ARC will use 2xdatasz memory since it caches both the src and dst copies -datasz=$(expr ${arcmem} / 1048576 \* 2 / 3) +datasz=$((arcmem / 1048576 * 2 / 3)) log_note "Running longer test with ${datasz}MB of data" sleeptime=15 run_tests
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608242248.u7OMmuYq053455>