1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-22 17:35:59 +03:00
lvm2/test/shell/udev-pvscan-vgchange.sh

542 lines
13 KiB
Bash
Raw Normal View History

#!/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
# FIXME: currently test relies on several system properties to be
# explcitely configure and directly modifies their state
#
# $ 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
skip "LVM_TEST_DEVICE_LIST is unset"
else
echo "LVM_TEST_DEVICE_LIST is set to '$LVM_TEST_DEVICE_LIST'"
fi
test -e "$LVM_TEST_DEVICE_LIST" || skip
num_devs=$(wc -l < "$LVM_TEST_DEVICE_LIST")
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
rm status || true
# time for service to be started
sleep 1
while systemctl status lvm-activate-$vgw |tee status && test "$wait" -le 30; do
sleep .2
wait=$(( wait + 1 ))
done
cat status || true
}
# 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" || true
ls "$RUNDIR/lvm/vgs_online/$vg1" || true
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
find "$RUNDIR/lvm"
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 -c active)
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
wipe_all
rm "$DF"
touch "$DF"
aux mdadm_create --metadata=1.0 --level 1 --chunk=64 --raid-devices=2 "$dev1" "$dev2"
mddev=$(< MD_DEV)
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"
_clear_online_files
aux 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
# 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
_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
aux lvmconf 'devices/filter = [ "a|.*|" ]'
aux lvmconf 'devices/global_filter = [ "a|.*|" ]'
#
# system.devices contains different product_uuid and incorrect device IDs
#
SYS_DIR="$PWD/test/sys"
aux lvmconf "devices/use_devicesfile = 1" \
"devices/device_id_sysfs_dir = \"$SYS_DIR/\""
WWID1="naa.111"
WWID2="naa.222"
PRODUCT_UUID1="11111111-2222-3333-4444-555555555555"
PRODUCT_UUID2="11111111-2222-3333-4444-666666666666"
vgcreate $vg11 "$dev1"
lvcreate -l1 -an -n $lv1 $vg11 "$dev1"
eval "$(pvs --noheading --nameprefixes -o major,minor,uuid "$dev1")"
MAJOR1=$LVM2_PV_MAJOR
MINOR1=$LVM2_PV_MINOR
OPVID1=$LVM2_PV_UUID
PVID1=${OPVID1//-/}
mkdir -p "$SYS_DIR/dev/block/$MAJOR1:$MINOR1/device"
echo "$WWID1" > "$SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid"
mkdir -p "$SYS_DIR/devices/virtual/dmi/id/"
echo "$PRODUCT_UUID1" > "$SYS_DIR/devices/virtual/dmi/id/product_uuid"
vgimportdevices $vg11
grep $PRODUCT_UUID1 "$DF"
grep $PVID1 "$DF"
grep $WWID1 "$DF"
grep "$dev1" "$DF"
# change wwid for dev1 and product_uuid for host
echo "$WWID2" > "$SYS_DIR/dev/block/$MAJOR1:$MINOR1/device/wwid"
echo "$PRODUCT_UUID2" > "$SYS_DIR/devices/virtual/dmi/id/product_uuid"
_clear_online_files
udevadm trigger --settle -c add "/sys/block/$BDEV1"
wait_lvm_activate $vg11
ls "$RUNDIR/lvm/vgs_online/$vg11"
journalctl -u lvm-activate-$vg11 | tee out || true
grep "now active" out
# Run ordinary command that will refresh device ID in system.devices
pvs -o+uuid | tee out
grep "$dev1" out
grep "$OPVID1" out
# check new wwid for dev1 and new product_uuid for host
cat "$DF"
grep $PRODUCT_UUID2 "$DF"
not grep $PRODUCT_UUID1 "$DF"
grep $PVID1 "$DF"
grep $WWID2 "$DF"
not grep $WWID1 "$DF"
grep "$dev1" "$DF"
check lv_field $vg11/$lv1 lv_active "active"
vgchange -an $vg11
vgremove -y $vg11
rm -rf "$SYS_DIR"
wipe_all