aboutsummaryrefslogtreecommitdiff
path: root/tests/sys/geom
diff options
context:
space:
mode:
Diffstat (limited to 'tests/sys/geom')
-rw-r--r--tests/sys/geom/Makefile7
-rw-r--r--tests/sys/geom/Makefile.depend11
-rw-r--r--tests/sys/geom/class/Makefile21
-rw-r--r--tests/sys/geom/class/Makefile.depend11
-rw-r--r--tests/sys/geom/class/concat/1_test.sh23
-rw-r--r--tests/sys/geom/class/concat/2_test.sh30
-rw-r--r--tests/sys/geom/class/concat/Makefile16
-rw-r--r--tests/sys/geom/class/concat/Makefile.depend11
-rw-r--r--tests/sys/geom/class/concat/conf.sh15
-rw-r--r--tests/sys/geom/class/eli/Makefile43
-rw-r--r--tests/sys/geom/class/eli/Makefile.depend11
-rw-r--r--tests/sys/geom/class/eli/attach_d_test.sh38
-rwxr-xr-xtests/sys/geom/class/eli/conf.sh69
-rw-r--r--tests/sys/geom/class/eli/configure_b_B_test.sh129
-rw-r--r--tests/sys/geom/class/eli/delkey_test.sh140
-rw-r--r--tests/sys/geom/class/eli/detach_l_test.sh44
-rw-r--r--tests/sys/geom/class/eli/init_B_test.sh104
-rw-r--r--tests/sys/geom/class/eli/init_J_test.sh126
-rw-r--r--tests/sys/geom/class/eli/init_a_test.sh50
-rwxr-xr-xtests/sys/geom/class/eli/init_alias_test.sh64
-rw-r--r--tests/sys/geom/class/eli/init_i_P_test.sh22
-rw-r--r--tests/sys/geom/class/eli/init_test.sh55
-rw-r--r--tests/sys/geom/class/eli/integrity_copy_test.sh88
-rw-r--r--tests/sys/geom/class/eli/integrity_data_test.sh45
-rw-r--r--tests/sys/geom/class/eli/integrity_hmac_test.sh46
-rw-r--r--tests/sys/geom/class/eli/kill_test.sh97
-rw-r--r--tests/sys/geom/class/eli/nokey_test.sh65
-rw-r--r--tests/sys/geom/class/eli/onetime_a_test.sh45
-rw-r--r--tests/sys/geom/class/eli/onetime_d_test.sh34
-rw-r--r--tests/sys/geom/class/eli/onetime_test.sh50
-rw-r--r--tests/sys/geom/class/eli/readonly_test.sh94
-rw-r--r--tests/sys/geom/class/eli/resize_test.sh148
-rw-r--r--tests/sys/geom/class/eli/setkey_test.sh156
-rw-r--r--tests/sys/geom/class/gate/1_test.sh63
-rw-r--r--tests/sys/geom/class/gate/2_test.sh48
-rw-r--r--tests/sys/geom/class/gate/3_test.sh49
-rw-r--r--tests/sys/geom/class/gate/Makefile17
-rw-r--r--tests/sys/geom/class/gate/Makefile.depend11
-rwxr-xr-xtests/sys/geom/class/gate/conf.sh8
-rw-r--r--tests/sys/geom/class/geom_subr.sh58
-rw-r--r--tests/sys/geom/class/mirror/1_test.sh23
-rw-r--r--tests/sys/geom/class/mirror/2_test.sh52
-rw-r--r--tests/sys/geom/class/mirror/3_test.sh64
-rw-r--r--tests/sys/geom/class/mirror/4_test.sh66
-rw-r--r--tests/sys/geom/class/mirror/5_test.sh64
-rw-r--r--tests/sys/geom/class/mirror/6_test.sh45
-rw-r--r--tests/sys/geom/class/mirror/7_test.sh64
-rw-r--r--tests/sys/geom/class/mirror/Makefile21
-rw-r--r--tests/sys/geom/class/mirror/Makefile.depend11
-rw-r--r--tests/sys/geom/class/mirror/conf.sh15
-rw-r--r--tests/sys/geom/class/nop/Makefile9
-rw-r--r--tests/sys/geom/class/nop/Makefile.depend11
-rwxr-xr-xtests/sys/geom/class/nop/nop_test.sh166
-rw-r--r--tests/sys/geom/class/raid3/10_test.sh32
-rw-r--r--tests/sys/geom/class/raid3/11_test.sh32
-rw-r--r--tests/sys/geom/class/raid3/12_test.sh38
-rw-r--r--tests/sys/geom/class/raid3/1_test.sh28
-rw-r--r--tests/sys/geom/class/raid3/2_test.sh32
-rw-r--r--tests/sys/geom/class/raid3/3_test.sh36
-rw-r--r--tests/sys/geom/class/raid3/4_test.sh36
-rw-r--r--tests/sys/geom/class/raid3/5_test.sh36
-rw-r--r--tests/sys/geom/class/raid3/6_test.sh40
-rw-r--r--tests/sys/geom/class/raid3/7_test.sh43
-rw-r--r--tests/sys/geom/class/raid3/8_test.sh39
-rw-r--r--tests/sys/geom/class/raid3/9_test.sh42
-rw-r--r--tests/sys/geom/class/raid3/Makefile26
-rw-r--r--tests/sys/geom/class/raid3/Makefile.depend11
-rw-r--r--tests/sys/geom/class/raid3/conf.sh15
-rw-r--r--tests/sys/geom/class/shsec/1_test.sh28
-rw-r--r--tests/sys/geom/class/shsec/2_test.sh52
-rw-r--r--tests/sys/geom/class/shsec/Makefile16
-rw-r--r--tests/sys/geom/class/shsec/Makefile.depend11
-rw-r--r--tests/sys/geom/class/shsec/conf.sh15
-rw-r--r--tests/sys/geom/class/stripe/1_test.sh23
-rw-r--r--tests/sys/geom/class/stripe/2_test.sh30
-rw-r--r--tests/sys/geom/class/stripe/Makefile16
-rw-r--r--tests/sys/geom/class/stripe/Makefile.depend11
-rw-r--r--tests/sys/geom/class/stripe/conf.sh15
-rw-r--r--tests/sys/geom/class/uzip/1_endian_big.img.uzip.uue87
-rw-r--r--tests/sys/geom/class/uzip/1_endian_little.img.uzip.uue110
-rw-r--r--tests/sys/geom/class/uzip/1_test.sh34
-rw-r--r--tests/sys/geom/class/uzip/Makefile42
-rw-r--r--tests/sys/geom/class/uzip/Makefile.depend11
-rwxr-xr-xtests/sys/geom/class/uzip/conf.sh20
-rw-r--r--tests/sys/geom/class/uzip/etalon/etalon.txt43
85 files changed, 3823 insertions, 0 deletions
diff --git a/tests/sys/geom/Makefile b/tests/sys/geom/Makefile
new file mode 100644
index 000000000000..bf8604dcabc3
--- /dev/null
+++ b/tests/sys/geom/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+TESTSDIR= ${TESTSBASE}/sys/geom
+
+TESTS_SUBDIRS+= class
+
+.include <bsd.test.mk>
diff --git a/tests/sys/geom/Makefile.depend b/tests/sys/geom/Makefile.depend
new file mode 100644
index 000000000000..f80275d86ab1
--- /dev/null
+++ b/tests/sys/geom/Makefile.depend
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/tests/sys/geom/class/Makefile b/tests/sys/geom/class/Makefile
new file mode 100644
index 000000000000..b633fd081ee1
--- /dev/null
+++ b/tests/sys/geom/class/Makefile
@@ -0,0 +1,21 @@
+# $FreeBSD$
+
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/geom/class
+
+TESTS_SUBDIRS+= concat
+TESTS_SUBDIRS+= eli
+TESTS_SUBDIRS+= gate
+# XXX: might not work due to geom(4) changes; more investigation's needed
+#TESTS_SUBDIRS+= gpt
+TESTS_SUBDIRS+= mirror
+TESTS_SUBDIRS+= nop
+TESTS_SUBDIRS+= raid3
+TESTS_SUBDIRS+= shsec
+TESTS_SUBDIRS+= stripe
+TESTS_SUBDIRS+= uzip
+
+${PACKAGE}FILES+= geom_subr.sh
+
+.include <bsd.test.mk>
diff --git a/tests/sys/geom/class/Makefile.depend b/tests/sys/geom/class/Makefile.depend
new file mode 100644
index 000000000000..f80275d86ab1
--- /dev/null
+++ b/tests/sys/geom/class/Makefile.depend
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/tests/sys/geom/class/concat/1_test.sh b/tests/sys/geom/class/concat/1_test.sh
new file mode 100644
index 000000000000..ef80a61bc18e
--- /dev/null
+++ b/tests/sys/geom/class/concat/1_test.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo '1..1'
+
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
+
+gconcat create $name /dev/$us0 /dev/$us1 /dev/$us2 || exit 1
+devwait
+
+# Size of created device should be 1MB + 2MB + 3MB.
+
+size=`diskinfo /dev/concat/${name} | awk '{print $3}'`
+
+if [ $size -eq 6291456 ]; then
+ echo "ok - Size is 6291456"
+else
+ echo "not ok - Size is 6291456"
+fi
diff --git a/tests/sys/geom/class/concat/2_test.sh b/tests/sys/geom/class/concat/2_test.sh
new file mode 100644
index 000000000000..95636be860eb
--- /dev/null
+++ b/tests/sys/geom/class/concat/2_test.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo '1..1'
+
+tsize=6
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
+
+dd if=/dev/random of=${src} bs=1m count=$tsize >/dev/null 2>&1
+
+gconcat create $name /dev/$us0 /dev/$us1 /dev/$us2 || exit 1
+devwait
+
+dd if=${src} of=/dev/concat/${name} bs=1m count=$tsize >/dev/null 2>&1
+dd if=/dev/concat/${name} of=${dst} bs=1m count=$tsize >/dev/null 2>&1
+
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok - md5 checksum comparison"
+else
+ echo "ok - md5 checksum comparison"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/concat/Makefile b/tests/sys/geom/class/concat/Makefile
new file mode 100644
index 000000000000..b0849962aa01
--- /dev/null
+++ b/tests/sys/geom/class/concat/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
+
+TAP_TESTS_SH+= 1_test
+TAP_TESTS_SH+= 2_test
+
+${PACKAGE}FILES+= conf.sh
+
+.for t in ${TAP_TESTS_SH}
+TEST_METADATA.$t+= required_user="root"
+.endfor
+
+.include <bsd.test.mk>
diff --git a/tests/sys/geom/class/concat/Makefile.depend b/tests/sys/geom/class/concat/Makefile.depend
new file mode 100644
index 000000000000..f80275d86ab1
--- /dev/null
+++ b/tests/sys/geom/class/concat/Makefile.depend
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/tests/sys/geom/class/concat/conf.sh b/tests/sys/geom/class/concat/conf.sh
new file mode 100644
index 000000000000..374ed12aecc2
--- /dev/null
+++ b/tests/sys/geom/class/concat/conf.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $FreeBSD$
+
+name="$(mktemp -u concat.XXXXXX)"
+class="concat"
+base=`basename $0`
+
+gconcat_test_cleanup()
+{
+ [ -c /dev/$class/$name ] && gconcat destroy $name
+ geom_test_cleanup
+}
+trap gconcat_test_cleanup ABRT EXIT INT TERM
+
+. `dirname $0`/../geom_subr.sh
diff --git a/tests/sys/geom/class/eli/Makefile b/tests/sys/geom/class/eli/Makefile
new file mode 100644
index 000000000000..f108f877aabd
--- /dev/null
+++ b/tests/sys/geom/class/eli/Makefile
@@ -0,0 +1,43 @@
+# $FreeBSD$
+
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
+
+TAP_TESTS_SH+= attach_d_test
+TAP_TESTS_SH+= configure_b_B_test
+TAP_TESTS_SH+= delkey_test
+TAP_TESTS_SH+= detach_l_test
+TAP_TESTS_SH+= init_B_test
+TAP_TESTS_SH+= init_J_test
+TAP_TESTS_SH+= init_a_test
+TAP_TESTS_SH+= init_alias_test
+TAP_TESTS_SH+= init_i_P_test
+TAP_TESTS_SH+= init_test
+TAP_TESTS_SH+= integrity_copy_test
+TAP_TESTS_SH+= integrity_data_test
+TAP_TESTS_SH+= integrity_hmac_test
+TAP_TESTS_SH+= kill_test
+TAP_TESTS_SH+= nokey_test
+TAP_TESTS_SH+= onetime_a_test
+TAP_TESTS_SH+= onetime_d_test
+TAP_TESTS_SH+= onetime_test
+TAP_TESTS_SH+= readonly_test
+TAP_TESTS_SH+= resize_test
+TAP_TESTS_SH+= setkey_test
+
+TEST_METADATA.init_a_test+= timeout="3600"
+TEST_METADATA.init_test+= timeout="600"
+TEST_METADATA.integrity_copy_test+= timeout="3600"
+TEST_METADATA.integrity_data_test+= timeout="1800"
+TEST_METADATA.integrity_hmac_test+= timeout="1800"
+TEST_METADATA.onetime_a_test+= timeout="1800"
+TEST_METADATA.onetime_test+= timeout="1800"
+
+${PACKAGE}FILES+= conf.sh
+
+.for t in ${TAP_TESTS_SH}
+TEST_METADATA.$t+= required_user="root"
+.endfor
+
+.include <bsd.test.mk>
diff --git a/tests/sys/geom/class/eli/Makefile.depend b/tests/sys/geom/class/eli/Makefile.depend
new file mode 100644
index 000000000000..f80275d86ab1
--- /dev/null
+++ b/tests/sys/geom/class/eli/Makefile.depend
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/tests/sys/geom/class/eli/attach_d_test.sh b/tests/sys/geom/class/eli/attach_d_test.sh
new file mode 100644
index 000000000000..5d700b3270c7
--- /dev/null
+++ b/tests/sys/geom/class/eli/attach_d_test.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+keyfile=`mktemp $base.XXXXXX` || exit 1
+mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
+
+echo "1..3"
+
+dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
+
+geli init -B none -P -K $keyfile md${no}
+geli attach -d -p -k $keyfile md${no}
+if [ -c /dev/md${no}.eli ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+# Be sure it doesn't detach on read.
+dd if=/dev/md${no}.eli of=/dev/null 2>/dev/null
+sleep 1
+if [ -c /dev/md${no}.eli ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+true > /dev/md${no}.eli
+sleep 1
+if [ ! -c /dev/md${no}.eli ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+
+rm -f $keyfile
diff --git a/tests/sys/geom/class/eli/conf.sh b/tests/sys/geom/class/eli/conf.sh
new file mode 100755
index 000000000000..5ac291b2e15d
--- /dev/null
+++ b/tests/sys/geom/class/eli/conf.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+# $FreeBSD$
+
+class="eli"
+base=`basename $0`
+
+# We need to use linear probing in order to detect the first available md(4)
+# device instead of using mdconfig -a -t, because geli(8) attachs md(4) devices
+no=0
+while [ -c /dev/md$no ]; do
+ : $(( no += 1 ))
+done
+
+# Execute `func` for each combination of cipher, sectorsize, and hmac algo
+# `func` usage should be:
+# func <cipher> <aalgo> <secsize>
+for_each_geli_config() {
+ func=$1
+
+ for cipher in aes-xts:128 aes-xts:256 \
+ aes-cbc:128 aes-cbc:192 aes-cbc:256 \
+ 3des-cbc:192 \
+ blowfish-cbc:128 blowfish-cbc:160 blowfish-cbc:192 \
+ blowfish-cbc:224 blowfish-cbc:256 blowfish-cbc:288 \
+ blowfish-cbc:320 blowfish-cbc:352 blowfish-cbc:384 \
+ blowfish-cbc:416 blowfish-cbc:448 \
+ camellia-cbc:128 camellia-cbc:192 camellia-cbc:256; do
+ ealgo=${cipher%%:*}
+ keylen=${cipher##*:}
+ for aalgo in hmac/md5 hmac/sha1 hmac/ripemd160 hmac/sha256 \
+ hmac/sha384 hmac/sha512; do
+ for secsize in 512 1024 2048 4096 8192; do
+ ${func} $cipher $aalgo $secsize
+ done
+ done
+ done
+}
+
+# Execute `func` for each combination of cipher, and sectorsize, with no hmac
+# `func` usage should be:
+# func <cipher> <secsize>
+for_each_geli_config_nointegrity() {
+ func=$1
+
+ for cipher in aes-xts:128 aes-xts:256 \
+ aes-cbc:128 aes-cbc:192 aes-cbc:256 \
+ 3des-cbc:192 \
+ blowfish-cbc:128 blowfish-cbc:160 blowfish-cbc:192 \
+ blowfish-cbc:224 blowfish-cbc:256 blowfish-cbc:288 \
+ blowfish-cbc:320 blowfish-cbc:352 blowfish-cbc:384 \
+ blowfish-cbc:416 blowfish-cbc:448 \
+ camellia-cbc:128 camellia-cbc:192 camellia-cbc:256; do
+ ealgo=${cipher%%:*}
+ keylen=${cipher##*:}
+ for secsize in 512 1024 2048 4096 8192; do
+ ${func} $cipher $aalgo $secsize
+ done
+ done
+}
+
+
+geli_test_cleanup()
+{
+ [ -c /dev/md${no}.eli ] && geli detach md${no}.eli
+ mdconfig -d -u $no
+}
+trap geli_test_cleanup ABRT EXIT INT TERM
+
+. `dirname $0`/../geom_subr.sh
diff --git a/tests/sys/geom/class/eli/configure_b_B_test.sh b/tests/sys/geom/class/eli/configure_b_B_test.sh
new file mode 100644
index 000000000000..b6cdf4fe1d9a
--- /dev/null
+++ b/tests/sys/geom/class/eli/configure_b_B_test.sh
@@ -0,0 +1,129 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
+
+echo "1..17"
+
+geli init -B none -P -K /dev/null md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+
+geli dump md${no} | egrep 'flags: 0x0$' >/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+
+geli init -B none -b -P -K /dev/null md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+
+geli dump md${no} | egrep 'flags: 0x2$' >/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 4"
+else
+ echo "not ok 4"
+fi
+
+geli configure -B md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 5"
+else
+ echo "not ok 5"
+fi
+
+geli dump md${no} | egrep 'flags: 0x0$' >/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 6"
+else
+ echo "not ok 6"
+fi
+
+geli configure -b md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 7"
+else
+ echo "not ok 7"
+fi
+
+geli dump md${no} | egrep 'flags: 0x2$' >/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 8"
+else
+ echo "not ok 8"
+fi
+
+geli attach -p -k /dev/null md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 9"
+else
+ echo "not ok 9"
+fi
+
+geli list md${no}.eli | egrep '^Flags: .*BOOT' >/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 10"
+else
+ echo "not ok 10"
+fi
+
+geli configure -B md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 11"
+else
+ echo "not ok 11"
+fi
+
+geli list md${no}.eli | egrep '^Flags: .*BOOT' >/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 12"
+else
+ echo "not ok 12"
+fi
+
+geli dump md${no} | egrep 'flags: 0x0$' >/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 13"
+else
+ echo "not ok 13"
+fi
+
+geli configure -b md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 14"
+else
+ echo "not ok 14"
+fi
+
+geli list md${no}.eli | egrep '^Flags: .*BOOT' >/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 15"
+else
+ echo "not ok 15"
+fi
+
+geli dump md${no} | egrep 'flags: 0x2$' >/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 16"
+else
+ echo "not ok 16"
+fi
+
+geli detach md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 17"
+else
+ echo "not ok 17"
+fi
diff --git a/tests/sys/geom/class/eli/delkey_test.sh b/tests/sys/geom/class/eli/delkey_test.sh
new file mode 100644
index 000000000000..67b253efd0d8
--- /dev/null
+++ b/tests/sys/geom/class/eli/delkey_test.sh
@@ -0,0 +1,140 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+keyfile1=`mktemp $base.XXXXXX` || exit 1
+keyfile2=`mktemp $base.XXXXXX` || exit 1
+keyfile3=`mktemp $base.XXXXXX` || exit 1
+keyfile4=`mktemp $base.XXXXXX` || exit 1
+mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
+
+echo "1..14"
+
+dd if=/dev/random of=${keyfile1} bs=512 count=16 >/dev/null 2>&1
+dd if=/dev/random of=${keyfile2} bs=512 count=16 >/dev/null 2>&1
+dd if=/dev/random of=${keyfile3} bs=512 count=16 >/dev/null 2>&1
+dd if=/dev/random of=${keyfile4} bs=512 count=16 >/dev/null 2>&1
+
+geli init -B none -P -K $keyfile1 md${no}
+geli attach -p -k $keyfile1 md${no}
+geli setkey -n 1 -P -K $keyfile2 md${no}
+
+# Remove key 0 for attached provider.
+geli delkey -n 0 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+geli detach md${no}
+
+# We cannot use keyfile1 anymore.
+geli attach -p -k $keyfile1 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+
+# Attach with key 1.
+geli attach -p -k $keyfile2 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+
+# We cannot remove last key without -f option (for attached provider).
+geli delkey -n 1 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 4"
+else
+ echo "not ok 4"
+fi
+
+# Remove last key for attached provider.
+geli delkey -f -n 1 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 5"
+else
+ echo "not ok 5"
+fi
+
+# If there are no valid keys, but provider is attached, we can save situation.
+geli setkey -n 0 -P -K $keyfile3 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 6"
+else
+ echo "not ok 6"
+fi
+geli detach md${no}
+
+# We cannot use keyfile2 anymore.
+geli attach -p -k $keyfile2 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 7"
+else
+ echo "not ok 7"
+fi
+
+# Attach with key 0.
+geli attach -p -k $keyfile3 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 8"
+else
+ echo "not ok 8"
+fi
+
+# Setup key 1.
+geli setkey -n 1 -P -K $keyfile4 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 9"
+else
+ echo "not ok 9"
+fi
+geli detach md${no}
+
+# Remove key 1 for detached provider.
+geli delkey -n 1 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 10"
+else
+ echo "not ok 10"
+fi
+
+# We cannot use keyfile4 anymore.
+geli attach -p -k $keyfile4 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 11"
+else
+ echo "not ok 11"
+fi
+
+# We cannot remove last key without -f option (for detached provider).
+geli delkey -n 0 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 12"
+else
+ echo "not ok 12"
+fi
+
+# Remove last key for detached provider.
+geli delkey -f -n 0 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 13"
+else
+ echo "not ok 13"
+fi
+
+# We cannot use keyfile3 anymore.
+geli attach -p -k $keyfile3 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 14"
+else
+ echo "not ok 14"
+fi
+
+rm -f $keyfile1 $keyfile2 $keyfile3 $keyfile4
diff --git a/tests/sys/geom/class/eli/detach_l_test.sh b/tests/sys/geom/class/eli/detach_l_test.sh
new file mode 100644
index 000000000000..605ae94e6bf0
--- /dev/null
+++ b/tests/sys/geom/class/eli/detach_l_test.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+keyfile=`mktemp $base.XXXXXX` || exit 1
+mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
+
+echo "1..4"
+
+dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
+
+geli init -B none -P -K $keyfile md${no}
+geli attach -p -k $keyfile md${no}
+if [ -c /dev/md${no}.eli ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+# Be sure it doesn't detach before 'detach -l'.
+dd if=/dev/md${no}.eli of=/dev/null 2>/dev/null
+sleep 1
+if [ -c /dev/md${no}.eli ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+geli detach -l md${no}
+if [ -c /dev/md${no}.eli ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+dd if=/dev/md${no}.eli of=/dev/null 2>/dev/null
+sleep 1
+if [ ! -c /dev/md${no}.eli ]; then
+ echo "ok 4"
+else
+ echo "not ok 4"
+fi
+
+rm -f $keyfile
diff --git a/tests/sys/geom/class/eli/init_B_test.sh b/tests/sys/geom/class/eli/init_B_test.sh
new file mode 100644
index 000000000000..3ba743cfbc64
--- /dev/null
+++ b/tests/sys/geom/class/eli/init_B_test.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+keyfile=`mktemp $base.XXXXXX` || exit 1
+backupfile=`mktemp $base.XXXXXX` || exit 1
+
+echo "1..13"
+
+dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
+
+mdconfig -a -t malloc -s $sectors -u $no || exit 1
+
+# -B none
+rm -f /var/backups/md${no}.eli
+geli init -B none -P -K $keyfile md${no} 2>/dev/null
+if [ ! -f /var/backups/md${no}.eli ]; then
+ echo "ok 1 - -B none"
+else
+ echo "not ok 1 - -B none"
+fi
+
+# no -B
+rm -f /var/backups/md${no}.eli
+geli init -P -K $keyfile md${no} >/dev/null 2>&1
+if [ -f /var/backups/md${no}.eli ]; then
+ echo "ok 2 - no -B"
+else
+ echo "not ok 2 - no -B"
+fi
+geli clear md${no}
+geli attach -p -k $keyfile md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 3 - no -B"
+else
+ echo "not ok 3 - no -B"
+fi
+if [ ! -c /dev/md${no}.eli ]; then
+ echo "ok 4 - no -B"
+else
+ echo "not ok 4 - no -B"
+fi
+geli restore /var/backups/md${no}.eli md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 5 - no -B"
+else
+ echo "not ok 5 - no -B"
+fi
+geli attach -p -k $keyfile md${no} 2>/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 6 - no -B"
+else
+ echo "not ok 6 - no -B"
+fi
+if [ -c /dev/md${no}.eli ]; then
+ echo "ok 7 - no -B"
+else
+ echo "not ok 7 - no -B"
+fi
+geli detach md${no}
+rm -f /var/backups/md${no}.eli
+
+# -B file
+rm -f $backupfile
+geli init -B $backupfile -P -K $keyfile md${no} >/dev/null 2>&1
+if [ -f $backupfile ]; then
+ echo "ok 8 - -B file"
+else
+ echo "not ok 8 - -B file"
+fi
+geli clear md${no}
+geli attach -p -k $keyfile md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 9 - -B file"
+else
+ echo "not ok 9 - -B file"
+fi
+if [ ! -c /dev/md${no}.eli ]; then
+ echo "ok 10 - -B file"
+else
+ echo "not ok 10 - -B file"
+fi
+geli restore $backupfile md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 11 - -B file"
+else
+ echo "not ok 11 - -B file"
+fi
+geli attach -p -k $keyfile md${no} 2>/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 12 - -B file"
+else
+ echo "not ok 12 - -B file"
+fi
+if [ -c /dev/md${no}.eli ]; then
+ echo "ok 13 - -B file"
+else
+ echo "not ok 13 - -B file"
+fi
+
+rm -f $backupfile $keyfile
diff --git a/tests/sys/geom/class/eli/init_J_test.sh b/tests/sys/geom/class/eli/init_J_test.sh
new file mode 100644
index 000000000000..266a3d537e03
--- /dev/null
+++ b/tests/sys/geom/class/eli/init_J_test.sh
@@ -0,0 +1,126 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+keyfile0=`mktemp $base.XXXXXX` || exit 1
+keyfile1=`mktemp $base.XXXXXX` || exit 1
+passfile0=`mktemp $base.XXXXXX` || exit 1
+passfile1=`mktemp $base.XXXXXX` || exit 1
+mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
+
+echo "1..150"
+
+dd if=/dev/random of=${keyfile0} bs=512 count=16 >/dev/null 2>&1
+dd if=/dev/random of=${keyfile1} bs=512 count=16 >/dev/null 2>&1
+dd if=/dev/random bs=512 count=16 2>/dev/null | sha1 > ${passfile0}
+dd if=/dev/random bs=512 count=16 2>/dev/null | sha1 > ${passfile1}
+
+i=1
+for iter in -1 0 64; do
+ geli init -i ${iter} -B none -J ${passfile0} -P md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli init -i ${iter} -B none -J ${passfile0} -P -K ${keyfile0} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli init -i ${iter} -B none -J ${passfile0} -K ${keyfile0} md${no} 2>/dev/null || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile0} -p md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -j ${passfile0} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -j ${keyfile0} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${passfile0} -p md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -j ${keyfile0} -k ${passfile0} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -j ${keyfile0} -k ${keyfile0} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -j ${passfile0} -k ${passfile0} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -j ${passfile0} -k ${keyfile0} md${no} 2>/dev/null || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli detach md${no} || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ cat ${keyfile0} | geli attach -j ${passfile0} -k - md${no} 2>/dev/null || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli detach md${no} || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ cat ${passfile0} | geli attach -j - -k ${keyfile0} md${no} 2>/dev/null || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli detach md${no} || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+
+ geli init -i ${iter} -B none -J ${passfile0} -J ${passfile1} -P md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli init -i ${iter} -B none -J ${passfile0} -J ${passfile1} -P -K ${keyfile0} -K ${keyfile1} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli init -i ${iter} -B none -J ${passfile0} -J ${passfile1} -K ${keyfile0} -K ${keyfile1} md${no} 2>/dev/null || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile0} -p md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile1} -p md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -j ${passfile0} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -j ${passfile1} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile0} -k ${keyfile1} -p md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -j ${passfile0} -j ${passfile1} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile0} -j ${passfile0} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile0} -j ${passfile1} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile1} -j ${passfile0} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile1} -j ${passfile1} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile0} -j ${passfile0} -j ${passfile1} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile1} -j ${passfile0} -j ${passfile1} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile0} -k ${keyfile1} -j ${passfile0} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile0} -k ${keyfile1} -j ${passfile1} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile1} -k ${keyfile0} -j ${passfile0} -j ${passfile1} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile0} -k ${keyfile1} -j ${passfile1} -j ${passfile0} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -k ${keyfile1} -k ${keyfile0} -j ${passfile1} -j ${passfile0} md${no} 2>/dev/null && echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli attach -j ${passfile0} -j ${passfile1} -k ${keyfile0} -k ${keyfile1} md${no} 2>/dev/null || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli detach md${no} || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ cat ${passfile0} | geli attach -j - -j ${passfile1} -k ${keyfile0} -k ${keyfile1} md${no} 2>/dev/null || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli detach md${no} || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ cat ${passfile1} | geli attach -j ${passfile0} -j - -k ${keyfile0} -k ${keyfile1} md${no} 2>/dev/null || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli detach md${no} || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ cat ${keyfile0} | geli attach -j ${passfile0} -j ${passfile1} -k - -k ${keyfile1} md${no} 2>/dev/null || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli detach md${no} || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ cat ${keyfile1} | geli attach -j ${passfile0} -j ${passfile1} -k ${keyfile0} -k - md${no} 2>/dev/null || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli detach md${no} || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ cat ${keyfile0} ${keyfile1} | geli attach -j ${passfile0} -j ${passfile1} -k - md${no} 2>/dev/null || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli detach md${no} || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ cat ${passfile0} ${passfile1} | awk '{printf "%s", $0}' | geli attach -j - -k ${keyfile0} -k ${keyfile1} md${no} 2>/dev/null || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+ geli detach md${no} || echo -n "not "
+ echo "ok ${i}"; i=$((i+1))
+done
+
+rm -f ${keyfile0} ${keyfile1} ${passfile0} ${passfile1}
diff --git a/tests/sys/geom/class/eli/init_a_test.sh b/tests/sys/geom/class/eli/init_a_test.sh
new file mode 100644
index 000000000000..9b5b251c930b
--- /dev/null
+++ b/tests/sys/geom/class/eli/init_a_test.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+keyfile=`mktemp $base.XXXXXX` || exit 1
+rnd=`mktemp $base.XXXXXX` || exit 1
+
+do_test() {
+ cipher=$1
+ aalgo=$2
+ secsize=$3
+ ealgo=${cipher%%:*}
+ keylen=${cipher##*:}
+
+ mdconfig -a -t malloc -s `expr $secsize \* $sectors + 512`b -u $no || exit 1
+ geli init -B none -a $aalgo -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null
+ geli attach -p -k $keyfile md${no}
+
+ secs=`diskinfo /dev/md${no}.eli | awk '{print $4}'`
+
+ dd if=${rnd} of=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null
+
+ md_rnd=`dd if=${rnd} bs=${secsize} count=${secs} 2>/dev/null | md5`
+ md_ddev=`dd if=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null | md5`
+
+ if [ ${md_rnd} = ${md_ddev} ]; then
+ echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ else
+ echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ fi
+ i=$((i+1))
+
+ geli detach md${no}
+ mdconfig -d -u $no
+}
+
+echo "1..600"
+
+i=1
+
+dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
+dd if=/dev/random of=${rnd} bs=8192 count=${sectors} >/dev/null 2>&1
+
+for_each_geli_config do_test
+
+rm -f $rnd
+rm -f $keyfile
diff --git a/tests/sys/geom/class/eli/init_alias_test.sh b/tests/sys/geom/class/eli/init_alias_test.sh
new file mode 100755
index 000000000000..0422bee07065
--- /dev/null
+++ b/tests/sys/geom/class/eli/init_alias_test.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+# $FreeBSD$
+
+# Test "geli init"'s various cipher aliases
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+keyfile=`mktemp $base.XXXXXX` || exit 1
+rnd=`mktemp $base.XXXXXX` || exit 1
+
+do_test() {
+ ealgo=$1
+ keylen=$2
+ expected_ealgo=$3
+ expected_keylen=$4
+
+ geli init -B none -e $ealgo -l $keylen -P -K $keyfile md${no} 2>/dev/null
+ geli attach -p -k $keyfile md${no}
+ real_ealgo=`geli list md${no}.eli | awk '/EncryptionAlgorithm/ {print $2}'`
+ real_keylen=`geli list md${no}.eli | awk '/KeyLength/ {print $2}'`
+
+ if [ ${real_ealgo} = ${expected_ealgo} ]; then
+ echo "ok $i - ${ealgo} aliased to ${real_ealgo}"
+ else
+ echo "not ok $i - expected ${expected_ealgo} but got ${real_ealgo}"
+ fi
+ i=$((i+1))
+
+ if [ ${real_keylen} = ${expected_keylen} ]; then
+ echo "ok $i - keylen=${keylen} for ealgo=${ealgo} aliases to ${real_keylen}"
+ else
+ echo "not ok $i - expected ${expected_keylen} but got ${real_keylen}"
+ fi
+ i=$((i+1))
+
+ geli detach md${no}
+}
+
+echo "1..38"
+i=1
+mdconfig -a -t malloc -s 1024k -u $no || exit 1
+dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
+
+for spec in aes:0:AES-XTS:128 aes:128:AES-XTS:128 aes:256:AES-XTS:256 \
+ 3des:0:3DES-CBC:192 3des:192:3DES-CBC:192 \
+ blowfish:0:Blowfish-CBC:128 blowfish:128:Blowfish-CBC:128 \
+ blowfish:160:Blowfish-CBC:160 blowfish:192:Blowfish-CBC:192 \
+ blowfish:224:Blowfish-CBC:224 blowfish:256:Blowfish-CBC:256 \
+ blowfish:288:Blowfish-CBC:288 blowfish:352:Blowfish-CBC:352 \
+ blowfish:384:Blowfish-CBC:384 blowfish:416:Blowfish-CBC:416 \
+ blowfish:448:Blowfish-CBC:448 \
+ camellia:0:CAMELLIA-CBC:128 camellia:128:CAMELLIA-CBC:128 \
+ camellia:256:CAMELLIA-CBC:256 ; do
+
+ ealgo=`echo $spec | cut -d : -f 1`
+ keylen=`echo $spec | cut -d : -f 2`
+ expected_ealgo=`echo $spec | cut -d : -f 3`
+ expected_keylen=`echo $spec | cut -d : -f 4`
+
+ do_test $ealgo $keylen $expected_ealgo $expected_keylen
+done
+
+rm -f $keyfile
diff --git a/tests/sys/geom/class/eli/init_i_P_test.sh b/tests/sys/geom/class/eli/init_i_P_test.sh
new file mode 100644
index 000000000000..1c59a97d391c
--- /dev/null
+++ b/tests/sys/geom/class/eli/init_i_P_test.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+keyfile=`mktemp $base.XXXXXX` || exit 1
+mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
+
+echo "1..1"
+
+dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
+
+geli init -B none -i 64 -P -K ${keyfile} md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+
+rm -f $keyfile
diff --git a/tests/sys/geom/class/eli/init_test.sh b/tests/sys/geom/class/eli/init_test.sh
new file mode 100644
index 000000000000..31fca551436f
--- /dev/null
+++ b/tests/sys/geom/class/eli/init_test.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=32
+keyfile=`mktemp $base.XXXXXX` || exit 1
+rnd=`mktemp $base.XXXXXX` || exit 1
+
+echo "1..200"
+
+do_test() {
+ cipher=$1
+ secsize=$2
+ ealgo=${cipher%%:*}
+ keylen=${cipher##*:}
+
+ mdconfig -a -t malloc -s `expr $secsize \* $sectors + 512`b -u $no || exit 1
+
+ geli init -B none -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null
+ geli attach -p -k $keyfile md${no}
+
+ secs=`diskinfo /dev/md${no}.eli | awk '{print $4}'`
+
+ dd if=/dev/random of=${rnd} bs=${secsize} count=${secs} >/dev/null 2>&1
+ dd if=${rnd} of=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null
+
+ md_rnd=`dd if=${rnd} bs=${secsize} count=${secs} 2>/dev/null | md5`
+ md_ddev=`dd if=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null | md5`
+ md_edev=`dd if=/dev/md${no} bs=${secsize} count=${secs} 2>/dev/null | md5`
+
+ if [ ${md_rnd} = ${md_ddev} ]; then
+ echo "ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ else
+ echo "not ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ fi
+ i=$((i+1))
+ if [ ${md_rnd} != ${md_edev} ]; then
+ echo "ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ else
+ echo "not ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ fi
+ i=$((i+1))
+
+ geli detach md${no}
+ mdconfig -d -u $no
+}
+
+i=1
+dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
+for_each_geli_config_nointegrity do_test
+
+rm -f $rnd
+rm -f $keyfile
diff --git a/tests/sys/geom/class/eli/integrity_copy_test.sh b/tests/sys/geom/class/eli/integrity_copy_test.sh
new file mode 100644
index 000000000000..ae345d74cae3
--- /dev/null
+++ b/tests/sys/geom/class/eli/integrity_copy_test.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+keyfile=`mktemp $base.XXXXXX` || exit 1
+sector=`mktemp $base.XXXXXX` || exit 1
+
+echo "1..2400"
+
+do_test() {
+ cipher=$1
+ aalgo=$2
+ secsize=$3
+ ealgo=${cipher%%:*}
+ keylen=${cipher##*:}
+
+ mdconfig -a -t malloc -s `expr $secsize \* 2 + 512`b -u $no || exit 1
+ geli init -B none -a $aalgo -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null
+ geli attach -p -k $keyfile md${no}
+
+ dd if=/dev/random of=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1
+
+ dd if=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ echo "ok $i - small 1 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ else
+ echo "not ok $i - small 1 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ fi
+ i=$((i+1))
+
+ geli detach md${no}
+ # Copy first small sector to the second small sector.
+ # This should be detected as corruption.
+ dd if=/dev/md${no} of=${sector} bs=512 count=1 >/dev/null 2>&1
+ dd if=${sector} of=/dev/md${no} bs=512 count=1 seek=1 >/dev/null 2>&1
+ geli attach -p -k $keyfile md${no}
+
+ dd if=/dev/md${no}.eli of=/dev/null bs=${secsize} count=1 >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ echo "ok $i - small 2 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ else
+ echo "not ok $i - small 2 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ fi
+ i=$((i+1))
+
+ ms=`diskinfo /dev/md${no} | awk '{print $3 - 512}'`
+ ns=`diskinfo /dev/md${no}.eli | awk '{print $4}'`
+ usecsize=`echo "($ms / $ns) - (($ms / $ns) % 512)" | bc`
+
+ # Fix the corruption
+ dd if=/dev/random of=/dev/md${no}.eli bs=${secsize} count=2 >/dev/null 2>&1
+
+ dd if=/dev/md${no}.eli bs=${secsize} count=2 >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ echo "ok $i - big 1 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ else
+ echo "not ok $i - big 1 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ fi
+ i=$((i+1))
+
+ geli detach md${no}
+ # Copy first big sector to the second big sector.
+ # This should be detected as corruption.
+ dd if=/dev/md${no} of=${sector} bs=${usecsize} count=1 >/dev/null 2>&1
+ dd if=${sector} of=/dev/md${no} bs=${usecsize} count=1 seek=1 >/dev/null 2>&1
+ geli attach -p -k $keyfile md${no}
+
+ dd if=/dev/md${no}.eli of=/dev/null bs=${secsize} count=2 >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ echo "ok $i - big 2 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ else
+ echo "not ok $i - big 2 aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ fi
+ i=$((i+1))
+
+ geli detach md${no}
+ mdconfig -d -u $no
+}
+
+
+i=1
+dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
+
+for_each_geli_config do_test
+
+rm -f $keyfile $sector
diff --git a/tests/sys/geom/class/eli/integrity_data_test.sh b/tests/sys/geom/class/eli/integrity_data_test.sh
new file mode 100644
index 000000000000..73b950a58a5e
--- /dev/null
+++ b/tests/sys/geom/class/eli/integrity_data_test.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+keyfile=`mktemp $base.XXXXXX` || exit 1
+sector=`mktemp $base.XXXXXX` || exit 1
+
+echo "1..600"
+
+do_test() {
+ cipher=$1
+ aalgo=$2
+ secsize=$3
+ ealgo=${cipher%%:*}
+ keylen=${cipher##*:}
+
+ mdconfig -a -t malloc -s `expr $secsize \* 2 + 512`b -u $no || exit 1
+ geli init -B none -a $aalgo -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null
+
+ # Corrupt 8 bytes of data.
+ dd if=/dev/md${no} of=${sector} bs=512 count=1 >/dev/null 2>&1
+ dd if=/dev/random of=${sector} bs=1 count=8 seek=64 conv=notrunc >/dev/null 2>&1
+ dd if=${sector} of=/dev/md${no} bs=512 count=1 >/dev/null 2>&1
+ geli attach -p -k $keyfile md${no}
+
+ dd if=/dev/md${no}.eli of=/dev/null bs=${secsize} count=1 >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ else
+ echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ fi
+ i=$((i+1))
+
+ geli detach md${no}
+ mdconfig -d -u $no
+}
+
+i=1
+dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
+
+for_each_geli_config do_test
+
+rm -f $keyfile $sector
diff --git a/tests/sys/geom/class/eli/integrity_hmac_test.sh b/tests/sys/geom/class/eli/integrity_hmac_test.sh
new file mode 100644
index 000000000000..6e1dfa585108
--- /dev/null
+++ b/tests/sys/geom/class/eli/integrity_hmac_test.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+keyfile=`mktemp $base.XXXXXX` || exit 1
+sector=`mktemp $base.XXXXXX` || exit 1
+
+echo "1..600"
+
+do_test() {
+ cipher=$1
+ aalgo=$2
+ secsize=$3
+ ealgo=${cipher%%:*}
+ keylen=${cipher##*:}
+
+ mdconfig -a -t malloc -s `expr $secsize \* 2 + 512`b -u $no || exit 2
+ geli init -B none -a $aalgo -e $ealgo -l $keylen -P -K $keyfile -s $secsize md${no} 2>/dev/null
+
+ # Corrupt 8 bytes of HMAC.
+ dd if=/dev/md${no} of=${sector} bs=512 count=1 >/dev/null 2>&1
+ dd if=/dev/random of=${sector} bs=1 count=16 conv=notrunc >/dev/null 2>&1
+ dd if=${sector} of=/dev/md${no} bs=512 count=1 >/dev/null 2>&1
+ geli attach -p -k $keyfile md${no}
+
+ dd if=/dev/md${no}.eli bs=${secsize} count=1 >/dev/null 2>&1
+ if [ $? -ne 0 ]; then
+ echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ else
+ echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ fi
+ i=$((i+1))
+
+ geli detach md${no}
+ mdconfig -d -u $no
+}
+
+
+i=1
+dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
+
+for_each_geli_config do_test
+
+rm -f $keyfile $sector
diff --git a/tests/sys/geom/class/eli/kill_test.sh b/tests/sys/geom/class/eli/kill_test.sh
new file mode 100644
index 000000000000..ccced9f47397
--- /dev/null
+++ b/tests/sys/geom/class/eli/kill_test.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+keyfile1=`mktemp $base.XXXXXX` || exit 1
+keyfile2=`mktemp $base.XXXXXX` || exit 1
+mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
+
+echo "1..9"
+
+dd if=/dev/random of=${keyfile1} bs=512 count=16 >/dev/null 2>&1
+dd if=/dev/random of=${keyfile2} bs=512 count=16 >/dev/null 2>&1
+
+geli init -B none -P -K $keyfile1 md${no}
+geli attach -p -k $keyfile1 md${no}
+geli setkey -n 1 -P -K $keyfile2 md${no}
+
+# Kill attached provider.
+geli kill md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+sleep 1
+# Provider should be automatically detached.
+if [ ! -c /dev/md{$no}.eli ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+
+# We cannot use keyfile1 anymore.
+geli attach -p -k $keyfile1 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+
+# We cannot use keyfile2 anymore.
+geli attach -p -k $keyfile2 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 4"
+else
+ echo "not ok 4"
+fi
+
+geli init -B none -P -K $keyfile1 md${no}
+geli setkey -n 1 -p -k $keyfile1 -P -K $keyfile2 md${no}
+
+# Should be possible to attach with keyfile1.
+geli attach -p -k $keyfile1 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 5"
+else
+ echo "not ok 5"
+fi
+geli detach md${no}
+
+# Should be possible to attach with keyfile2.
+geli attach -p -k $keyfile2 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 6"
+else
+ echo "not ok 6"
+fi
+geli detach md${no}
+
+# Kill detached provider.
+geli kill md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 7"
+else
+ echo "not ok 7"
+fi
+
+# We cannot use keyfile1 anymore.
+geli attach -p -k $keyfile1 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 8"
+else
+ echo "not ok 8"
+fi
+
+# We cannot use keyfile2 anymore.
+geli attach -p -k $keyfile2 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 9"
+else
+ echo "not ok 9"
+fi
+
+rm -f $keyfile1 $keyfile2
diff --git a/tests/sys/geom/class/eli/nokey_test.sh b/tests/sys/geom/class/eli/nokey_test.sh
new file mode 100644
index 000000000000..f32e1a4f1eba
--- /dev/null
+++ b/tests/sys/geom/class/eli/nokey_test.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+keyfile=`mktemp $base.XXXXXX` || exit 1
+mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
+
+echo "1..8"
+
+geli init -B none -P md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+
+dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
+
+geli init -B none -P -K ${keyfile} md${no} 2>/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+geli attach -p md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+geli attach -p -k ${keyfile} md${no} 2>/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 4"
+else
+ echo "not ok 4"
+fi
+geli setkey -n 0 -P md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 5"
+else
+ echo "not ok 5"
+fi
+geli detach md${no} 2>/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 6"
+else
+ echo "not ok 6"
+fi
+geli setkey -n 0 -p -P -K ${keyfile} md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 7"
+else
+ echo "not ok 7"
+fi
+geli setkey -n 0 -p -k ${keyfile} -P md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 8"
+else
+ echo "not ok 8"
+fi
+
+rm -f $keyfile
diff --git a/tests/sys/geom/class/eli/onetime_a_test.sh b/tests/sys/geom/class/eli/onetime_a_test.sh
new file mode 100644
index 000000000000..0cccf3031355
--- /dev/null
+++ b/tests/sys/geom/class/eli/onetime_a_test.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=8
+rnd=`mktemp $base.XXXXXX` || exit 1
+
+echo "1..600"
+
+do_test() {
+ cipher=$1
+ aalgo=$2
+ secsize=$3
+ ealgo=${cipher%%:*}
+ keylen=${cipher##*:}
+
+ mdconfig -a -t malloc -s `expr $secsize \* $sectors + 512`b -u $no || exit 1
+ geli onetime -a $aalgo -e $ealgo -l $keylen -s $secsize md${no} 2>/dev/null
+
+ secs=`diskinfo /dev/md${no}.eli | awk '{print $4}'`
+
+ dd if=${rnd} of=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null
+
+ md_rnd=`dd if=${rnd} bs=${secsize} count=${secs} 2>/dev/null | md5`
+ md_ddev=`dd if=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null | md5`
+
+ if [ ${md_rnd} = ${md_ddev} ]; then
+ echo "ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ else
+ echo "not ok $i - aalgo=${aalgo} ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ fi
+ i=$((i+1))
+
+ geli detach md${no}
+ mdconfig -d -u $no
+}
+
+i=1
+dd if=/dev/random of=${rnd} bs=1024 count=1024 >/dev/null 2>&1
+
+for_each_geli_config do_test
+
+rm -f $rnd
diff --git a/tests/sys/geom/class/eli/onetime_d_test.sh b/tests/sys/geom/class/eli/onetime_d_test.sh
new file mode 100644
index 000000000000..51a6abb8c97a
--- /dev/null
+++ b/tests/sys/geom/class/eli/onetime_d_test.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+mdconfig -a -t malloc -s $sectors -u $no || exit 1
+
+echo "1..3"
+
+geli onetime -d md${no}
+if [ -c /dev/md${no}.eli ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+# Be sure it doesn't detach on read.
+dd if=/dev/md${no}.eli of=/dev/null 2>/dev/null
+sleep 1
+if [ -c /dev/md${no}.eli ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+true > /dev/md${no}.eli
+sleep 1
+if [ ! -c /dev/md${no}.eli ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+
+mdconfig -d -u $no
diff --git a/tests/sys/geom/class/eli/onetime_test.sh b/tests/sys/geom/class/eli/onetime_test.sh
new file mode 100644
index 000000000000..3cade152829a
--- /dev/null
+++ b/tests/sys/geom/class/eli/onetime_test.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+
+echo "1..200"
+
+do_test() {
+ cipher=$1
+ secsize=$2
+ ealgo=${cipher%%:*}
+ keylen=${cipher##*:}
+
+ rnd=`mktemp $base.XXXXXX` || exit 1
+ mdconfig -a -t malloc -s `expr $secsize \* $sectors`b -u $no || exit 1
+
+ geli onetime -e $ealgo -l $keylen -s $secsize md${no} 2>/dev/null
+
+ secs=`diskinfo /dev/md${no}.eli | awk '{print $4}'`
+
+ dd if=/dev/random of=${rnd} bs=${secsize} count=${secs} >/dev/null 2>&1
+ dd if=${rnd} of=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null
+
+ md_rnd=`dd if=${rnd} bs=${secsize} count=${secs} 2>/dev/null | md5`
+ md_ddev=`dd if=/dev/md${no}.eli bs=${secsize} count=${secs} 2>/dev/null | md5`
+ md_edev=`dd if=/dev/md${no} bs=${secsize} count=${secs} 2>/dev/null | md5`
+
+ if [ ${md_rnd} = ${md_ddev} ]; then
+ echo "ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ else
+ echo "not ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ fi
+ i=$((i+1))
+ if [ ${md_rnd} != ${md_edev} ]; then
+ echo "ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ else
+ echo "not ok $i - ealgo=${ealgo} keylen=${keylen} sec=${secsize}"
+ fi
+ i=$((i+1))
+
+ geli detach md${no}
+ rm -f $rnd
+ mdconfig -d -u $no
+}
+
+i=1
+for_each_geli_config_nointegrity do_test
diff --git a/tests/sys/geom/class/eli/readonly_test.sh b/tests/sys/geom/class/eli/readonly_test.sh
new file mode 100644
index 000000000000..721ad62f3b5f
--- /dev/null
+++ b/tests/sys/geom/class/eli/readonly_test.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+keyfile=`mktemp $base.XXXXXX` || exit 1
+mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
+
+echo "1..11"
+
+dd if=/dev/random of=${keyfile} bs=512 count=16 >/dev/null 2>&1
+
+geli init -B none -P -K $keyfile md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+
+geli attach -r -p -k $keyfile md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+
+sh -c "true >/dev/md${no}.eli" 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+
+geli kill md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 4"
+else
+ echo "not ok 4"
+fi
+
+# kill should detach provider...
+if [ ! -c /dev/md{$no}.eli ]; then
+ echo "ok 5"
+else
+ echo "not ok 5"
+fi
+
+# ...but not destroy the metadata.
+geli attach -r -p -k $keyfile md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 6"
+else
+ echo "not ok 6"
+fi
+
+geli setkey -n 1 -P -K /dev/null md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 7"
+else
+ echo "not ok 7"
+fi
+
+geli delkey -n 0 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 8"
+else
+ echo "not ok 8"
+fi
+
+geli delkey -f -n 0 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 9"
+else
+ echo "not ok 9"
+fi
+
+geli list md${no}.eli | egrep '^Flags: .*READ-ONLY' >/dev/null
+if [ $? -eq 0 ]; then
+ echo "ok 10"
+else
+ echo "not ok 10"
+fi
+
+geli detach md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 11"
+else
+ echo "not ok 11"
+fi
+
+mdconfig -d -u $no
+rm -f $keyfile
diff --git a/tests/sys/geom/class/eli/resize_test.sh b/tests/sys/geom/class/eli/resize_test.sh
new file mode 100644
index 000000000000..7a7cf635837b
--- /dev/null
+++ b/tests/sys/geom/class/eli/resize_test.sh
@@ -0,0 +1,148 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+echo 1..27
+
+BLK=512
+BLKS_PER_MB=2048
+
+md=$(mdconfig -s40m) || exit 1
+unit=${md#md}
+i=1
+
+setsize() {
+ partszMB=$1 unitszMB=$2
+
+ {
+ echo a: $(($partszMB * $BLKS_PER_MB)) 0 4.2BSD 1024 8192
+ echo c: $(($unitszMB * $BLKS_PER_MB)) 0 unused 0 0
+ } | bsdlabel -R $md /dev/stdin
+}
+
+# Initialise
+
+setsize 10 40 || echo -n "not "
+echo ok $i - "Sized ${md}a to 10m"
+i=$((i + 1))
+
+echo secret >tmp.key
+geli init -Bnone -PKtmp.key ${md}a || echo -n "not "
+echo ok $i - "Initialised geli on ${md}a"
+i=$((i + 1))
+geli attach -pk tmp.key ${md}a || echo -n "not "
+echo ok $i - "Attached ${md}a as ${md}a.eli"
+i=$((i + 1))
+
+newfs -U ${md}a.eli >/dev/null || echo -n "not "
+echo ok $i - "Initialised the filesystem on ${md}a.eli"
+i=$((i + 1))
+out=$(fsck -tufs -y ${md}a.eli)
+echo "$out" | fgrep -q MODIFIED && echo -n "not "
+echo ok $i - "fsck says ${md}a.eli is clean," $(echo $(echo "$out" | wc -l)) \
+ "lines of output"
+i=$((i + 1))
+
+
+# Doing a backup, resize & restore must be forced (with -f) as geli
+# verifies that the provider size in the metadata matches the consumer.
+
+geli backup ${md}a tmp.meta || echo -n "not "
+echo ok $i - "Backed up ${md}a metadata"
+i=$((i + 1))
+
+geli detach ${md}a.eli || echo -n "not "
+echo ok $i - "Detached ${md}a.eli"
+i=$((i + 1))
+
+setsize 20 40 || echo -n "not "
+echo ok $i - "Sized ${md}a to 20m"
+i=$((i + 1))
+geli attach -pktmp.key ${md}a && echo -n "not "
+echo ok $i - "Attaching ${md}a fails after resizing the consumer"
+i=$((i + 1))
+
+geli restore tmp.meta ${md}a && echo -n "not "
+echo ok $i - "Restoring metadata on ${md}a.eli fails without -f"
+i=$((i + 1))
+geli restore -f tmp.meta ${md}a || echo -n "not "
+echo ok $i - "Restoring metadata on ${md}a.eli can be forced"
+i=$((i + 1))
+
+geli attach -pktmp.key ${md}a || echo -n "not "
+echo ok $i - "Attaching ${md}a is now possible"
+i=$((i + 1))
+
+growfs -y ${md}a.eli >/dev/null || echo -n "not "
+echo ok $i - "Extended the filesystem on ${md}a.eli"
+i=$((i + 1))
+
+out=$(fsck -tufs -y ${md}a.eli)
+echo "$out" | fgrep -q MODIFIED && echo -n "not "
+echo ok $i - "fsck says ${md}a.eli is clean," $(echo $(echo "$out" | wc -l)) \
+ "lines of output"
+i=$((i + 1))
+
+
+# Now do the resize properly
+
+geli detach ${md}a.eli || echo -n "not "
+echo ok $i - "Detached ${md}a.eli"
+i=$((i + 1))
+
+setsize 30 40 || echo -n "not "
+echo ok $i - "Sized ${md}a to 30m"
+i=$((i + 1))
+
+geli resize -s20m ${md}a || echo -n "not "
+echo ok $i - "Resizing works ok"
+i=$((i + 1))
+geli resize -s20m ${md}a && echo -n "not "
+echo ok $i - "Resizing doesn't work a 2nd time (no old metadata)"
+i=$((i + 1))
+
+geli attach -pktmp.key ${md}a || echo -n "not "
+echo ok $i - "Attaching ${md}a works ok"
+i=$((i + 1))
+
+growfs -y ${md}a.eli >/dev/null || echo -n "not "
+echo ok $i - "Extended the filesystem on ${md}a.eli"
+i=$((i + 1))
+
+out=$(fsck -tufs -y ${md}a.eli)
+echo "$out" | fgrep -q MODIFIED && echo -n "not "
+echo ok $i - "fsck says ${md}a.eli is clean," $(echo $(echo "$out" | wc -l)) \
+ "lines of output"
+i=$((i + 1))
+
+geli detach ${md}a.eli
+gpart destroy -F $md >/dev/null
+
+
+# Verify that the man page example works, changing ada0 to $md,
+# 1g to 20m, 2g to 30m and keyfile to tmp.key, and adding -B none
+# to geli init.
+
+gpart create -s GPT $md || echo -n "not "
+echo ok $i - "Installed a GPT on ${md}"
+i=$((i + 1))
+gpart add -s 20m -t freebsd-ufs -i 1 $md || echo -n "not "
+echo ok $i - "Added a 20m partition in slot 1"
+i=$((i + 1))
+geli init -B none -K tmp.key -P ${md}p1 || echo -n "not "
+echo ok $i - "Initialised geli on ${md}p1"
+i=$((i + 1))
+gpart resize -s 30m -i 1 $md || echo -n "not "
+echo ok $i - "Resized partition ${md}p1 to 30m"
+i=$((i + 1))
+geli resize -s 20m ${md}p1 || echo -n "not "
+echo ok $i - "Resized geli on ${md}p1 to 30m"
+i=$((i + 1))
+geli attach -k tmp.key -p ${md}p1 || echo -n "not "
+echo ok $i - "Attached ${md}p1.eli"
+i=$((i + 1))
+
+geli detach ${md}p1.eli
+
+rm tmp.*
diff --git a/tests/sys/geom/class/eli/setkey_test.sh b/tests/sys/geom/class/eli/setkey_test.sh
new file mode 100644
index 000000000000..458100c7da86
--- /dev/null
+++ b/tests/sys/geom/class/eli/setkey_test.sh
@@ -0,0 +1,156 @@
+#!/bin/sh
+# $FreeBSD$
+
+. $(dirname $0)/conf.sh
+
+base=`basename $0`
+sectors=100
+rnd=`mktemp $base.XXXXXX` || exit 1
+keyfile1=`mktemp $base.XXXXXX` || exit 1
+keyfile2=`mktemp $base.XXXXXX` || exit 1
+keyfile3=`mktemp $base.XXXXXX` || exit 1
+keyfile4=`mktemp $base.XXXXXX` || exit 1
+keyfile5=`mktemp $base.XXXXXX` || exit 1
+mdconfig -a -t malloc -s `expr $sectors + 1` -u $no || exit 1
+
+echo "1..16"
+
+dd if=/dev/random of=${rnd} bs=512 count=${sectors} >/dev/null 2>&1
+hash1=`dd if=${rnd} bs=512 count=${sectors} 2>/dev/null | md5`
+dd if=/dev/random of=${keyfile1} bs=512 count=16 >/dev/null 2>&1
+dd if=/dev/random of=${keyfile2} bs=512 count=16 >/dev/null 2>&1
+dd if=/dev/random of=${keyfile3} bs=512 count=16 >/dev/null 2>&1
+dd if=/dev/random of=${keyfile4} bs=512 count=16 >/dev/null 2>&1
+dd if=/dev/random of=${keyfile5} bs=512 count=16 >/dev/null 2>&1
+
+geli init -B none -P -K $keyfile1 md${no}
+geli attach -p -k $keyfile1 md${no}
+
+dd if=${rnd} of=/dev/md${no}.eli bs=512 count=${sectors} 2>/dev/null
+rm -f $rnd
+hash2=`dd if=/dev/md${no}.eli bs=512 count=${sectors} 2>/dev/null | md5`
+
+# Change current key (0) for attached provider.
+geli setkey -P -K $keyfile2 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+geli detach md${no}
+
+# We cannot use keyfile1 anymore.
+geli attach -p -k $keyfile1 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
+
+# Attach with new key.
+geli attach -p -k $keyfile2 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 3"
+else
+ echo "not ok 3"
+fi
+hash3=`dd if=/dev/md${no}.eli bs=512 count=${sectors} 2>/dev/null | md5`
+
+# Change key 1 for attached provider.
+geli setkey -n 1 -P -K $keyfile3 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 4"
+else
+ echo "not ok 4"
+fi
+geli detach md${no}
+
+# Attach with key 1.
+geli attach -p -k $keyfile3 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 5"
+else
+ echo "not ok 5"
+fi
+hash4=`dd if=/dev/md${no}.eli bs=512 count=${sectors} 2>/dev/null | md5`
+geli detach md${no}
+
+# Change current (1) key for detached provider.
+geli setkey -p -k $keyfile3 -P -K $keyfile4 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 6"
+else
+ echo "not ok 6"
+fi
+
+# We cannot use keyfile3 anymore.
+geli attach -p -k $keyfile3 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 7"
+else
+ echo "not ok 7"
+fi
+
+# Attach with key 1.
+geli attach -p -k $keyfile4 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 8"
+else
+ echo "not ok 8"
+fi
+hash5=`dd if=/dev/md${no}.eli bs=512 count=${sectors} 2>/dev/null | md5`
+geli detach md${no}
+
+# Change key 0 for detached provider.
+geli setkey -n 0 -p -k $keyfile4 -P -K $keyfile5 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 9"
+else
+ echo "not ok 9"
+fi
+
+# We cannot use keyfile2 anymore.
+geli attach -p -k $keyfile2 md${no} 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo "ok 10"
+else
+ echo "not ok 10"
+fi
+
+# Attach with key 0.
+geli attach -p -k $keyfile5 md${no}
+if [ $? -eq 0 ]; then
+ echo "ok 11"
+else
+ echo "not ok 11"
+fi
+hash6=`dd if=/dev/md${no}.eli bs=512 count=${sectors} 2>/dev/null | md5`
+geli detach md${no}
+
+if [ ${hash1} = ${hash2} ]; then
+ echo "ok 12"
+else
+ echo "not ok 12"
+fi
+if [ ${hash1} = ${hash3} ]; then
+ echo "ok 13"
+else
+ echo "not ok 13"
+fi
+if [ ${hash1} = ${hash4} ]; then
+ echo "ok 14"
+else
+ echo "not ok 14"
+fi
+if [ ${hash1} = ${hash5} ]; then
+ echo "ok 15"
+else
+ echo "not ok 15"
+fi
+if [ ${hash1} = ${hash6} ]; then
+ echo "ok 16"
+else
+ echo "not ok 16"
+fi
+
+rm -f $keyfile1 $keyfile2 $keyfile3 $keyfile4 $keyfile5
diff --git a/tests/sys/geom/class/gate/1_test.sh b/tests/sys/geom/class/gate/1_test.sh
new file mode 100644
index 000000000000..ba573bb6e122
--- /dev/null
+++ b/tests/sys/geom/class/gate/1_test.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo '1..2'
+
+base=`basename $0`
+us=0
+while [ -c /dev/ggate${us} ]; do
+ : $(( us += 1 ))
+done
+pidfile=ggated.$$.pid
+conf=`mktemp $base.XXXXXX` || exit 1
+port=33080
+
+work=$(attach_md -t malloc -s 1M)
+src=$(attach_md -t malloc -s 1M)
+
+test_cleanup()
+{
+ ggatec destroy -f -u $us
+ pkill -F $pidfile
+ geom_test_cleanup
+}
+trap test_cleanup ABRT EXIT INT TERM
+
+dd if=/dev/random of=/dev/$work bs=1m count=1 conv=sync
+dd if=/dev/random of=/dev/$src bs=1m count=1 conv=sync
+src_checksum=$(md5 -q /dev/$src)
+
+echo "127.0.0.1 RW /dev/$work" > $conf
+
+if ! ggated -p $port -F $pidfile $conf; then
+ echo 'ggated failed to start'
+ echo 'Bail out!'
+ exit 1
+fi
+sleep 1
+if ! ggatec create -p $port -u $us 127.0.0.1 /dev/$work; then
+ echo 'ggatec create failed'
+ echo 'Bail out!'
+ exit 1
+fi
+sleep 1
+
+dd if=/dev/${src} of=/dev/ggate${us} bs=1m count=1
+sleep 1
+
+work_checksum=$(md5 -q /dev/$work)
+if [ "$work_checksum" != "$src_checksum" ]; then
+ echo "not ok 1 - md5 checksums didn't match ($work_checksum != $src_checksum)"
+ echo "not ok 2 # SKIP"
+else
+ echo 'ok 1 - md5 checksum'
+
+ ggate_checksum=$(md5 -q /dev/ggate${us})
+ if [ "$ggate_checksum" != "$src_checksum" ]; then
+ echo "not ok 2 - md5 checksums didn't match ($ggate_checksum != $src_checksum)"
+ else
+ echo 'ok 2 - md5 checksum'
+ fi
+fi
diff --git a/tests/sys/geom/class/gate/2_test.sh b/tests/sys/geom/class/gate/2_test.sh
new file mode 100644
index 000000000000..be89accfcb9c
--- /dev/null
+++ b/tests/sys/geom/class/gate/2_test.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+base=`basename $0`
+us=46
+work=`mktemp -u $base.XXXXXX` || exit 1
+src=`mktemp -u $base.XXXXXX` || exit 1
+
+test_cleanup()
+{
+ ggatel destroy -f -u $us
+ rm -f $work $src
+
+ geom_test_cleanup
+}
+trap test_cleanup ABRT EXIT INT TERM
+
+dd if=/dev/random of=$work bs=1m count=1 conv=sync
+dd if=/dev/random of=$src bs=1m count=1 conv=sync
+
+if ! ggatel create -u $us $work; then
+ echo 'ggatel create failed'
+ echo 'Bail out!'
+ exit 1
+fi
+
+dd if=${src} of=/dev/ggate${us} bs=1m count=1
+sleep 1
+
+echo '1..2'
+
+src_checksum=$(md5 -q $src)
+work_checksum=$(md5 -q $work)
+if [ "$work_checksum" != "$src_checksum" ]; then
+ echo "not ok 1 - md5 checksums didn't match ($work_checksum != $src_checksum) # TODO: bug 204616"
+ echo 'not ok 2 # SKIP'
+else
+ echo 'ok 1 - md5 checksum'
+
+ ggate_checksum=$(md5 -q /dev/ggate${us})
+ if [ "$ggate_checksum" != "$src_checksum" ]; then
+ echo "not ok 2 - md5 checksums didn't match ($ggate_checksum != $src_checksum)"
+ else
+ echo 'ok 2 - md5 checksum'
+ fi
+fi
diff --git a/tests/sys/geom/class/gate/3_test.sh b/tests/sys/geom/class/gate/3_test.sh
new file mode 100644
index 000000000000..3511df761ca6
--- /dev/null
+++ b/tests/sys/geom/class/gate/3_test.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+base=`basename $0`
+us=47
+
+test_cleanup()
+{
+ ggatel destroy -f -u $us
+
+ geom_test_cleanup
+}
+trap test_cleanup ABRT EXIT INT TERM
+
+work=$(attach_md -t malloc -s 1M)
+src=$(attach_md -t malloc -s 1M)
+
+dd if=/dev/random of=/dev/$work bs=1m count=1 conv=sync
+dd if=/dev/random of=/dev/$src bs=1m count=1 conv=sync
+src_checksum=$(md5 -q /dev/$src)
+
+if ! ggatel create -u $us /dev/$work; then
+ echo 'ggatel create failed'
+ echo 'Bail out!'
+ exit 1
+fi
+
+sleep 1
+dd if=/dev/${src} of=/dev/ggate${us} bs=1m count=1 conv=sync
+sleep 1
+
+echo '1..2'
+
+work_checksum=$(md5 -q /dev/$work)
+if [ "$work_checksum" != "$src_checksum" ]; then
+ echo "not ok 1 - md5 checksums didn't match ($work_checksum != $src_checksum)"
+ echo 'not ok 2 # SKIP'
+else
+ echo 'ok 1 - md5 checksum'
+
+ ggate_checksum=$(md5 -q /dev/ggate${us})
+ if [ "$ggate_checksum" != "$src_checksum" ]; then
+ echo "not ok 2 - md5 checksums didn't match ($ggate_checksum != $src_checksum)"
+ else
+ echo 'ok 2 - md5 checksum'
+ fi
+fi
diff --git a/tests/sys/geom/class/gate/Makefile b/tests/sys/geom/class/gate/Makefile
new file mode 100644
index 000000000000..c034bf037efb
--- /dev/null
+++ b/tests/sys/geom/class/gate/Makefile
@@ -0,0 +1,17 @@
+# $FreeBSD$
+
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
+
+TAP_TESTS_SH+= 1_test
+TAP_TESTS_SH+= 2_test
+TAP_TESTS_SH+= 3_test
+
+${PACKAGE}FILES+= conf.sh
+
+.for t in ${TAP_TESTS_SH}
+TEST_METADATA.$t+= required_user="root"
+.endfor
+
+.include <bsd.test.mk>
diff --git a/tests/sys/geom/class/gate/Makefile.depend b/tests/sys/geom/class/gate/Makefile.depend
new file mode 100644
index 000000000000..f80275d86ab1
--- /dev/null
+++ b/tests/sys/geom/class/gate/Makefile.depend
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/tests/sys/geom/class/gate/conf.sh b/tests/sys/geom/class/gate/conf.sh
new file mode 100755
index 000000000000..7e22ce46af66
--- /dev/null
+++ b/tests/sys/geom/class/gate/conf.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+# $FreeBSD$
+
+name="$(mktemp -u gate.XXXXXX)"
+class="gate"
+base=`basename $0`
+
+. `dirname $0`/../geom_subr.sh
diff --git a/tests/sys/geom/class/geom_subr.sh b/tests/sys/geom/class/geom_subr.sh
new file mode 100644
index 000000000000..b03ee434c4e8
--- /dev/null
+++ b/tests/sys/geom/class/geom_subr.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+# $FreeBSD$
+
+devwait()
+{
+ while :; do
+ if [ -c /dev/${class}/${name} ]; then
+ return
+ fi
+ sleep 0.2
+ done
+}
+
+attach_md()
+{
+ local test_md
+
+ test_md=$(mdconfig -a "$@") || exit
+ echo $test_md >> $TEST_MDS_FILE || exit
+ echo $test_md
+}
+
+geom_test_cleanup()
+{
+ local test_md
+
+ if [ -f "$TEST_MDS_FILE" ]; then
+ while read test_md; do
+ # The "#" tells the TAP parser this is a comment
+ echo "# Removing test memory disk: $test_md"
+ mdconfig -d -u $test_md
+ done < $TEST_MDS_FILE
+ fi
+ rm -f "$TEST_MDS_FILE"
+}
+
+if [ $(id -u) -ne 0 ]; then
+ echo '1..0 # SKIP tests must be run as root'
+ exit 0
+fi
+# If the geom class isn't already loaded, try loading it.
+if ! kldstat -q -m g_${class}; then
+ if ! geom ${class} load; then
+ echo "1..0 # SKIP could not load module for geom class=${class}"
+ exit 0
+ fi
+fi
+
+# Need to keep track of the test md devices to avoid the scenario where a test
+# failing will cause the other tests to bomb out, or a test failing will leave
+# a large number of md(4) devices lingering around
+: ${TMPDIR=/tmp}
+export TMPDIR
+if ! TEST_MDS_FILE=$(mktemp ${TMPDIR}/test_mds.XXXXXX); then
+ echo 'Failed to create temporary file for tracking the test md(4) devices'
+ echo 'Bail out!'
+ exit 1
+fi
diff --git a/tests/sys/geom/class/mirror/1_test.sh b/tests/sys/geom/class/mirror/1_test.sh
new file mode 100644
index 000000000000..af82a14730c2
--- /dev/null
+++ b/tests/sys/geom/class/mirror/1_test.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
+
+gmirror label $name /dev/$us0 /dev/$us1 /dev/$us2 || exit 1
+devwait
+
+# Size of created device should be 1MB - 512b.
+
+size=`diskinfo /dev/mirror/${name} | awk '{print $3}'`
+
+if [ $size -eq 1048064 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
diff --git a/tests/sys/geom/class/mirror/2_test.sh b/tests/sys/geom/class/mirror/2_test.sh
new file mode 100644
index 000000000000..5605c44eb464
--- /dev/null
+++ b/tests/sys/geom/class/mirror/2_test.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..4"
+
+balance="round-robin"
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+us0=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+us1=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+us2=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+
+gmirror label -b $balance $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+dd if=${src} of=/dev/mirror/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+dd if=/dev/${us0} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 2"
+else
+ echo "ok 2"
+fi
+dd if=/dev/${us1} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 3"
+else
+ echo "ok 3"
+fi
+
+dd if=/dev/${us2} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 4"
+else
+ echo "ok 4"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/mirror/3_test.sh b/tests/sys/geom/class/mirror/3_test.sh
new file mode 100644
index 000000000000..b7f85255e076
--- /dev/null
+++ b/tests/sys/geom/class/mirror/3_test.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..5"
+
+balance="round-robin"
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+us0=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+us1=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+us2=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+
+gmirror label -b $balance $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+dd if=${src} of=/dev/mirror/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+gmirror remove $name ${us0}
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 2"
+else
+ echo "ok 2"
+fi
+
+gmirror remove $name ${us1}
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 3"
+else
+ echo "ok 3"
+fi
+
+gmirror remove $name ${us2}
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 4"
+else
+ echo "ok 4"
+fi
+
+# mirror/${name} should be removed.
+if [ -c /dev/${name} ]; then
+ echo "not ok 5"
+else
+ echo "ok 5"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/mirror/4_test.sh b/tests/sys/geom/class/mirror/4_test.sh
new file mode 100644
index 000000000000..6efcc021ef65
--- /dev/null
+++ b/tests/sys/geom/class/mirror/4_test.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..5"
+
+balance="load"
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+us0=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+us1=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+us2=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+
+gmirror label -b $balance $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+dd if=${src} of=/dev/mirror/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+gmirror remove $name ${us0}
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 2"
+else
+ echo "ok 2"
+fi
+
+gmirror remove $name ${us1}
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 3"
+else
+ echo "ok 3"
+fi
+
+gmirror remove $name ${us2}
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 4"
+else
+ echo "ok 4"
+fi
+
+gmirror destroy $name
+
+# mirror/${name} should be removed.
+if [ -c /dev/${name} ]; then
+ echo "not ok 5"
+else
+ echo "ok 5"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/mirror/5_test.sh b/tests/sys/geom/class/mirror/5_test.sh
new file mode 100644
index 000000000000..3a176b55531f
--- /dev/null
+++ b/tests/sys/geom/class/mirror/5_test.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..5"
+
+balance="split"
+ddbs=8192
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+us0=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+us1=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+us2=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+
+gmirror label -b $balance -s `expr $ddbs / 2` $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+dd if=${src} of=/dev/mirror/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+gmirror remove $name ${us0}
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 2"
+else
+ echo "ok 2"
+fi
+
+gmirror remove $name ${us1}
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 3"
+else
+ echo "ok 3"
+fi
+
+gmirror remove $name ${us2}
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 4"
+else
+ echo "ok 4"
+fi
+
+# mirror/${name} should be removed.
+if [ -c /dev/${name} ]; then
+ echo "not ok 5"
+else
+ echo "ok 5"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/mirror/6_test.sh b/tests/sys/geom/class/mirror/6_test.sh
new file mode 100644
index 000000000000..68036e9c8c6a
--- /dev/null
+++ b/tests/sys/geom/class/mirror/6_test.sh
@@ -0,0 +1,45 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..2"
+
+balance="split"
+ddbs=8192
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+us0=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+us1=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+us2=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+
+gmirror label -b $balance -s `expr $ddbs / 2` $name /dev/${us0} /dev/${us1} || exit 1
+devwait
+
+dd if=${src} of=/dev/mirror/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+dd if=/dev/zero of=/dev/${us2} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+# Connect disk to the mirror.
+gmirror insert ${name} ${us2}
+# Wait for synchronization.
+sleep 1
+dd if=/dev/${us2} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 2"
+else
+ echo "ok 2"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/mirror/7_test.sh b/tests/sys/geom/class/mirror/7_test.sh
new file mode 100644
index 000000000000..f5bf71ab7a3b
--- /dev/null
+++ b/tests/sys/geom/class/mirror/7_test.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..5"
+
+balance="prefer"
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+us0=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+us1=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+us2=$(attach_md -t malloc -s `expr $nblocks1 + 1`) || exit 1
+
+gmirror label -b $balance $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+dd if=${src} of=/dev/mirror/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+gmirror remove $name ${us0}
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 2"
+else
+ echo "ok 2"
+fi
+
+gmirror remove $name ${us1}
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 3"
+else
+ echo "ok 3"
+fi
+
+gmirror remove $name ${us2}
+dd if=/dev/mirror/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 4"
+else
+ echo "ok 4"
+fi
+
+# mirror/${name} should be removed.
+if [ -c /dev/${name} ]; then
+ echo "not ok 5"
+else
+ echo "ok 5"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/mirror/Makefile b/tests/sys/geom/class/mirror/Makefile
new file mode 100644
index 000000000000..2665631d606b
--- /dev/null
+++ b/tests/sys/geom/class/mirror/Makefile
@@ -0,0 +1,21 @@
+# $FreeBSD$
+
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
+
+TAP_TESTS_SH+= 1_test
+TAP_TESTS_SH+= 2_test
+TAP_TESTS_SH+= 3_test
+TAP_TESTS_SH+= 4_test
+TAP_TESTS_SH+= 5_test
+TAP_TESTS_SH+= 6_test
+TAP_TESTS_SH+= 7_test
+
+${PACKAGE}FILES+= conf.sh
+
+.for t in ${TAP_TESTS_SH}
+TEST_METADATA.$t+= required_user="root"
+.endfor
+
+.include <bsd.test.mk>
diff --git a/tests/sys/geom/class/mirror/Makefile.depend b/tests/sys/geom/class/mirror/Makefile.depend
new file mode 100644
index 000000000000..f80275d86ab1
--- /dev/null
+++ b/tests/sys/geom/class/mirror/Makefile.depend
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/tests/sys/geom/class/mirror/conf.sh b/tests/sys/geom/class/mirror/conf.sh
new file mode 100644
index 000000000000..d8595f199bf3
--- /dev/null
+++ b/tests/sys/geom/class/mirror/conf.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $FreeBSD$
+
+name="$(mktemp -u mirror.XXXXXX)"
+class="mirror"
+base=`basename $0`
+
+gmirror_test_cleanup()
+{
+ [ -c /dev/$class/$name ] && gmirror destroy $name
+ geom_test_cleanup
+}
+trap gmirror_test_cleanup ABRT EXIT INT TERM
+
+. `dirname $0`/../geom_subr.sh
diff --git a/tests/sys/geom/class/nop/Makefile b/tests/sys/geom/class/nop/Makefile
new file mode 100644
index 000000000000..e2d639f79cdf
--- /dev/null
+++ b/tests/sys/geom/class/nop/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
+
+ATF_TESTS_SH+= nop_test
+
+.include <bsd.test.mk>
diff --git a/tests/sys/geom/class/nop/Makefile.depend b/tests/sys/geom/class/nop/Makefile.depend
new file mode 100644
index 000000000000..f80275d86ab1
--- /dev/null
+++ b/tests/sys/geom/class/nop/Makefile.depend
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/tests/sys/geom/class/nop/nop_test.sh b/tests/sys/geom/class/nop/nop_test.sh
new file mode 100755
index 000000000000..35cc191de170
--- /dev/null
+++ b/tests/sys/geom/class/nop/nop_test.sh
@@ -0,0 +1,166 @@
+# Copyright (c) 2016 Alan Somers
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+
+MD_DEVS="md.devs"
+PLAINFILES=plainfiles
+
+atf_test_case diskinfo cleanup
+diskinfo_head()
+{
+ atf_set "descr" "gnop should preserve diskinfo's basic properties"
+ atf_set "require.user" "root"
+ atf_set "timeout" 15
+}
+diskinfo_body()
+{
+ us=$(alloc_md)
+ atf_check gnop create /dev/${us}
+ md_secsize=$(diskinfo ${us} | cut -wf 2)
+ md_mediasize=$(diskinfo ${us} | cut -wf 3)
+ md_stripesize=$(diskinfo ${us} | cut -wf 5)
+ nop_secsize=$(diskinfo ${us}.nop | cut -wf 2)
+ nop_mediasize=$(diskinfo ${us}.nop | cut -wf 3)
+ nop_stripesize=$(diskinfo ${us}.nop | cut -wf 5)
+ atf_check_equal "$md_secsize" "$nop_secsize"
+ atf_check_equal "$md_mediasize" "$nop_mediasize"
+ atf_check_equal "$md_stripesize" "$nop_stripesize"
+}
+diskinfo_cleanup()
+{
+ common_cleanup
+}
+
+atf_test_case io cleanup
+io_head()
+{
+ atf_set "descr" "I/O works on gnop devices"
+ atf_set "require.user" "root"
+ atf_set "timeout" 15
+}
+io_body()
+{
+ us=$(alloc_md)
+ atf_check gnop create /dev/${us}
+
+ echo src >> $PLAINFILES
+ echo dst >> $PLAINFILES
+ dd if=/dev/random of=src bs=1m count=1 >/dev/null 2>&1
+ dd if=src of=/dev/${us}.nop bs=1m count=1 > /dev/null 2>&1
+ dd if=/dev/${us}.nop of=dst bs=1m count=1 > /dev/null 2>&1
+
+ atf_check_equal `md5 -q src` `md5 -q dst`
+}
+io_cleanup()
+{
+ common_cleanup
+}
+
+atf_test_case size cleanup
+size_head()
+{
+ atf_set "descr" "Test gnop's -s option"
+ atf_set "require.user" "root"
+ atf_set "timeout" 15
+}
+size_body()
+{
+ us=$(alloc_md)
+ for mediasize in 65536 524288 1048576; do
+ atf_check gnop create -s ${mediasize} /dev/${us}
+ gnop_mediasize=`diskinfo /dev/${us}.nop | cut -wf 3`
+ atf_check_equal "${mediasize}" "${gnop_mediasize}"
+ atf_check gnop destroy /dev/${us}.nop
+ done
+ # We shouldn't be able to extend the provider's size
+ atf_check -s not-exit:0 -e ignore gnop create -s 2097152 /dev/${us}
+}
+size_cleanup()
+{
+ common_cleanup
+}
+
+atf_test_case stripesize cleanup
+stripesize_head()
+{
+ atf_set "descr" "Test gnop's -p and -P options"
+ atf_set "require.user" "root"
+ atf_set "timeout" 15
+}
+stripesize_body()
+{
+ us=$(alloc_md)
+ for ss in 512 1024 2048 4096 8192; do
+ for sofs in `seq 0 512 ${ss}`; do
+ [ "$sofs" -eq "$ss" ] && continue
+ atf_check gnop create -p ${ss} -P ${sofs} /dev/${us}
+ gnop_ss=`diskinfo /dev/${us}.nop | cut -wf 5`
+ gnop_sofs=`diskinfo /dev/${us}.nop | cut -wf 6`
+ atf_check_equal "${ss}" "${gnop_ss}"
+ atf_check_equal "${sofs}" "${gnop_sofs}"
+ atf_check gnop destroy /dev/${us}.nop
+ done
+ done
+}
+stripesize_cleanup()
+{
+ common_cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case io
+ atf_add_test_case diskinfo
+ atf_add_test_case stripesize
+ atf_add_test_case size
+}
+
+alloc_md()
+{
+ local md
+
+ md=$(mdconfig -a -t swap -s 1M) || atf_fail "mdconfig -a failed"
+ echo ${md} >> $MD_DEVS
+ echo ${md}
+}
+
+common_cleanup()
+{
+ if [ -f "$MD_DEVS" ]; then
+ while read test_md; do
+ gnop destroy -f ${test_md}.nop 2>/dev/null
+ mdconfig -d -u $test_md 2>/dev/null
+ done < $MD_DEVS
+ rm $MD_DEVS
+ fi
+
+ if [ -f "$PLAINFILES" ]; then
+ while read f; do
+ rm -f ${f}
+ done < ${PLAINFILES}
+ rm ${PLAINFILES}
+ fi
+ true
+}
diff --git a/tests/sys/geom/class/raid3/10_test.sh b/tests/sys/geom/class/raid3/10_test.sh
new file mode 100644
index 000000000000..edd827d03ddf
--- /dev/null
+++ b/tests/sys/geom/class/raid3/10_test.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+graid3 label -r $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+dd if=/dev/raid3/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/raid3/11_test.sh b/tests/sys/geom/class/raid3/11_test.sh
new file mode 100644
index 000000000000..0407261ca7df
--- /dev/null
+++ b/tests/sys/geom/class/raid3/11_test.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+graid3 label -w $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+dd if=/dev/raid3/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/raid3/12_test.sh b/tests/sys/geom/class/raid3/12_test.sh
new file mode 100644
index 000000000000..10533c6710d1
--- /dev/null
+++ b/tests/sys/geom/class/raid3/12_test.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+nblocks1=9
+nblocks2=`expr $nblocks1 - 1`
+nblocks3=`expr $nblocks2 / 2`
+
+us0=$(attach_md -t malloc -s $nblocks1) || exit 1
+us1=$(attach_md -t malloc -s $nblocks1) || exit 1
+us2=$(attach_md -t malloc -s $nblocks1) || exit 1
+
+dd if=/dev/random of=/dev/${us0} count=$nblocks1 >/dev/null 2>&1
+dd if=/dev/random of=/dev/${us1} count=$nblocks1 >/dev/null 2>&1
+dd if=/dev/random of=/dev/${us2} count=$nblocks1 >/dev/null 2>&1
+
+graid3 label -w $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+# Wait for synchronization.
+sleep 2
+graid3 stop $name
+# Break one component.
+dd if=/dev/random of=/dev/${us1} count=$nblocks2 >/dev/null 2>&1
+# Provoke retaste of the rest components.
+true > /dev/${us0}
+true > /dev/${us2}
+sleep 1
+
+dd if=/dev/raid3/${name} of=/dev/null bs=1k count=$nblocks3 >/dev/null 2>&1
+ec=$?
+if [ $ec -eq 0 ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
diff --git a/tests/sys/geom/class/raid3/1_test.sh b/tests/sys/geom/class/raid3/1_test.sh
new file mode 100644
index 000000000000..4c0b4a230c69
--- /dev/null
+++ b/tests/sys/geom/class/raid3/1_test.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..2"
+
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
+
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} 2>/dev/null || exit 1
+devwait
+
+# Size of created device should be 2MB - 1024B.
+
+mediasize=`diskinfo /dev/raid3/${name} | awk '{print $3}'`
+if [ $mediasize -eq 2096128 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+sectorsize=`diskinfo /dev/raid3/${name} | awk '{print $2}'`
+if [ $sectorsize -eq 1024 ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
diff --git a/tests/sys/geom/class/raid3/2_test.sh b/tests/sys/geom/class/raid3/2_test.sh
new file mode 100644
index 000000000000..22ebd38f6987
--- /dev/null
+++ b/tests/sys/geom/class/raid3/2_test.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+dd if=/dev/raid3/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/raid3/3_test.sh b/tests/sys/geom/class/raid3/3_test.sh
new file mode 100644
index 000000000000..f068b064242b
--- /dev/null
+++ b/tests/sys/geom/class/raid3/3_test.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+#
+# Reading without one DATA component (so with parity).
+#
+graid3 remove -n 1 $name
+dd if=/dev/raid3/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/raid3/4_test.sh b/tests/sys/geom/class/raid3/4_test.sh
new file mode 100644
index 000000000000..810f13db4066
--- /dev/null
+++ b/tests/sys/geom/class/raid3/4_test.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+#
+# Writing without one DATA component.
+#
+graid3 remove -n 1 $name
+dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+dd if=/dev/raid3/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/raid3/5_test.sh b/tests/sys/geom/class/raid3/5_test.sh
new file mode 100644
index 000000000000..7bc8d42eb185
--- /dev/null
+++ b/tests/sys/geom/class/raid3/5_test.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+#
+# Writing without PARITY component.
+#
+graid3 remove -n 2 $name
+dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+dd if=/dev/raid3/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/raid3/6_test.sh b/tests/sys/geom/class/raid3/6_test.sh
new file mode 100644
index 000000000000..20bf1922bca6
--- /dev/null
+++ b/tests/sys/geom/class/raid3/6_test.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+#
+# Rebuild of DATA component.
+#
+graid3 remove -n 1 $name
+dd if=/dev/zero of=/dev/${us1} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
+graid3 insert -n 1 $name md${us1}
+sleep 1
+
+dd if=/dev/raid3/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/raid3/7_test.sh b/tests/sys/geom/class/raid3/7_test.sh
new file mode 100644
index 000000000000..23666f8f4c59
--- /dev/null
+++ b/tests/sys/geom/class/raid3/7_test.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+#
+# Rebuild of PARITY component.
+#
+graid3 remove -n 2 $name
+dd if=/dev/zero of=/dev/${us2} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
+graid3 insert -n 2 $name md${us2}
+sleep 1
+# Remove DATA component, so PARITY component can be used while reading.
+graid3 remove -n 1 $name
+dd if=/dev/zero of=/dev/${us1} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
+
+dd if=/dev/raid3/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/raid3/8_test.sh b/tests/sys/geom/class/raid3/8_test.sh
new file mode 100644
index 000000000000..2eb9b1a7dc92
--- /dev/null
+++ b/tests/sys/geom/class/raid3/8_test.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+#
+# Writing without DATA component and rebuild of DATA component.
+#
+graid3 remove -n 1 $name
+dd if=/dev/zero of=/dev/${us1} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
+dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+graid3 insert -n 1 $name md${us1}
+sleep 1
+
+dd if=/dev/raid3/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/raid3/9_test.sh b/tests/sys/geom/class/raid3/9_test.sh
new file mode 100644
index 000000000000..0ef010a00a78
--- /dev/null
+++ b/tests/sys/geom/class/raid3/9_test.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+ddbs=2048
+nblocks1=1024
+nblocks2=`expr $nblocks1 / \( $ddbs / 512 \)`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+us0=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us1=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+us2=$(attach_md -t malloc -s $(expr $nblocks1 + 1)) || exit 1
+
+dd if=/dev/random of=${src} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+
+graid3 label $name /dev/${us0} /dev/${us1} /dev/${us2} || exit 1
+devwait
+
+#
+# Writing without PARITY component and rebuild of PARITY component.
+#
+graid3 remove -n 2 $name
+dd if=/dev/zero of=/dev/${us2} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
+dd if=${src} of=/dev/raid3/${name} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+graid3 insert -n 2 $name md${us2}
+sleep 1
+# Remove DATA component, so PARITY component can be used while reading.
+graid3 remove -n 1 $name
+dd if=/dev/zero of=/dev/${us1} bs=512 count=`expr $nblocks1 + 1` >/dev/null 2>&1
+
+dd if=/dev/raid3/${name} of=${dst} bs=$ddbs count=$nblocks2 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/raid3/Makefile b/tests/sys/geom/class/raid3/Makefile
new file mode 100644
index 000000000000..a53a937cee69
--- /dev/null
+++ b/tests/sys/geom/class/raid3/Makefile
@@ -0,0 +1,26 @@
+# $FreeBSD$
+
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
+
+TAP_TESTS_SH+= 1_test
+TAP_TESTS_SH+= 2_test
+TAP_TESTS_SH+= 3_test
+TAP_TESTS_SH+= 4_test
+TAP_TESTS_SH+= 5_test
+TAP_TESTS_SH+= 6_test
+TAP_TESTS_SH+= 7_test
+TAP_TESTS_SH+= 8_test
+TAP_TESTS_SH+= 9_test
+TAP_TESTS_SH+= 10_test
+TAP_TESTS_SH+= 11_test
+TAP_TESTS_SH+= 12_test
+
+${PACKAGE}FILES+= conf.sh
+
+.for t in ${TAP_TESTS_SH}
+TEST_METADATA.$t+= required_user="root"
+.endfor
+
+.include <bsd.test.mk>
diff --git a/tests/sys/geom/class/raid3/Makefile.depend b/tests/sys/geom/class/raid3/Makefile.depend
new file mode 100644
index 000000000000..f80275d86ab1
--- /dev/null
+++ b/tests/sys/geom/class/raid3/Makefile.depend
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/tests/sys/geom/class/raid3/conf.sh b/tests/sys/geom/class/raid3/conf.sh
new file mode 100644
index 000000000000..f1b270aacd4d
--- /dev/null
+++ b/tests/sys/geom/class/raid3/conf.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $FreeBSD$
+
+name="$(mktemp -u graid3.XXXXXX)"
+class="raid3"
+base=`basename $0`
+
+graid3_test_cleanup()
+{
+ [ -c /dev/$class/$name ] && graid3 stop $name
+ geom_test_cleanup
+}
+trap graid3_test_cleanup ABRT EXIT INT TERM
+
+. `dirname $0`/../geom_subr.sh
diff --git a/tests/sys/geom/class/shsec/1_test.sh b/tests/sys/geom/class/shsec/1_test.sh
new file mode 100644
index 000000000000..ab0bb37ea445
--- /dev/null
+++ b/tests/sys/geom/class/shsec/1_test.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..2"
+
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
+
+gshsec label $name /dev/${us0} /dev/${us1} /dev/${us2} 2>/dev/null || exit 1
+devwait
+
+# Size of created device should be 1MB - 512B.
+
+mediasize=`diskinfo /dev/shsec/${name} | awk '{print $3}'`
+if [ $mediasize -eq 1048064 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
+sectorsize=`diskinfo /dev/shsec/${name} | awk '{print $2}'`
+if [ $sectorsize -eq 512 ]; then
+ echo "ok 2"
+else
+ echo "not ok 2"
+fi
diff --git a/tests/sys/geom/class/shsec/2_test.sh b/tests/sys/geom/class/shsec/2_test.sh
new file mode 100644
index 000000000000..9dfe36ace48f
--- /dev/null
+++ b/tests/sys/geom/class/shsec/2_test.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..4"
+
+nblocks1=1024
+nblocks2=`expr $nblocks1 + 1`
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+dd if=/dev/random of=${src} count=$nblocks1 >/dev/null 2>&1
+
+us0=$(attach_md -t malloc -s $nblocks2) || exit 1
+us1=$(attach_md -t malloc -s $nblocks2) || exit 1
+us2=$(attach_md -t malloc -s $nblocks2) || exit 1
+
+gshsec label $name /dev/$us0 /dev/$us1 /dev/$us2 || exit 1
+devwait
+
+dd if=${src} of=/dev/shsec/${name} count=$nblocks1 >/dev/null 2>&1
+
+dd if=/dev/shsec/${name} of=${dst} count=$nblocks1 >/dev/null 2>&1
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+dd if=/dev/${us0} of=${dst} count=$nblocks1 >/dev/null 2>&1
+if [ `md5 -q ${src}` = `md5 -q ${dst}` ]; then
+ echo "not ok 2"
+else
+ echo "ok 2"
+fi
+
+dd if=/dev/${us1} of=${dst} count=$nblocks1 >/dev/null 2>&1
+if [ `md5 -q ${src}` = `md5 -q ${dst}` ]; then
+ echo "not ok 3"
+else
+ echo "ok 3"
+fi
+
+dd if=/dev/${us2} of=${dst} count=$nblocks1 >/dev/null 2>&1
+if [ `md5 -q ${src}` = `md5 -q ${dst}` ]; then
+ echo "not ok 4"
+else
+ echo "ok 4"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/shsec/Makefile b/tests/sys/geom/class/shsec/Makefile
new file mode 100644
index 000000000000..b0849962aa01
--- /dev/null
+++ b/tests/sys/geom/class/shsec/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
+
+TAP_TESTS_SH+= 1_test
+TAP_TESTS_SH+= 2_test
+
+${PACKAGE}FILES+= conf.sh
+
+.for t in ${TAP_TESTS_SH}
+TEST_METADATA.$t+= required_user="root"
+.endfor
+
+.include <bsd.test.mk>
diff --git a/tests/sys/geom/class/shsec/Makefile.depend b/tests/sys/geom/class/shsec/Makefile.depend
new file mode 100644
index 000000000000..f80275d86ab1
--- /dev/null
+++ b/tests/sys/geom/class/shsec/Makefile.depend
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/tests/sys/geom/class/shsec/conf.sh b/tests/sys/geom/class/shsec/conf.sh
new file mode 100644
index 000000000000..7800eb7764ab
--- /dev/null
+++ b/tests/sys/geom/class/shsec/conf.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $FreeBSD$
+
+name="$(mktemp -u shsec.XXXXXX)"
+class="shsec"
+base=`basename $0`
+
+shsec_test_cleanup()
+{
+ [ -c /dev/$class/$name ] && gshsec stop $name
+ geom_test_cleanup
+}
+trap shsec_test_cleanup ABRT EXIT INT TERM
+
+. `dirname $0`/../geom_subr.sh
diff --git a/tests/sys/geom/class/stripe/1_test.sh b/tests/sys/geom/class/stripe/1_test.sh
new file mode 100644
index 000000000000..7923763a4c29
--- /dev/null
+++ b/tests/sys/geom/class/stripe/1_test.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
+
+gstripe create -s 16384 $name /dev/$us0 /dev/$us1 /dev/$us2 || exit 1
+devwait
+
+# Size of created device should be 1MB * 3.
+
+size=`diskinfo /dev/stripe/${name} | awk '{print $3}'`
+
+if [ $size -eq 3145728 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
diff --git a/tests/sys/geom/class/stripe/2_test.sh b/tests/sys/geom/class/stripe/2_test.sh
new file mode 100644
index 000000000000..f6e11f5a5821
--- /dev/null
+++ b/tests/sys/geom/class/stripe/2_test.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+# $FreeBSD$
+
+. `dirname $0`/conf.sh
+
+echo "1..1"
+
+tsize=3
+src=`mktemp $base.XXXXXX` || exit 1
+dst=`mktemp $base.XXXXXX` || exit 1
+
+dd if=/dev/random of=${src} bs=1m count=$tsize >/dev/null 2>&1
+
+us0=$(attach_md -t malloc -s 1M) || exit 1
+us1=$(attach_md -t malloc -s 2M) || exit 1
+us2=$(attach_md -t malloc -s 3M) || exit 1
+
+gstripe create -s 8192 $name /dev/$us0 /dev/$us1 /dev/$us2 || exit 1
+devwait
+
+dd if=${src} of=/dev/stripe/${name} bs=1m count=$tsize >/dev/null 2>&1
+dd if=/dev/stripe/${name} of=${dst} bs=1m count=$tsize >/dev/null 2>&1
+
+if [ `md5 -q ${src}` != `md5 -q ${dst}` ]; then
+ echo "not ok 1"
+else
+ echo "ok 1"
+fi
+
+rm -f ${src} ${dst}
diff --git a/tests/sys/geom/class/stripe/Makefile b/tests/sys/geom/class/stripe/Makefile
new file mode 100644
index 000000000000..b0849962aa01
--- /dev/null
+++ b/tests/sys/geom/class/stripe/Makefile
@@ -0,0 +1,16 @@
+# $FreeBSD$
+
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
+
+TAP_TESTS_SH+= 1_test
+TAP_TESTS_SH+= 2_test
+
+${PACKAGE}FILES+= conf.sh
+
+.for t in ${TAP_TESTS_SH}
+TEST_METADATA.$t+= required_user="root"
+.endfor
+
+.include <bsd.test.mk>
diff --git a/tests/sys/geom/class/stripe/Makefile.depend b/tests/sys/geom/class/stripe/Makefile.depend
new file mode 100644
index 000000000000..f80275d86ab1
--- /dev/null
+++ b/tests/sys/geom/class/stripe/Makefile.depend
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/tests/sys/geom/class/stripe/conf.sh b/tests/sys/geom/class/stripe/conf.sh
new file mode 100644
index 000000000000..fd0f41c6c5e6
--- /dev/null
+++ b/tests/sys/geom/class/stripe/conf.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# $FreeBSD$
+
+name="$(mktemp -u stripe.XXXXXX)"
+class="stripe"
+base=`basename $0`
+
+gstripe_test_cleanup()
+{
+ [ -c /dev/$class/$name ] && gstripe destroy $name
+ geom_test_cleanup
+}
+trap gstripe_test_cleanup ABRT EXIT INT TERM
+
+. `dirname $0`/../geom_subr.sh
diff --git a/tests/sys/geom/class/uzip/1_endian_big.img.uzip.uue b/tests/sys/geom/class/uzip/1_endian_big.img.uzip.uue
new file mode 100644
index 000000000000..b4903e487dca
--- /dev/null
+++ b/tests/sys/geom/class/uzip/1_endian_big.img.uzip.uue
@@ -0,0 +1,87 @@
+#
+# $FreeBSD$
+#
+
+begin 644 1_endian_big.img.uzip
+M(R$O8FEN+W-H"B-6,BXP($9O<FUA=`HH:VQD<W1A="`M<6T@9U]U>FEP?'QK
+M;&1L;V%D(&=E;VU?=7II<"D^)BTF)FUO=6YT7V-D.38V,"`O9&5V+V!M9&-O
+M;F9I9R`M868@)#!@+G5Z:7`@)#$*97AI="`D/PH``````````````$``````
+M0`````````*0`````````I`````````"D`````````*0`````````I``````
+M```#;P````````-O````````!#$````````$,0````````2H````````!*@`
+M```````&T@````````B4````````",4````````(Q0````````NZ````````
+M"[H````````,@0````````R!````````#($````````,@0````````R!````
+M````#($````````,@0````````R!````````#($````````,@0````````R!
+M````````#($````````,@0````````R!````````#($````````,@0``````
+M``R!````````#($````````,@0````````R!````````#($````````,@0``
+M``````R!````````#($````````,@0````````R!````````#($````````,
+M@0````````R!````````#($````````,@0````````R!````````#($`````
+M```,@0````````R!````````#($````````,@0````````R!````````#($`
+M```````,@0````````R!````````#($````````,@0````````R!````````
+M#($````````,@0````````R!````````#*UXVNW4/0Z",!3`\3:B,FA@A,W1
+MN,C@`3R$":?0R<'!Q.H)3+R0DZOQ(L3%N1:H:``3'=#E_TM>WX.TI7P4(0J!
+MB8&)H8E(U)-"*)/\M'9M9+16)JYIZ9GHF7!LOU8>_LLT6:WJ+A`GVU/G,IH\
+M^_EOEI*.EW4K5./Y8BF`!AW3YK!W\JP>Q]5/M+Q]<NY?%BTK56#SVN;^)]/$
+MR:Y;FO!L<]3L#4R+QOXK;C]Z<N9?)E;VS2FWK75^>F.SI^L&A3,9LE,`````
+M``````````````````````#PC3L712#(>-KMU#T*PD`0AN$)_FTA)*7I+,4J
+MA0?P$()7L=+U<K;B1<0;K+/)$,6LH(4_Q?O`EUG"[F9#F(BT)IJI9J:I)"T3
+M\5J*.':66@A><XG#7#/6]&U>KTEQMTT]]JD'K,_[P_`T7]SF%4^.$M=GJ1-Z
+M`?Z"[[9/P_WD.-UV*:UNK8Y>V2;VZ,.&1ZO59U]@V5Z^3/]ELK$OY]T@A.;V
+MSFH>4HO*55;2`P```````````````````````````'C'%6?Y%ZQXVNW.L0W"
+M,!"&40<J"FHH&8-%$,M0P#89@4$8@@(Q`2+\A8-DA?04[TF?BSM9NE)BM3@<
+MGY>A?'7CLTVGM*Z+?5J6>=WXN>K3-3W2+=W3+IUKC?:&UN;G]/T:9DSNFLX`
+M``````````````````#@;WP`XC\HZGC:Y=MY*`11'`?PL>[<-AN28\D5Y:I=
+M(6W:+<+F_H-"<H3P%]:1W$H16C8*191(2,Z4L$V6M"3''XZ4*]:5<K6TN<HB
+M?Q#ZOC_F-[TW]7Z?WFN:]V:&(+ZWZ$:Z#!'`92-<'/V?\F4=$Q3YVI<J-=DA
+M0E(H?(KW;Z*0%DB>RLZ?8TV;&?F%;IF_Q*5\TJ;\4<,[[E=_91Y!XUZWRJ*L
+M<$K35O_P<,OY"]L)!?G+E`S?C/_B1Y%*ICI1/<]L'Z-X7X$MCOE"'NZ_Y%?\
+MZ0[<!.H-R/<_YQC6'K*_0^3!1_9G'52K(ON+1)-^R/Z<[DX2V2_5IA0C^]EV
+MY?7(_@D?EC6R/U2P$H?LKZ`1Y\C^S,L;Z.<_[Y)-?V2_GHBM@^R7:#CV(?N-
+M2^T'D/U)$RIKR/Z6!:UM9+\:(^@&>OY[GW0C^\?6)YG(_K:2/%-DO\V4S2"R
+MO\/\7!_9?U1&LT3V6VEVG2#[!;OQ5&1_(N<R'MF?.G=D@NS/M]CA(?OGZX^A
+MW__QI4O0^Q^5XV8^R'Z'GNA>9#^;EXS,)Z+NI'7(_HMID039K[RW,(_L]Y+<
+M'R+[&Q.VKI#]Z3-NT.L?NI1>"SW_N7[5R'[.,C\$V<\=K[%#]AM'%A@@^V-3
+M3M.1_;D<6SKT^F\V"WK_V\+1-1S9+^S7O$7VVY.COLC^B#D&]/^/`=D;P\C^
+MX++F*F1_4\8Z]/<O&0.N!<A^HS"K$60_TXC'^$_Y/@#S,;!8>-KEVETK@V$8
+M!_!E8<W*2T@M,_,R)[1ERBQ'FB*)4BQ9B2'9DLCCT&J1#9,'*TN+;3BP1M,.
+M:&Q6#C2)PF;$D)48FBDFOH03_:]/</_JOE[NKIM"^=OXR5PJH`!'.MLL0?:'
+M.>8@LG]"&FQ"]K.>-")D_X+/58OL%Z<.C2#[OYY)`MF_&]+F(ON9L3W0]]^H
+M?HE']MN,!CJRGU]^487L3UP[IB'[3Z/9M\A^1_*;'=E?[XUV(OMK.`-"9'^:
+M2O&*[%^G;EY"Y_^5&GK^HW]86Y#]#7WN'62_/Y!Q@NR_OF'HD/WV$I*![-_8
+M]Y<A^U7R/>C^_][H\2#[+<QM%[*?%Z>"[O_DMP5Z_U7ML[F1_33=L`#9S\YI
+M2T+V?W8'>,C^>\%D,[*_B`P_(/MMH?PPLM\M<\XC^\<.%,A\"FM+/([L=R0P
+MO<C^+.E<'K)?:^J"WO^:.(04V:\L5$#GOY`0=2#[E[E6/;)_<=!?@>S7!#@6
+M9+_><`C]_F-4RJ'K'Z&_@_[_W-M^#KW_JSO3SB+[4\3T?F1_ZVK,"K(_(E$Z
+MH><_JBL$7?]DI5/(_J/':>C^/Q/A%B/[V:I1_G\Z[R\+%8'F>-KMPS$-`"`0
+M`+%#`#MB$<^K8&J35JLZ\\X=````````````````````\-T#NY8`HWC:[91+
+M;]0P$,=WRR(J"PFNE3C,TDJ`M%T!%Q`<H-OR$%2J!"M5W'`V3NS6CBO;(<V%
+MQY?CRI5/P5<H8R>E%2"$Q/,P/VGC9.P9C_\SWL%@L#0X/QI.!XFEP:71TK3[
+M.#.X.#H[]14_Z.9&PX_+3`2N;34-AV%`$,0/>?O5]_#X9?F?I#/\QK+2CZ_[
+M\=S/A-G]].[]5P$_]./U/WN`^U\>?YD1_@[[RKU=/GMTU)G?]..%H^\YK<R'
+M*W0'"((@"((@B/^)5;8*:P^=$+/G6VMLE;$G&[/9@V>[.YM/7S"V+1KE89,[
+M9[5F5PMG#<RELW4I(4@!V];NJZI<?Z2Y]\"K''8E#["AU4+`0UNC82Z%$Q.X
+M<?O6S6N,O9PWW$/FE-:JG"2/&,=K%60+P;X2GFVI',K6B31;*I-I`:I*ZQJ>
+MB3ML0VLPRO@6&HR=)C+K;!F])VRCCVFL$>!XD!YL'4J'KE/&+L]$PWNG)SS+
+MA&OL8G\"I@5OJS'#=&&/-QX7X$$R%3#WN':AOQ@7/"SDF)T.5&=[=8:K7=Z=
+MR<NZ2J$*5QME:P\S-`OGJ^1[F;''Z(GB@41]7UEWP#7XQKH\GE3BVCMLVU8E
+M!&6Z+0RO#N.!"BL@"A9+$&!]G3VWX(0/(H_FK$V+Y[4)M8&`9>WT\+A7#KR1
+MZEC+Y(]ZX"RF[*.Q+@KEY?%<VB6Z3=)!3FO58+%`M`*%+:#0W.`NF_@$C%\4
+M6L6\3S5)J'4IL%8I5LPFJQW6-$_;1CF-&#.V4T6E&SN&D[>NE%TD?O*>$NI%
+MRS3/<6-1!?"56NP+MXXB+_;'46$MBA"WR`7O"Y-25\'CZ7@>ER3/DNO:',B8
+M>(:^L4V2+I+[)`?V)^\[\$2'>VPS%B38V#O<&9^:*!/<1!4SVX[9#M:?9WNQ
+M_CEOQWB1M+96=B]HN!(S6$CK0I0C5AZ[8<^VT]]R4>[^RD6A?T:"(`B"(`B"
+M(`B"(`B"(`B"(`B"(`B"(`B"(`B"(`B"^/_X#/X6=T5XVNW7+0H"01B`X=EQ
+M004Q>@3!,B`8A$V#;#$+1@4/(=C4H,VD[@FT>`9ABPB;-GD$,6@0L_B#)L$@
+MIOW>)\Q/?&>FC%(JI7*N8]23=BZN-J\-DL\>[_?_0;\7F<?0//4WW^8?5)-Z
+MGJ&)/<GOR?'CEN3^2I"=2^XOM^U><O\B\J:2^[N'25IR_R`*ZY+[>ZOE5G+_
+M-:^'DOO]TF@FN7]=LT7)_8U@UY'</RZH,[]*``````````````````````#P
+M3S?_-B4S>-KMT#$!```,`B"C&]T*>_9!!!(```````````````````!X405W
+M`]:``($`````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+=````````````````````````````````````````
+`
+end
diff --git a/tests/sys/geom/class/uzip/1_endian_little.img.uzip.uue b/tests/sys/geom/class/uzip/1_endian_little.img.uzip.uue
new file mode 100644
index 000000000000..044dd3107929
--- /dev/null
+++ b/tests/sys/geom/class/uzip/1_endian_little.img.uzip.uue
@@ -0,0 +1,110 @@
+#
+# $FreeBSD$
+#
+
+begin 644 1_endian_little.img.uzip
+M(R$O8FEN+W-H"B-6,BXP($9O<FUA=`HH:VQD<W1A="`M<6T@9U]U>FEP?'QK
+M;&1L;V%D(&=E;VU?=7II<"D^)BTF)FUO=6YT7V-D.38V,"`O9&5V+V!M9&-O
+M;F9I9R`M868@)#!@+G5Z:7`@)#$*97AI="`D/PH``````````````$``````
+M0`````````*0`````````W<````````$G@````````>&````````!ZT`````
+M```'U`````````?[````````""(````````(20````````AP````````")<`
+M```````(O@````````CE````````"0P````````),P````````E:````````
+M"8$````````)J`````````G/````````"?8````````*'0````````I$````
+M````"FL````````*D@````````JY````````"N`````````+!P````````LN
+M````````"U4````````+?`````````NC````````"\H````````+\0``````
+M``P8````````##\````````,9@````````R-````````#+0````````,VP``
+M``````T"````````#2D````````-4`````````UW````````#9X````````-
+MQ0````````WL````````#A,````````..@````````YA````````#H@`````
+M```.KP````````[6````````#OT````````/)`````````]+````````#W(`
+M```````/F0````````_`````````#^<````````0#@```````!`U````````
+M$%P````````0@P```````!"J````````$-9XVNW4L0K",!"`X8LM$@1!!T$G
+M.[JZ.W3Q#1Q\`P??H(LZ^T@^B*L/(L1+>L6L#E:0_X-KKTU"C[8Y$0``````
+M````````\"\F&G.-2F-E]X*ZK8=[*47NA8@3FZ#77MJ(-O'P"$&>(8PU'75C
+M>M!E[3J?/4SS6D^#[-I9&I]WV%Z/J8;2HEMO\V+4-A[SQFI(4YV<^9KHS?3B
+MTJ\]LW.NRO+RQW5:+=T^:_*]^T%YJ1]D"V)?D*QG?%5M^[YGWMY3[%?AY)S7
+M(L+2>F3QGN>R]QOM%H[]`0``````````@%Z]`'B8&[EXVNW9,4H#013&\?>2
+M1=:`J(6@E2G3"I86VW@#A=Q`P1ND,:ESD13!TB9-;F'K$3R`,+ZW^U8'42$$
+M-\W_!]_N;':&?0R9:4:D<60YM0PMH_@MF=7%WE@*D9>^B$ITL.=2FK@KO[RF
+M).\I'5AST+ZSBPUKQK6=HUW9K9<]:S3]>W?7\X>ZAB+2CH]^GBK>>WL2-=1=
+M5:8"=.5XIO5?^R3NN6'6+G9<9]32KK-)OG8W**_>#[(!OB](MF?\JRK6?<?*
+MF"??K]*C:FE%I//8(_M?_32;7W=SIJP/````````````=.ZVM_]YKJ=^PO;3
+MN;K\?L;W_91K85E:GBS/EGOK<&D96Z9;57J8/[REG?F[2I^/]48C````````
+M``````#8S@?5^JSR>-KMFL]/%#$4QQ<EAC1ZY_@62!2R;((7#9J871`-DI`(
+M"7JSL].9%MHI:3L,X\W_Q:OZ!_@/>3'Q3_"UL[`<](07X7V2V7;:OA_]OLY<
+M9GN]V\W/T9VN,VV^;]Q[%]M?W[X<76U7KQ-DX=)];^U!=UWP^=-<:A?GN_NO
+MBW^.OW;-^/-_B4\0!$$0!$$0!$$0!$$0!$$0!$$0!$'<#.+7YX]X/>_-OA$3
+M!'$[B/]+N=^;GQO.^G>&>',7^S_F%I@(7-MJ&,X#:440-XUEM@PK.TZ(\<'V
+M"EMF;'<T'K]\>[2_]>8]8WNB41ZVN'-6:_:H<-;`H72V+B4$*6#/VA-5E>NO
+M-/<>>)7#D>0!1EI-!.S8&@<.I7!B`!M/GSQ>9>S#8<,]9$YIK<I!LHA^O%9!
+MMA#LF?!L6^50MDZDV5*93`M055K7\$QLLI'68)3Q+33H.TUDUMDR6@_8:.K3
+M6"/`\2`]V#J4#DV'C"V-1<.G1KL\RX1K[.1D`*8%;ZL^PW3AF#<>%^!&,A4P
+M][AVHB\')SQ,9)]==51GQW6&JUW>[<G+NDJN"E<;96L/8QP6SE?)=HFQUVB)
+MXH%$?<^L.^4:?&-='G<J<>TFV[-5"4&9+H3AU7G<4&$%1,%B"0*LK[,#"T[X
+M(/(XG+5I\6%M0FT@8%D[/3S&RH$W4EUHF>Q1#YS%E'T<K(M">7DQEZ)$LT':
+MR%6M&BP6B%:@L`44FAN,LH6_@/Z+0JN8]Y5#$FI="JQ5\A6SR6J'-<U3V"BG
+M$7W&]JNH=&/[,.MUI>P\\5D_)305+=,\Q\"B"N`K-3D1;AU%GISTH\):%"&&
+MR`6?%B:EKH+'W?$\+DF6)=>U.94Q\0QMXS%)NDCNDQQX/OGT!,YT>,&V8D&"
+MC6>'.^/3(<H$-U'%S+9]MH_UY]EQK'_.VSX^2%I;*[L.#CR,&4RD=2'*$2N/
+MI^'8ML-_\J`\N\Z#0F]&@B`(@B`(@B`(@B`(@OC_^0WE#GM@>-KMP3$!````
+MPJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!````PJ#U3VT,
+M'Z````````````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````
+M``````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````````````
+M``````"`MP%````!>-KMP3$!````PJ#U3VT,'Z````````````````````"`
+MMP%````!>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%````!
+M>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!
+M````PJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!````PJ#U
+M3VT,'Z````````````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``
+M``````````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````````
+M``````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````````````````
+M``"`MP%````!>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%`
+M```!>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%````!>-KM
+MP3$!````PJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!````
+MPJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!````PJ#U3VT,
+M'Z````````````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````
+M``````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````````````
+M``````"`MP%````!>-KMP3$!````PJ#U3VT,'Z````````````````````"`
+MMP%````!>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%````!
+M>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!
+M````PJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!````PJ#U
+M3VT,'Z````````````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``
+M``````````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````````
+M``````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````````````````
+M``"`MP%````!>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%`
+M```!>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%````!>-KM
+MP3$!````PJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!````
+MPJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!````PJ#U3VT,
+M'Z````````````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````
+M``````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````````````
+M``````"`MP%````!>-KMP3$!````PJ#U3VT,'Z````````````````````"`
+MMP%````!>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%````!
+M>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!
+M````PJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!````PJ#U
+M3VT,'Z````````````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``
+M``````````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````````
+M``````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````````````````
+M``"`MP%````!>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%`
+M```!>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%````!>-KM
+MP3$!````PJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!````
+MPJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!````PJ#U3VT,
+M'Z````````````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````
+M``````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````````````
+M``````"`MP%````!>-KMP3$!````PJ#U3VT,'Z````````````````````"`
+MMP%````!>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%````!
+M>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!
+M````PJ#U3VT,'Z````````````````````"`MP%````!>-KMP3$!````PJ#U
+M3VT,'Z````````````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``
+M``````````````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````````
+M``````````"`MP%````!>-KMP3$!````PJ#U3VT,'Z``````````````````
+M``"`MP%````!>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%`
+M```!>-KMP3$!````PJ#U3VT,'Z````````````````````"`MP%````!>-KM
+MP3$!````PJ#U3VT,'Z````````````````````"`MP%````!>-KMT#$!```,
+M`B"C&]T*>_9!!!(```````````````````!X405W`]:``($`````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+M````````````````````````````````````````````````````````````
+2````````````````````````
+`
+end
diff --git a/tests/sys/geom/class/uzip/1_test.sh b/tests/sys/geom/class/uzip/1_test.sh
new file mode 100644
index 000000000000..c73f20e18764
--- /dev/null
+++ b/tests/sys/geom/class/uzip/1_test.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+# $FreeBSD$
+
+testsdir=$(dirname $0)
+. $testsdir/conf.sh
+
+# Check host endianness
+ret=$(echo I | tr -d "[:space:]" | od -to2 | head -n1 | awk '{print $2}' | cut -c6)
+if [ "$ret" = "1" ]; then
+ # Little endian
+ UUE=$testsdir/1_endian_little.img.uzip.uue
+elif [ "$ret" = "0" ]; then
+ # Big endian
+ UUE=$testsdir/1_endian_big.img.uzip.uue
+else
+ echo "Couldn't detect host endianness"
+ exit 2
+fi
+
+echo "1..1"
+
+uudecode $UUE
+us0=$(attach_md -f $(basename $UUE .uue)) || exit 1
+sleep 1
+
+mount -o ro /dev/${us0}.uzip "${mntpoint}" || exit 1
+
+#cat "${mntpoint}/etalon.txt"
+diff -I '\$FreeBSD.*\$' -u $testsdir/etalon/etalon.txt "${mntpoint}/etalon.txt"
+if [ $? -eq 0 ]; then
+ echo "ok 1"
+else
+ echo "not ok 1"
+fi
diff --git a/tests/sys/geom/class/uzip/Makefile b/tests/sys/geom/class/uzip/Makefile
new file mode 100644
index 000000000000..88f9e47ccced
--- /dev/null
+++ b/tests/sys/geom/class/uzip/Makefile
@@ -0,0 +1,42 @@
+#
+# $FreeBSD$
+#
+# Regression test for geom_uzip.
+#
+
+PACKAGE= tests
+
+TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
+
+IMAGE= 1_endian_unknown_autogenerated.img
+ZIMAGE= ${IMAGE}.uzip
+UZIMAGE= ${ZIMAGE}.uue
+
+CLEANFILES+= ${IMAGE} ${UZIMAGE} ${ZIMAGE}
+
+${IMAGE}:
+ makefs -s 1048576 ${.TARGET} ${.CURDIR}/etalon
+
+${ZIMAGE}: ${IMAGE}
+ mkuzip -o ${.TARGET} ${.ALLSRC}
+
+${UZIMAGE}: ${IMAGE} ${ZIMAGE}
+ printf "#\n# $$" >${.TARGET}
+ printf "FreeBSD$$\n#\n\n" >> ${.TARGET}
+ uuencode ${ZIMAGE} ${ZIMAGE} >>${.TARGET}
+
+${PACKAGE}FILES+= conf.sh 1_endian_big.img.uzip.uue \
+ 1_endian_little.img.uzip.uue
+
+FILESGROUPS+= etalon
+etalon+= etalon/etalon.txt
+etalonDIR= ${TESTSDIR}/etalon
+etalonPACKAGE= ${PACKAGE}
+
+TAP_TESTS_SH+= 1_test
+
+.for t in ${TAP_TESTS_SH}
+TEST_METADATA.$t+= required_user="root"
+.endfor
+
+.include <bsd.test.mk>
diff --git a/tests/sys/geom/class/uzip/Makefile.depend b/tests/sys/geom/class/uzip/Makefile.depend
new file mode 100644
index 000000000000..f80275d86ab1
--- /dev/null
+++ b/tests/sys/geom/class/uzip/Makefile.depend
@@ -0,0 +1,11 @@
+# $FreeBSD$
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+
+
+.include <dirdeps.mk>
+
+.if ${DEP_RELDIR} == ${_DEP_RELDIR}
+# local dependencies - needed for -jN in clean tree
+.endif
diff --git a/tests/sys/geom/class/uzip/conf.sh b/tests/sys/geom/class/uzip/conf.sh
new file mode 100755
index 000000000000..9a22841fdbe9
--- /dev/null
+++ b/tests/sys/geom/class/uzip/conf.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+# $FreeBSD$
+
+class="uzip"
+base=`basename $0`
+
+uzip_test_cleanup()
+{
+ if [ -n "$mntpoint" ]; then
+ umount $mntpoint
+ rmdir $mntpoint
+ fi
+ geom_test_cleanup
+}
+trap uzip_test_cleanup ABRT EXIT INT TERM
+
+. `dirname $0`/../geom_subr.sh
+
+# NOTE: make sure $TMPDIR has been set by geom_subr.sh if unset [by kyua, etc]
+mntpoint=$(mktemp -d tmp.XXXXXX) || exit
diff --git a/tests/sys/geom/class/uzip/etalon/etalon.txt b/tests/sys/geom/class/uzip/etalon/etalon.txt
new file mode 100644
index 000000000000..cb8acf31f650
--- /dev/null
+++ b/tests/sys/geom/class/uzip/etalon/etalon.txt
@@ -0,0 +1,43 @@
+#
+# $FreeBSD$
+#
+
+JABBERWOCKY
+
+Lewis Carroll
+(from Through the Looking-Glass and What Alice Found There, 1872)
+
+`Twas brillig, and the slithy toves
+Did gyre and gimble in the wabe:
+All mimsy were the borogoves,
+And the mome raths outgrabe.
+
+"Beware the Jabberwock, my son!
+The jaws that bite, the claws that catch!
+Beware the Jubjub bird, and shun
+The frumious Bandersnatch!"
+
+He took his vorpal sword in hand:
+Long time the manxome foe he sought --
+So rested he by the Tumtum tree,
+And stood awhile in thought.
+
+And, as in uffish thought he stood,
+The Jabberwock, with eyes of flame,
+Came whiffling through the tulgey wood,
+And burbled as it came!
+
+One, two! One, two! And through and through
+The vorpal blade went snicker-snack!
+He left it dead, and with its head
+He went galumphing back.
+
+"And, has thou slain the Jabberwock?
+Come to my arms, my beamish boy!
+O frabjous day! Callooh! Callay!'
+He chortled in his joy.
+
+`Twas brillig, and the slithy toves
+Did gyre and gimble in the wabe;
+All mimsy were the borogoves,
+And the mome raths outgrabe.