Compare commits

...

No commits in common. "c8" and "c9-beta" have entirely different histories.
c8 ... c9-beta

133 changed files with 2374 additions and 16925 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/LVM2.2.03.14.tgz
SOURCES/LVM2.2.03.21.tgz

View File

@ -1 +1 @@
e5d4364e823d72b9a08b3aecc13cd677972830f0 SOURCES/LVM2.2.03.14.tgz
b6d4a84bf1f0306f43f447c7531021d5c126edbf SOURCES/LVM2.2.03.21.tgz

View File

@ -1,545 +0,0 @@
From 63c4458aaf67d114c677baf657a7e9e43440f349 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 20 Dec 2021 14:22:02 -0600
Subject: [PATCH 01/54] Revert "new udev autoactivation"
This reverts commit 67722b312390cdab29c076c912e14bd739c5c0f6.
---
scripts/Makefile.in | 1 +
test/shell/udev-pvscan-vgchange.sh | 403 -----------------------------
udev/69-dm-lvm.rules.in | 87 -------
udev/Makefile.in | 2 +-
5 files changed, 4 insertions(+), 492 deletions(-)
delete mode 100644 test/shell/udev-pvscan-vgchange.sh
delete mode 100644 udev/69-dm-lvm.rules.in
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
index 0d7f45680..ee0acb6f6 100644
--- a/scripts/Makefile.in
+++ b/scripts/Makefile.in
@@ -92,6 +92,7 @@ install_systemd_generators:
install_systemd_units: install_dbus_service
@echo " [INSTALL] systemd_units"
$(Q) $(INSTALL_DIR) $(systemd_unit_dir)
+ $(Q) $(INSTALL_DATA) lvm2-pvscan.service $(systemd_unit_dir)/lvm2-pvscan@.service
ifeq ("@BUILD_DMEVENTD@", "yes")
$(Q) $(INSTALL_DATA) dm_event_systemd_red_hat.socket $(systemd_unit_dir)/dm-event.socket
$(Q) $(INSTALL_DATA) dm_event_systemd_red_hat.service $(systemd_unit_dir)/dm-event.service
diff --git a/test/shell/udev-pvscan-vgchange.sh b/test/shell/udev-pvscan-vgchange.sh
deleted file mode 100644
index c81acf0ce..000000000
--- a/test/shell/udev-pvscan-vgchange.sh
+++ /dev/null
@@ -1,403 +0,0 @@
-#!/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
-}
-
-# udevadm trigger runs udev rule which runs systemd-run --no-wait vgchange -aay
-# Because of --no-wait, we need to wait for the transient systemd
-# service to be gone before checking the effects of the vgchange.
-
-wait_lvm_activate() {
- local vgw=$1
- local wait=0
-
- while systemctl status lvm-activate-$vgw > /dev/null && 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_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"
-
-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
-
-_clear_online_files
-
-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
-
diff --git a/udev/69-dm-lvm.rules.in b/udev/69-dm-lvm.rules.in
deleted file mode 100644
index 39e5b9807..000000000
--- a/udev/69-dm-lvm.rules.in
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (C) 2012,2021 Red Hat, Inc. All rights reserved.
-#
-# This file is part of LVM.
-#
-# This rule requires blkid to be called on block devices before so only devices
-# used as LVM PVs are processed (ID_FS_TYPE="LVM2_member").
-
-SUBSYSTEM!="block", GOTO="lvm_end"
-(LVM_EXEC_RULE)
-
-ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="lvm_end"
-
-# Only process devices already marked as a PV - this requires blkid to be called before.
-ENV{ID_FS_TYPE}!="LVM2_member", GOTO="lvm_end"
-ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="lvm_end"
-ACTION=="remove", GOTO="lvm_end"
-
-# Create /dev/disk/by-id/lvm-pv-uuid-<PV_UUID> symlink for each PV
-ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-id/lvm-pv-uuid-$env{ID_FS_UUID_ENC}"
-
-# If the PV is a special device listed below, scan only if the device is
-# properly activated. These devices are not usable after an ADD event,
-# but they require an extra setup and they are ready after a CHANGE event.
-# Also support coldplugging with ADD event but only if the device is already
-# properly activated.
-# This logic should be eventually moved to rules where those particular
-# devices are processed primarily (MD and loop).
-
-# DM device:
-KERNEL!="dm-[0-9]*", GOTO="next"
-ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}=="1", GOTO="lvm_scan"
-GOTO="lvm_end"
-
-# MD device:
-LABEL="next"
-KERNEL!="md[0-9]*", GOTO="next"
-IMPORT{db}="LVM_MD_PV_ACTIVATED"
-ACTION=="add", ENV{LVM_MD_PV_ACTIVATED}=="1", GOTO="lvm_scan"
-ACTION=="change", ENV{LVM_MD_PV_ACTIVATED}!="1", TEST=="md/array_state", ENV{LVM_MD_PV_ACTIVATED}="1", GOTO="lvm_scan"
-ACTION=="add", KERNEL=="md[0-9]*p[0-9]*", GOTO="lvm_scan"
-ENV{LVM_MD_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0"
-GOTO="lvm_end"
-
-# Loop device:
-LABEL="next"
-KERNEL!="loop[0-9]*", GOTO="next"
-ACTION=="add", ENV{LVM_LOOP_PV_ACTIVATED}=="1", GOTO="lvm_scan"
-ACTION=="change", ENV{LVM_LOOP_PV_ACTIVATED}!="1", TEST=="loop/backing_file", ENV{LVM_LOOP_PV_ACTIVATED}="1", GOTO="lvm_scan"
-ENV{LVM_LOOP_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0"
-GOTO="lvm_end"
-
-LABEL="next"
-ACTION!="add", GOTO="lvm_end"
-
-LABEL="lvm_scan"
-
-ENV{SYSTEMD_READY}="1"
-
-# pvscan will check if this device completes a VG,
-# i.e. all PVs in the VG are now present with the
-# arrival of this PV. If so, it prints to stdout:
-# LVM_VG_NAME_COMPLETE='foo'
-#
-# When the VG is complete it can be activated, so
-# vgchange -aay <vgname> is run. It is run via
-# systemd since it can take longer to run than
-# udev wants to block when processing rules.
-# (if there are hundreds of LVs to activate,
-# the vgchange can take many seconds.)
-#
-# pvscan only reads the single device specified,
-# and uses temp files under /run/lvm to check if
-# other PVs in the VG are present.
-#
-# If event_activation=0 in lvm.conf, this pvscan
-# (using checkcomplete) will do nothing, so that
-# no event-based autoactivation will be happen.
-#
-# TODO: adjust the output of vgchange -aay so that
-# it's better suited to appearing in the journal.
-
-IMPORT{program}="(LVM_EXEC)/lvm pvscan --cache --listvg --checkcomplete --vgonline --udevoutput --journal=output $env{DEVNAME}"
-ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemd-run -r --no-block --property DefaultDependencies=no --unit lvm-activate-$env{LVM_VG_NAME_COMPLETE} lvm vgchange -aay --nohints $env{LVM_VG_NAME_COMPLETE}"
-GOTO="lvm_end"
-
-LABEL="lvm_end"
-
diff --git a/udev/Makefile.in b/udev/Makefile.in
index e777dda16..e32cba921 100644
--- a/udev/Makefile.in
+++ b/udev/Makefile.in
@@ -18,7 +18,7 @@ top_builddir = @top_builddir@
include $(top_builddir)/make.tmpl
DM_RULES=10-dm.rules 13-dm-disk.rules 95-dm-notify.rules
-LVM_RULES=11-dm-lvm.rules 69-dm-lvm.rules
+LVM_RULES=11-dm-lvm.rules 69-dm-lvm-metad.rules
DM_DIR=$(shell $(GREP) "\#define DM_DIR" $(top_srcdir)/libdm/misc/dm-ioctl.h | $(AWK) '{print $$3}')
--
2.34.3

View File

@ -0,0 +1,84 @@
From ecea7b14c453a58831f2dda5a0aa869ee4601dff Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 24 Apr 2023 15:47:45 -0500
Subject: [PATCH 1/2] fix dev_name use in add_areas_line
This function was relying on dev_name() returning NULL
to indicate no device, but dev_name never returns NULL.
(cherry picked from commit 31cfcf7ce9aab5dd16ba15e48bfe33be849fad4c)
---
lib/activate/dev_manager.c | 45 ++++++++++++++++++++++++--------------
1 file changed, 29 insertions(+), 16 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 07d58733e..ac3f01718 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -3000,34 +3000,47 @@ static int _add_error_area(struct dev_manager *dm, struct dm_tree_node *node,
return 1;
}
+static int _bad_pv_area(struct lv_segment *seg, uint32_t s)
+{
+ struct stat info;
+ const char *name;
+ struct device *dev;
+
+ if (!seg_pvseg(seg, s))
+ return 1;
+ if (!seg_pv(seg, s))
+ return 1;
+ if (!(dev = seg_dev(seg, s)))
+ return 1;
+ if (dm_list_empty(&dev->aliases))
+ return 1;
+ /* FIXME Avoid repeating identical stat in dm_tree_node_add_target_area */
+ name = dev_name(dev);
+ if (stat(name, &info) < 0)
+ return 1;
+ if (!S_ISBLK(info.st_mode))
+ return 1;
+ return 0;
+}
+
int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
struct dm_tree_node *node, uint32_t start_area,
uint32_t areas)
{
+ struct cmd_context *cmd = seg->lv->vg->cmd;
uint64_t extent_size = seg->lv->vg->extent_size;
uint32_t s;
char *dlid;
- struct stat info;
const char *name;
unsigned num_error_areas = 0;
unsigned num_existing_areas = 0;
- /* FIXME Avoid repeating identical stat in dm_tree_node_add_target_area */
for (s = start_area; s < areas; s++) {
-
- /* FIXME: dev_name() does not return NULL! It needs to check if dm_list_empty(&dev->aliases)
- but this knot of logic is too complex to pull apart without careful deconstruction. */
-
- if ((seg_type(seg, s) == AREA_PV &&
- (!seg_pvseg(seg, s) || !seg_pv(seg, s) || !seg_dev(seg, s) ||
- !(name = dev_name(seg_dev(seg, s))) || !*name ||
- stat(name, &info) < 0 || !S_ISBLK(info.st_mode))) ||
- (seg_type(seg, s) == AREA_LV && !seg_lv(seg, s))) {
- if (!seg->lv->vg->cmd->partial_activation) {
- if (!seg->lv->vg->cmd->degraded_activation ||
- !lv_is_raid_type(seg->lv)) {
- log_error("Aborting. LV %s is now incomplete "
- "and '--activationmode partial' was not specified.",
+ if (((seg_type(seg, s) == AREA_PV) && _bad_pv_area(seg, s)) ||
+ ((seg_type(seg, s) == AREA_LV) && !seg_lv(seg, s))) {
+ if (!cmd->partial_activation) {
+ if (!cmd->degraded_activation || !lv_is_raid_type(seg->lv)) {
+ log_error("Aborting. LV %s is incomplete and --activationmode partial was not specified.",
display_lvname(seg->lv));
return 0;
}
--
2.40.1

View File

@ -1,450 +0,0 @@
From 2091305b796d5552fd991c527a0359a0b4d8fde0 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Mon, 20 Dec 2021 13:38:23 -0600
Subject: [PATCH 02/54] Revert "pvscan: only add device args to dev cache"
This reverts commit 33e47182f773c1a902b533580b63a803906de55d.
---
lib/device/dev-cache.c | 204 +++-----------------------------
lib/device/dev-cache.h | 6 +-
lib/device/device_id.c | 27 ++---
lib/device/device_id.h | 1 -
test/shell/devicesfile-basic.sh | 2 +-
tools/pvscan.c | 58 ++++-----
6 files changed, 52 insertions(+), 246 deletions(-)
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 33b75a9a9..c6e5f68cf 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1852,7 +1852,7 @@ int setup_devices_file(struct cmd_context *cmd)
* Add all system devices to dev-cache, and attempt to
* match all devices_file entries to dev-cache entries.
*/
-int setup_devices(struct cmd_context *cmd)
+static int _setup_devices(struct cmd_context *cmd, int no_file_match)
{
int file_exists;
int lock_mode = 0;
@@ -1979,6 +1979,13 @@ int setup_devices(struct cmd_context *cmd)
*/
dev_cache_scan(cmd);
+ /*
+ * The caller uses "no_file_match" if it wants to match specific devs
+ * itself, instead of matching everything in device_ids_match.
+ */
+ if (no_file_match && cmd->enable_devices_file)
+ return 1;
+
/*
* Match entries from cmd->use_devices with device structs in dev-cache.
*/
@@ -1987,6 +1994,16 @@ int setup_devices(struct cmd_context *cmd)
return 1;
}
+int setup_devices(struct cmd_context *cmd)
+{
+ return _setup_devices(cmd, 0);
+}
+
+int setup_devices_no_file_match(struct cmd_context *cmd)
+{
+ return _setup_devices(cmd, 1);
+}
+
/*
* The alternative to setup_devices() when the command is interested
* in using only one PV.
@@ -2055,188 +2072,3 @@ int setup_device(struct cmd_context *cmd, const char *devname)
return 1;
}
-/*
- * pvscan --cache is specialized/optimized to look only at command args,
- * so this just sets up the devices file, then individual devices are
- * added to dev-cache and matched with device_ids later in pvscan.
- */
-
-int setup_devices_for_pvscan_cache(struct cmd_context *cmd)
-{
- if (cmd->enable_devices_list) {
- if (!_setup_devices_list(cmd))
- return_0;
- return 1;
- }
-
- if (!setup_devices_file(cmd))
- return_0;
-
- if (!cmd->enable_devices_file)
- return 1;
-
- if (!devices_file_exists(cmd)) {
- log_debug("Devices file not found, ignoring.");
- cmd->enable_devices_file = 0;
- return 1;
- }
-
- if (!lock_devices_file(cmd, LOCK_SH)) {
- log_error("Failed to lock the devices file to read.");
- return 0;
- }
-
- if (!device_ids_read(cmd)) {
- log_error("Failed to read the devices file.");
- unlock_devices_file(cmd);
- return 0;
- }
-
- unlock_devices_file(cmd);
- return 1;
-}
-
-
-/* Get a device name from a devno. */
-
-static char *_get_devname_from_devno(struct cmd_context *cmd, dev_t devno)
-{
- char path[PATH_MAX];
- char devname[PATH_MAX];
- char namebuf[NAME_LEN];
- char line[1024];
- int major = MAJOR(devno);
- int minor = MINOR(devno);
- int line_major;
- int line_minor;
- uint64_t line_blocks;
- DIR *dir;
- struct dirent *dirent;
- FILE *fp;
-
- /*
- * $ ls /sys/dev/block/8:0/device/block/
- * sda
- */
- if (major_is_scsi_device(cmd->dev_types, major)) {
- if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/device/block",
- dm_sysfs_dir(), major, minor) < 0) {
- return NULL;
- }
-
- if (!(dir = opendir(path)))
- return NULL;
-
- while ((dirent = readdir(dir))) {
- if (dirent->d_name[0] == '.')
- continue;
- if (dm_snprintf(devname, sizeof(devname), "/dev/%s", dirent->d_name) < 0) {
- devname[0] = '\0';
- stack;
- }
- break;
- }
- closedir(dir);
-
- if (devname[0]) {
- log_debug("Found %s for %d:%d from sys", devname, major, minor);
- return _strdup(devname);
- }
- return NULL;
- }
-
- /*
- * $ cat /sys/dev/block/253:3/dm/name
- * mpatha
- */
- if (major == cmd->dev_types->device_mapper_major) {
- if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/dm/name",
- dm_sysfs_dir(), major, minor) < 0) {
- return NULL;
- }
-
- if (!get_sysfs_value(path, namebuf, sizeof(namebuf), 0))
- return NULL;
-
- if (dm_snprintf(devname, sizeof(devname), "/dev/mapper/%s", namebuf) < 0) {
- devname[0] = '\0';
- stack;
- }
-
- if (devname[0]) {
- log_debug("Found %s for %d:%d from sys", devname, major, minor);
- return _strdup(devname);
- }
- return NULL;
- }
-
- /*
- * /proc/partitions lists
- * major minor #blocks name
- */
-
- if (!(fp = fopen("/proc/partitions", "r")))
- return NULL;
-
- while (fgets(line, sizeof(line), fp)) {
- if (sscanf(line, "%u %u %llu %s", &line_major, &line_minor, (unsigned long long *)&line_blocks, namebuf) != 4)
- continue;
- if (line_major != major)
- continue;
- if (line_minor != minor)
- continue;
-
- if (dm_snprintf(devname, sizeof(devname), "/dev/%s", namebuf) < 0) {
- devname[0] = '\0';
- stack;
- }
- break;
- }
- fclose(fp);
-
- if (devname[0]) {
- log_debug("Found %s for %d:%d from proc", devname, major, minor);
- return _strdup(devname);
- }
-
- /*
- * If necessary, this could continue searching by stat'ing /dev entries.
- */
-
- return NULL;
-}
-
-int setup_devname_in_dev_cache(struct cmd_context *cmd, const char *devname)
-{
- struct stat buf;
- struct device *dev;
-
- if (stat(devname, &buf) < 0) {
- log_error("Cannot access device %s.", devname);
- return 0;
- }
-
- if (!S_ISBLK(buf.st_mode)) {
- log_error("Invaild device type %s.", devname);
- return 0;
- }
-
- if (!_insert_dev(devname, buf.st_rdev))
- return_0;
-
- if (!(dev = (struct device *) dm_hash_lookup(_cache.names, devname)))
- return_0;
-
- return 1;
-}
-
-int setup_devno_in_dev_cache(struct cmd_context *cmd, dev_t devno)
-{
- const char *devname;
-
- if (!(devname = _get_devname_from_devno(cmd, devno)))
- return_0;
-
- return setup_devname_in_dev_cache(cmd, devname);
-}
-
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
index 143848d6d..635dc4fc9 100644
--- a/lib/device/dev-cache.h
+++ b/lib/device/dev-cache.h
@@ -77,11 +77,7 @@ int get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor);
int setup_devices_file(struct cmd_context *cmd);
int setup_devices(struct cmd_context *cmd);
+int setup_devices_no_file_match(struct cmd_context *cmd);
int setup_device(struct cmd_context *cmd, const char *devname);
-/* Normal device setup functions are split up for pvscan optimization. */
-int setup_devices_for_pvscan_cache(struct cmd_context *cmd);
-int setup_devname_in_dev_cache(struct cmd_context *cmd, const char *devname);
-int setup_devno_in_dev_cache(struct cmd_context *cmd, dev_t devno);
-
#endif
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
index 167bf661b..eb06109ff 100644
--- a/lib/device/device_id.c
+++ b/lib/device/device_id.c
@@ -1534,22 +1534,6 @@ int device_ids_match_dev(struct cmd_context *cmd, struct device *dev)
* passes the filter.
*/
-void device_ids_match_device_list(struct cmd_context *cmd)
-{
- struct dev_use *du;
-
- dm_list_iterate_items(du, &cmd->use_devices) {
- if (du->dev)
- continue;
- if (!(du->dev = dev_cache_get(cmd, du->devname, NULL))) {
- log_warn("Device not found for %s.", du->devname);
- } else {
- /* Should we set dev->id? Which idtype? Use --deviceidtype? */
- du->dev->flags |= DEV_MATCHED_USE_ID;
- }
- }
-}
-
void device_ids_match(struct cmd_context *cmd)
{
struct dev_iter *iter;
@@ -1557,7 +1541,16 @@ void device_ids_match(struct cmd_context *cmd)
struct device *dev;
if (cmd->enable_devices_list) {
- device_ids_match_device_list(cmd);
+ dm_list_iterate_items(du, &cmd->use_devices) {
+ if (du->dev)
+ continue;
+ if (!(du->dev = dev_cache_get(cmd, du->devname, NULL))) {
+ log_warn("Device not found for %s.", du->devname);
+ } else {
+ /* Should we set dev->id? Which idtype? Use --deviceidtype? */
+ du->dev->flags |= DEV_MATCHED_USE_ID;
+ }
+ }
return;
}
diff --git a/lib/device/device_id.h b/lib/device/device_id.h
index 0ada35c94..939b3a0f4 100644
--- a/lib/device/device_id.h
+++ b/lib/device/device_id.h
@@ -32,7 +32,6 @@ int device_id_add(struct cmd_context *cmd, struct device *dev, const char *pvid,
void device_id_pvremove(struct cmd_context *cmd, struct device *dev);
void device_ids_match(struct cmd_context *cmd);
int device_ids_match_dev(struct cmd_context *cmd, struct device *dev);
-void device_ids_match_device_list(struct cmd_context *cmd);
void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs, int *device_ids_invalid, int noupdate);
int device_ids_version_unchanged(struct cmd_context *cmd);
void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_list, int *search_count, int noupdate);
diff --git a/test/shell/devicesfile-basic.sh b/test/shell/devicesfile-basic.sh
index 9c3455c76..7ba9e2c7f 100644
--- a/test/shell/devicesfile-basic.sh
+++ b/test/shell/devicesfile-basic.sh
@@ -283,7 +283,7 @@ not ls "$RUNDIR/lvm/pvs_online/$PVID3"
# arg in devices list
_clear_online_files
pvscan --devices "$dev3" --cache -aay "$dev3"
-pvscan --devices "$dev4","$dev3" --cache -aay "$dev4"
+pvscan --devices "$dev4" --cache -aay "$dev4"
check lv_field $vg2/$lv2 lv_active "active"
vgchange -an $vg2
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 95d593d57..8e2611361 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -857,21 +857,11 @@ static int _get_devs_from_saved_vg(struct cmd_context *cmd, const char *vgname,
devno = MKDEV(file_major, file_minor);
- if (!setup_devno_in_dev_cache(cmd, devno)) {
- log_error_pvscan(cmd, "No device set up for %d:%d PVID %s", file_major, file_minor, pvid);
- goto bad;
- }
-
if (!(dev = dev_cache_get_by_devt(cmd, devno, NULL, NULL))) {
log_error_pvscan(cmd, "No device found for %d:%d PVID %s", file_major, file_minor, pvid);
goto bad;
}
- /*
- * Do not need to match device_id here, see comment after
- * get_devs_from_saved_vg about relying on pvid online file.
- */
-
name1 = dev_name(dev);
name2 = pvl->pv->device_hint;
@@ -1109,11 +1099,17 @@ static int _pvscan_aa(struct cmd_context *cmd, struct pvscan_aa_params *pp,
* PROCESS_SKIP_SCAN: we have already done lvmcache_label_scan
* so tell process_each to skip it.
*/
+ if (do_all)
+ read_flags |= PROCESS_SKIP_SCAN;
+ /*
+ * When the command is processing specific devs (not all), it
+ * has done setup_devices_no_file_match() to avoid matching ids
+ * fo all devs unnecessarily, but now that we're falling back
+ * to process_each_vg() we need to complete the id matching.
+ */
if (!do_all)
- lvmcache_label_scan(cmd);
-
- read_flags |= PROCESS_SKIP_SCAN;
+ device_ids_match(cmd);
ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, read_flags, 0, handle, _pvscan_aa_single);
}
@@ -1196,15 +1192,11 @@ static int _get_args_devs(struct cmd_context *cmd, struct dm_list *pvscan_args,
/* in common usage, no dev will be found for a devno */
dm_list_iterate_items(arg, pvscan_args) {
- if (arg->devname) {
- if (!setup_devname_in_dev_cache(cmd, arg->devname))
- log_error_pvscan(cmd, "No device set up for name arg %s", arg->devname);
+ if (arg->devname)
arg->dev = dev_cache_get(cmd, arg->devname, NULL);
- } else if (arg->devno) {
- if (!setup_devno_in_dev_cache(cmd, arg->devno))
- log_error_pvscan(cmd, "No device set up for devno arg %d", (int)arg->devno);
+ else if (arg->devno)
arg->dev = dev_cache_get_by_devt(cmd, arg->devno, NULL, NULL);
- } else
+ else
return_0;
}
@@ -1680,13 +1672,11 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
cmd->pvscan_cache_single = 1;
/*
- * Special pvscan-specific setup steps to avoid looking
- * at any devices except for device args.
- * Read devices file and determine if devices file will be used.
- * Does not do dev_cache_scan (adds nothing to dev-cache), and
- * does not do any device id matching.
+ * "no_file_match" means that when the devices file is used,
+ * setup_devices will skip matching devs to devices file entries.
+ * Specific devs must be matched later with device_ids_match_dev().
*/
- if (!setup_devices_for_pvscan_cache(cmd)) {
+ if (!setup_devices_no_file_match(cmd)) {
log_error_pvscan(cmd, "Failed to set up devices.");
return 0;
}
@@ -1745,21 +1735,17 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
log_debug("pvscan_cache_args: filter devs nodata");
/*
- * Match dev args with the devices file because special/optimized
- * device setup was used above which does not check the devices file.
- * If a match fails here do not exclude it, that will be done below by
- * passes_filter() which runs filter-deviceid. The
- * relax_deviceid_filter case needs to be able to work around
+ * Match dev args with the devices file because
+ * setup_devices_no_file_match() was used above which skipped checking
+ * the devices file. If a match fails here do not exclude it, that
+ * will be done below by passes_filter() which runs filter-deviceid.
+ * The relax_deviceid_filter case needs to be able to work around
* unmatching devs.
*/
-
if (cmd->enable_devices_file) {
- dm_list_iterate_items(devl, &pvscan_devs)
+ dm_list_iterate_items_safe(devl, devl2, &pvscan_devs)
device_ids_match_dev(cmd, devl->dev);
-
}
- if (cmd->enable_devices_list)
- device_ids_match_device_list(cmd);
if (cmd->enable_devices_file && device_ids_use_devname(cmd)) {
relax_deviceid_filter = 1;
--
2.34.3

View File

@ -0,0 +1,510 @@
From fb1e53f229f4bcde07df4b562927e213bd7f8d17 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 22 Mar 2023 13:05:43 -0500
Subject: [PATCH 2/2] raidintegrity: allow snapshots
(cherry picked from commit fd6e113bba5fed5ee41152cde33220294c24ce2b)
---
lib/activate/dev_manager.c | 6 +-
lib/metadata/integrity_manip.c | 5 -
lib/metadata/snapshot_manip.c | 2 -
test/shell/snapshot-raid.sh | 441 +++++++++++++++++++++++++++++++++
4 files changed, 446 insertions(+), 8 deletions(-)
create mode 100644 test/shell/snapshot-raid.sh
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index ac3f01718..1f4d7c98b 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -3039,7 +3039,11 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
if (((seg_type(seg, s) == AREA_PV) && _bad_pv_area(seg, s)) ||
((seg_type(seg, s) == AREA_LV) && !seg_lv(seg, s))) {
if (!cmd->partial_activation) {
- if (!cmd->degraded_activation || !lv_is_raid_type(seg->lv)) {
+ if (!cmd->degraded_activation ||
+ (!lv_is_raid_type(seg->lv) &&
+ !lv_is_integrity(seg->lv) &&
+ !lv_is_integrity_metadata(seg->lv) &&
+ !lv_is_integrity_origin(seg->lv))) {
log_error("Aborting. LV %s is incomplete and --activationmode partial was not specified.",
display_lvname(seg->lv));
return 0;
diff --git a/lib/metadata/integrity_manip.c b/lib/metadata/integrity_manip.c
index 456795532..506b9f06b 100644
--- a/lib/metadata/integrity_manip.c
+++ b/lib/metadata/integrity_manip.c
@@ -508,11 +508,6 @@ int lv_add_integrity_to_raid(struct logical_volume *lv, struct integrity_setting
return 0;
}
- if (lv_is_origin(lv)) {
- log_error("Integrity cannot be added to snapshot origins.");
- return 0;
- }
-
seg_top = first_seg(lv);
area_count = seg_top->area_count;
diff --git a/lib/metadata/snapshot_manip.c b/lib/metadata/snapshot_manip.c
index 822b8da77..b34079d08 100644
--- a/lib/metadata/snapshot_manip.c
+++ b/lib/metadata/snapshot_manip.c
@@ -423,8 +423,6 @@ int validate_snapshot_origin(const struct logical_volume *origin_lv)
}
} else if (lv_is_raid_type(origin_lv) && !lv_is_raid(origin_lv)) {
err = "raid subvolumes";
- } else if (lv_is_raid(origin_lv) && lv_raid_has_integrity((struct logical_volume *)origin_lv)) {
- err = "raid with integrity";
}
out:
diff --git a/test/shell/snapshot-raid.sh b/test/shell/snapshot-raid.sh
new file mode 100644
index 000000000..757bf911e
--- /dev/null
+++ b/test/shell/snapshot-raid.sh
@@ -0,0 +1,441 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 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
+
+# Test snapshots of raid
+
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+which mkfs.ext4 || skip
+
+mount_dir="mnt"
+mkdir -p "$mount_dir"
+
+snap_dir="mnt_snap"
+mkdir -p "$snap_dir"
+
+_sync_percent() {
+ local checklv=$1
+ get lv_field "$checklv" sync_percent | cut -d. -f1
+}
+
+_wait_sync() {
+ local checklv=$1
+
+ for i in $(seq 1 10) ; do
+ sync=$(_sync_percent "$checklv")
+ echo "sync_percent is $sync"
+
+ if test "$sync" = "100"; then
+ return
+ fi
+
+ sleep 1
+ done
+ echo "timeout waiting for recalc"
+ dmsetup status "$DM_DEV_DIR/mapper/${checklv/\//-}"
+ return 1
+}
+
+
+# add and remove a snapshot
+
+test_add_del_snap() {
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
+
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
+ touch "$mount_dir/A"
+
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
+
+ touch "$mount_dir/B"
+ not ls "$snap_dir/B"
+ touch "$snap_dir/C"
+ not ls "$mount_dir/C"
+ ls "$mount_dir/A"
+ ls "$snap_dir/A"
+
+ umount "$snap_dir"
+ lvremove -y $vg/snap
+ umount "$mount_dir"
+}
+
+# add and remove snapshot while origin has a missing raid image
+
+test_snap_with_missing_image() {
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
+
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
+ touch "$mount_dir/A"
+
+ aux disable_dev "$dev1"
+ lvs -a -o+devices $vg
+
+ not lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
+
+ aux enable_dev "$dev1"
+ _wait_sync $vg/$lv1
+
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
+
+ aux disable_dev "$dev1"
+ lvs -a -o+devices $vg
+
+ lvremove -y $vg/snap
+
+ aux enable_dev "$dev1"
+ vgextend --restoremissing $vg "$dev1"
+ lvs -a -o+devices $vg
+ _wait_sync $vg/$lv1
+
+ umount "$mount_dir"
+}
+
+# raid image is lost and restored while a snapshot exists
+
+test_missing_image_with_snap() {
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
+
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
+ touch "$mount_dir/A"
+
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
+
+ aux disable_dev "$dev1"
+ lvs -a -o+devices $vg
+
+ touch "$mount_dir/B"
+ not ls "$snap_dir/B"
+ touch "$snap_dir/C"
+ not ls "$mount_dir/C"
+ ls "$mount_dir/A"
+ ls "$snap_dir/A"
+
+ aux enable_dev "$dev1"
+ _wait_sync $vg/$lv1
+
+ ls "$mount_dir/B"
+ ls "$snap_dir/C"
+
+ umount "$snap_dir"
+ lvremove -y $vg/snap
+ umount "$mount_dir"
+}
+
+# add and remove raid image while snapshot exists
+
+test_add_del_image_with_snap() {
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
+
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
+ touch "$mount_dir/A"
+
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
+
+ touch "$mount_dir/B"
+ touch "$snap_dir/C"
+
+ lvconvert -y -m+1 $vg/$lv1 "$dev4"
+ _wait_sync $vg/$lv1
+
+ ls "$mount_dir/B"
+ ls "$snap_dir/C"
+ ls "$mount_dir/A"
+ ls "$snap_dir/A"
+
+ touch "$mount_dir/B2"
+ touch "$snap_dir/C2"
+
+ lvconvert -y -m-1 $vg/$lv1 "$dev4"
+
+ ls "$mount_dir/B"
+ ls "$snap_dir/C"
+ ls "$mount_dir/A"
+ ls "$snap_dir/A"
+ ls "$mount_dir/B2"
+ ls "$snap_dir/C2"
+ umount "$snap_dir"
+ lvremove -y $vg/snap
+
+ umount "$mount_dir"
+}
+
+test_replace_image_with_snap() {
+ # add an image to replace
+ lvconvert -y -m+1 $vg/$lv1 "$dev4"
+ _wait_sync $vg/$lv1
+
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
+
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
+ touch "$mount_dir/A"
+
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
+
+ touch "$mount_dir/B"
+ touch "$snap_dir/C"
+
+ lvconvert -y --replace "$dev4" $vg/$lv1 "$dev5"
+ _wait_sync $vg/$lv1
+
+ ls "$mount_dir/B"
+ ls "$snap_dir/C"
+ ls "$mount_dir/A"
+ ls "$snap_dir/A"
+
+ touch "$mount_dir/B2"
+ touch "$snap_dir/C2"
+
+ umount "$snap_dir"
+ lvremove -y $vg/snap
+
+ # put lv1 back to original state with images on dev1 and dev2
+ lvconvert -y -m-1 $vg/$lv1 "$dev5"
+
+ umount "$mount_dir"
+}
+
+test_repair_image_with_snap() {
+ # add an image to repair
+ lvconvert -y -m+1 $vg/$lv1 "$dev4"
+ _wait_sync $vg/$lv1
+
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
+
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
+ touch "$mount_dir/A"
+
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
+
+ touch "$mount_dir/B"
+ touch "$snap_dir/C"
+
+ aux disable_dev "$dev4"
+ lvs -a -o+devices $vg
+
+ lvconvert -y --repair $vg/$lv1 "$dev5"
+ _wait_sync $vg/$lv1
+
+ ls "$mount_dir/B"
+ ls "$snap_dir/C"
+ ls "$mount_dir/A"
+ ls "$snap_dir/A"
+
+ touch "$mount_dir/B2"
+ touch "$snap_dir/C2"
+
+ umount "$snap_dir"
+ lvremove -y $vg/snap
+
+ aux enable_dev "$dev4"
+ lvs -a -o+devices $vg
+ vgck --updatemetadata $vg
+
+ # put lv1 back to original state with images on dev1 and dev2
+ lvconvert -y -m-1 $vg/$lv1 "$dev5"
+
+ umount "$mount_dir"
+}
+
+test_merge_snap()
+{
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
+
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
+ touch "$mount_dir/A"
+
+ lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
+
+ touch "$mount_dir/B"
+ touch "$snap_dir/C"
+
+ umount "$snap_dir"
+
+ lvconvert --merge $vg/snap
+
+ # the merge will begin once the origin is not in use
+ umount "$mount_dir"
+
+ lvs -a $vg
+ lvchange -an $vg/$lv1
+ lvchange -ay $vg/$lv1
+ lvs -a $vg
+
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
+ ls "$mount_dir/A"
+ ls "$mount_dir/C"
+ not ls "$mount_dir/B"
+
+ umount "$mount_dir"
+}
+
+test_extend_snap()
+{
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
+
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
+ touch "$mount_dir/A"
+
+ lvcreate -s -n snap -L8M $vg/$lv1 "$dev3"
+ mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
+
+ touch "$mount_dir/B"
+ touch "$snap_dir/C"
+
+ lvextend -L+8M $vg/snap
+
+ umount "$mount_dir"
+ umount "$snap_dir"
+ lvremove -y $vg/snap
+}
+
+test_fill_snap()
+{
+ mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
+
+ mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
+ touch "$mount_dir/A"
+
+ lvcreate -s -n snap -L4M $vg/$lv1 "$dev3"
+
+ lvs -a $vg
+ get lv_field $vg/snap lv_attr | grep "swi-a-s---"
+
+ dd if=/dev/zero of="$mount_dir/1" bs=1M count=1 oflag=sync
+ dd if=/dev/zero of="$mount_dir/2" bs=1M count=1 oflag=sync
+ dd if=/dev/zero of="$mount_dir/3" bs=1M count=1 oflag=sync
+ dd if=/dev/zero of="$mount_dir/4" bs=1M count=1 oflag=sync
+ dd if=/dev/zero of="$mount_dir/5" bs=1M count=1 oflag=sync
+
+ lvs -a $vg
+ get lv_field $vg/snap lv_attr | grep "swi-I-s---"
+ check lv_field $vg/snap data_percent "100.00"
+
+ umount "$mount_dir"
+ lvremove -y $vg/snap
+}
+
+aux prepare_devs 5 200
+
+vgcreate $SHARED $vg "$dev1" "$dev2" "$dev3" "$dev4" "$dev5"
+
+lvcreate --type raid1 -m1 -n $lv1 -L128M $vg "$dev1" "$dev2"
+_wait_sync $vg/$lv1
+test_add_del_snap
+test_snap_with_missing_image
+test_missing_image_with_snap
+test_add_del_image_with_snap
+test_replace_image_with_snap
+test_repair_image_with_snap
+test_merge_snap
+test_extend_snap
+test_fill_snap
+lvremove -y $vg/$lv1
+
+lvcreate --type raid1 -m1 --raidintegrity y -n $lv1 -L128M $vg "$dev1" "$dev2"
+_wait_sync $vg/${lv1}_rimage_0
+_wait_sync $vg/${lv1}_rimage_1
+_wait_sync $vg/$lv1
+test_add_del_snap
+test_snap_with_missing_image
+test_missing_image_with_snap
+test_add_del_image_with_snap
+test_replace_image_with_snap
+test_repair_image_with_snap
+test_merge_snap
+test_extend_snap
+test_fill_snap
+lvremove -y $vg/$lv1
+
+# Repeat above with cache|writecache on the raid image?
+
+#
+# Add/remove integrity while a snapshot exists
+#
+
+lvcreate --type raid1 -m1 -n $lv1 -L128M $vg "$dev1" "$dev2"
+_wait_sync $vg/$lv1
+mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
+
+mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
+touch "$mount_dir/A"
+
+lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
+mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
+
+touch "$mount_dir/B"
+touch "$snap_dir/C"
+
+lvconvert --raidintegrity y $vg/$lv1
+_wait_sync $vg/${lv1}_rimage_0
+_wait_sync $vg/${lv1}_rimage_1
+
+ls "$mount_dir/B"
+ls "$snap_dir/C"
+ls "$mount_dir/A"
+ls "$snap_dir/A"
+
+touch "$mount_dir/B2"
+touch "$snap_dir/C2"
+
+lvconvert --raidintegrity n $vg/$lv1
+
+ls "$mount_dir/B"
+ls "$snap_dir/C"
+ls "$mount_dir/A"
+ls "$snap_dir/A"
+ls "$mount_dir/B2"
+ls "$snap_dir/C2"
+umount "$snap_dir"
+umount "$mount_dir"
+lvremove -y $vg/snap
+lvremove -y $vg/$lv1
+
+#
+# Add integrity not allowed with missing image and snapshot exists
+#
+
+lvcreate --type raid1 -m1 -n $lv1 -L128M $vg "$dev1" "$dev2"
+_wait_sync $vg/$lv1
+mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
+
+mount "$DM_DEV_DIR/$vg/$lv1" "$mount_dir"
+touch "$mount_dir/A"
+
+lvcreate -s -n snap -L12M $vg/$lv1 "$dev3"
+mount "$DM_DEV_DIR/$vg/snap" "$snap_dir"
+
+touch "$mount_dir/B"
+touch "$snap_dir/C"
+
+aux disable_dev "$dev1"
+lvs -a $vg
+
+not lvconvert --raidintegrity y $vg/$lv1
+
+aux enable_dev "$dev1"
+lvs -a $vg
+
+umount "$snap_dir"
+umount "$mount_dir"
+lvremove -y $vg/snap
+lvremove -y $vg/$lv1
+
+vgremove -ff $vg
+
--
2.40.1

View File

@ -0,0 +1,26 @@
From 1835574e39e9417b3800469fe80ce47d2210b9a7 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Sun, 23 Apr 2023 12:49:37 +0200
Subject: [PATCH 3/8] lvmdbus: preserve PATH envvar
(cherry picked from commit afc02ae6e7234e1190cedf5c74ca3d6367efd7d1)
---
daemons/lvmdbusd/lvm_shell_proxy.py.in | 2 ++
1 file changed, 2 insertions(+)
diff --git a/daemons/lvmdbusd/lvm_shell_proxy.py.in b/daemons/lvmdbusd/lvm_shell_proxy.py.in
index b8c8fa565..02a776e1d 100755
--- a/daemons/lvmdbusd/lvm_shell_proxy.py.in
+++ b/daemons/lvmdbusd/lvm_shell_proxy.py.in
@@ -154,6 +154,8 @@ class LVMShellProxy(object):
# If any env variables contain LVM we will propagate them too
for k, v in os.environ.items():
+ if "PATH" in k:
+ local_env[k] = v
if "LVM" in k:
local_env[k] = v
--
2.40.1

View File

@ -1,34 +0,0 @@
From a5a2d5fa1ec47a5a548db4cf435dc84de7ce7c31 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Wed, 20 Oct 2021 16:12:41 -0500
Subject: [PATCH 03/54] pvscan: fix messages from coverity changes
---
tools/pvscan.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/pvscan.c b/tools/pvscan.c
index 8e2611361..f60c4a2ca 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -1354,7 +1354,7 @@ static int _online_devs(struct cmd_context *cmd, int do_all, struct dm_list *pvs
devsize = dev->size;
if (!devsize &&
!dev_get_size(dev, &devsize)) {
- log_print("pvscan[%d] PV %s can get device size.", getpid(), dev_name(dev));
+ log_print_pvscan(cmd, "PV %s missing device size.", dev_name(dev));
release_vg(vg);
continue;
}
@@ -1786,7 +1786,7 @@ static int _pvscan_cache_args(struct cmd_context *cmd, int argc, char **argv,
int has_pvid;
if (!label_read_pvid(devl->dev, &has_pvid)) {
- log_print("pvscan[%d] %s cannot read.", getpid(), dev_name(devl->dev));
+ log_print_pvscan(cmd, "%s cannot read label.", dev_name(devl->dev));
dm_list_del(&devl->list);
continue;
}
--
2.34.3

View File

@ -0,0 +1,43 @@
From 80b73e2901d470fd3d1f45664626980167091f02 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 25 Apr 2023 14:46:36 -0500
Subject: [PATCH 4/8] lvmcache: fix valgrind error when dropping md duplicate
When lvmcache info is dropped because it's an md component,
then the lvmcache vginfo can also be dropped, but the list
iterator was still using the list head in vginfo, so break
from the loop earlier to avoid it.
(cherry picked from commit 6d262eaf640dead7861c1a7716e216b9bcea75e5)
---
lib/cache/lvmcache.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index b8a9eac25..127d29229 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -1503,6 +1503,9 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
*/
dm_list_iterate_items_safe(vginfo, vginfo2, &_vginfos) {
+ char vgid[ID_LEN + 1] __attribute__((aligned(8))) = { 0 };
+ memcpy(vgid, vginfo->vgid, ID_LEN);
+
dm_list_iterate_items_safe(info, info2, &vginfo->infos) {
dev = info->dev;
device_hint = _get_pvsummary_device_hint(dev->pvid);
@@ -1557,6 +1560,10 @@ void lvmcache_extra_md_component_checks(struct cmd_context *cmd)
/* lvmcache_del will also delete vginfo if info was last one */
lvmcache_del(info);
cmd->filter->wipe(cmd, cmd->filter, dev, NULL);
+
+ /* If vginfo was deleted don't continue using vginfo->infos */
+ if (!_search_vginfos_list(NULL, vgid))
+ break;
}
}
}
--
2.40.1