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