Commit 533c87e2 authored by Ming Lei's avatar Ming Lei Committed by Jens Axboe
Browse files

selftests: ublk: add test for UBLK_F_QUIESCE

Add test generic_11 for covering new control command of
UBLK_U_CMD_QUIESCE_DEV.

Add 'quiesce -n dev_id' sub-command on ublk utility for transitioning
device state to quiesce states, then verify the feature via generic_10
by doing quiesce and recovery.

Cc: Yoav Cohen <yoav@nvidia.com>
Link: https://lore.kernel.org/linux-block/DM4PR12MB632807AB7CDCE77D1E5AB7D0A9B92@DM4PR12MB6328.namprd12.prod.outlook.com/


Signed-off-by: default avatarMing Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20250522163523.406289-4-ming.lei@redhat.com


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent b465ae7b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ TEST_PROGS += test_generic_07.sh
TEST_PROGS += test_generic_08.sh
TEST_PROGS += test_generic_09.sh
TEST_PROGS += test_generic_10.sh
TEST_PROGS += test_generic_11.sh

TEST_PROGS += test_null_01.sh
TEST_PROGS += test_null_02.sh
+39 −0
Original line number Diff line number Diff line
@@ -228,6 +228,18 @@ static int ublk_ctrl_update_size(struct ublk_dev *dev,
	return __ublk_ctrl_cmd(dev, &data);
}

static int ublk_ctrl_quiesce_dev(struct ublk_dev *dev,
				 unsigned int timeout_ms)
{
	struct ublk_ctrl_cmd_data data = {
		.cmd_op	= UBLK_U_CMD_QUIESCE_DEV,
		.flags	= CTRL_CMD_HAS_DATA,
	};

	data.data[0] = timeout_ms;
	return __ublk_ctrl_cmd(dev, &data);
}

static const char *ublk_dev_state_desc(struct ublk_dev *dev)
{
	switch (dev->dev_info.state) {
@@ -1053,6 +1065,9 @@ static int __cmd_dev_add(const struct dev_ctx *ctx)
	info->nr_hw_queues = nr_queues;
	info->queue_depth = depth;
	info->flags = ctx->flags;
	if ((features & UBLK_F_QUIESCE) &&
			(info->flags & UBLK_F_USER_RECOVERY))
		info->flags |= UBLK_F_QUIESCE;
	dev->tgt.ops = ops;
	dev->tgt.sq_depth = depth;
	dev->tgt.cq_depth = depth;
@@ -1250,6 +1265,7 @@ static int cmd_dev_get_features(void)
		[const_ilog2(UBLK_F_USER_RECOVERY_FAIL_IO)] = "RECOVERY_FAIL_IO",
		[const_ilog2(UBLK_F_UPDATE_SIZE)] = "UPDATE_SIZE",
		[const_ilog2(UBLK_F_AUTO_BUF_REG)] = "AUTO_BUF_REG",
		[const_ilog2(UBLK_F_QUIESCE)] = "QUIESCE",
	};
	struct ublk_dev *dev;
	__u64 features = 0;
@@ -1316,6 +1332,26 @@ static int cmd_dev_update_size(struct dev_ctx *ctx)
	return ret;
}

static int cmd_dev_quiesce(struct dev_ctx *ctx)
{
	struct ublk_dev *dev = ublk_ctrl_init();
	int ret = -EINVAL;

	if (!dev)
		return -ENODEV;

	if (ctx->dev_id < 0) {
		fprintf(stderr, "device id isn't provided for quiesce\n");
		goto out;
	}
	dev->dev_info.dev_id = ctx->dev_id;
	ret = ublk_ctrl_quiesce_dev(dev, 10000);

out:
	ublk_ctrl_deinit(dev);
	return ret;
}

static void __cmd_create_help(char *exe, bool recovery)
{
	int i;
@@ -1359,6 +1395,7 @@ static int cmd_dev_help(char *exe)
	printf("\t -a list all devices, -n list specified device, default -a \n\n");
	printf("%s features\n", exe);
	printf("%s update_size -n dev_id -s|--size size_in_bytes \n", exe);
	printf("%s quiesce -n dev_id\n", exe);
	return 0;
}

@@ -1523,6 +1560,8 @@ int main(int argc, char *argv[])
		ret = cmd_dev_get_features();
	else if (!strcmp(cmd, "update_size"))
		ret = cmd_dev_update_size(&ctx);
	else if (!strcmp(cmd, "quiesce"))
		ret = cmd_dev_quiesce(&ctx);
	else
		cmd_dev_help(argv[0]);

+29 −3
Original line number Diff line number Diff line
@@ -220,6 +220,26 @@ _recover_ublk_dev() {
	echo "$state"
}

# quiesce device and return ublk device state
__ublk_quiesce_dev()
{
	local dev_id=$1
	local exp_state=$2
	local state

	if ! ${UBLK_PROG} quiesce -n "${dev_id}"; then
		state=$(_get_ublk_dev_state "${dev_id}")
		return "$state"
	fi

	for ((j=0;j<50;j++)); do
		state=$(_get_ublk_dev_state "${dev_id}")
		[ "$state" == "$exp_state" ] && break
		sleep 1
	done
	echo "$state"
}

# kill the ublk daemon and return ublk device state
__ublk_kill_daemon()
{
@@ -308,20 +328,26 @@ run_io_and_kill_daemon()

run_io_and_recover()
{
	local action=$1
	local state
	local dev_id

	shift 1
	dev_id=$(_add_ublk_dev "$@")
	_check_add_dev "$TID" $?

	fio --name=job1 --filename=/dev/ublkb"${dev_id}" --ioengine=libaio \
		--rw=readwrite --iodepth=256 --size="${size}" --numjobs=4 \
		--rw=randread --iodepth=256 --size="${size}" --numjobs=4 \
		--runtime=20 --time_based > /dev/null 2>&1 &
	sleep 4

	if [ "$action" == "kill_daemon" ]; then
		state=$(__ublk_kill_daemon "${dev_id}" "QUIESCED")
	elif [ "$action" == "quiesce_dev" ]; then
		state=$(__ublk_quiesce_dev "${dev_id}" "QUIESCED")
	fi
	if [ "$state" != "QUIESCED" ]; then
		echo "device isn't quiesced($state) after killing daemon"
		echo "device isn't quiesced($state) after $action"
		return 255
	fi

+1 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ ERR_CODE=0

ublk_run_recover_test()
{
	run_io_and_recover "$@"
	run_io_and_recover "kill_daemon" "$@"
	ERR_CODE=$?
	if [ ${ERR_CODE} -ne 0 ]; then
		echo "$TID failure: $*"
+1 −1
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ ERR_CODE=0

ublk_run_recover_test()
{
	run_io_and_recover "$@"
	run_io_and_recover "kill_daemon" "$@"
	ERR_CODE=$?
	if [ ${ERR_CODE} -ne 0 ]; then
		echo "$TID failure: $*"
Loading