diff mbox series

[blktests,4/9] common/scsi_debug: introduce _configure_scsi_debug

Message ID 20230417124728.458630-5-shinichiro@fastmail.com (mailing list archive)
State New, archived
Headers show
Series support built-in scsi_debug | expand

Commit Message

Shin'ichiro Kawasaki April 17, 2023, 12:47 p.m. UTC
From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>

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 search sysfs files corresponding to the keys in
/sys/bus/pseudo/drivers/scsi_debug or /sys/module/scsi_debug/parameters.
When it finds the file, it writes the value to the file. The original
values of the files are kept in the global array SCSI_DEBUG_VALUES and
restored by _exit_scsi_debug.

Among the parameters, 'add_host' has special meaning to add new hosts.
Then it is handled 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 | 113 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 112 insertions(+), 1 deletion(-)

Comments

Chaitanya Kulkarni April 18, 2023, 8:15 p.m. UTC | #1
On 4/17/23 05:47, Shin'ichiro Kawasaki wrote:
> From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
>
> 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 search sysfs files corresponding to the keys in
> /sys/bus/pseudo/drivers/scsi_debug or /sys/module/scsi_debug/parameters.
> When it finds the file, it writes the value to the file. The original
> values of the files are kept in the global array SCSI_DEBUG_VALUES and
> restored by _exit_scsi_debug.
>
> Among the parameters, 'add_host' has special meaning to add new hosts.
> Then it is handled 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>
> ---
>   


Looks good.

Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>

-ck
diff mbox series

Patch

diff --git a/common/scsi_debug b/common/scsi_debug
index 0bf768a..ee9edac 100644
--- a/common/scsi_debug
+++ b/common/scsi_debug
@@ -8,16 +8,49 @@  _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
+
 _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 +92,88 @@  _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[@]}")
+
+	SCSI_DEBUG_KEYS=()
+	SCSI_DEBUG_VALUES=()
+	for o in "$@"; do
+		key=${o%=*}
+		value=${o#*=}
+		SCSI_DEBUG_KEYS+=("${key}")
+		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
+			SCSI_DEBUG_VALUES+=("-${value}")
+			add_host_value=${value}
+		else
+			SCSI_DEBUG_VALUES+=("$(<"${path}")")
+			echo -n "${value}" > "${path}"
+		fi
+	done
+
+	echo "${add_host_value}" > ${SD_PSEUDO_PATH}/add_host
+
+	udevadm settle
+
+	_setup_scsi_debug_vars
+}
+
 _exit_scsi_debug() {
+	local i key path add_host_value=-1
+
 	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
+
+	for ((i = 0; i < ${#SCSI_DEBUG_KEYS[@]}; i++)); do
+		key=${SCSI_DEBUG_KEYS[i]}
+		if [[ $key == add_host ]]; then
+			add_host_value=${SCSI_DEBUG_VALUES[i]}
+		fi
+	done
+	echo "${add_host_value}" > ${SD_PSEUDO_PATH}/add_host
+
+	for ((i = 0; i < ${#SCSI_DEBUG_KEYS[@]}; i++)); do
+		key=${SCSI_DEBUG_KEYS[i]}
+		if ! path=$(_scsi_debug_key_path "${key}"); then
+			echo "sysfs to write $key is not avaialbe"
+			return 1
+		fi
+		if [[ $key != add_host ]]; then
+			echo -n "${SCSI_DEBUG_VALUES[i]}" > "${path}"
+		fi
+	done
+	unset SCSI_DEBUG_KEYS
+	unset SCSI_DEBUG_VALUES
 }