1
0
Fork 0

Merging upstream version 4.2+20231026.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-14 06:32:02 +01:00
parent bb079da599
commit a701b01644
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
30 changed files with 956 additions and 423 deletions

107
tests/00confnames Normal file
View file

@ -0,0 +1,107 @@
set -x -e
. tests/templates/names_template
# Test how <devname> and <name> from config are handled during Incremental assemblation.
# 1-6 <devnode> only tests (no <name> in config).
# 6-10 <devname> and <name> combinations are tested.
# 11-13 corner cases.
names_create "/dev/md/name"
local _UUID="$(mdadm -D --export /dev/md127 | grep MD_UUID | cut -d'=' -f2)"
[[ "$_UUID" == "" ]] && echo "Cannot obtain UUID for $DEVNODE_NAME" && exit 1
# 1. <devname> definition consistent with metadata name.
names_make_conf $_UUID "/dev/md/name" "empty" $config
mdadm -S "/dev/md127"
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"
# 2. Same as 1, but use short name form of <devname>.
names_make_conf $_UUID "name" "empty" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"
# 3. Same as 1, but use different <devname> than metadata provides.
names_make_conf $_UUID "/dev/md/other" "empty" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "other" "name"
mdadm -S "/dev/md127"
# 4. Same as 3, but use short name form of <devname>.
names_make_conf $_UUID "other" "empty" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "other" "name"
mdadm -S "/dev/md127"
# 5. Force particular node creation by setting <devname> to /dev/mdX. Link is not created in this
# case.
names_make_conf $_UUID "/dev/md4" "empty" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md4" "empty" "name"
mdadm -S "/dev/md4"
# 6. <devname> set to /dev/mdX, <name> same as in metadata.
# Metadata name and default node used - controversial. Current behavior documented.
names_make_conf $_UUID "/dev/md22" "name" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"
# 7. <devname> set to /dev/mdX, <name> different than in metadata.
# Metadata name and default node used - controversial. Current behavior documented.
names_make_conf $_UUID "/dev/md8" "other" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"
# 8. Both <devname> and <name> different than in metadata.
# Metadata name and default node used - controversial. Current behavior documented.
names_make_conf $_UUID "devnode" "other_name" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"
# 9. <devname> set to metadata name, <name> different than in metadata.
# Metadata name and default node used - controversial. Current behavior documented.
names_make_conf $_UUID "name" "other_name" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"
# 10. Bad <devname> set, no <name>.
# Metadata name and default node used - expected.
names_make_conf $_UUID "/im/bad/devname" "empty" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"
# 11. <devname> with some special symbols and locales, no <name>.
# <devname> should be ignored.
names_make_conf $_UUID "tźż-\.,<>st+-" "empty" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"
# 12. No <devname> and <name> set.
# Metadata name and default node used - expected.
names_make_conf $_UUID "empty" "empty" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"
# 13. No <devname>, <name> set to /dev/mdX.
# Entry should be ignored, it is not ignored but result is good anyway.
names_make_conf $_UUID "empty" "/dev/md12" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"
# 13. No <devname>, <name> with special symbols and locales.
# Entry should be ignored, it is not ignored but result is good anyway.
names_make_conf $_UUID "empty" "./\śćń#&" $config
mdadm -I $dev0 --config=$config
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"

View file

