Blame SOURCES/0006-new-udev-autoactivation.patch

9db2f0
From 15562a3c2761d206e47258ee11e25dac17427fce Mon Sep 17 00:00:00 2001
9db2f0
From: David Teigland <teigland@redhat.com>
9db2f0
Date: Fri, 26 Mar 2021 11:39:05 -0500
9db2f0
Subject: [PATCH 06/11] new udev autoactivation
9db2f0
9db2f0
new udev rule 69-dm-lvm.rules replaces
9db2f0
69-dm-lvm-meta.rules and lvm2-pvscan.service
9db2f0
9db2f0
udev rule calls pvscan directly on the added device
9db2f0
9db2f0
pvscan output indicates if a complete VG can be activated
9db2f0
9db2f0
udev env var LVM_VG_NAME_COMPLETE is used to pass complete
9db2f0
VG name from pvscan to the udev rule
9db2f0
9db2f0
udev rule uses systemd-run to run vgchange -aay <vgname>
9db2f0
---
9db2f0
 scripts/Makefile.in                |   1 -
9db2f0
 test/shell/udev-pvscan-vgchange.sh | 403 +++++++++++++++++++++++++++++++++++++
9db2f0
 udev/69-dm-lvm.rules.in            |  87 ++++++++
9db2f0
 udev/Makefile.in                   |   2 +-
9db2f0
 5 files changed, 492 insertions(+), 4 deletions(-)
9db2f0
 create mode 100644 test/shell/udev-pvscan-vgchange.sh
9db2f0
 create mode 100644 udev/69-dm-lvm.rules.in
9db2f0
9db2f0
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
9db2f0
index 1fe88ca..60449e1 100644
9db2f0
--- a/scripts/Makefile.in
9db2f0
+++ b/scripts/Makefile.in
9db2f0
@@ -92,7 +92,6 @@ install_systemd_generators:
9db2f0
 install_systemd_units:	install_dbus_service
9db2f0
 	@echo "    [INSTALL] systemd_units"
9db2f0
 	$(Q) $(INSTALL_DIR) $(systemd_unit_dir)
9db2f0
-	$(Q) $(INSTALL_DATA) lvm2-pvscan.service $(systemd_unit_dir)/lvm2-pvscan@.service
9db2f0
 ifeq ("@BUILD_DMEVENTD@", "yes")
9db2f0
 	$(Q) $(INSTALL_DATA) dm_event_systemd_red_hat.socket $(systemd_unit_dir)/dm-event.socket
9db2f0
 	$(Q) $(INSTALL_DATA) dm_event_systemd_red_hat.service $(systemd_unit_dir)/dm-event.service
