xref: /spdk/test/ublk/ublk.sh (revision f6866117acb32c78d5ea7bd76ba330284655af35)
1#!/usr/bin/env bash
2#  SPDX-License-Identifier: BSD-3-Clause
3#  Copyright (C) 2022 Intel Corporation.
4#  All rights reserved.
5#
6testdir=$(readlink -f "$(dirname $0)")
7rootdir=$(readlink -f "$testdir/../..")
8source "$rootdir/test/common/autotest_common.sh"
9source "$rootdir/test/lvol/common.sh"
10
11if [[ -z $1 ]]; then
12	NUM_DEVS=4
13	NUM_QUEUE=4
14	QUEUE_DEPTH=512
15	MALLOC_SIZE_MB=128
16	# issue ublk_stop_disk cmds before ublk_destroy_target
17	STOP_DISKS=1
18else
19	# Use smaller parameters when user specifies the number
20	# of devices, to guard against memory exhaustion.
21	NUM_DEVS=$1
22	NUM_QUEUE=1
23	QUEUE_DEPTH=16
24	MALLOC_SIZE_MB=2
25fi
26
27MALLOC_BS=4096
28FILE_SIZE=$((MALLOC_SIZE_MB * 1024 * 1024))
29MAX_DEV_ID=$((NUM_DEVS - 1))
30
31function test_create_ublk() {
32	# create a ublk target
33	ublk_target=$(rpc_cmd ublk_create_target)
34	# create a malloc bdev
35	malloc_name=$(rpc_cmd bdev_malloc_create $MALLOC_SIZE_MB $MALLOC_BS)
36	# Add ublk device
37	ublk_id=$(rpc_cmd ublk_start_disk $malloc_name 0 -q $NUM_QUEUE -d $QUEUE_DEPTH)
38	ublk_path="/dev/ublkb$ublk_id"
39	ublk_dev=$(rpc_cmd ublk_get_disks -n $ublk_id)
40	# verify its parameters
41	[[ "$(jq -r '.[0].ublk_device' <<< "$ublk_dev")" = "$ublk_path" ]]
42	[[ "$(jq -r '.[0].id' <<< "$ublk_dev")" = "$ublk_id" ]]
43	[[ "$(jq -r '.[0].queue_depth' <<< "$ublk_dev")" = "$QUEUE_DEPTH" ]]
44	[[ "$(jq -r '.[0].num_queues' <<< "$ublk_dev")" = "$NUM_QUEUE" ]]
45	[[ "$(jq -r '.[0].bdev_name' <<< "$ublk_dev")" = "$malloc_name" ]]
46
47	# Run fio in background that writes to ublk
48	run_fio_test /dev/ublkb0 0 $FILE_SIZE "write" "0xcc" "--time_based --runtime=10"
49
50	# clean up
51	rpc_cmd ublk_stop_disk "$ublk_id"
52	# make sure we can't delete the same ublk
53	NOT rpc_cmd ublk_stop_disk "$ublk_id"
54	rpc_cmd ublk_destroy_target
55
56	rpc_cmd bdev_malloc_delete "$malloc_name"
57	check_leftover_devices
58}
59
60function test_create_multi_ublk() {
61	# create a ublk target
62	ublk_target=$(rpc_cmd ublk_create_target)
63
64	for i in $(seq 0 $MAX_DEV_ID); do
65		# create a malloc bdev
66		malloc_name=$(rpc_cmd bdev_malloc_create -b "Malloc${i}" $MALLOC_SIZE_MB $MALLOC_BS)
67		# add ublk device
68		ublk_id=$(rpc_cmd ublk_start_disk $malloc_name "${i}" -q $NUM_QUEUE -d $QUEUE_DEPTH)
69	done
70
71	ublk_dev=$(rpc_cmd ublk_get_disks)
72	for i in $(seq 0 $MAX_DEV_ID); do
73		# verify its parameters
74		[[ "$(jq -r ".[${i}].ublk_device" <<< "$ublk_dev")" = "/dev/ublkb${i}" ]]
75		[[ "$(jq -r ".[${i}].id" <<< "$ublk_dev")" = "${i}" ]]
76		[[ "$(jq -r ".[${i}].queue_depth" <<< "$ublk_dev")" = "$QUEUE_DEPTH" ]]
77		[[ "$(jq -r ".[${i}].num_queues" <<< "$ublk_dev")" = "$NUM_QUEUE" ]]
78		[[ "$(jq -r ".[${i}].bdev_name" <<< "$ublk_dev")" = "Malloc${i}" ]]
79	done
80
81	# To help test the ctrl cmd queuing logic, we omit the ublk_stop_disk
82	# RPCs.  Then the ublk_destroy_target RPC will stop all of the disks
83	# in very quick succession which exhausts the control io_uring SQEs
84	if [[ "$STOP_DISKS" = "1" ]]; then
85		for i in $(seq 0 $MAX_DEV_ID); do
86			rpc_cmd ublk_stop_disk "${i}"
87		done
88	fi
89
90	# Shutting down a lot of disks can take a long time, so extend the RPC timeout
91	"$rootdir/scripts/rpc.py" -t 120 ublk_destroy_target
92
93	for i in $(seq 0 $MAX_DEV_ID); do
94		rpc_cmd bdev_malloc_delete "Malloc${i}"
95	done
96	check_leftover_devices
97}
98
99function cleanup() {
100	killprocess $spdk_pid
101}
102
103modprobe ublk_drv
104"$SPDK_BIN_DIR/spdk_tgt" -m 0x3 -L ublk &
105spdk_pid=$!
106trap 'cleanup; exit 1' SIGINT SIGTERM EXIT
107waitforlisten $spdk_pid
108
109run_test "test_create_ublk" test_create_ublk
110run_test "test_create_multi_ublk" test_create_multi_ublk
111
112trap - SIGINT SIGTERM EXIT
113cleanup
114