@ -1,93 +1,44 @@
set -x -e
. tests/templates/names_template
# Test how <devname> and --name= are handled for create mode.
# We need to check three properties, generated from those parameters:
# - devnode name
# - link in /dev/md/ (MD_DEVNAME property from --detail --export)
# - name in metadata (MD_NAME property from --examine --export)
function _verify() {
local DEVNODE_NAME="$1"
local WANTED_LINK="$2"
local WANTED_NAME="$3"
local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)"
if [[ "$?" != "0" ]]; then
echo "Cannot get details for $DEVNODE_NAME - unexpected devnode."
exit 1
fi
if [[ "$WANTED_LINK" != "empty" ]]; then
local EXPECTED="MD_DEVNAME=$WANTED_LINK"
if [[ "$RES" != "$EXPECTED" ]]; then
echo "$RES doesn't match $EXPECTED."
exit 1
fi
fi
local RES="$(mdadm -E --export $dev0 | grep MD_NAME)"
if [[ "$?" != "0" ]]; then
echo "Cannot get metadata from $dev0."
exit 1
fi
local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME"
if [[ "$RES" != "$EXPECTED" ]]; then
echo "$RES doesn't match $EXPECTED."
exit 1
fi
}
function _create() {
local DEVNAME=$1
local NAME=$2
if [[ -z "$NAME" ]]; then
mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force
else
mdadm -CR "$DEVNAME" --name="$NAME" -l0 -n 1 $dev0 --force
fi
if [[ "$?" != "0" ]]; then
echo "Cannot create device."
exit 1
fi
}
# The most trivial case.
_create "/dev/md/name"
_verify "/dev/md127" "name" "name"
names_create "/dev/md/name"
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"
_create "name"
_verify "/dev/md127" "name" "name"
names_create "name"
names_verify "/dev/md127" "name" "name"
mdadm -S "/dev/md127"
# Use 'mdX' as name.
_create "/dev/md/md0"
_verify "/dev/md127" "md0" "md0"
names_create "/dev/md/md0"
names_verify "/dev/md127" "md0" "md0"
mdadm -S "/dev/md127"
_create "md0"
_verify "/dev/md127" "md0" "md0"
names_create "md0"
names_verify "/dev/md127" "md0" "md0"
mdadm -S "/dev/md127"
# <devnode> is used to create MD_DEVNAME but, name is used to create MD_NAME.
_create "/dev/md/devnode" "name"
_verify "/dev/md127" "devnode" "name"
names_create "/dev/md/devnode" "name"
names_verify "/dev/md127" "devnode" "name"
mdadm -S "/dev/md127"
_create "devnode" "name"
_verify "/dev/md127" "devnode" "name"
names_create "devnode" "name"
names_verify "/dev/md127" "devnode" "name"
mdadm -S "/dev/md127"
# Devnode points to /dev/ directory. MD_DEVNAME doesn't exist.
_create "/dev/md0"
_verify "/dev/md0" "empty" "0"
names_create "/dev/md0"
names_verify "/dev/md0" "empty" "0"
mdadm -S "/dev/md0"
# Devnode points to /dev/ directory and name is set.
_create "/dev/md0" "name"
_verify "/dev/md0" "empty" "name"
names_create "/dev/md0" "name"
names_verify "/dev/md0" "empty" "name"
mdadm -S "/dev/md0"
# Devnode is a special ignore keyword. Should be rejected.
names_create "<ignore>" "name", "true"

View file

@ -3,8 +3,8 @@ set -x
# create an array with a name
mdadm -CR $md0 -l0 -n2 --metadata=1 --name="Fred" $dev0 $dev1
mdadm -E $dev0 | grep 'Name : [^:]*:Fred ' > /dev/null || exit 1
mdadm -D $md0 | grep 'Name : [^:]*:Fred ' > /dev/null || exit 1
mdadm -E $dev0 | grep 'Name : Fred' > /dev/null || exit 1
mdadm -D $md0 | grep 'Name : Fred' > /dev/null || exit 1
mdadm -S $md0
mdadm -A $md0 --name="Fred" $devlist

34
tests/23rdev-lifetime Normal file
View file

