]> www.infradead.org Git - users/sagi/blktests.git/commitdiff
common/scsi_debug: introduce _configure_scsi_debug
authorShin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Tue, 25 Apr 2023 11:47:43 +0000 (20:47 +0900)
committerShin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Tue, 23 May 2023 07:16:44 +0000 (16:16 +0900)
To set up scsi_debug devices with built-in scsi_debug module, introduce
a new helper function _configure_scsi_debug. It works in similar manner
as _init_scsi_debug which sets up scsi_debug devices with loadable
scsi_debug module.

_configure_scsi_debug takes parameters of scsi_debug devices in format
of 'key=value' as its arguments. It calls another new helper function
_scsi_debug_key_path to find sysfs files corresponding to the keys in
/sys/module/scsi_debug/parameters or /sys/bus/pseudo/drivers/scsi_debug.
When the file is found, write the value to the file.

Before setting the parameters through sysfs files, save current values
of scsi_debug parameters in ORIG_SCSI_DEBUG_PARAMS. Use the saved values
to restore parameters in _exit_scsi_debug. Do this value restore not
only for the parameters modified in _configure_scsi_debug but also for
the parameters modified by test cases.

Among the parameters, 'add_host' has special meaning to add new hosts.
Then handle it separately so that it is set at last in
_configure_scsi_debug, and restored at first in _exit_scsi_debug.

Also record the hosts which exist before _configure_scsi_debug in the
array ORIG_SCSI_DEBUG_HOSTS. Those hosts should not be used for testing,
then do not add them to SCSI_DEBUG_HOSTS.

Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
common/scsi_debug

index 0bf768ab50382958b14d953f570756d779b727c7..60e7d639448b864177fa1c64000b2033a4aad979 100644 (file)
@@ -8,16 +8,51 @@ _have_scsi_debug() {
        _have_driver scsi_debug
 }
 
+SD_PARAM_PATH=/sys/module/scsi_debug/parameters
+SD_PSEUDO_PATH=/sys/bus/pseudo/drivers/scsi_debug
+
+_scsi_debug_key_path() {
+       local key=${1}
+
+       path="${SD_PARAM_PATH}/$key"
+       if [[ ! -e $path ]]; then
+               path="${SD_PSEUDO_PATH}/$key"
+       fi
+       if [[ ! -w $path ]]; then
+               return 1
+       fi
+
+       echo "$path"
+}
+
+declare -a SCSI_DEBUG_HOSTS
+declare -a SCSI_DEBUG_TARGETS
+declare -a SCSI_DEBUG_DEVICES
+declare -a ORIG_SCSI_DEBUG_HOSTS
+declare -A ORIG_SCSI_DEBUG_PARAMS
+declare SCSI_DEBUG_ADD_HOST_RESTORE_VALUE
+
 _setup_scsi_debug_vars() {
        local host_sysfs host target_sysfs target
+       local -i i
+
        SCSI_DEBUG_HOSTS=()
        SCSI_DEBUG_TARGETS=()
        SCSI_DEBUG_DEVICES=()
+
        for host_sysfs in /sys/class/scsi_host/*; do
                if [[ "$(cat "${host_sysfs}/proc_name")" = scsi_debug ]]; then
                        host="${host_sysfs#/sys/class/scsi_host/host}"
+                       local orig_host=0
+                       for ((i=0;i<${#ORIG_SCSI_DEBUG_HOSTS[@]};i++)); do
+                               if ((host == ORIG_SCSI_DEBUG_HOSTS[i])); then
+                                       orig_host=1
+                               fi
+                       done
+                       ((orig_host)) && continue
                        SCSI_DEBUG_HOSTS+=("$host")
                        for target_sysfs in /sys/class/scsi_device/"$host":*; do
+                               [[ ! -e $target_sysfs ]] && break
                                target="${target_sysfs#/sys/class/scsi_device/}"
                                SCSI_DEBUG_TARGETS+=("$target")
                                SCSI_DEBUG_DEVICES+=("$(ls "$target_sysfs/device/block")")
@@ -59,10 +94,86 @@ _init_scsi_debug() {
        _setup_scsi_debug_vars
 }
 
+_configure_scsi_debug() {
+       local -a args=("$@")
+       local -a values
+       local key value path add_host_value=1
+       local -i i
+
+       udevadm settle
+
+       # fall back to _init_scsi_debug because scsi_debug is loadable
+       if _module_file_exists scsi_debug; then
+               _init_scsi_debug "${args[@]}"
+               return
+       fi
+
+       # zoned device is not yet configurable due to read-only zbc parameter
+       if (( RUN_FOR_ZONED )) && ! _have_module scsi_debug; then
+               return 1
+       fi
+
+       # List SCSI_DEBUG_HOSTS before configuration
+       ORIG_SCSI_DEBUG_HOSTS=()
+       _setup_scsi_debug_vars >& /dev/null
+       ORIG_SCSI_DEBUG_HOSTS=("${SCSI_DEBUG_HOSTS[@]}")
+
+       # Save current values of all scsi_debug parameters except add_host
+       for path in "$SD_PARAM_PATH"/* "$SD_PSEUDO_PATH"/*; do
+               if [[ -f $path && ! $path =~ add_host ]] &&
+                          [[ $(stat -c "%A" "$path") =~ rw ]]; then
+                       unset "ORIG_SCSI_DEBUG_PARAMS[$path]"
+                       ORIG_SCSI_DEBUG_PARAMS["$path"]="$(<"$path")"
+               fi
+       done
+
+       # Modify parameters specifeid with key=value arguments
+       for o in "$@"; do
+               key=${o%=*}
+               value=${o#*=}
+               values+=("${value}")
+               if ! path=$(_scsi_debug_key_path "$key"); then
+                       echo "sysfs to write $key is not avaialbe"
+                       return 1
+               fi
+               if [[ $key == add_host ]]; then
+                       add_host_value=${value}
+               else
+                       if ! echo -n "$value" > "$path"; then
+                               echo "Failed to set $path: $value"
+                       fi
+               fi
+       done
+
+       echo "${add_host_value}" > ${SD_PSEUDO_PATH}/add_host
+       SCSI_DEBUG_ADD_HOST_RESTORE_VALUE="-${add_host_value}"
+
+       udevadm settle
+
+       _setup_scsi_debug_vars
+}
+
 _exit_scsi_debug() {
+       local path value
+
        unset SCSI_DEBUG_HOSTS
        unset SCSI_DEBUG_TARGETS
        unset SCSI_DEBUG_DEVICES
        udevadm settle
-       modprobe -r scsi_debug
+
+       if _module_file_exists scsi_debug; then
+               modprobe -r scsi_debug
+               return
+       fi
+
+       echo "${SCSI_DEBUG_ADD_HOST_RESTORE_VALUE}" > ${SD_PSEUDO_PATH}/add_host
+
+       # Restore parameters modified in _configure_scsi_debug or during test
+       for path in "${!ORIG_SCSI_DEBUG_PARAMS[@]}"; do
+               value=${ORIG_SCSI_DEBUG_PARAMS[$path]}
+               if [[ "$value" != $(<"$path") ]]; then
+                       echo -n "$value" > "$path"
+               fi
+               unset "ORIG_SCSI_DEBUG_PARAMS[$path]"
+       done
 }