From 40e8ee2a48d2b2ffe641773b934b82d087e30bd8 Mon Sep 17 00:00:00 2001 From: Yifan Bian Date: Tue, 27 Dec 2022 05:00:48 +0000 Subject: [PATCH] test/ublk: add basic tests for verifying ublk Signed-off-by: Yifan Bian Co-authored-by: Xiaodong Liu Change-Id: I3416b904e61b673ab622e5ff70099c97d0f7765c Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16081 Reviewed-by: Michal Berger Reviewed-by: Jim Harris Reviewed-by: Ben Walker Tested-by: SPDK CI Jenkins --- autotest.sh | 2 + test/common/autotest_common.sh | 4 ++ test/json_config/clear_config.py | 12 +++++ test/ublk/ublk.sh | 93 ++++++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+) create mode 100755 test/ublk/ublk.sh diff --git a/autotest.sh b/autotest.sh index 915141663..f9c7f6086 100755 --- a/autotest.sh +++ b/autotest.sh @@ -229,6 +229,8 @@ if [ $SPDK_RUN_FUNCTIONAL_TEST -eq 1 ]; then if [[ $SPDK_TEST_XNVME -eq 1 ]]; then run_test "nvme_xnvme" test/nvme/xnvme/xnvme.sh run_test "blockdev_xnvme" test/bdev/blockdev.sh "xnvme" + # Run ublk with xnvme since they have similar kernel dependencies + run_test "ublk" test/ublk/ublk.sh fi fi diff --git a/test/common/autotest_common.sh b/test/common/autotest_common.sh index f5ae033ef..a663391ed 100755 --- a/test/common/autotest_common.sh +++ b/test/common/autotest_common.sh @@ -479,6 +479,10 @@ function get_config_params() { fi fi + if [[ -f /usr/include/liburing/io_uring.h && -f /usr/include/linux/ublk_cmd.h ]]; then + config_params+=' --with-ublk' + fi + if [ $SPDK_TEST_RAID5 -eq 1 ]; then config_params+=' --with-raid5f' fi diff --git a/test/json_config/clear_config.py b/test/json_config/clear_config.py index 4cc6aca89..e271fa4e2 100755 --- a/test/json_config/clear_config.py +++ b/test/json_config/clear_config.py @@ -131,6 +131,18 @@ def clear_nbd_subsystem(args, nbd_config): args.client.call(destroy_method, {'nbd_device': nbd['params']['nbd_device']}) +def get_ublk_destroy_method(ublk): + delete_method_map = {'ublk_start_disk': "ublk_stop_disk"} + return delete_method_map[ublk['method']] + + +def clear_ublk_subsystem(args, ublk_config): + for ublk in ublk_config: + destroy_method = get_ublk_destroy_method(ublk) + if destroy_method: + args.client.call(destroy_method, {'ublk_device': ublk['params']['ublk_device']}) + + def clear_net_framework_subsystem(args, net_framework_config): pass diff --git a/test/ublk/ublk.sh b/test/ublk/ublk.sh new file mode 100755 index 000000000..f4da54208 --- /dev/null +++ b/test/ublk/ublk.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (C) 2022 Intel Corporation. +# All rights reserved. +# +testdir=$(readlink -f "$(dirname $0)") +rootdir=$(readlink -f "$testdir/../..") +source "$rootdir/test/common/autotest_common.sh" +source "$rootdir/test/lvol/common.sh" + +MALLOC_SIZE_MB=128 +MALLOC_BS=4096 +NUM_QUEUE=4 +QUEUE_DEPTH=512 +FILE_SIZE=$((MALLOC_SIZE_MB * 1024 * 1024)) + +function test_create_ublk() { + # create a ublk target + ublk_target=$(rpc_cmd ublk_create_target) + # create a malloc bdev + malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS) + # Add ublk device + ublk_id=$(rpc_cmd ublk_start_disk $malloc_name 0 -q $NUM_QUEUE -d $QUEUE_DEPTH) + ublk_path="/dev/ublkb$ublk_id" + ublk_dev=$(rpc_cmd ublk_get_disks -n $ublk_id) + # verify its parameters + [[ "$(jq -r '.[0].ublk_device' <<< "$ublk_dev")" = "$ublk_path" ]] + [[ "$(jq -r '.[0].id' <<< "$ublk_dev")" = "$ublk_id" ]] + [[ "$(jq -r '.[0].queue_depth' <<< "$ublk_dev")" = "$QUEUE_DEPTH" ]] + [[ "$(jq -r '.[0].num_queues' <<< "$ublk_dev")" = "$NUM_QUEUE" ]] + [[ "$(jq -r '.[0].bdev_name' <<< "$ublk_dev")" = "$malloc_name" ]] + + # Run fio in background that writes to ublk + run_fio_test /dev/ublkb0 0 $FILE_SIZE "write" "0xcc" "--time_based --runtime=10" + + # clean up + rpc_cmd ublk_stop_disk "$ublk_id" + # make sure we can't delete the same ublk + NOT rpc_cmd ublk_stop_disk "$ublk_id" + rpc_cmd ublk_destroy_target + + rpc_cmd bdev_malloc_delete "$malloc_name" + check_leftover_devices +} + +function test_create_multi_ublk() { + # create a ublk target + ublk_target=$(rpc_cmd ublk_create_target) + + for i in {0..3}; do + # create a malloc bdev + malloc_name=$(rpc_cmd bdev_malloc_create -b "Malloc${i}" $MALLOC_SIZE_MB $MALLOC_BS) + # add ublk device + ublk_id=$(rpc_cmd ublk_start_disk $malloc_name "${i}" -q $NUM_QUEUE -d $QUEUE_DEPTH) + done + + ublk_dev=$(rpc_cmd ublk_get_disks) + for i in {0..3}; do + # verify its parameters + [[ "$(jq -r ".[${i}].ublk_device" <<< "$ublk_dev")" = "/dev/ublkb${i}" ]] + [[ "$(jq -r ".[${i}].id" <<< "$ublk_dev")" = "${i}" ]] + [[ "$(jq -r ".[${i}].queue_depth" <<< "$ublk_dev")" = "$QUEUE_DEPTH" ]] + [[ "$(jq -r ".[${i}].num_queues" <<< "$ublk_dev")" = "$NUM_QUEUE" ]] + [[ "$(jq -r ".[${i}].bdev_name" <<< "$ublk_dev")" = "Malloc${i}" ]] + done + + # clean up + for i in {0..3}; do + rpc_cmd ublk_stop_disk "${i}" + done + rpc_cmd ublk_destroy_target + + for i in {0..3}; do + rpc_cmd bdev_malloc_delete "Malloc${i}" + done + check_leftover_devices +} + +function cleanup() { + killprocess $spdk_pid +} + +modprobe ublk_drv +"$SPDK_BIN_DIR/spdk_tgt" -m 0x3 & +spdk_pid=$! +trap 'cleanup; exit 1' SIGINT SIGTERM EXIT +waitforlisten $spdk_pid + +run_test "test_create_ublk" test_create_ublk +run_test "test_create_multi_ublk" test_create_multi_ublk + +trap - SIGINT SIGTERM EXIT +cleanup