Skip to content

Commit

Permalink
nvme: add test for controller rescan under I/O load
Browse files Browse the repository at this point in the history
Add a test that repeatedly rescans nvme controllers while doing IO
on an nvme namespace connected to these controllers. The purpose
of the test is to make sure that no I/O errors or data corruption
occurs because of the rescan operations. The test uses sub-second
sleeps, which can't be easily accomplished in bash because of
missing floating-point arithmetic (and because usleep(1) isn't
portable). Therefore an awk program is used to trigger the
device rescans.

Link: https://lore.kernel.org/linux-nvme/[email protected]/
Signed-off-by: Martin Wilck <[email protected]>
Signed-off-by: Shin'ichiro Kawasaki <[email protected]>
  • Loading branch information
Martin Wilck authored and kawasaki committed Sep 4, 2024
1 parent c634b8a commit ed9b60a
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 0 deletions.
76 changes: 76 additions & 0 deletions tests/nvme/053
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-3.0+
# Copyright (C) 2024 Martin Wilck, SUSE LLC
#
# Repeatedly rescans nvme controllers while doing IO on an nvme namespace
# connected to these controllers, and make sure that no I/O errors or data
# corruption occurs.

. tests/nvme/rc

DESCRIPTION="test controller rescan under I/O load"
TIMED=1
: "${TIMEOUT:=60}"

rescan_controller() {
local path
path="$1/rescan_controller"

[[ -f "$path" ]] || {
echo "cannot rescan $1"
return 1
}

awk -f "$TMPDIR/rescan.awk" \
-v path="$path" -v timeout="$TIMEOUT" -v seed="$2" &
}

create_rescan_script() {
cat >"$TMPDIR/rescan.awk" <<EOF
@load "time"
BEGIN {
srand(seed);
finish = gettimeofday() + strtonum(timeout);
while (gettimeofday() < finish) {
sleep(0.1 + 5 * rand());
printf("1\n") > path;
close(path);
}
}
EOF
}

test_device() {
local -a ctrls
local i st line

echo "Running ${TEST_NAME}"
create_rescan_script

while IFS= read -r line; do
ctrls+=("$line")
done < <(_nvme_get_ctrl_list)
_run_fio_verify_io --filename="$TEST_DEV" --time_based &> "$FULL" &

for i in "${!ctrls[@]}"; do
rescan_controller "${ctrls[$i]}" "$i"
done

while true; do
wait -n &>/dev/null
st=$?
case $st in
127)
break
;;
0)
;;
*)
echo "child process exited with $st!"
;;
esac
done

echo "Test complete"
}
2 changes: 2 additions & 0 deletions tests/nvme/053.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Running nvme/053
Test complete
18 changes: 18 additions & 0 deletions tests/nvme/rc
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,24 @@ _test_dev_nvme_nsid() {
cat "${TEST_DEV_SYSFS}/nsid"
}

_nvme_get_ctrl_list() {
local subsys
local c

subsys=$(readlink "${TEST_DEV_SYSFS}/device/subsystem")
case $subsys in
*/nvme)
readlink -f "${TEST_DEV_SYSFS}/device"
;;
*/nvme-subsystem)
for c in "${TEST_DEV_SYSFS}"/device/nvme*; do
[[ -L "$c" ]] || continue
[[ -f "$c/dev" ]] && readlink -f "$c"
done
;;
esac
}

_nvme_calc_rand_io_size() {
local img_size_mb
local io_size_kb
Expand Down

0 comments on commit ed9b60a

Please sign in to comment.