blktests: add add_disk() error handling testing
cover blktests: add add_disk() error handling testing
This adds the tests for testing error handling on the add_disk() paths.
Luis Chamberlain (2):
null_blk: add ability to use a quiet modprobe
block: add add_disk() error handling tests
common/null_blk | 8 ++- tests/block/013 | 156 ++++++++++++++++++++++++++++++++++++++++++++ tests/block/013.out | 4 +- 3 files changed, 164 insertions(+), 4 deletions(-) create mode 100755 tests/block/013
Signature · 1 line
2.30.2
PATCH 1/2 null_blk: add ability to use a quiet modprobe
We may want to ignore modprobe errors. For instance when doing error injection.
Signed-off-by Luis Chamberlain <[email protected]>
--- common/null_blk | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
common/null_blk +7 -1
@@ -19,9 +19,15 @@ _init_null_blk() { _remove_null_blk_devices local zoned="" + local modprobe_load_args="" + + if [ ! -z "$NULL_BLK_QUIET_MODPROBE" ]; then + modprobe_load_args="-q" + fi + if (( RUN_FOR_ZONED )); then zoned="zoned=1"; fi - if ! modprobe -r null_blk || ! modprobe null_blk "$@" "${zoned}" ; then + if ! modprobe -r null_blk || ! modprobe null_blk $modprobe_load_args "$@" "${zoned}" ; then return 1 fi
Signature · 1 line
2.30.2
PATCH 2/2 block: add add_disk() error handling tests
In reply to Luis ChamberlainIf your kernel has the new CONFIG_FAIL_ADD_DISK which adds error injection to the add_disk() paths, we'll run tests against each possible test path and ensure that the kernel doesn't crash / break / leak.
Signed-off-by Luis Chamberlain <[email protected]>
--- tests/block/013 | 156 ++++++++++++++++++++++++++++++++++++++++++++ tests/block/013.out | 4 +- 2 files changed, 157 insertions(+), 3 deletions(-) create mode 100755 tests/block/013
tests/block/013 new file +156 -0
@@ -0,0 +1,156 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-3.0+ +# Copyright (C) 2021 Luis Chamberlain <[email protected]> + +# Trigger the block *add_disk()() error path. We used to not have +# any error path handling for add_disk(). Only recently have we +# added support for this. There are many places in which the +# function call for add_disk() can fail, this test allows us to +# force each path which could fail and test it. +# +# Correctness is verified by running the tests many times, looking +# for kernel errors, crashes or memory leaks. + +. tests/block/rc +. common/null_blk + +DESCRIPTION="trigger the add_disk() error paths" +QUICK=1 + +if [ -z "$SYS_DEBUGFS" ]; then + SYS_DEBUGFS="/sys/kernel/debug" +fi + +if [ -z "$SYS_DEBUGFS_BLOCK_DIR" ]; then + SYS_DEBUGFS_BLOCK_DIR="$SYS_DEBUGFS/block" +fi + +if [ -z "$BLOCK_ADD_DISK_FAIL_DEBUGFS_DIR" ]; then + BLOCK_ADD_DISK_FAIL_DEBUGFS_DIR="$SYS_DEBUGFS_BLOCK_DIR/config_fail_add_disk" +fi + +if [ -z "$BLOCK_ADD_DISK_CONFIG_DIR" ]; then + BLOCK_ADD_DISK_CONFIG_DIR="$SYS_DEBUGFS_BLOCK_DIR/fail_add_disk" +fi + +if [ -z "$KMEMLEAK_DEBUG_FILE" ]; then + KMEMLEAK_DEBUG_FILE="$SYS_DEBUGFS/kmemleak" +fi + +requires() { + _have_kernel_option FAIL_ADD_DISK + _have_kernel_option FAULT_INJECTION_DEBUG_FS + _have_kernel_option DEBUG_KMEMLEAK + _have_null_blk +} + +kmemleak_clear() +{ + echo clear > $KMEMLEAK_DEBUG_FILE +} + +kmemleak_verify() +{ + echo scan > $KMEMLEAK_DEBUG_FILE + cat $KMEMLEAK_DEBUG_FILE +} + +enable_add_disk_failures() +{ + echo 1 > $BLOCK_ADD_DISK_CONFIG_DIR/interval + echo 100 > $BLOCK_ADD_DISK_CONFIG_DIR/probability +} + +disable_add_disk_failures() +{ + echo 0 > $BLOCK_ADD_DISK_CONFIG_DIR/interval + echo 0 > $BLOCK_ADD_DISK_CONFIG_DIR/probability +} + +disable_add_disk_failure_paths() +{ + local fail_files_paths + local fail_path_bool + + fail_files_paths=$(ls -1 $BLOCK_ADD_DISK_FAIL_DEBUGFS_DIR) + + for fail_path_bool in ${fail_files_paths}; do + echo N > $BLOCK_ADD_DISK_FAIL_DEBUGFS_DIR/$fail_path_bool + if [[ $? -ne 0 ]]; then + echo "Could not disable $fail_path_bool" + fi + done +} + +test_add_disk_failures() +{ + local fail_files + local fail_path + local leak_wc + local test_add_disk_cnt=$1 + + fail_files=$(ls -1 $BLOCK_ADD_DISK_FAIL_DEBUGFS_DIR) + + # We enable only one failure path at a time. The order does not matter + # and so whatever order we get alphabetically is fine. We test for + # correctness by checking for crashes, and memory leaks. + for fail_path in ${fail_files}; do + disable_add_disk_failure_paths + echo Y > $BLOCK_ADD_DISK_FAIL_DEBUGFS_DIR/$fail_path + if [[ $? -ne 0 ]]; then + echo "Could not enable failure injection for $fail_path" + echo "on loop $test_add_disk_cnt" + fi + + NULL_BLK_QUIET_MODPROBE="y" + if _init_null_blk queue_mode=2 ; then + echo "Loading of null_blk should have failed while testing" + echo "add_disk() failure on $fail_path loop test" + echo "number $test_add_disk_cnt" + return 1 + fi + unset NULL_BLK_QUIET_MODPROBE + + leak_wc=$(kmemleak_verify | wc -l) + if [[ $leak_wc -ne 0 ]]; then + echo "Memory leak detected while testing add_disk()" + echo "failure path on $fail_path loop test" + echo "number $test_add_disk_cnt" + kmemleak_verify + fi + done +} + +test() { + local test_loop_cnt + local test_loop_max=5 + local final_leak_w + + enable_add_disk_failures + kmemleak_clear + + for test_loop_cnt in $(seq 1 $test_loop_max); do + test_add_disk_failures $test_loop_cnt + done + + disable_add_disk_failure_paths + disable_add_disk_failures + + # Last check is just a sanity check to ensure we can still load + # the null block module correctly/ + if ! _init_null_blk queue_mode=2; then + echo "Loading null_blk failed after disabling error injection" + return 1 + fi + + leak_wc=$(kmemleak_verify | wc -l) + if [[ $leak_wc -ne 0 ]]; then + echo "Memleak after disabling add_disk() error injection" + kmemleak_verify + fi + kmemleak_clear + + _exit_null_blk + + echo Passed +}
tests/block/013.out +1 -3
@@ -1,3 +1 @@ -Running block/013 -Device or resource busy -Test complete +Passed
Signature · 1 line
2.30.2