@@ -15,8 +15,16 @@ _remove_ublk_devices() {
src/miniublk del -a
}
+_get_ublk_dev_state() {
+ src/miniublk list -n "$1" | grep "state" | awk '{print $11}'
+}
+
+_get_ublk_daemon_pid() {
+ src/miniublk list -n "$1" | grep "pid" | awk '{print $7}'
+}
+
_init_ublk() {
- _remove_ublk_devices
+ _remove_ublk_devices > /dev/null 2>&1
modprobe -rq ublk_drv
if ! modprobe ublk_drv; then
new file mode 100755
@@ -0,0 +1,47 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2023 Ziyang Zhang
+#
+# Test ublk delete
+
+. tests/ublk/rc
+
+DESCRIPTION="test ublk delete"
+
+_run() {
+ local type=$1
+
+ if [ "$type" == "null" ]; then
+ ${UBLK_PROG} add -t null -n 0 > "$FULL" 2>&1
+ else
+ truncate -s 1G "$TMPDIR/img"
+ ${UBLK_PROG} add -t loop -f "$TMPDIR/img" -n 0 > "$FULL" 2>&1
+ fi
+
+ udevadm settle
+ if ! ${UBLK_PROG} list -n 0 >> "$FULL" 2>&1; then
+ echo "fail to list dev"
+ fi
+
+ _run_fio_rand_io --filename=/dev/ublkb0 --time_based \
+ --runtime=30 >> "$FULL" 2>&1 &
+ sleep 2
+
+ ${UBLK_PROG} del -n 0 >> "$FULL" 2>&1
+}
+
+test() {
+ echo "Running ${TEST_NAME}"
+
+ if ! _init_ublk; then
+ return 1
+ fi
+
+ for type in "null" "loop"; do
+ _run "$type"
+ done
+
+ _exit_ublk
+
+ echo "Test complete"
+}
new file mode 100644
@@ -0,0 +1,2 @@
+Running ublk/001
+Test complete
new file mode 100755
@@ -0,0 +1,62 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2023 Ziyang Zhang
+#
+# Test ublk crash with delete after dead confirmation
+
+. tests/ublk/rc
+
+DESCRIPTION="test ublk crash with delete after dead confirmation"
+
+_run() {
+ local type=$1
+
+ if [ "$type" == "null" ]; then
+ ${UBLK_PROG} add -t null -n 0 > "$FULL" 2>&1
+ else
+ truncate -s 1G "$TMPDIR/img"
+ ${UBLK_PROG} add -t loop -f "$TMPDIR/img" -n 0 > "$FULL" 2>&1
+ fi
+
+ udevadm settle
+ if ! ${UBLK_PROG} list -n 0 >> "$FULL" 2>&1; then
+ echo "fail to list dev"
+ fi
+
+ _run_fio_rand_io --filename=/dev/ublkb0 --time_based \
+ --runtime=30 >> "$FULL" 2>&1 &
+ sleep 2
+
+ kill -9 "$(_get_ublk_daemon_pid 0)"
+
+ local secs=0
+ local state=""
+ while [ "$secs" -lt 20 ]; do
+ state="$(_get_ublk_dev_state 0)"
+ [ "$state" == "DEAD" ] && break
+ sleep 1
+ (( secs++ ))
+ done
+
+ state="$(_get_ublk_dev_state 0)"
+ [ "$state" != "DEAD" ] && echo \
+ "device is $state after killing queue daemon"
+
+ ${UBLK_PROG} del -n 0 >> "$FULL" 2>&1
+}
+
+test() {
+ echo "Running ${TEST_NAME}"
+
+ if ! _init_ublk; then
+ return 1
+ fi
+
+ for type in "null" "loop"; do
+ _run "$type"
+ done
+
+ _exit_ublk
+
+ echo "Test complete"
+}
new file mode 100644
@@ -0,0 +1,2 @@
+Running ublk/002
+Test complete
new file mode 100755
@@ -0,0 +1,52 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2023 Ziyang Zhang
+#
+# Test mounting block device exported by ublk
+
+. tests/ublk/rc
+
+DESCRIPTION="test mounting block device exported by ublk"
+
+requires() {
+ _have_program mkfs.ext4
+}
+
+test() {
+ local expect_fstype="ext4"
+ local mnt="$TMPDIR/mnt"
+
+ echo "Running ${TEST_NAME}"
+
+ if ! _init_ublk; then
+ return 1
+ fi
+
+ truncate -s 1G "$TMPDIR/img"
+ ${UBLK_PROG} add -t loop -f "$TMPDIR/img" -n 0 > "$FULL" 2>&1
+
+ udevadm settle
+ if ! ${UBLK_PROG} list -n 0 >> "$FULL" 2>&1; then
+ echo "fail to list dev"
+ fi
+
+ wipefs -a /dev/ublkb0 >> "$FULL" 2>&1
+ mkfs."$expect_fstype" /dev/ublkb0 >> "$FULL" 2>&1
+ mkdir -p "$mnt"
+ mount /dev/ublkb0 "$mnt" >> "$FULL" 2>&1
+
+ local ublk_fstype
+ ublk_fstype="$(findmnt -l -o FSTYPE -n "$mnt")"
+ if [ "$ublk_fstype" != "$expect_fstype" ]; then
+ echo "got $ublk_fstype, should be $expect_fstype"
+ fi
+ umount "$mnt" > /dev/null 2>&1
+
+ ${UBLK_PROG} del -n 0 >> "$FULL" 2>&1
+
+ _exit_ublk
+
+ echo "Test complete"
+}
+
+
new file mode 100644
@@ -0,0 +1,2 @@
+Running ublk/003
+Test complete
new file mode 100755
@@ -0,0 +1,49 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2023 Ziyang Zhang
+#
+# Test ublk crash with delete just after daemon kill
+
+. tests/ublk/rc
+
+DESCRIPTION="test ublk crash with delete just after daemon kill"
+
+_run() {
+ local type=$1
+
+ if [ "$type" == "null" ]; then
+ ${UBLK_PROG} add -t null -n 0 > "$FULL" 2>&1
+ else
+ truncate -s 1G "$TMPDIR/img"
+ ${UBLK_PROG} add -t loop -f "$TMPDIR/img" -n 0 > "$FULL" 2>&1
+ fi
+
+ udevadm settle
+ if ! ${UBLK_PROG} list -n 0 >> "$FULL" 2>&1; then
+ echo "fail to list dev"
+ fi
+
+ _run_fio_rand_io --filename=/dev/ublkb0 --time_based \
+ --runtime=30 >> "$FULL" 2>&1 &
+ sleep 2
+
+ kill -9 "$(_get_ublk_daemon_pid 0)"
+
+ ${UBLK_PROG} del -n 0 >> "$FULL" 2>&1
+}
+
+test() {
+ echo "Running ${TEST_NAME}"
+
+ if ! _init_ublk; then
+ return 1
+ fi
+
+ for type in "null" "loop"; do
+ _run "$type"
+ done
+
+ _exit_ublk
+
+ echo "Test complete"
+}
new file mode 100644
@@ -0,0 +1,2 @@
+Running ublk/004
+Test complete
new file mode 100755
@@ -0,0 +1,77 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2023 Ziyang Zhang
+#
+# Test ublk recovery with one time daemon kill:
+# (1)kill all ubq_deamon, (2)recover with new ubq_daemon,
+# (3)delete dev
+
+. tests/ublk/rc
+
+DESCRIPTION="test ublk recovery with one time daemon kill"
+
+_run() {
+ local type=$1
+
+ if [ "$type" == "null" ]; then
+ ${UBLK_PROG} add -t null -n 0 -r > "$FULL" 2>&1
+ else
+ truncate -s 1G "$TMPDIR/img"
+ ${UBLK_PROG} add -t loop -f "$TMPDIR/img" -n 0 -r > "$FULL" 2>&1
+ fi
+
+ udevadm settle
+ if ! ${UBLK_PROG} list -n 0 >> "$FULL" 2>&1; then
+ echo "fail to list dev"
+ fi
+
+ _run_fio_rand_io --filename=/dev/ublkb0 --time_based \
+ --runtime=30 >> "$FULL" 2>&1 &
+ sleep 2
+
+ kill -9 "$(_get_ublk_daemon_pid 0)"
+
+ local secs=0
+ local state=""
+ while [ "$secs" -lt 20 ]; do
+ state="$(_get_ublk_dev_state 0)"
+ [ "$state" == "QUIESCED" ] && break
+ sleep 1
+ (( secs++ ))
+ done
+
+ state="$(_get_ublk_dev_state 0)"
+ [ "$state" != "QUIESCED" ] && echo "device is $state after killing queue daemon"
+
+ if [ "$type" == "null" ]; then
+ ${UBLK_PROG} recover -t null -n 0 >> "$FULL" 2>&1
+ else
+ ${UBLK_PROG} recover -t loop -f "$TMPDIR/img" -n 0 >> "$FULL" 2>&1
+ fi
+
+ while [ "$secs" -lt 20 ]; do
+ state="$(_get_ublk_dev_state 0)"
+ [ "$state" == "LIVE" ] && break
+ sleep 1
+ (( secs++ ))
+ done
+ [ "$state" != "LIVE" ] && echo "device is $state after recovery"
+
+ ${UBLK_PROG} del -n 0 >> "$FULL" 2>&1
+}
+
+test() {
+ echo "Running ${TEST_NAME}"
+
+ if ! _init_ublk; then
+ return 1
+ fi
+
+ for type in "null" "loop"; do
+ _run "$type"
+ done
+
+ _exit_ublk
+
+ echo "Test complete"
+}
new file mode 100644
@@ -0,0 +1,2 @@
+Running ublk/005
+Test complete
new file mode 100755
@@ -0,0 +1,81 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2023 Ziyang Zhang
+#
+# Test ublk recovery with two times daemon kill:
+# (1)kill all ubq_deamon, (2)recover with new ubq_daemon,
+# (3)kill all ubq_deamon, (4)delete dev
+
+. tests/ublk/rc
+
+DESCRIPTION="test ublk recovery with two times daemon kill"
+
+_run() {
+ local type=$1
+
+ if [ "$type" == "null" ]; then
+ ${UBLK_PROG} add -t null -n 0 -r > "$FULL" 2>&1
+ else
+ truncate -s 1G "$TMPDIR/img"
+ ${UBLK_PROG} add -t loop -f "$TMPDIR/img" -n 0 -r > "$FULL" 2>&1
+ fi
+
+ udevadm settle
+ if ! ${UBLK_PROG} list -n 0 >> "$FULL" 2>&1; then
+ echo "fail to list dev"
+ fi
+
+ _run_fio_rand_io --filename=/dev/ublkb0 --time_based \
+ --runtime=30 >> "$FULL" 2>&1 &
+ sleep 2
+
+ kill -9 "$(_get_ublk_daemon_pid 0)"
+
+ local secs=0
+ local state=""
+ while [ "$secs" -lt 20 ]; do
+ state="$(_get_ublk_dev_state 0)"
+ [ "$state" == "QUIESCED" ] && break
+ sleep 1
+ (( secs++ ))
+ done
+
+ state="$(_get_ublk_dev_state 0)"
+ [ "$state" != "QUIESCED" ] && echo "device is $state after killing queue daemon"
+
+ if [ "$type" == "null" ]; then
+ ${UBLK_PROG} recover -t null -n 0 >> "$FULL" 2>&1
+ else
+ ${UBLK_PROG} recover -t loop -f "$TMPDIR/img" -n 0 >> "$FULL" 2>&1
+ fi
+
+ secs=0
+ while [ "$secs" -lt 20 ]; do
+ state="$(_get_ublk_dev_state 0)"
+ [ "$state" == "LIVE" ] && break
+ sleep 1
+ (( secs++ ))
+ done
+ [ "$state" != "LIVE" ] && echo "device is $state after recovery"
+
+ kill -9 "$(_get_ublk_daemon_pid 0)"
+
+ ${UBLK_PROG} del -n 0 >> "$FULL" 2>&1
+}
+
+test() {
+ echo "Running ${TEST_NAME}"
+
+ if ! _init_ublk; then
+ return 1
+ fi
+
+ for type in "null" "loop"; do
+ _run "$type"
+ done
+
+ _exit_ublk
+
+ echo "Test complete"
+}
+
new file mode 100644
@@ -0,0 +1,2 @@
+Running ublk/006
+Test complete
new file mode 100644
@@ -0,0 +1,17 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-3.0+
+# Copyright (C) 2023 Ziyang Zhang
+#
+# ublk tests.
+
+. common/rc
+. common/ublk
+. common/fio
+
+group_requires() {
+ _have_root
+ _have_ublk
+ _have_fio
+}
+
+export UBLK_PROG="src/miniublk"
It is very important to test ublk crash handling since the userspace part is not reliable. Especially we should test removing device, killing ublk daemons and user recovery feature. Add five new tests for ublk to cover these cases. Signed-off-by: Ziyang Zhang <ZiyangZhang@linux.alibaba.com> --- common/ublk | 10 +++++- tests/ublk/001 | 47 +++++++++++++++++++++++++++ tests/ublk/001.out | 2 ++ tests/ublk/002 | 62 +++++++++++++++++++++++++++++++++++ tests/ublk/002.out | 2 ++ tests/ublk/003 | 52 +++++++++++++++++++++++++++++ tests/ublk/003.out | 2 ++ tests/ublk/004 | 49 ++++++++++++++++++++++++++++ tests/ublk/004.out | 2 ++ tests/ublk/005 | 77 +++++++++++++++++++++++++++++++++++++++++++ tests/ublk/005.out | 2 ++ tests/ublk/006 | 81 ++++++++++++++++++++++++++++++++++++++++++++++ tests/ublk/006.out | 2 ++ tests/ublk/rc | 17 ++++++++++ 14 files changed, 406 insertions(+), 1 deletion(-) create mode 100755 tests/ublk/001 create mode 100644 tests/ublk/001.out create mode 100755 tests/ublk/002 create mode 100644 tests/ublk/002.out create mode 100755 tests/ublk/003 create mode 100644 tests/ublk/003.out create mode 100755 tests/ublk/004 create mode 100644 tests/ublk/004.out create mode 100755 tests/ublk/005 create mode 100644 tests/ublk/005.out create mode 100755 tests/ublk/006 create mode 100644 tests/ublk/006.out create mode 100644 tests/ublk/rc