aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2018-01-10 19:41:05 +0000
committerMark Johnston <markj@FreeBSD.org>2018-01-10 19:41:05 +0000
commita19e74290194cd27ff028cf93bb4d4256c3b15db (patch)
treee68890a6d714874ebef0012683fadd8aec8c89df
parent762f440f15383dc2e42d911e161a342a61227ef3 (diff)
downloadsrc-a19e74290194cd27ff028cf93bb4d4256c3b15db.tar.gz
src-a19e74290194cd27ff028cf93bb4d4256c3b15db.zip
Add regression tests for r327779.
MFC after: 2 weeks Sponsored by: Dell EMC Isilon
Notes
Notes: svn path=/head/; revision=327780
-rw-r--r--tests/sys/geom/class/mirror/Makefile2
-rw-r--r--tests/sys/geom/class/mirror/sync_error.sh110
2 files changed, 112 insertions, 0 deletions
diff --git a/tests/sys/geom/class/mirror/Makefile b/tests/sys/geom/class/mirror/Makefile
index 095fb901cfaf..817d5d66e971 100644
--- a/tests/sys/geom/class/mirror/Makefile
+++ b/tests/sys/geom/class/mirror/Makefile
@@ -18,6 +18,8 @@ TAP_TESTS_SH+= 11_test
TAP_TESTS_SH+= 12_test
TAP_TESTS_SH+= 13_test
+ATF_TESTS_SH+= sync_error
+
${PACKAGE}FILES+= conf.sh
.for t in ${TAP_TESTS_SH}
diff --git a/tests/sys/geom/class/mirror/sync_error.sh b/tests/sys/geom/class/mirror/sync_error.sh
new file mode 100644
index 000000000000..89fd31e9d935
--- /dev/null
+++ b/tests/sys/geom/class/mirror/sync_error.sh
@@ -0,0 +1,110 @@
+# $FreeBSD$
+
+REG_READ_FP=debug.fail_point.g_mirror_regular_request_read
+
+atf_test_case sync_read_error_2_disks cleanup
+sync_read_error_2_disks_head()
+{
+ atf_set "descr" \
+ "Ensure that we properly handle read errors during synchronization."
+ atf_set "require.user" "root"
+}
+sync_read_error_2_disks_body()
+{
+ . $(atf_get_srcdir)/conf.sh
+
+ f1=$(mktemp ${base}.XXXXXX)
+ f2=$(mktemp ${base}.XXXXXX)
+
+ atf_check dd if=/dev/zero bs=1M count=32 of=$f1 status=none
+ atf_check truncate -s 32M $f2
+
+ md1=$(attach_md -t vnode -f ${f1})
+ md2=$(attach_md -t vnode -f ${f2})
+
+ atf_check gmirror label $name $md1
+ devwait
+
+ atf_check -s exit:0 -e empty -o not-empty sysctl ${REG_READ_FP}='1*return(5)'
+
+ # If a read error occurs while synchronizing and the mirror contains
+ # a single active disk, gmirror has no choice but to fail the
+ # synchronization and kick the new disk out of the mirror.
+ atf_check gmirror insert $name $md2
+ sleep 0.1
+ syncwait
+ atf_check [ $(gmirror status -s $name | wc -l) -eq 1 ]
+ atf_check -s exit:0 -o match:"DEGRADED $md1 \(ACTIVE\)" \
+ gmirror status -s $name
+}
+sync_read_error_2_disks_cleanup()
+{
+ . $(atf_get_srcdir)/conf.sh
+
+ atf_check -s exit:0 -e empty -o not-empty sysctl ${REG_READ_FP}='off'
+ gmirror_test_cleanup
+}
+
+atf_test_case sync_read_error_3_disks cleanup
+sync_read_error_3_disks_head()
+{
+ atf_set "descr" \
+ "Ensure that we properly handle read errors during synchronization."
+ atf_set "require.user" "root"
+}
+sync_read_error_3_disks_body()
+{
+ . $(atf_get_srcdir)/conf.sh
+
+ f1=$(mktemp ${base}.XXXXXX)
+ f2=$(mktemp ${base}.XXXXXX)
+ f3=$(mktemp ${base}.XXXXXX)
+
+ atf_check dd if=/dev/random bs=1M count=32 of=$f1 status=none
+ atf_check truncate -s 32M $f2
+ atf_check truncate -s 32M $f3
+
+ md1=$(attach_md -t vnode -f ${f1})
+ md2=$(attach_md -t vnode -f ${f2})
+ md3=$(attach_md -t vnode -f ${f3})
+
+ atf_check gmirror label $name $md1
+ devwait
+
+ atf_check gmirror insert $name $md2
+ syncwait
+
+ atf_check -s exit:0 -e empty -o not-empty sysctl ${REG_READ_FP}='1*return(5)'
+
+ # If a read error occurs while synchronizing a new disk, and we have
+ # multiple active disks, we retry the read after an error. The disk
+ # which returned the read error is kicked out of the mirror.
+ atf_check gmirror insert $name $md3
+ syncwait
+ atf_check [ $(gmirror status -s $name | wc -l) -eq 2 ]
+ atf_check -s exit:0 -o match:"DEGRADED $md3 \(ACTIVE\)" \
+ gmirror status -s $name
+
+ # Make sure that the two active disks are identical. Destroy the
+ # mirror first so that the metadata sectors are wiped.
+ if $(gmirror status -s $name | grep -q $md1); then
+ active=$md1
+ else
+ active=$md2
+ fi
+ atf_check gmirror destroy $name
+ atf_check cmp /dev/$active /dev/$md3
+}
+sync_read_error_3_disks_cleanup()
+{
+ . $(atf_get_srcdir)/conf.sh
+
+ atf_check -s exit:0 -e empty -o not-empty sysctl ${REG_READ_FP}='off'
+ gmirror_test_cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case sync_read_error_2_disks
+ atf_add_test_case sync_read_error_3_disks
+}