From: Shin'ichiro Kawasaki <shinichiro.kawasaki@xxxxxxx> 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/bus/pseudo/drivers/scsi_debug or /sys/module/scsi_debug/parameters. 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@xxxxxxx> --- common/scsi_debug | 112 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/common/scsi_debug b/common/scsi_debug index 0bf768a..3d83d8a 100644 --- a/common/scsi_debug +++ b/common/scsi_debug @@ -8,16 +8,51 @@ _have_scsi_debug() { _have_driver scsi_debug } +SD_PSEUDO_PATH=/sys/bus/pseudo/drivers/scsi_debug +SD_PARAM_PATH=/sys/module/scsi_debug/parameters + +_scsi_debug_key_path() { + local key=${1} + + path="${SD_PSEUDO_PATH}/$key" + if [[ ! -e $path ]]; then + path="${SD_PARAM_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,85 @@ _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 + ORIG_SCSI_DEBUG_PARAMS=() + for path in "$SD_PSEUDO_PATH"/* "$SD_PARAM_PATH"/*; do + if [[ -f $path && ! $path =~ add_host ]] && + [[ $(stat -c "%A" "$path") =~ rw ]]; then + 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 + echo "restore $path" >> /tmp/debug + echo -n "$value" > "$path" + 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 + done + unset ORIG_SCSI_DEBUG_PARAMS } -- 2.40.0