From 99f93ea6fc8cdce934768fb748f75ac549612164 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 26 Mar 2021 11:39:05 -0500 Subject: [PATCH 06/10] new udev and systemd autoactivation new udev rule: 69-dm-lvm.rules . calls pvscan directly on the added device . pvscan output indicates if a complete VG can be activated . the complete VG name to activate is set in env var LVM_VG_NAME_COMPLETE . this replaces 69-dm-lvm-meta.rules new unit file: lvm-vgchange@.service . udev rule above starts this using systemctl start if LVM_VG_NAME_COMPLETE is set . the service runs vgchange -aay on the vg . this replaces lvm2-pvscan@.service --- configure.ac | 1 + scripts/Makefile.in | 3 +- scripts/lvm-vgchange.service.in | 12 +++++++ scripts/lvmdump.sh.in | 3 ++ udev/69-dm-lvm.rules.in | 80 +++++++++++++++++++++++++++++++++++++++++ udev/Makefile.in | 2 +- 7 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 scripts/lvm-vgchange.service.in create mode 100644 udev/69-dm-lvm.rules.in diff --git a/configure.ac b/configure.ac index 9d8193c..d0f1049 100644 --- a/configure.ac +++ b/configure.ac @@ -1966,6 +1966,7 @@ libdm/libdevmapper.pc man/Makefile po/Makefile scripts/lvm2-pvscan.service +scripts/lvm-vgchange.service scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service diff --git a/scripts/Makefile.in b/scripts/Makefile.in index e8f6742..4ba5aca 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -88,7 +88,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 + $(Q) $(INSTALL_DATA) lvm-vgchange.service $(systemd_unit_dir)/lvm-vgchange@.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 @@ -139,6 +139,7 @@ DISTCLEAN_TARGETS += \ dm_event_systemd_red_hat.socket \ lvmdump.sh \ lvm2-pvscan.service \ + lvm-vgchange.service \ lvm2_cluster_activation_red_hat.sh \ lvm2_cluster_activation_systemd_red_hat.service \ lvm2_clvmd_systemd_red_hat.service \ diff --git a/scripts/lvm-vgchange.service.in b/scripts/lvm-vgchange.service.in new file mode 100644 index 0000000..8ae0df8 --- /dev/null +++ b/scripts/lvm-vgchange.service.in @@ -0,0 +1,12 @@ +[Unit] +Description=LVM event activation of VG %i +Documentation=man:vgchange(8) +DefaultDependencies=no +StartLimitIntervalSec=0 +Before=shutdown.target +Conflicts=shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=no +ExecStart=@SBINDIR@/lvm vgchange -aay --config log/prefix=\"\" %i diff --git a/scripts/lvmdump.sh.in b/scripts/lvmdump.sh.in index 0685d85..91340dd 100644 --- a/scripts/lvmdump.sh.in +++ b/scripts/lvmdump.sh.in @@ -300,6 +300,9 @@ if (( sysreport )); then for unit in $("$GREP" lvm2-pvscan "$sysreport_dir/systemd_unit_list" | cut -d " " -f 1); do log "$SYSTEMCTL status -l --no-pager -n $log_lines -o short-precise $unit >> \"$sysreport_dir/systemd_lvm2_pvscan_service_status\"" done + for unit in $("$GREP" lvm-vgchange "$sysreport_dir/systemd_unit_list" | cut -d " " -f 1); do + log "$SYSTEMCTL status -l --no-pager -n $log_lines -o short-precise $unit >> \"$sysreport_dir/systemd_lvm_vgchange_service_status\"" + done fi fi diff --git a/udev/69-dm-lvm.rules.in b/udev/69-dm-lvm.rules.in new file mode 100644 index 0000000..9869d1b --- /dev/null +++ b/udev/69-dm-lvm.rules.in @@ -0,0 +1,80 @@ +# 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- 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 +# the lvm-vgchange service is started which runs +# vgchange -aay . +# +# 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. + +IMPORT{program}="(LVM_EXEC)/lvm pvscan --cache --listvg --checkcomplete --vgonline --udevoutput --journal=output $env{DEVNAME}" +ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="/usr/bin/systemctl start lvm-vgchange@$env{LVM_VG_NAME_COMPLETE}.service" +GOTO="lvm_end" + +LABEL="lvm_end" diff --git a/udev/Makefile.in b/udev/Makefile.in index e32cba9..e777dda 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-metad.rules +LVM_RULES=11-dm-lvm.rules 69-dm-lvm.rules DM_DIR=$(shell $(GREP) "\#define DM_DIR" $(top_srcdir)/libdm/misc/dm-ioctl.h | $(AWK) '{print $$3}') -- 1.8.3.1