9db2f0
diff --git a/test/shell/udev-pvscan-vgchange.sh b/test/shell/udev-pvscan-vgchange.sh
9db2f0
new file mode 100644
9db2f0
index 0000000..c81acf0
9db2f0
--- /dev/null
9db2f0
+++ b/test/shell/udev-pvscan-vgchange.sh
9db2f0
@@ -0,0 +1,403 @@
9db2f0
+#!/usr/bin/env bash
9db2f0
+
9db2f0
+# Copyright (C) 2021 Red Hat, Inc. All rights reserved.
9db2f0
+#
9db2f0
+# This copyrighted material is made available to anyone wishing to use,
9db2f0
+# modify, copy, or redistribute it subject to the terms and conditions
9db2f0
+# of the GNU General Public License v.2.
9db2f0
+#
9db2f0
+# You should have received a copy of the GNU General Public License
9db2f0
+# along with this program; if not, write to the Free Software Foundation,
9db2f0
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
9db2f0
+
9db2f0
+test_description='udev rule and systemd unit run vgchange'
9db2f0
+
9db2f0
+SKIP_WITH_LVMPOLLD=1
9db2f0
+SKIP_WITH_LVMLOCKD=1
9db2f0
+
9db2f0
+. lib/inittest
9db2f0
+
9db2f0
+#
9db2f0
+# $ cat /tmp/devs
9db2f0
+# /dev/sdb
9db2f0
+# /dev/sdc
9db2f0
+# /dev/sdd
9db2f0
+#
9db2f0
+# Specify this file as LVM_TEST_DEVICE_LIST=/tmp/devs
9db2f0
+# when running the test.
9db2f0
+#
9db2f0
+# This test will wipe these devices.
9db2f0
+#
9db2f0
+
9db2f0
+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
9db2f0
+
9db2f0
+test -e "$LVM_TEST_DEVICE_LIST" || skip
9db2f0
+
9db2f0
+num_devs=$(cat $LVM_TEST_DEVICE_LIST | wc -l)
9db2f0
+
9db2f0
+RUNDIR="/run"
9db2f0
+test -d "$RUNDIR" || RUNDIR="/var/run"
9db2f0
+PVS_ONLINE_DIR="$RUNDIR/lvm/pvs_online"
9db2f0
+VGS_ONLINE_DIR="$RUNDIR/lvm/vgs_online"
9db2f0
+PVS_LOOKUP_DIR="$RUNDIR/lvm/pvs_lookup"
9db2f0
+
9db2f0
+_clear_online_files() {
9db2f0
+	# wait till udev is finished
9db2f0
+	aux udev_wait
9db2f0
+	rm -f "$PVS_ONLINE_DIR"/*
9db2f0
+	rm -f "$VGS_ONLINE_DIR"/*
9db2f0
+	rm -f "$PVS_LOOKUP_DIR"/*
9db2f0
+}
9db2f0
+
9db2f0
+test -d "$PVS_ONLINE_DIR" || mkdir -p "$PVS_ONLINE_DIR"
9db2f0
+test -d "$VGS_ONLINE_DIR" || mkdir -p "$VGS_ONLINE_DIR"
9db2f0
+test -d "$PVS_LOOKUP_DIR" || mkdir -p "$PVS_LOOKUP_DIR"
9db2f0
+_clear_online_files
9db2f0
+
9db2f0
+aux prepare_real_devs
9db2f0
+
9db2f0
+aux lvmconf 'devices/dir = "/dev"'
9db2f0
+aux lvmconf 'devices/use_devicesfile = 1'
9db2f0
+DFDIR="$LVM_SYSTEM_DIR/devices"
9db2f0
+DF="$DFDIR/system.devices"
9db2f0
+mkdir $DFDIR || true
9db2f0
+not ls $DF
9db2f0
+
9db2f0
+get_real_devs
9db2f0
+
9db2f0
+wipe_all() {
9db2f0
+	for dev in "${REAL_DEVICES[@]}"; do
9db2f0
+		wipefs -a $dev
9db2f0
+	done
9db2f0
+}
9db2f0
+
9db2f0
+# udevadm trigger runs udev rule which runs systemd-run --no-wait vgchange -aay
9db2f0
+# Because of --no-wait, we need to wait for the transient systemd
9db2f0
+# service to be gone before checking the effects of the vgchange.
9db2f0
+
9db2f0
+wait_lvm_activate() {
9db2f0
+	local vgw=$1
9db2f0
+	local wait=0
9db2f0
+
9db2f0
+	while systemctl status lvm-activate-$vgw > /dev/null && test "$wait" -le 30; do
9db2f0
+		sleep .2
9db2f0
+		wait=$(( wait + 1 ))
9db2f0
+	done
9db2f0
+}
9db2f0
+
9db2f0
+# Test requires 3 devs
9db2f0
+test $num_devs -gt 2 || skip
9db2f0
+BDEV1=$(basename "$dev1")
9db2f0
+BDEV2=$(basename "$dev2")
9db2f0
+BDEV3=$(basename "$dev3")
9db2f0
+
9db2f0
+wipe_all
9db2f0
+touch $DF
9db2f0
+for dev in "${REAL_DEVICES[@]}"; do
9db2f0
+	pvcreate $dev
9db2f0
+done
9db2f0
+
9db2f0
+# 1 dev, 1 vg, 1 lv
9db2f0
+
9db2f0
+vgcreate $vg1 "$dev1"
9db2f0
+lvcreate -l1 -an -n $lv1 $vg1 "$dev1"
9db2f0
+
9db2f0
+PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
9db2f0
+
9db2f0
+_clear_online_files
9db2f0
+udevadm trigger --settle -c add /sys/block/$BDEV1
9db2f0
+
9db2f0
+wait_lvm_activate $vg1
9db2f0
+
9db2f0
+ls "$RUNDIR/lvm/pvs_online/$PVID1"
9db2f0
+ls "$RUNDIR/lvm/vgs_online/$vg1"
9db2f0
+journalctl -u lvm-activate-$vg1 | tee out || true
9db2f0
+grep "now active" out
9db2f0
+check lv_field $vg1/$lv1 lv_active "active"
9db2f0
+
9db2f0
+vgchange -an $vg1
9db2f0
+vgremove -y $vg1
9db2f0
+
9db2f0
+
9db2f0
+# 2 devs, 1 vg, 2 lvs
9db2f0
+
9db2f0
+vgcreate $vg2 "$dev1" "$dev2"
9db2f0
+lvcreate -l1 -an -n $lv1 $vg2 "$dev1"
9db2f0
+lvcreate -l1 -an -n $lv2 $vg2 "$dev2"
9db2f0
+
9db2f0
+PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
9db2f0
+PVID2=$(pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}')
9db2f0
+
9db2f0
+_clear_online_files
9db2f0
+
9db2f0
+udevadm trigger --settle -c add /sys/block/$BDEV1
9db2f0
+ls "$RUNDIR/lvm/pvs_online/$PVID1"
9db2f0
+not ls "$RUNDIR/lvm/vgs_online/$vg2"
9db2f0
+journalctl -u lvm-activate-$vg2 | tee out || true
9db2f0
+not grep "now active" out
9db2f0
+check lv_field $vg2/$lv1 lv_active ""
9db2f0
+check lv_field $vg2/$lv2 lv_active ""
9db2f0
+
9db2f0
+udevadm trigger --settle -c add /sys/block/$BDEV2
9db2f0
+ls "$RUNDIR/lvm/pvs_online/$PVID2"
9db2f0
+ls "$RUNDIR/lvm/vgs_online/$vg2"
9db2f0
+
9db2f0
+wait_lvm_activate $vg2
9db2f0
+
9db2f0
+journalctl -u lvm-activate-$vg2 | tee out || true
9db2f0
+grep "now active" out
9db2f0
+check lv_field $vg2/$lv1 lv_active "active"
9db2f0
+check lv_field $vg2/$lv2 lv_active "active"
9db2f0
+
9db2f0
+vgchange -an $vg2
9db2f0
+vgremove -y $vg2
9db2f0
+
9db2f0
+
9db2f0
+# 3 devs, 1 vg, 4 lvs, concurrent pvscans
9db2f0
+# (attempting to have the pvscans run concurrently and race
9db2f0
+# to activate the VG)
9db2f0
+
9db2f0
+vgcreate $vg3 "$dev1" "$dev2" "$dev3"
9db2f0
+lvcreate -l1 -an -n $lv1 $vg3 "$dev1"
9db2f0
+lvcreate -l1 -an -n $lv2 $vg3 "$dev2"
9db2f0
+lvcreate -l1 -an -n $lv3 $vg3 "$dev3"
9db2f0
+lvcreate -l8 -an -n $lv4 -i 2 $vg3 "$dev1" "$dev2"
9db2f0
+
9db2f0
+PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
9db2f0
+PVID2=$(pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}')
9db2f0
+PVID3=$(pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}')
9db2f0
+
9db2f0
+_clear_online_files
9db2f0
+
9db2f0
+udevadm trigger -c add /sys/block/$BDEV1 &
9db2f0
+udevadm trigger -c add /sys/block/$BDEV2 &
9db2f0
+udevadm trigger -c add /sys/block/$BDEV3
9db2f0
+
9db2f0
+aux udev_wait
9db2f0
+wait_lvm_activate $vg3
9db2f0
+
9db2f0
+ls "$RUNDIR/lvm/pvs_online/$PVID1"
9db2f0
+ls "$RUNDIR/lvm/pvs_online/$PVID2"
9db2f0
+ls "$RUNDIR/lvm/pvs_online/$PVID3"
9db2f0
+ls "$RUNDIR/lvm/vgs_online/$vg3"
9db2f0
+journalctl -u lvm-activate-$vg3 | tee out || true
9db2f0
+grep "now active" out
9db2f0
+check lv_field $vg3/$lv1 lv_active "active"
9db2f0
+check lv_field $vg3/$lv2 lv_active "active"
9db2f0
+check lv_field $vg3/$lv3 lv_active "active"
9db2f0
+check lv_field $vg3/$lv4 lv_active "active"
9db2f0
+
9db2f0
+vgchange -an $vg3
9db2f0
+vgremove -y $vg3
9db2f0
+
9db2f0
+
9db2f0
+# 3 devs, 1 vg, 4 lvs, concurrent pvscans, metadata on only 1 PV
9db2f0
+
9db2f0
+wipe_all
9db2f0
+rm $DF
9db2f0
+touch $DF
9db2f0
+pvcreate --metadatacopies 0 "$dev1"
9db2f0
+pvcreate --metadatacopies 0 "$dev2"
9db2f0
+pvcreate "$dev3"
9db2f0
+
9db2f0
+vgcreate $vg4 "$dev1" "$dev2" "$dev3"
9db2f0
+lvcreate -l1 -an -n $lv1 $vg4 "$dev1"
9db2f0
+lvcreate -l1 -an -n $lv2 $vg4 "$dev2"
9db2f0
+lvcreate -l1 -an -n $lv3 $vg4 "$dev3"
9db2f0
+lvcreate -l8 -an -n $lv4 -i 2 $vg4 "$dev1" "$dev2"
9db2f0
+
9db2f0
+PVID1=$(pvs "$dev1" --noheading -o uuid | tr -d - | awk '{print $1}')
9db2f0
+PVID2=$(pvs "$dev2" --noheading -o uuid | tr -d - | awk '{print $1}')
9db2f0
+PVID3=$(pvs "$dev3" --noheading -o uuid | tr -d - | awk '{print $1}')
9db2f0
+
9db2f0
+_clear_online_files
9db2f0
+
9db2f0
+udevadm trigger -c add /sys/block/$BDEV1 &
9db2f0
+udevadm trigger -c add /sys/block/$BDEV2 &
9db2f0
+udevadm trigger -c add /sys/block/$BDEV3
9db2f0
+
9db2f0
+aux udev_wait
9db2f0
+wait_lvm_activate $vg4
9db2f0
+
9db2f0
+ls "$RUNDIR/lvm/pvs_online/$PVID1"
9db2f0
+ls "$RUNDIR/lvm/pvs_online/$PVID2"
9db2f0
+ls "$RUNDIR/lvm/pvs_online/$PVID3"
9db2f0
+ls "$RUNDIR/lvm/vgs_online/$vg4"
9db2f0
+journalctl -u lvm-activate-$vg4 | tee out || true
9db2f0
+grep "now active" out
9db2f0
+check lv_field $vg4/$lv1 lv_active "active"
9db2f0
+check lv_field $vg4/$lv2 lv_active "active"
9db2f0
+check lv_field $vg4/$lv3 lv_active "active"
9db2f0
+check lv_field $vg4/$lv4 lv_active "active"
9db2f0
+
9db2f0
+vgchange -an $vg4
9db2f0
+vgremove -y $vg4
9db2f0
+
9db2f0
+
9db2f0
+# 3 devs, 3 vgs, 2 lvs in each vg, concurrent pvscans
9db2f0
+
9db2f0
+wipe_all
9db2f0
+rm $DF
9db2f0
+touch $DF
9db2f0
+
9db2f0
+vgcreate $vg5 "$dev1"
9db2f0
+vgcreate $vg6 "$dev2"
9db2f0
+vgcreate $vg7 "$dev3"
9db2f0
+lvcreate -l1 -an -n $lv1 $vg5
9db2f0
+lvcreate -l1 -an -n $lv2 $vg5
9db2f0
+lvcreate -l1 -an -n $lv1 $vg6
9db2f0
+lvcreate -l1 -an -n $lv2 $vg6
9db2f0
+lvcreate -l1 -an -n $lv1 $vg7
9db2f0
+lvcreate -l1 -an -n $lv2 $vg7
9db2f0
+
9db2f0
+_clear_online_files
9db2f0
+
9db2f0
+udevadm trigger -c add /sys/block/$BDEV1 &
9db2f0
+udevadm trigger -c add /sys/block/$BDEV2 &
9db2f0
+udevadm trigger -c add /sys/block/$BDEV3
9db2f0
+
9db2f0
+aux udev_wait
9db2f0
+wait_lvm_activate $vg5
9db2f0
+wait_lvm_activate $vg6
9db2f0
+wait_lvm_activate $vg7
9db2f0
+
9db2f0
+ls "$RUNDIR/lvm/vgs_online/$vg5"
9db2f0
+ls "$RUNDIR/lvm/vgs_online/$vg6"
9db2f0
+ls "$RUNDIR/lvm/vgs_online/$vg7"
9db2f0
+journalctl -u lvm-activate-$vg5 | tee out || true
9db2f0
+grep "now active" out
9db2f0
+journalctl -u lvm-activate-$vg6 | tee out || true
9db2f0
+grep "now active" out
9db2f0
+journalctl -u lvm-activate-$vg7 | tee out || true
9db2f0
+grep "now active" out
9db2f0
+check lv_field $vg5/$lv1 lv_active "active"
9db2f0
+check lv_field $vg5/$lv2 lv_active "active"
9db2f0
+check lv_field $vg6/$lv1 lv_active "active"
9db2f0
+check lv_field $vg6/$lv2 lv_active "active"
9db2f0
+check lv_field $vg7/$lv1 lv_active "active"
9db2f0
+check lv_field $vg7/$lv2 lv_active "active"
9db2f0
+
9db2f0
+vgchange -an $vg5
9db2f0
+vgremove -y $vg5
9db2f0
+vgchange -an $vg6
9db2f0
+vgremove -y $vg6
9db2f0
+vgchange -an $vg7
9db2f0
+vgremove -y $vg7
9db2f0
+
9db2f0
+# 3 devs, 1 vg, 1000 LVs
9db2f0
+
9db2f0
+wipe_all
9db2f0
+rm $DF
9db2f0
+touch $DF
9db2f0
+pvcreate --metadatacopies 0 "$dev1"
9db2f0
+pvcreate "$dev2"
9db2f0
+pvcreate "$dev3"
9db2f0
+vgcreate -s 128K $vg8 "$dev1" "$dev2" "$dev3"
9db2f0
+
9db2f0
+# Number of LVs to create
9db2f0
+TEST_DEVS=1000
9db2f0
+# On low-memory boxes let's not stress too much
9db2f0
+test "$(aux total_mem)" -gt 524288 || TEST_DEVS=256
9db2f0
+
9db2f0
+vgcfgbackup -f data $vg8
9db2f0
+
9db2f0
+# Generate a lot of devices (size of 1 extent)
9db2f0
+awk -v TEST_DEVS=$TEST_DEVS '/^\t\}/ {
9db2f0
+    printf("\t}\n\tlogical_volumes {\n");
9db2f0
+    cnt=0;
9db2f0
+    for (i = 0; i < TEST_DEVS; i++) {
9db2f0
+        printf("\t\tlvol%06d  {\n", i);
9db2f0
+        printf("\t\t\tid = \"%06d-1111-2222-3333-2222-1111-%06d\"\n", i, i);
9db2f0
+        print "\t\t\tstatus = [\"READ\", \"WRITE\", \"VISIBLE\"]";
9db2f0
+        print "\t\t\tsegment_count = 1";
9db2f0
+        print "\t\t\tsegment1 {";
9db2f0
+        print "\t\t\t\tstart_extent = 0";
9db2f0
+        print "\t\t\t\textent_count = 1";
9db2f0
+        print "\t\t\t\ttype = \"striped\"";
9db2f0
+        print "\t\t\t\tstripe_count = 1";
9db2f0
+        print "\t\t\t\tstripes = [";
9db2f0
+        print "\t\t\t\t\t\"pv0\", " cnt++;
9db2f0
+        printf("\t\t\t\t]\n\t\t\t}\n\t\t}\n");
9db2f0
+      }
9db2f0
+  }
9db2f0
+  {print}
9db2f0
+' data >data_new
9db2f0
+
9db2f0
+vgcfgrestore -f data_new $vg8
9db2f0
+
9db2f0
+_clear_online_files
9db2f0
+
9db2f0
+udevadm trigger -c add /sys/block/$BDEV1 &
9db2f0
+udevadm trigger -c add /sys/block/$BDEV2 &
9db2f0
+udevadm trigger -c add /sys/block/$BDEV3
9db2f0
+
9db2f0
+aux udev_wait
9db2f0
+wait_lvm_activate $vg8
9db2f0
+
9db2f0
+ls "$RUNDIR/lvm/vgs_online/$vg8"
9db2f0
+journalctl -u lvm-activate-$vg8 | tee out || true
9db2f0
+grep "now active" out
9db2f0
+
9db2f0
+num_active=$(lvs $vg8 --noheading -o active | grep active | wc -l)
9db2f0
+
9db2f0
+test $num_active -eq $TEST_DEVS
9db2f0
+
9db2f0
+vgchange -an $vg8
9db2f0
+vgremove -y $vg8
9db2f0
+
9db2f0
+# 1 pv on an md dev, 1 vg
9db2f0
+
9db2f0
+wait_md_create() {
9db2f0
+	local md=$1
9db2f0
+
9db2f0
+	while :; do
9db2f0
+		if ! grep "$(basename $md)" /proc/mdstat; then
9db2f0
+			echo "$md not ready"
9db2f0
+			cat /proc/mdstat
9db2f0
+			sleep 2
9db2f0
+		else
9db2f0
+			break
9db2f0
+		fi
9db2f0
+	done
9db2f0
+	echo "$md" > WAIT_MD_DEV
9db2f0
+}
9db2f0
+
9db2f0
+test -f /proc/mdstat && grep -q raid1 /proc/mdstat || \
9db2f0
+       modprobe raid1 || skip
9db2f0
+
9db2f0
+mddev="/dev/md33"
9db2f0
+not grep $mddev /proc/mdstat || skip
9db2f0
+
9db2f0
+wipe_all
9db2f0
+rm $DF
9db2f0
+touch $DF
9db2f0
+
9db2f0
+mdadm --create --metadata=1.0 "$mddev" --level 1 --chunk=64 --raid-devices=2 "$dev1" "$dev2"
9db2f0
+wait_md_create "$mddev"
9db2f0
+vgcreate $vg9 "$mddev"
9db2f0
+
9db2f0
+PVIDMD=`pvs $mddev --noheading -o uuid | tr -d - | awk '{print $1}'`
9db2f0
+BDEVMD=$(basename "$mddev")
9db2f0
+
9db2f0
+lvcreate -l1 -an -n $lv1 $vg9
9db2f0
+lvcreate -l1 -an -n $lv2 $vg9
9db2f0
+
9db2f0
+_clear_online_files
9db2f0
+
9db2f0
+udevadm trigger --settle -c add /sys/block/$BDEVMD
9db2f0
+
9db2f0
+wait_lvm_activate $vg9
9db2f0
+
9db2f0
+ls "$RUNDIR/lvm/vgs_online/$vg9"
9db2f0
+journalctl -u lvm-activate-$vg9 | tee out || true
9db2f0
+grep "now active" out
9db2f0
+check lv_field $vg9/$lv1 lv_active "active"
9db2f0
+check lv_field $vg9/$lv2 lv_active "active"
9db2f0
+
9db2f0
+vgchange -an $vg9
9db2f0
+vgremove -y $vg9
9db2f0
+
9db2f0
+mdadm --stop "$mddev"
9db2f0
+aux udev_wait
9db2f0
+wipe_all
9db2f0
+
9db2f0
diff --git a/udev/69-dm-lvm.rules.in b/udev/69-dm-lvm.rules.in
9db2f0
new file mode 100644
9db2f0
index 0000000..03c8fbb
9db2f0
--- /dev/null
9db2f0
+++ b/udev/69-dm-lvm.rules.in
9db2f0
@@ -0,0 +1,87 @@
9db2f0
+# Copyright (C) 2012,2021 Red Hat, Inc. All rights reserved.
9db2f0
+#
9db2f0
+# This file is part of LVM.
9db2f0
+#
9db2f0
+# This rule requires blkid to be called on block devices before so only devices
9db2f0
+# used as LVM PVs are processed (ID_FS_TYPE="LVM2_member").
9db2f0
+
9db2f0
+SUBSYSTEM!="block", GOTO="lvm_end"
9db2f0
+(LVM_EXEC_RULE)
9db2f0
+
9db2f0
+ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", GOTO="lvm_end"
9db2f0
+
9db2f0
+# Only process devices already marked as a PV - this requires blkid to be called before.
9db2f0
+ENV{ID_FS_TYPE}!="LVM2_member", GOTO="lvm_end"
9db2f0
+ENV{DM_MULTIPATH_DEVICE_PATH}=="1", GOTO="lvm_end"
9db2f0
+ACTION=="remove", GOTO="lvm_end"
9db2f0
+
9db2f0
+# Create /dev/disk/by-id/lvm-pv-uuid-<PV_UUID> symlink for each PV
9db2f0
+ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-id/lvm-pv-uuid-$env{ID_FS_UUID_ENC}"
9db2f0
+
9db2f0
+# If the PV is a special device listed below, scan only if the device is
9db2f0
+# properly activated. These devices are not usable after an ADD event,
9db2f0
+# but they require an extra setup and they are ready after a CHANGE event.
9db2f0
+# Also support coldplugging with ADD event but only if the device is already
9db2f0
+# properly activated.
9db2f0
+# This logic should be eventually moved to rules where those particular
9db2f0
+# devices are processed primarily (MD and loop).
9db2f0
+
9db2f0
+# DM device:
9db2f0
+KERNEL!="dm-[0-9]*", GOTO="next"
9db2f0
+ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}=="1", GOTO="lvm_scan"
9db2f0
+GOTO="lvm_end"
9db2f0
+
9db2f0
+# MD device:
9db2f0
+LABEL="next"
9db2f0
+KERNEL!="md[0-9]*", GOTO="next"
9db2f0
+IMPORT{db}="LVM_MD_PV_ACTIVATED"
9db2f0
+ACTION=="add", ENV{LVM_MD_PV_ACTIVATED}=="1", GOTO="lvm_scan"
9db2f0
+ACTION=="change", ENV{LVM_MD_PV_ACTIVATED}!="1", TEST=="md/array_state", ENV{LVM_MD_PV_ACTIVATED}="1", GOTO="lvm_scan"
9db2f0
+ACTION=="add", KERNEL=="md[0-9]*p[0-9]*", GOTO="lvm_scan"
9db2f0
+ENV{LVM_MD_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0"
9db2f0
+GOTO="lvm_end"
9db2f0
+
9db2f0
+# Loop device:
9db2f0
+LABEL="next"
9db2f0
+KERNEL!="loop[0-9]*", GOTO="next"
9db2f0
+ACTION=="add", ENV{LVM_LOOP_PV_ACTIVATED}=="1", GOTO="lvm_scan"
9db2f0
+ACTION=="change", ENV{LVM_LOOP_PV_ACTIVATED}!="1", TEST=="loop/backing_file", ENV{LVM_LOOP_PV_ACTIVATED}="1", GOTO="lvm_scan"
9db2f0
+ENV{LVM_LOOP_PV_ACTIVATED}!="1", ENV{SYSTEMD_READY}="0"
9db2f0
+GOTO="lvm_end"
9db2f0
+
9db2f0
+LABEL="next"
9db2f0
+ACTION!="add", GOTO="lvm_end"
9db2f0
+
9db2f0
+LABEL="lvm_scan"
9db2f0
+
9db2f0
+ENV{SYSTEMD_READY}="1"
9db2f0
+
9db2f0
+# pvscan will check if this device completes a VG,
9db2f0
+# i.e. all PVs in the VG are now present with the
9db2f0
+# arrival of this PV.  If so, it prints to stdout:
9db2f0
+# LVM_VG_NAME_COMPLETE='foo'
9db2f0
+#
9db2f0
+# When the VG is complete it can be activated, so
9db2f0
+# vgchange -aay <vgname> is run.  It is run via
9db2f0
+# systemd since it can take longer to run than
9db2f0
+# udev wants to block when processing rules.
9db2f0
+# (if there are hundreds of LVs to activate,
9db2f0
+# the vgchange can take many seconds.)
9db2f0
+#
9db2f0
+# pvscan only reads the single device specified,
9db2f0
+# and uses temp files under /run/lvm to check if
9db2f0
+# other PVs in the VG are present.
9db2f0
+#
9db2f0
+# If event_activation=0 in lvm.conf, this pvscan
9db2f0
+# (using checkcomplete) will do nothing, so that
9db2f0
+# no event-based autoactivation will be happen.
9db2f0
+#
9db2f0
+# TODO: adjust the output of vgchange -aay so that
9db2f0
+# it's better suited to appearing in the journal.
9db2f0
+
9db2f0
+IMPORT{program}="(LVM_EXEC)/lvm pvscan --cache --listvg --checkcomplete --vgonline --udevoutput --journal=output $env{DEVNAME}"
9db2f0
+ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemd-run --no-block --property DefaultDependencies=no --unit lvm-activate-$env{LVM_VG_NAME_COMPLETE} lvm vgchange -aay $env{LVM_VG_NAME_COMPLETE}"
9db2f0
+GOTO="lvm_end"
9db2f0
+
9db2f0
+LABEL="lvm_end"
9db2f0
+
9db2f0
diff --git a/udev/Makefile.in b/udev/Makefile.in
9db2f0
index e32cba9..e777dda 100644
9db2f0
--- a/udev/Makefile.in
9db2f0
+++ b/udev/Makefile.in
9db2f0
@@ -18,7 +18,7 @@ top_builddir = @top_builddir@
9db2f0
 include $(top_builddir)/make.tmpl
9db2f0
 
9db2f0
 DM_RULES=10-dm.rules 13-dm-disk.rules 95-dm-notify.rules
9db2f0
-LVM_RULES=11-dm-lvm.rules 69-dm-lvm-metad.rules
9db2f0
+LVM_RULES=11-dm-lvm.rules 69-dm-lvm.rules
9db2f0
 
9db2f0
 DM_DIR=$(shell $(GREP) "\#define DM_DIR" $(top_srcdir)/libdm/misc/dm-ioctl.h | $(AWK) '{print $$3}')
9db2f0
 
9db2f0
-- 
9db2f0
1.8.3.1
9db2f0