xref: /linux/tools/testing/selftests/ublk/test_generic_15.sh (revision bea82c80a5d64247045280b6d23e3ff95c355f56)
1*60cf8637SMing Lei#!/bin/bash
2*60cf8637SMing Lei# SPDX-License-Identifier: GPL-2.0
3*60cf8637SMing Lei
4*60cf8637SMing Lei. "$(cd "$(dirname "$0")" && pwd)"/test_common.sh
5*60cf8637SMing Lei
6*60cf8637SMing LeiTID="generic_15"
7*60cf8637SMing LeiERR_CODE=0
8*60cf8637SMing Lei
9*60cf8637SMing Lei_test_partition_scan_no_hang()
10*60cf8637SMing Lei{
11*60cf8637SMing Lei	local recovery_flag=$1
12*60cf8637SMing Lei	local expected_state=$2
13*60cf8637SMing Lei	local dev_id
14*60cf8637SMing Lei	local state
15*60cf8637SMing Lei	local daemon_pid
16*60cf8637SMing Lei	local start_time
17*60cf8637SMing Lei	local elapsed
18*60cf8637SMing Lei
19*60cf8637SMing Lei	# Create ublk device with fault_inject target and very large delay
20*60cf8637SMing Lei	# to simulate hang during partition table read
21*60cf8637SMing Lei	# --delay_us 60000000 = 60 seconds delay
22*60cf8637SMing Lei	# Use _add_ublk_dev_no_settle to avoid udevadm settle hang waiting
23*60cf8637SMing Lei	# for partition scan events to complete
24*60cf8637SMing Lei	if [ "$recovery_flag" = "yes" ]; then
25*60cf8637SMing Lei		echo "Testing partition scan with recovery support..."
26*60cf8637SMing Lei		dev_id=$(_add_ublk_dev_no_settle -t fault_inject -q 1 -d 1 --delay_us 60000000 -r 1)
27*60cf8637SMing Lei	else
28*60cf8637SMing Lei		echo "Testing partition scan without recovery..."
29*60cf8637SMing Lei		dev_id=$(_add_ublk_dev_no_settle -t fault_inject -q 1 -d 1 --delay_us 60000000)
30*60cf8637SMing Lei	fi
31*60cf8637SMing Lei
32*60cf8637SMing Lei	_check_add_dev "$TID" $?
33*60cf8637SMing Lei
34*60cf8637SMing Lei	# The add command should return quickly because partition scan is async.
35*60cf8637SMing Lei	# Now sleep briefly to let the async partition scan work start and hit
36*60cf8637SMing Lei	# the delay in the fault_inject handler.
37*60cf8637SMing Lei	sleep 1
38*60cf8637SMing Lei
39*60cf8637SMing Lei	# Kill the ublk daemon while partition scan is potentially blocked
40*60cf8637SMing Lei	# And check state transitions properly
41*60cf8637SMing Lei	start_time=${SECONDS}
42*60cf8637SMing Lei	daemon_pid=$(_get_ublk_daemon_pid "${dev_id}")
43*60cf8637SMing Lei	state=$(__ublk_kill_daemon "${dev_id}" "${expected_state}")
44*60cf8637SMing Lei	elapsed=$((SECONDS - start_time))
45*60cf8637SMing Lei
46*60cf8637SMing Lei	# Verify the device transitioned to expected state
47*60cf8637SMing Lei	if [ "$state" != "${expected_state}" ]; then
48*60cf8637SMing Lei		echo "FAIL: Device state is $state, expected ${expected_state}"
49*60cf8637SMing Lei		ERR_CODE=255
50*60cf8637SMing Lei		${UBLK_PROG} del -n "${dev_id}" > /dev/null 2>&1
51*60cf8637SMing Lei		return
52*60cf8637SMing Lei	fi
53*60cf8637SMing Lei	echo "PASS: Device transitioned to ${expected_state} in ${elapsed}s without hanging"
54*60cf8637SMing Lei
55*60cf8637SMing Lei	# Clean up the device
56*60cf8637SMing Lei	${UBLK_PROG} del -n "${dev_id}" > /dev/null 2>&1
57*60cf8637SMing Lei}
58*60cf8637SMing Lei
59*60cf8637SMing Lei_prep_test "partition_scan" "verify async partition scan prevents IO hang"
60*60cf8637SMing Lei
61*60cf8637SMing Lei# Test 1: Without recovery support - should transition to DEAD
62*60cf8637SMing Lei_test_partition_scan_no_hang "no" "DEAD"
63*60cf8637SMing Lei
64*60cf8637SMing Lei# Test 2: With recovery support - should transition to QUIESCED
65*60cf8637SMing Lei_test_partition_scan_no_hang "yes" "QUIESCED"
66*60cf8637SMing Lei
67*60cf8637SMing Lei_cleanup_test "partition_scan"
68*60cf8637SMing Lei_show_result $TID $ERR_CODE
69