mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-22 17:35:59 +03:00
25b58310e3
When an online PV completed a VG, the standard activation functions were used to activate the VG. These functions use a full scan of all devs. When many pvscans are run during startup and need to activate many VGs, scanning all devs from all the pvscans can take a long time. Optimize VG activation in pvscan to scan only the devs in the VG being activated. This makes use of the online file info that was used to determine the VG was complete. The downside of this approach is that pvscan activation will not detect duplicate PVs and block activation, where a normal activation command (which scans all devices) would.
343 lines
6.8 KiB
Bash
343 lines
6.8 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# Copyright (C) 2008-2013,2018 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
|
|
|
|
RUNDIR="/run"
|
|
test -d "$RUNDIR" || RUNDIR="/var/run"
|
|
PVS_ONLINE_DIR="$RUNDIR/lvm/pvs_online"
|
|
VGS_ONLINE_DIR="$RUNDIR/lvm/vgs_online"
|
|
|
|
_clear_online_files() {
|
|
# wait till udev is finished
|
|
aux udev_wait
|
|
rm -f "$PVS_ONLINE_DIR"/*
|
|
rm -f "$VGS_ONLINE_DIR"/*
|
|
}
|
|
|
|
. lib/inittest
|
|
|
|
aux prepare_devs 3
|
|
get_devs
|
|
|
|
dd if=/dev/zero of="$dev1" || true
|
|
dd if=/dev/zero of="$dev2" || true
|
|
dd if=/dev/zero of="$dev3" || true
|
|
|
|
vgcreate $SHARED $vg "$dev1" "$dev2" "$dev3"
|
|
|
|
pvs
|
|
|
|
dd if="$dev1" of=meta1 bs=4k count=2
|
|
|
|
sed 's/flags =/flagx =/' meta1 > meta1.bad
|
|
|
|
dd if=meta1.bad of="$dev1"
|
|
|
|
pvs 2>&1 | tee out
|
|
grep "bad metadata text" out
|
|
|
|
pvs "$dev1"
|
|
pvs "$dev2"
|
|
pvs "$dev3"
|
|
|
|
# bad metadata in one mda doesn't prevent using
|
|
# the VG since other mdas are fine and usable
|
|
lvcreate -l1 $vg
|
|
|
|
|
|
vgck --updatemetadata $vg
|
|
|
|
pvs 2>&1 | tee out
|
|
not grep "bad metadata text" out
|
|
|
|
pvs "$dev1"
|
|
pvs "$dev2"
|
|
pvs "$dev3"
|
|
|
|
vgchange -an $vg
|
|
vgremove -ff $vg
|
|
|
|
|
|
#
|
|
# Same test as above, but corrupt metadata text
|
|
# on two of the three PVs, leaving one good
|
|
# copy of the metadata.
|
|
#
|
|
|
|
dd if=/dev/zero of="$dev1" || true
|
|
dd if=/dev/zero of="$dev2" || true
|
|
dd if=/dev/zero of="$dev3" || true
|
|
|
|
vgcreate $SHARED $vg "$dev1" "$dev2" "$dev3"
|
|
|
|
pvs
|
|
|
|
dd if="$dev1" of=meta1 bs=4k count=2
|
|
dd if="$dev2" of=meta2 bs=4k count=2
|
|
|
|
sed 's/READ/RRRR/' meta1 > meta1.bad
|
|
sed 's/seqno =/sss =/' meta2 > meta2.bad
|
|
|
|
dd if=meta1.bad of="$dev1"
|
|
dd if=meta2.bad of="$dev2"
|
|
|
|
pvs 2>&1 | tee out
|
|
grep "bad metadata text" out > out2
|
|
grep "$dev1" out2
|
|
grep "$dev2" out2
|
|
|
|
pvs "$dev1"
|
|
pvs "$dev2"
|
|
pvs "$dev3"
|
|
|
|
# bad metadata in one mda doesn't prevent using
|
|
# the VG since other mdas are fine
|
|
lvcreate -l1 $vg
|
|
|
|
|
|
vgck --updatemetadata $vg
|
|
|
|
pvs 2>&1 | tee out
|
|
not grep "bad metadata text" out
|
|
|
|
pvs "$dev1"
|
|
pvs "$dev2"
|
|
pvs "$dev3"
|
|
|
|
vgchange -an $vg
|
|
vgremove -ff $vg
|
|
|
|
#
|
|
# Three PVs where two have one mda, and the third
|
|
# has two mdas. The first mda is corrupted on all
|
|
# thee PVs, but the second mda on the third PV
|
|
# makes the VG usable.
|
|
#
|
|
|
|
dd if=/dev/zero of="$dev1" || true
|
|
dd if=/dev/zero of="$dev2" || true
|
|
dd if=/dev/zero of="$dev3" || true
|
|
|
|
pvcreate "$dev1"
|
|
pvcreate "$dev2"
|
|
pvcreate --pvmetadatacopies 2 "$dev3"
|
|
|
|
vgcreate $SHARED $vg "$dev1" "$dev2" "$dev3"
|
|
|
|
pvs
|
|
|
|
dd if="$dev1" of=meta1 bs=4k count=2
|
|
dd if="$dev2" of=meta2 bs=4k count=2
|
|
dd if="$dev3" of=meta3 bs=4k count=2
|
|
|
|
sed 's/READ/RRRR/' meta1 > meta1.bad
|
|
sed 's/seqno =/sss =/' meta2 > meta2.bad
|
|
sed 's/id =/id/' meta3 > meta3.bad
|
|
|
|
dd if=meta1.bad of="$dev1"
|
|
dd if=meta2.bad of="$dev2"
|
|
dd if=meta3.bad of="$dev3"
|
|
|
|
pvs 2>&1 | tee out
|
|
grep "bad metadata text" out > out2
|
|
grep "$dev1" out2
|
|
grep "$dev2" out2
|
|
grep "$dev3" out2
|
|
|
|
pvs "$dev1"
|
|
pvs "$dev2"
|
|
pvs "$dev3"
|
|
|
|
# bad metadata in some mdas doesn't prevent using
|
|
# the VG if there's a good mda found
|
|
lvcreate -l1 $vg
|
|
|
|
|
|
vgck --updatemetadata $vg
|
|
|
|
pvs 2>&1 | tee out
|
|
not grep "bad metadata text" out
|
|
|
|
pvs "$dev1"
|
|
pvs "$dev2"
|
|
pvs "$dev3"
|
|
|
|
vgchange -an $vg
|
|
vgremove -ff $vg
|
|
|
|
#
|
|
# Test that vgck --updatemetadata will update old metadata
|
|
# and repair bad metadata text at the same time from different
|
|
# devices.
|
|
#
|
|
|
|
dd if=/dev/zero of="$dev1" || true
|
|
dd if=/dev/zero of="$dev2" || true
|
|
dd if=/dev/zero of="$dev3" || true
|
|
|
|
pvcreate "$dev1"
|
|
pvcreate "$dev2"
|
|
pvcreate --pvmetadatacopies 2 "$dev3"
|
|
|
|
vgcreate $SHARED $vg "$dev1" "$dev2" "$dev3"
|
|
|
|
# Put bad metadata onto dev1
|
|
dd if="$dev1" of=meta1 bs=4k count=2
|
|
sed 's/READ/RRRR/' meta1 > meta1.bad
|
|
dd if=meta1.bad of="$dev1"
|
|
|
|
pvs 2>&1 | tee out
|
|
grep "bad metadata text" out > out2
|
|
grep "$dev1" out2
|
|
|
|
# We can still use the VG with other available
|
|
# mdas, skipping the bad mda.
|
|
|
|
lvcreate -n $lv1 -l1 -an $vg "$dev1"
|
|
lvcreate -n $lv2 -l1 -an $vg "$dev1"
|
|
|
|
# Put old metadata onto dev2 by updating
|
|
# the VG while dev2 is disabled.
|
|
aux disable_dev "$dev2"
|
|
|
|
pvs
|
|
pvs "$dev1"
|
|
not pvs "$dev2"
|
|
pvs "$dev3"
|
|
lvs $vg/$lv1
|
|
lvs $vg/$lv2
|
|
|
|
lvremove $vg/$lv2
|
|
|
|
aux enable_dev "$dev2"
|
|
|
|
# Both old and bad metadata are reported.
|
|
pvs 2>&1 | tee out
|
|
grep "ignoring metadata seqno" out
|
|
grep "bad metadata text" out
|
|
pvs "$dev1"
|
|
pvs "$dev2"
|
|
pvs "$dev3"
|
|
|
|
lvs $vg/$lv1
|
|
not lvs $vg/$lv2
|
|
|
|
# fixes the bad metadata on dev1, and
|
|
# fixes the old metadata on dev2.
|
|
vgck --updatemetadata $vg
|
|
|
|
pvs 2>&1 | tee out
|
|
not grep "ignoring metadata seqno" out
|
|
not grep "bad metadata text" out
|
|
pvs "$dev1"
|
|
pvs "$dev2"
|
|
pvs "$dev3"
|
|
|
|
lvs $vg/$lv1
|
|
|
|
vgchange -an $vg
|
|
vgremove -ff $vg
|
|
|
|
#
|
|
# Test pvscan activation with bad PVs
|
|
#
|
|
|
|
dd if=/dev/zero of="$dev1" || true
|
|
dd if=/dev/zero of="$dev2" || true
|
|
dd if=/dev/zero of="$dev3" || true
|
|
|
|
vgcreate $SHARED $vg "$dev1" "$dev2" "$dev3"
|
|
|
|
PVID1=`pvs $dev1 --noheading -o uuid | tr -d - | awk '{print $1}'`
|
|
echo $PVID1
|
|
PVID2=`pvs $dev2 --noheading -o uuid | tr -d - | awk '{print $1}'`
|
|
echo $PVID2
|
|
PVID3=`pvs $dev3 --noheading -o uuid | tr -d - | awk '{print $1}'`
|
|
echo $PVID3
|
|
|
|
pvs
|
|
|
|
dd if="$dev1" of=meta1 bs=4k count=2
|
|
dd if="$dev2" of=meta2 bs=4k count=2
|
|
|
|
sed 's/READ/RRRR/' meta1 > meta1.bad
|
|
sed 's/seqno =/sss =/' meta2 > meta2.bad
|
|
|
|
dd if=meta1.bad of="$dev1"
|
|
dd if=meta2.bad of="$dev2"
|
|
|
|
pvs 2>&1 | tee out
|
|
grep "bad metadata text" out > out2
|
|
grep "$dev1" out2
|
|
grep "$dev2" out2
|
|
|
|
pvs "$dev1"
|
|
pvs "$dev2"
|
|
pvs "$dev3"
|
|
|
|
# bad metadata in one mda doesn't prevent using
|
|
# the VG since other mdas are fine
|
|
lvcreate -l1 -n $lv1 $vg
|
|
|
|
vgchange -an $vg
|
|
|
|
_clear_online_files
|
|
|
|
# pvscan of one dev with bad metadata will result
|
|
# in the dev acting like a PV without metadata,
|
|
# which causes pvscan to scan all devs to find the
|
|
# VG it belongs to. In this case it finds all the
|
|
# other devs in the VG are online and activates the
|
|
# VG.
|
|
pvscan --cache -aay "$dev1"
|
|
ls "$RUNDIR/lvm/pvs_online/$PVID1"
|
|
ls "$RUNDIR/lvm/pvs_online/$PVID2"
|
|
ls "$RUNDIR/lvm/pvs_online/$PVID3"
|
|
ls "$RUNDIR/lvm/vgs_online/$vg"
|
|
|
|
lvs $vg
|
|
check lv_field $vg/$lv1 lv_active "active"
|
|
vgchange -an $vg
|
|
|
|
_clear_online_files
|
|
|
|
# scan the one pv with good metadata, does not scan any others
|
|
pvscan --cache -aay "$dev3"
|
|
not ls "$RUNDIR/lvm/pvs_online/$PVID1"
|
|
not ls "$RUNDIR/lvm/pvs_online/$PVID2"
|
|
ls "$RUNDIR/lvm/pvs_online/$PVID3"
|
|
not ls "$RUNDIR/lvm/vgs_online/$vg"
|
|
|
|
# scan the next pv with bad metadata, causes pvscan to scan
|
|
# and find all PVs and activate
|
|
pvscan --cache -aay "$dev2"
|
|
ls "$RUNDIR/lvm/pvs_online/$PVID1"
|
|
ls "$RUNDIR/lvm/pvs_online/$PVID2"
|
|
ls "$RUNDIR/lvm/pvs_online/$PVID3"
|
|
ls "$RUNDIR/lvm/vgs_online/$vg"
|
|
|
|
check lv_field $vg/$lv1 lv_active "active"
|
|
vgchange -an $vg
|
|
|
|
|
|
vgck --updatemetadata $vg
|
|
|
|
pvs 2>&1 | tee out
|
|
not grep "bad metadata text" out
|
|
|
|
pvs "$dev1"
|
|
pvs "$dev2"
|
|
pvs "$dev3"
|
|
|
|
vgchange -an $vg
|
|
vgremove -ff $vg
|
|
|