1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-06 17:18:29 +03:00
lvm2/test/shell/udev-pvscan-vgchange.sh
David Teigland d12baba1a9 pvscan: match device arg to filter symlink
This fixes an issue related to the optimization in
  "pvscan: only add device args to dev cache"

If the devices file is not used, and the lvm.conf filter
accepts devices via symlink names, then those devices won't
be accepted by pvscan for autoactivation.  To resolve this,
recognize when the filter contains symlinks and disable the
optimization.  When the optimization is disabled, a full
dev_cache_scan is performed, and symlinks are associated
with the device names passed to pvscan.  filter-regex
will accept a device if symlinks to that device are accepted.
2021-11-29 17:13:44 -06:00

466 lines
11 KiB
Bash

#!/usr/bin/env bash
# Copyright (C) 2021 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
test_description='udev rule and systemd unit run vgchange'
SKIP_WITH_LVMPOLLD=1
SKIP_WITH_LVMLOCKD=1
. lib/inittest
#
# $ cat /tmp/devs
# /dev/sdb
# /dev/sdc
# /dev/sdd
#
# Specify this file as LVM_TEST_DEVICE_LIST=/tmp/devs
# when running the test.
#
# This test will wipe these devices.
#
if [ -z ${LVM_TEST_DEVICE_LIST+x} ]; then echo "LVM_TEST_DEVICE_LIST is unset" && skip; else echo "LVM_TEST_DEVICE_LIST is set to '$LVM_TEST_DEVICE_LIST'"; fi
test -e "$LVM_TEST_DEVICE_LIST" || skip
num_devs=$(cat $LVM_TEST_DEVICE_LIST | wc -l)
RUNDIR="/run"
test -d "$RUNDIR" || RUNDIR="/var/run"
PVS_ONLINE_DIR="$RUNDIR/lvm/pvs_online"
VGS_ONLINE_DIR="$RUNDIR/lvm/vgs_online"
PVS_LOOKUP_DIR="$RUNDIR/lvm/pvs_lookup"
_clear_online_files() {
# wait till udev is finished
aux udev_wait
rm -f "$PVS_ONLINE_DIR"/*
rm -f "$VGS_ONLINE_DIR"/*
rm -f "$PVS_LOOKUP_DIR"/*
}
test -d "$PVS_ONLINE_DIR" || mkdir -p "$PVS_ONLINE_DIR"
test -d "$VGS_ONLINE_DIR" || mkdir -p "$VGS_ONLINE_DIR"
test -d "$PVS_LOOKUP_DIR" || mkdir -p "$PVS_LOOKUP_DIR"
_clear_online_files
aux prepare_real_devs
aux lvmconf 'devices/dir = "/dev"'
aux lvmconf 'devices/use_devicesfile = 1'
DFDIR="$LVM_SYSTEM_DIR/devices"
DF="$DFDIR/system.devices"
mkdir $DFDIR || true
not ls $DF
get_real_devs
wipe_all() {
for dev in "${REAL_DEVICES[@]}"; do
wipefs -a $dev
done
}
wait_lvm_activate() {
local vgw=$1
local wait=0
while systemctl status lvm-activate-$vgw | grep "active (running)" && test "$wait" -le 30; do
sleep .2
wait=$(( wait + 1 ))
done
}
# Test requires 3 devs
test $num_devs -gt 2 || skip
BDEV1=$(basename "$dev1")
BDEV2=$(basename "$dev2")
BDEV3=$(basename "$dev3")
wipe_all
touch $DF
for dev in "${REAL_DEVICES[@]}"; do
pvcreate $dev
done
# 1 dev, 1 vg, 1 lv
vgcreate $vg1 "$dev1"
lvcreate -l1 -an -n $lv1 $vg1 "$dev1"
PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
_clear_online_files
udevadm trigger --settle -c add /sys/block/$BDEV1
wait_lvm_activate $vg1
ls "$RUNDIR/lvm/pvs_online/$PVID1"
ls "$RUNDIR/lvm/vgs_online/$vg1"
journalctl -u lvm-activate-$vg1 | tee out || true
grep "now active" out
check lv_field $vg1/$lv1 lv_active "active"
vgchange -an $vg1
vgremove -y $vg1
# 2 devs, 1 vg, 2 lvs
vgcreate $vg2 "$dev1" "$dev2"
lvcreate -l1 -an -n $lv1 $vg2 "$dev1"
lvcreate -l1 -an -n $lv2 $vg2 "$dev2"
PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
PVID2=$(pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}')
_clear_online_files
udevadm trigger --settle -c add /sys/block/$BDEV1
ls "$RUNDIR/lvm/pvs_online/$PVID1"
not ls "$RUNDIR/lvm/vgs_online/$vg2"
journalctl -u lvm-activate-$vg2 | tee out || true
not grep "now active" out
check lv_field $vg2/$lv1 lv_active ""
check lv_field $vg2/$lv2 lv_active ""
udevadm trigger --settle -c add /sys/block/$BDEV2
ls "$RUNDIR/lvm/pvs_online/$PVID2"
ls "$RUNDIR/lvm/vgs_online/$vg2"
wait_lvm_activate $vg2
journalctl -u lvm-activate-$vg2 | tee out || true
grep "now active" out
check lv_field $vg2/$lv1 lv_active "active"
check lv_field $vg2/$lv2 lv_active "active"
vgchange -an $vg2
vgremove -y $vg2
# 3 devs, 1 vg, 4 lvs, concurrent pvscans
# (attempting to have the pvscans run concurrently and race
# to activate the VG)
vgcreate $vg3 "$dev1" "$dev2" "$dev3"
lvcreate -l1 -an -n $lv1 $vg3 "$dev1"
lvcreate -l1 -an -n $lv2 $vg3 "$dev2"
lvcreate -l1 -an -n $lv3 $vg3 "$dev3"
lvcreate -l8 -an -n $lv4 -i 2 $vg3 "$dev1" "$dev2"
PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
PVID2=$(pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}')
PVID3=$(pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}')
_clear_online_files
udevadm trigger -c add /sys/block/$BDEV1 &
udevadm trigger -c add /sys/block/$BDEV2 &
udevadm trigger -c add /sys/block/$BDEV3
aux udev_wait
wait_lvm_activate $vg3
ls "$RUNDIR/lvm/pvs_online/$PVID1"
ls "$RUNDIR/lvm/pvs_online/$PVID2"
ls "$RUNDIR/lvm/pvs_online/$PVID3"
ls "$RUNDIR/lvm/vgs_online/$vg3"
journalctl -u lvm-activate-$vg3 | tee out || true
grep "now active" out
check lv_field $vg3/$lv1 lv_active "active"
check lv_field $vg3/$lv2 lv_active "active"
check lv_field $vg3/$lv3 lv_active "active"
check lv_field $vg3/$lv4 lv_active "active"
vgchange -an $vg3
vgremove -y $vg3
# 3 devs, 1 vg, 4 lvs, concurrent pvscans, metadata on only 1 PV
wipe_all
rm $DF
touch $DF
pvcreate --metadatacopies 0 "$dev1"
pvcreate --metadatacopies 0 "$dev2"
pvcreate "$dev3"
vgcreate $vg4 "$dev1" "$dev2" "$dev3"
lvcreate -l1 -an -n $lv1 $vg4 "$dev1"
lvcreate -l1 -an -n $lv2 $vg4 "$dev2"
lvcreate -l1 -an -n $lv3 $vg4 "$dev3"
lvcreate -l8 -an -n $lv4 -i 2 $vg4 "$dev1" "$dev2"
PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
PVID2=$(pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}')
PVID3=$(pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}')
_clear_online_files
udevadm trigger -c add /sys/block/$BDEV1 &
udevadm trigger -c add /sys/block/$BDEV2 &
udevadm trigger -c add /sys/block/$BDEV3
aux udev_wait
wait_lvm_activate $vg4
ls "$RUNDIR/lvm/pvs_lookup/"
cat "$RUNDIR/lvm/pvs_lookup/$vg4" || true
ls "$RUNDIR/lvm/pvs_online/$PVID1"
ls "$RUNDIR/lvm/pvs_online/$PVID2"
ls "$RUNDIR/lvm/pvs_online/$PVID3"
ls "$RUNDIR/lvm/vgs_online/$vg4"
journalctl -u lvm-activate-$vg4 | tee out || true
grep "now active" out
check lv_field $vg4/$lv1 lv_active "active"
check lv_field $vg4/$lv2 lv_active "active"
check lv_field $vg4/$lv3 lv_active "active"
check lv_field $vg4/$lv4 lv_active "active"
vgchange -an $vg4
vgremove -y $vg4
# 3 devs, 3 vgs, 2 lvs in each vg, concurrent pvscans
wipe_all
rm $DF
touch $DF
vgcreate $vg5 "$dev1"
vgcreate $vg6 "$dev2"
vgcreate $vg7 "$dev3"
lvcreate -l1 -an -n $lv1 $vg5
lvcreate -l1 -an -n $lv2 $vg5
lvcreate -l1 -an -n $lv1 $vg6
lvcreate -l1 -an -n $lv2 $vg6
lvcreate -l1 -an -n $lv1 $vg7
lvcreate -l1 -an -n $lv2 $vg7
_clear_online_files
udevadm trigger -c add /sys/block/$BDEV1 &
udevadm trigger -c add /sys/block/$BDEV2 &
udevadm trigger -c add /sys/block/$BDEV3
aux udev_wait
wait_lvm_activate $vg5
wait_lvm_activate $vg6
wait_lvm_activate $vg7
ls "$RUNDIR/lvm/vgs_online/$vg5"
ls "$RUNDIR/lvm/vgs_online/$vg6"
ls "$RUNDIR/lvm/vgs_online/$vg7"
journalctl -u lvm-activate-$vg5 | tee out || true
grep "now active" out
journalctl -u lvm-activate-$vg6 | tee out || true
grep "now active" out
journalctl -u lvm-activate-$vg7 | tee out || true
grep "now active" out
check lv_field $vg5/$lv1 lv_active "active"
check lv_field $vg5/$lv2 lv_active "active"
check lv_field $vg6/$lv1 lv_active "active"
check lv_field $vg6/$lv2 lv_active "active"
check lv_field $vg7/$lv1 lv_active "active"
check lv_field $vg7/$lv2 lv_active "active"
vgchange -an $vg5
vgremove -y $vg5
vgchange -an $vg6
vgremove -y $vg6
vgchange -an $vg7
vgremove -y $vg7
# 3 devs, 1 vg, 1000 LVs
wipe_all
rm $DF
touch $DF
pvcreate --metadatacopies 0 "$dev1"
pvcreate "$dev2"
pvcreate "$dev3"
vgcreate -s 128K $vg8 "$dev1" "$dev2" "$dev3"
# Number of LVs to create
TEST_DEVS=1000
# On low-memory boxes let's not stress too much
test "$(aux total_mem)" -gt 524288 || TEST_DEVS=256
vgcfgbackup -f data $vg8
# Generate a lot of devices (size of 1 extent)
awk -v TEST_DEVS=$TEST_DEVS '/^\t\}/ {
printf("\t}\n\tlogical_volumes {\n");
cnt=0;
for (i = 0; i < TEST_DEVS; i++) {
printf("\t\tlvol%06d {\n", i);
printf("\t\t\tid = \"%06d-1111-2222-3333-2222-1111-%06d\"\n", i, i);
print "\t\t\tstatus = [\"READ\", \"WRITE\", \"VISIBLE\"]";
print "\t\t\tsegment_count = 1";
print "\t\t\tsegment1 {";
print "\t\t\t\tstart_extent = 0";
print "\t\t\t\textent_count = 1";
print "\t\t\t\ttype = \"striped\"";
print "\t\t\t\tstripe_count = 1";
print "\t\t\t\tstripes = [";
print "\t\t\t\t\t\"pv0\", " cnt++;
printf("\t\t\t\t]\n\t\t\t}\n\t\t}\n");
}
}
{print}
' data >data_new
vgcfgrestore -f data_new $vg8
_clear_online_files
udevadm trigger -c add /sys/block/$BDEV1 &
udevadm trigger -c add /sys/block/$BDEV2 &
udevadm trigger -c add /sys/block/$BDEV3
aux udev_wait
wait_lvm_activate $vg8
ls "$RUNDIR/lvm/vgs_online/$vg8"
journalctl -u lvm-activate-$vg8 | tee out || true
grep "now active" out
num_active=$(lvs $vg8 --noheading -o active | grep active | wc -l)
test $num_active -eq $TEST_DEVS
vgchange -an $vg8
vgremove -y $vg8
# 1 pv on an md dev, 1 vg
wait_md_create() {
local md=$1
while :; do
if ! grep "$(basename $md)" /proc/mdstat; then
echo "$md not ready"
cat /proc/mdstat
sleep 2
else
break
fi
done
echo "$md" > WAIT_MD_DEV
}
test -f /proc/mdstat && grep -q raid1 /proc/mdstat || \
modprobe raid1 || skip
mddev="/dev/md33"
not grep $mddev /proc/mdstat || skip
wipe_all
rm $DF
touch $DF
mdadm --create --metadata=1.0 "$mddev" --level 1 --chunk=64 --raid-devices=2 "$dev1" "$dev2"
wait_md_create "$mddev"
vgcreate $vg9 "$mddev"
lvmdevices --adddev "$mddev" || true
PVIDMD=`pvs $mddev --noheading -o uuid | tr -d - | awk '{print $1}'`
BDEVMD=$(basename "$mddev")
lvcreate -l1 -an -n $lv1 $vg9
lvcreate -l1 -an -n $lv2 $vg9
mdadm --stop "$mddev"
systemctl stop lvm-activate-$vg9 || true
_clear_online_files
mdadm --assemble "$mddev" "$dev1" "$dev2"
# this trigger might be redundant because the mdadm --assemble
# probably triggers an add uevent
udevadm trigger --settle -c add /sys/block/$BDEVMD
wait_lvm_activate $vg9
ls "$RUNDIR/lvm/vgs_online/$vg9"
journalctl -u lvm-activate-$vg9 | tee out || true
grep "now active" out
check lv_field $vg9/$lv1 lv_active "active"
check lv_field $vg9/$lv2 lv_active "active"
vgchange -an $vg9
vgremove -y $vg9
mdadm --stop "$mddev"
aux udev_wait
wipe_all
systemctl stop lvm-activate-$vg1
systemctl stop lvm-activate-$vg2
systemctl stop lvm-activate-$vg3
systemctl stop lvm-activate-$vg4
systemctl stop lvm-activate-$vg5
systemctl stop lvm-activate-$vg6
systemctl stop lvm-activate-$vg7
systemctl stop lvm-activate-$vg8
systemctl stop lvm-activate-$vg9
# no devices file, filter with symlink of PV
# the pvscan needs to look at all dev names to
# match the symlink in the filter with the
# dev name (or major minor) passed to pvscan.
# This test doesn't really belong in this file
# because it's not testing lvm-activate.
aux lvmconf 'devices/use_devicesfile = 0'
_clear_online_files
rm "$DF"
vgcreate $vg10 "$dev1"
lvcreate -l1 -an -n $lv1 $vg10 "$dev1"
PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
# PVID with dashes
OPVID1=`pvs "$dev1" --noheading -o uuid | awk '{print $1}'`
udevadm trigger --settle -c add /sys/block/$BDEV1
# uevent from the trigger should create this symlink
ls /dev/disk/by-id/lvm-pv-uuid-$OPVID1
vgchange -an $vg10
systemctl stop lvm-activate-$vg10
_clear_online_files
aux lvmconf "devices/filter = [ \"a|/dev/disk/by-id/lvm-pv-uuid-$OPVID1|\", \"r|.*|\" ]"
aux lvmconf 'devices/global_filter = [ "a|.*|" ]'
pvscan --cache -aay "$dev1"
check lv_field $vg10/$lv1 lv_active "active"
vgchange -an $vg10
_clear_online_files
aux lvmconf 'devices/filter = [ "a|lvm-pv-uuid|", "r|.*|" ]'
aux lvmconf 'devices/global_filter = [ "a|.*|" ]'
pvscan --cache -aay "$dev1"
check lv_field $vg10/$lv1 lv_active "active"
vgchange -an $vg10
vgremove -y $vg10
wipe_all