mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-22 17:35:59 +03:00
264827cb98
The new option "--fs String" for lvresize/lvreduce/lvextend controls the handling of file systems before/after resizing the LV. --resizefs is the same as --fs resize. The new option "--fsmode String" can be used to control mounting and unmounting of the fs during resizing. Possible --fs values: checksize Only applies to reducing size; does nothing for extend. Check the fs size and reduce the LV if the fs is not using the affected space, i.e. the fs does not need to be shrunk. Fail the command without reducing the fs or LV if the fs is using the affected space. resize Resize the fs using the fs-specific resize command. This may include mounting, unmounting, or running fsck. See --fsmode to control mounting behavior, and --nofsck to disable fsck. resize_fsadm Use the old method of calling fsadm to handle the fs (deprecated.) Warning: this option does not prevent lvreduce from destroying file systems that are unmounted (or mounted if prompts are skipped.) ignore Resize the LV without checking for or handling a file system. Warning: using ignore when reducing the LV size may destroy the file system. Possible --fsmode values: manage Mount or unmount the fs as needed to resize the fs, and attempt to restore the original mount state at the end. nochange Do not mount or unmount the fs. If mounting or unmounting is required to resize the fs, then do not resize the fs or the LV and fail the command. offline Unmount the fs if it is mounted, and resize the fs while it is unmounted. If mounting is required to resize the fs, then do not resize the fs or the LV and fail the command. Notes on lvreduce: When no --fs or --resizefs option is specified: . lvextend default behavior is fs ignore. . lvreduce default behavior is fs checksize (includes activating the LV.) With the exception of --fs resize_fsadm|ignore, lvreduce requires the recent libblkid fields FSLASTBLOCK and FSBLOCKSIZE. FSLASTBLOCK*FSBLOCKSIZE is the last byte used by the fs on the LV, which determines if reducing the fs is necessary.
478 lines
10 KiB
Bash
478 lines
10 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
# Copyright (C) 2012 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
|
|
|
|
SKIP_WITH_LVMPOLLD=1
|
|
|
|
# hints are currently disabled with lvmlockd
|
|
SKIP_WITH_LVMLOCKD=1
|
|
|
|
. lib/inittest
|
|
|
|
RUNDIR="/run"
|
|
test -d "$RUNDIR" || RUNDIR="/var/run"
|
|
HINTS="$RUNDIR/lvm/hints"
|
|
NOHINTS="$RUNDIR/lvm/nohints"
|
|
NEWHINTS="$RUNDIR/lvm/newhints"
|
|
PREV="$RUNDIR/lvm/prev-hints"
|
|
|
|
# TODO:
|
|
# Test commands that ignore hints
|
|
# Test flock
|
|
|
|
|
|
aux lvmconf 'devices/scan_lvs = 0'
|
|
|
|
aux prepare_devs 6
|
|
|
|
# no PVs yet so hints should have no devs
|
|
pvs
|
|
not grep scan: $HINTS
|
|
|
|
#
|
|
# test --nohints option
|
|
#
|
|
|
|
pvcreate "$dev1"
|
|
pvcreate "$dev2"
|
|
# pvs --nohints does not create hints
|
|
pvs --nohints |tee out
|
|
grep "$dev1" out
|
|
grep "$dev2" out
|
|
not grep "$dev1" $HINTS
|
|
not grep "$dev2" $HINTS
|
|
# pvs creates hints
|
|
pvs
|
|
grep "$dev1" $HINTS
|
|
grep "$dev2" $HINTS
|
|
|
|
# save hints with dev1 and dev2 before dev3 is created
|
|
cp $HINTS $PREV
|
|
# pvcreate --nohints invalidates hints
|
|
pvcreate --nohints "$dev3"
|
|
ls $NEWHINTS
|
|
# pvs --nohints does not update hints
|
|
pvs --nohints |tee out
|
|
grep "$dev1" out
|
|
grep "$dev2" out
|
|
grep "$dev3" out
|
|
not grep "$dev3" $HINTS
|
|
# restore old hint file without dev3
|
|
cp $PREV $HINTS
|
|
# pvs --nohints does not update hints
|
|
pvs --nohints |tee out
|
|
grep "$dev1" out
|
|
grep "$dev2" out
|
|
grep "$dev3" out
|
|
grep "$dev1" $HINTS
|
|
grep "$dev2" $HINTS
|
|
not grep "$dev3" $HINTS
|
|
# pvs updates hints
|
|
pvs |tee out
|
|
grep "$dev1" out
|
|
grep "$dev2" out
|
|
grep "$dev3" out
|
|
grep "$dev1" $HINTS
|
|
grep "$dev2" $HINTS
|
|
grep "$dev3" $HINTS
|
|
|
|
aux wipefs_a "$dev1"
|
|
aux wipefs_a "$dev2"
|
|
aux wipefs_a "$dev3"
|
|
|
|
#
|
|
# vg1 uses dev1,dev2
|
|
#
|
|
# Test basics that PVs are in hints, not non-PV devs,
|
|
# and that only PVs are scanned when using hints.
|
|
#
|
|
|
|
rm $HINTS
|
|
|
|
vgcreate $vg1 "$dev1" "$dev2"
|
|
lvcreate -n $lv1 -l 4 $vg1
|
|
|
|
# test that only the two PVs are in hints
|
|
pvs
|
|
grep -v -E "$dev1|$dev2" $HINTS > tmptest
|
|
not grep scan: tmptest
|
|
|
|
# test that 'pvs' submits only three reads, one for each PV in hints
|
|
# for initial scan, and one more in vg_read rescan check
|
|
|
|
if which strace; then
|
|
strace -e io_submit pvs 2>&1|tee tmptest
|
|
test "$(grep io_submit tmptest | wc -l)" -eq 3
|
|
|
|
# test that 'pvs -a' submits seven reads, one for each device,
|
|
# and one more in vg_read rescan check
|
|
strace -e io_submit pvs -a 2>&1|tee tmptest
|
|
test "$(grep io_submit tmptest | wc -l)" -eq 7
|
|
fi
|
|
|
|
#
|
|
# vg2 uses dev3,dev4
|
|
#
|
|
# Test common commands that cause hints to be refreshed:
|
|
# pvcreate/vgcreate/vgextend/vgreduce/vgremove/pvremove
|
|
#
|
|
|
|
not pvs "$dev3"
|
|
not grep "$dev3" $HINTS
|
|
cp $HINTS $PREV
|
|
pvcreate "$dev3"
|
|
grep "# Created empty" $HINTS
|
|
cat $NEWHINTS
|
|
# next cmd recreates hints
|
|
pvs "$dev3"
|
|
grep "$dev3" $HINTS
|
|
not diff $HINTS $PREV
|
|
not cat $NEWHINTS
|
|
|
|
not vgs $vg2
|
|
cp $HINTS $PREV
|
|
vgcreate $vg2 "$dev3"
|
|
grep "# Created empty" $HINTS
|
|
cat $NEWHINTS
|
|
# next cmd recreates hints
|
|
vgs $vg2
|
|
grep $vg2 $HINTS
|
|
not diff $HINTS $PREV
|
|
not cat $NEWHINTS
|
|
|
|
cp $HINTS $PREV
|
|
vgextend $vg2 "$dev4"
|
|
grep "# Created empty" $HINTS
|
|
cat $NEWHINTS
|
|
# next cmd recreates hints
|
|
vgs $vg2
|
|
grep "$dev4" $HINTS
|
|
not diff $HINTS $PREV
|
|
not cat $NEWHINTS
|
|
|
|
cp $HINTS $PREV
|
|
vgreduce $vg2 "$dev4"
|
|
grep "# Created empty" $HINTS
|
|
cat $NEWHINTS
|
|
# next cmd recreates hints
|
|
vgs $vg2
|
|
grep "$dev4" $HINTS
|
|
not diff $HINTS $PREV
|
|
not cat $NEWHINTS
|
|
|
|
cp $HINTS $PREV
|
|
vgremove $vg2
|
|
grep "# Created empty" $HINTS
|
|
cat $NEWHINTS
|
|
# next cmd recreates hints
|
|
not vgs $vg2
|
|
not grep $vg2 $HINTS
|
|
not diff $HINTS $PREV
|
|
not cat $NEWHINTS
|
|
|
|
cp $HINTS $PREV
|
|
pvremove "$dev3" "$dev4"
|
|
grep "# Created empty" $HINTS
|
|
cat $NEWHINTS
|
|
# next cmd recreates hints
|
|
not pvs "$dev3"
|
|
not pvs "$dev4"
|
|
not grep "$dev3" $HINTS
|
|
not grep "$dev4" $HINTS
|
|
not diff $HINTS $PREV
|
|
not cat $NEWHINTS
|
|
|
|
#
|
|
# Test that adding a new device and removing a device
|
|
# causes hints to be recreated.
|
|
#
|
|
# with a devices file the appearance of a new device on
|
|
# the system does not disturb lvm, so this test doesn't
|
|
# apply
|
|
#
|
|
|
|
if ! lvmdevices; then
|
|
|
|
not pvs "$dev5"
|
|
|
|
# create a new temp device that will cause hint hash to change
|
|
DEVNAME=${PREFIX}pv99
|
|
echo "0 $(blockdev --getsize "$dev5") linear $dev5 0" | dmsetup create $DEVNAME
|
|
dmsetup status $DEVNAME
|
|
|
|
cp $HINTS $PREV
|
|
# pvs ignores current hints because of different dev hash and refreshes new hints
|
|
pvs
|
|
# devs listed in hints before and after are the same
|
|
grep scan: $PREV > scan1
|
|
grep scan: $HINTS > scan2
|
|
diff scan1 scan2
|
|
# hash listed before and after are different
|
|
cat $PREV
|
|
cat $HINTS
|
|
grep devs_hash $PREV > devs_hash1
|
|
grep devs_hash $HINTS > devs_hash2
|
|
not diff devs_hash1 devs_hash2
|
|
|
|
# hints are stable/unchanging
|
|
cp $HINTS $PREV
|
|
pvs
|
|
diff $HINTS $PREV
|
|
|
|
# remove the temp device which will cause hint hash to change again
|
|
dmsetup remove $DEVNAME
|
|
|
|
cp $HINTS $PREV
|
|
# pvs ignores current hints because of different dev hash and refreshes new hints
|
|
pvs
|
|
# devs listed in hints before and after are the same
|
|
grep scan: $PREV > scan1
|
|
grep scan: $HINTS > scan2
|
|
diff scan1 scan2
|
|
# hash listed before and after are different
|
|
grep devs_hash $PREV > devs_hash1
|
|
grep devs_hash $HINTS > devs_hash2
|
|
not diff devs_hash1 devs_hash2
|
|
|
|
# end of new device test for non-devicesfile case
|
|
fi
|
|
|
|
#
|
|
# Test that hints don't change from a bunch of commands
|
|
# that use hints and shouldn't change it.
|
|
#
|
|
|
|
# first create some more metadata using vg2
|
|
pvcreate "$dev3" "$dev4"
|
|
vgcreate $vg2 "$dev3"
|
|
lvcreate -n $lv1 -l1 $vg2
|
|
lvcreate -n $lv2 -l1 $vg2
|
|
|
|
cp $HINTS $PREV
|
|
lvm fullreport
|
|
lvchange -ay $vg1
|
|
lvchange -an $vg1
|
|
lvcreate -l1 -n $lv2 $vg1
|
|
lvcreate -l1 -an -n $lv3 $vg1
|
|
lvchange -an $vg1
|
|
lvremove $vg1/$lv3
|
|
lvresize --fs ignore -l+1 $vg1/$lv2
|
|
lvresize --fs ignore -l-1 $vg1/$lv2
|
|
lvdisplay
|
|
pvdisplay
|
|
vgdisplay
|
|
lvs
|
|
pvs
|
|
vgs
|
|
vgchange -ay $vg2
|
|
vgchange -an $vg2
|
|
vgck $vg2
|
|
lvrename $vg1 $lv2 $lv3
|
|
# no change in hints after all that
|
|
diff $HINTS $PREV
|
|
|
|
#
|
|
# Test that changing the filter will cause hint refresh
|
|
#
|
|
|
|
rm $HINTS $PREV
|
|
vgs
|
|
cp $HINTS $PREV
|
|
# this changes the filter to exclude dev5 which is not a PV
|
|
aux hide_dev "$dev5"
|
|
# next cmd sees different filter, ignores hints, creates new hints
|
|
pvs
|
|
not diff $HINTS $PREV
|
|
# run cmds using new filter
|
|
pvs
|
|
cp $HINTS $PREV
|
|
vgs
|
|
# hints are stable once refreshed
|
|
diff $HINTS $PREV
|
|
# this changes the filter to include dev5
|
|
aux unhide_dev "$dev5"
|
|
# next cmd sees different filter, ignores hints, creates new hints
|
|
pvs
|
|
not diff $HINTS $PREV
|
|
# hints are stable
|
|
cp $HINTS $PREV
|
|
vgs
|
|
diff $HINTS $PREV
|
|
|
|
#
|
|
# Test that changing scan_lvs will cause hint refresh
|
|
#
|
|
|
|
rm $HINTS $PREV
|
|
vgs
|
|
cp $HINTS $PREV
|
|
# change lvm.conf
|
|
aux lvmconf 'devices/scan_lvs = 1'
|
|
# next cmd sees new setting, ignores hints, creates new hints
|
|
pvs
|
|
not diff $HINTS $PREV
|
|
# run cmds using new filter
|
|
pvs
|
|
cp $HINTS $PREV
|
|
vgs
|
|
# hints are stable once refreshed
|
|
diff $HINTS $PREV
|
|
# change lvm.conf back
|
|
aux lvmconf 'devices/scan_lvs = 0'
|
|
# next cmd sees different scan_lvs, ignores hints, creates new hints
|
|
pvs
|
|
not diff $HINTS $PREV
|
|
# hints are stable once refreshed
|
|
cp $HINTS $PREV
|
|
pvs
|
|
diff $HINTS $PREV
|
|
|
|
#
|
|
# Test pvscan --cache to force hints refresh
|
|
#
|
|
|
|
# pvs (no change), pvscan (hints are new), pvs (no change)
|
|
rm $HINTS $PREV
|
|
pvs
|
|
cp $HINTS $PREV
|
|
# this next pvscan recreates the hints file
|
|
pvscan --cache
|
|
# the only diff will be "Created by pvscan ..." vs "Created by pvs ..."
|
|
not diff $HINTS $PREV
|
|
cp $HINTS $PREV
|
|
pvs
|
|
diff $HINTS $PREV
|
|
grep 'Created by pvscan' $HINTS
|
|
# dev4 is a PV not used by a VG, dev5 is not a PV
|
|
# using dd to copy skirts hint tracking so dev5 won't be seen
|
|
# (unless the dd triggers udev which triggers pvscan --cache $dev5,
|
|
# but I've not seen that happen in tests so far.)
|
|
dd if="$dev4" of="$dev5" bs=1M
|
|
# this pvs won't see dev5
|
|
pvs > foo
|
|
cat foo
|
|
grep "$dev4" foo
|
|
not grep "$dev5" foo
|
|
# no hints have changed after dd and pvs since dd cannot be detected
|
|
diff $HINTS $PREV
|
|
# force hints refresh, will see duplicate now
|
|
pvscan --cache
|
|
not diff $HINTS $PREV
|
|
cat $HINTS
|
|
pvs -a > foo
|
|
# after force refresh, both devs (dups) appear in output
|
|
cat foo
|
|
grep "$dev4" foo
|
|
grep "$dev5" foo
|
|
# clear PV from dev5
|
|
dd if=/dev/zero of="$dev5" bs=1M count=1
|
|
# this pvs won't use hints because of duplicate PVs,
|
|
# and will create new hints
|
|
cp $HINTS $PREV
|
|
pvs > foo
|
|
not diff $HINTS $PREV
|
|
grep "$dev4" foo
|
|
not grep "$dev5" foo
|
|
grep "$dev4" $HINTS
|
|
not grep "$dev5" $HINTS
|
|
|
|
#
|
|
# Test pvscan --cache <dev> forces refresh
|
|
#
|
|
|
|
rm $HINTS $PREV
|
|
pvs
|
|
cp $HINTS $PREV
|
|
# this next pvscan creates newhints to trigger a refresh
|
|
pvscan --cache "$dev4"
|
|
cat $NEWHINTS
|
|
# this next pvs creates new hints
|
|
pvs
|
|
# the only diff will be "Created by..."
|
|
not diff $HINTS $PREV
|
|
|
|
|
|
#
|
|
# Test pvck --repair forces refresh
|
|
#
|
|
|
|
rm $HINTS $PREV
|
|
pvs
|
|
cp $HINTS $PREV
|
|
pvck --repairtype label_header -y "$dev3"
|
|
cat $NEWHINTS
|
|
grep 'Created empty by pvck' $HINTS
|
|
# this next pvs creates new hints
|
|
pvs
|
|
# the only diff will be "Created by..."
|
|
not diff $HINTS $PREV
|
|
|
|
|
|
#
|
|
# Test incorrect dev-to-pvid info in hints is detected
|
|
# dev4 is a PV not in a VG
|
|
#
|
|
|
|
pvs
|
|
cp $HINTS tmp-old
|
|
# this pvchange will invalidate current hints
|
|
pvchange -u "$dev4"
|
|
grep "# Created empty" $HINTS
|
|
cat $NEWHINTS
|
|
# this next pvs will create new hints with the new uuid
|
|
pvs
|
|
grep "$dev4" $HINTS > tmp-newuuid
|
|
cp $HINTS tmp-new
|
|
not diff tmp-old tmp-new
|
|
# hints are stable
|
|
pvs
|
|
diff $HINTS tmp-new
|
|
# replace the current hints with the old hints with the old uuid
|
|
cp tmp-old $HINTS
|
|
# this next pvs will see wrong dev-to-pvid mapping and invalidate hints
|
|
pvs
|
|
cat $HINTS
|
|
cat $NEWHINTS
|
|
# this next pvs will create new hints with the new uuid
|
|
pvs
|
|
cat $HINTS
|
|
grep -f tmp-newuuid $HINTS
|
|
rm tmp-old tmp-new tmp-newuuid
|
|
|
|
|
|
#
|
|
# Test incorrent pvid-to-vgname info in hints is detected
|
|
#
|
|
|
|
# this vgcreate invalidates current hints
|
|
vgcreate $vg3 "$dev4"
|
|
# this pvs creates new hints
|
|
pvs
|
|
cp $HINTS tmp-old
|
|
# this vgrename will invalidate current hints
|
|
vgrename $vg3 $vg4
|
|
# this pvs will create new hints with the new vg name
|
|
pvs
|
|
cp $HINTS tmp-new
|
|
not diff tmp-old tmp-new
|
|
# replace the current hints with the old hints with the old vg name
|
|
cp tmp-old $HINTS
|
|
# this pvs will see wrong pvid-to-vgname mapping and invalidate hints
|
|
pvs
|
|
cat $NEWHINTS
|
|
# this pvs will create new hints with the new vg name
|
|
pvs
|
|
grep $vg4 $HINTS
|
|
|
|
vgremove -y $vg4
|
|
vgremove -y $vg2
|
|
vgremove -y $vg1
|