# 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" # Ignore PVs on LVs. # This is usually a case of an LV being used for a guest VM # image, where the guest is using lvm. The host should # ignore lvm data from the guest and not attempt to scan or # activate guest PVs/LVs. (To enable functions in this file # for PVs layered on LVs, set LVM_PVSCAN_ON_LVS="1" from a # custom udev rule.) ENV{ID_FS_TYPE}=="LVM2_member", ENV{DM_UUID}=="LVM-?*", ENV{LVM_PVSCAN_ON_LVS}!="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" 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" GOTO="lvm_end" LABEL="next" ACTION!="add", GOTO="lvm_end" LABEL="lvm_scan" # 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 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 --autoactivation event --udevoutput --journal=output $env{DEVNAME}" ENV{LVM_VG_NAME_COMPLETE}=="?*", RUN+="(SYSTEMDRUN) --no-block --property DefaultDependencies=no --unit lvm-activate-$env{LVM_VG_NAME_COMPLETE} (LVM_EXEC)/lvm vgchange -aay --autoactivation event $env{LVM_VG_NAME_COMPLETE}" GOTO="lvm_end" LABEL="lvm_end"