@ -0,0 +1,34 @@
devname=${dev0##*/}
devt=`cat /sys/block/$devname/dev`
pid=""
runtime=2
clean_up_test() {
pill -9 $pid
echo clear > /sys/block/md0/md/array_state
}
trap 'clean_up_test' EXIT
add_by_sysfs() {
while true; do
echo $devt > /sys/block/md0/md/new_dev
done
}
remove_by_sysfs(){
while true; do
echo remove > /sys/block/md0/md/dev-${devname}/state
done
}
echo md0 > /sys/module/md_mod/parameters/new_array || die "create md0 failed"
add_by_sysfs &
pid="$pid $!"
remove_by_sysfs &
pid="$pid $!"
sleep $runtime
exit 0

88
tests/24raid10deadlock Normal file
View file

@ -0,0 +1,88 @@
devs="$dev0 $dev1 $dev2 $dev3"
runtime=120
pid=""
action_pid=""
set_up_injection()
{
echo -1 > /sys/kernel/debug/fail_make_request/times
echo 1 > /sys/kernel/debug/fail_make_request/probability
echo 0 > /sys/kernel/debug/fail_make_request/verbose
echo 1 > /sys/block/${1##*/}/make-it-fail
}
clean_up_injection()
{
echo 0 > /sys/block/${1##*/}/make-it-fail
echo 0 > /sys/kernel/debug/fail_make_request/times
echo 0 > /sys/kernel/debug/fail_make_request/probability
echo 2 > /sys/kernel/debug/fail_make_request/verbose
}
test_rdev()
{
while true; do
mdadm -f $md0 $1 &> /dev/null
mdadm -r $md0 $1 &> /dev/null
mdadm --zero-superblock $1 &> /dev/null
mdadm -a $md0 $1 &> /dev/null
sleep $2
done
}
test_write_action()
{
while true; do
echo frozen > /sys/block/md0/md/sync_action
echo idle > /sys/block/md0/md/sync_action
sleep 0.1
done
}
set_up_test()
{
fio -h &> /dev/null || die "fio not found"
# create a simple raid10
mdadm -Cv -R -n 4 -l10 $md0 $devs || die "create raid10 failed"
}
clean_up_test()
{
clean_up_injection $dev0
pkill -9 fio
kill -9 $pid
kill -9 $action_pid
sleep 1
if ps $action_pid | tail -1 | awk '{print $3}' | grep D; then
die "thread that is writing sysfs is stuck in D state, deadlock is triggered"
fi
mdadm -S $md0
}
cat /sys/kernel/debug/fail_make_request/times || die "fault injection is not enabled"
trap 'clean_up_test' EXIT
set_up_test || die "set up test failed"
# backgroup io pressure
fio -filename=$md0 -rw=randwrite -direct=1 -name=test -bs=4k -numjobs=16 -iodepth=16 &
# trigger add/remove device by io failure
set_up_injection $dev0
test_rdev $dev0 2 &
pid="$pid $!"
# add/remove device directly
test_rdev $dev3 10 &
pid="$pid $!"
test_write_action &
action_pid="$!"
sleep $runtime
exit 0

View file

58
tests/24raid456deadlock Normal file
View file

@ -0,0 +1,58 @@
devs="$dev0 $dev1 $dev2 $dev3 $dev4 $dev5"
runtime=120
pid=""
old=`cat /proc/sys/vm/dirty_background_ratio`
test_write_action()
{
while true; do
echo check > /sys/block/md0/md/sync_action &> /dev/null
sleep 0.1
echo idle > /sys/block/md0/md/sync_action &> /dev/null
done
}
test_write_back()
{
fio -filename=$md0 -bs=4k -rw=write -numjobs=1 -name=test \
-time_based -runtime=$runtime &> /dev/null
}
set_up_test()
{
fio -h &> /dev/null || die "fio not found"
# create a simple raid6
mdadm -Cv -R -n 6 -l6 $md0 $devs --assume-clean || die "create raid6 failed"
# trigger dirty pages write back
echo 0 > /proc/sys/vm/dirty_background_ratio
}
clean_up_test()
{
echo $old > /proc/sys/vm/dirty_background_ratio
pkill -9 fio
kill -9 $pid
sleep 1
if ps $pid | tail -1 | awk '{print $3}' | grep D; then
die "thread that is writing sysfs is stuck in D state, deadlock is triggered"
fi
mdadm -S $md0
}
trap 'clean_up_test' EXIT
set_up_test || die "set up test failed"
test_write_back &
test_write_action &
pid="$!"
sleep $runtime
exit 0

View file

@ -0,0 +1,33 @@
devs="$dev0 $dev1 $dev2"
set_up_test()
{
mdadm -Cv -R -n 3 -l5 $md0 $devs --assume-clean --size=50M || die "create array failed"
mdadm -a $md0 $dev3 $dev4 || die "failed to bind new disk to array"
echo 1000 > /sys/block/md0/md/sync_speed_max
}
clean_up_test()
{
mdadm -S $md0
}
trap 'clean_up_test' EXIT
set_up_test || die "set up test failed"
# trigger reshape
mdadm --grow -l 6 $md0
sleep 1
# set up replacement
echo frozen > /sys/block/md0/md/sync_action
echo want_replacement > /sys/block/md0/md/rd0/state
echo reshape > /sys/block/md0/md/sync_action
sleep 1
# reassemeble array
mdadm -S $md0 || die "can't stop array"
mdadm --assemble $md0 $devs $dev3 $dev4 || die "can't assemble array"
exit 0

View file

@ -0,0 +1,35 @@
devs="$dev0 $dev1 $dev2"
set_up_test()
{
mdadm -Cv -R -n 3 -l5 $md0 $devs --size=50M || die "create array failed"
mdadm -a $md0 $dev3 || die "failed to bind new disk to array"
mkfs.xfs -f $md0 || die "mkfs failed"
xfs_ncheck $md0 || die "check fs failed"
}
clean_up_test()
{
mdadm -S $md0
}
trap 'clean_up_test' EXIT
set_up_test || die "set up test failed"
# trigger reshape
echo 1000 > /sys/block/md0/md/sync_speed_max
mdadm --grow -l 6 $md0
sleep 1
# stop and start reshape
echo frozen > /sys/block/md0/md/sync_action
echo system > /sys/block/md0/md/sync_speed_max
echo reshape > /sys/block/md0/md/sync_action
mdadm -W $md0
# check if data is corrupted
xfs_ncheck $md0 || die "data is corrupted after reshape"
exit 0

View file

@ -0,0 +1,34 @@
devs="$dev0 $dev1 $dev2"
set_up_test()
{
mdadm -Cv -R -n 3 -l5 $md0 $devs --size=50M || die "create array failed"
mdadm -a $md0 $dev3 || die "failed to bind new disk to array"
echo 1000 > /sys/block/md0/md/sync_speed_max
}
clean_up_test()
{
echo idle > /sys/block/md0/md/sync_action
mdadm -S $md0
}
trap 'clean_up_test' EXIT
set_up_test || die "set up test failed"
# trigger reshape
mdadm --grow -l 6 $md0
sleep 1
# stop reshape
echo frozen > /sys/block/md0/md/sync_action
# read accross reshape
dd if=$md0 of=/dev/NULL bs=1m count=100 iflag=direct &> /dev/null &
sleep 2
# suspend array
echo 1 > /sys/block/md0/md/suspend_lo
exit 0

View file

@ -0,0 +1,32 @@
devs="$dev0 $dev1 $dev2"
set_up_test()
{
mdadm -Cv -R -n 3 -l5 $md0 $devs --assume-clean --size=50M || die "create array failed"
mdadm -a $md0 $dev3 $dev4 || die "failed to bind new disk to array"
echo 1000 > /sys/block/md0/md/sync_speed_max
}
clean_up_test()
{
mdadm -S $md0
}
trap 'clean_up_test' EXIT
set_up_test || die "set up test failed"
# set up replacement
echo want_replacement > /sys/block/md0/md/rd0/state
sleep 1
# trigger reshape
echo frozen > /sys/block/md0/md/sync_action
mdadm --grow -l 6 $md0
sleep 1
# reassemeble array
mdadm -S $md0 || die "can't stop array"
mdadm --assemble $md0 $devs $dev3 $dev4 || die "can't assemble array"
exit 0

View file

@ -170,7 +170,6 @@ do_setup() {
dd if=/dev/zero of=$targetdir/mdtest$d count=$sz bs=1K > /dev/null 2>&1
# make sure udev doesn't touch
mdadm --zero $targetdir/mdtest$d 2> /dev/null
[ -b /dev/loop$d ] || mknod /dev/loop$d b 7 $d
if [ $d -eq 7 ]
then
losetup /dev/loop$d $targetdir/mdtest6 # for multipath use

View file

@ -0,0 +1,80 @@
# NAME is optional. Testing with native 1.2 superblock.
function names_create() {
local DEVNAME=$1
local NAME=$2
local NEG_TEST=$3
if [[ -z "$NAME" ]]; then
mdadm -CR "$DEVNAME" -l0 -n 1 $dev0 --force
else
mdadm -CR "$DEVNAME" --name="$NAME" --metadata=1.2 -l0 -n 1 $dev0 --force
fi
if [[ "$NEG_TEST" == "true" ]]; then
[[ "$?" == "0" ]] && return 0
echo "Negative verification failed"
exit 1
fi
if [[ "$?" != "0" ]]; then
echo "Cannot create device."
exit 1
fi
}
# Three properties to check:
# - devnode name
# - link in /dev/md/ (MD_DEVNAME property from --detail --export)
# - name in metadata (MD_NAME property from --detail --export)- that works only with 1.2 sb.
function names_verify() {
local DEVNODE_NAME="$1"
local WANTED_LINK="$2"
local WANTED_NAME="$3"
local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_DEVNAME)"
if [[ "$?" != "0" ]]; then
echo "Cannot get details for $DEVNODE_NAME - unexpected devnode."
exit 1
fi
if [[ "$WANTED_LINK" != "empty" ]]; then
local EXPECTED="MD_DEVNAME=$WANTED_LINK"
fi
if [[ "$RES" != "$EXPECTED" ]]; then
echo "$RES doesn't match $EXPECTED."
exit 1
fi
local RES="$(mdadm -D --export $DEVNODE_NAME | grep MD_NAME)"
if [[ "$?" != "0" ]]; then
echo "Cannot get metadata from $dev0."
exit 1
fi
local EXPECTED="MD_NAME=$(hostname):$WANTED_NAME"
if [[ "$RES" != "$EXPECTED" ]]; then
echo "$RES doesn't match $EXPECTED."
exit 1
fi
}
# Generate ARRAYLINE for tested array.
names_make_conf() {
local UUID="$1"
local WANTED_DEVNAME="$2"
local WANTED_NAME="$3"
local CONF="$4"
local LINE="ARRAY metadata=1.2 UUID=$UUID"
if [[ "$WANTED_DEVNAME" != "empty" ]]; then
LINE="$LINE $WANTED_DEVNAME"
fi
if [[ "$WANTED_NAME" != "empty" ]]; then
LINE="$LINE name=$WANTED_NAME"
fi
echo $LINE > $CONF
}