1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00
lvm2/udev/10-dm.rules.in

153 lines
7.2 KiB
Plaintext
Raw Normal View History

# Copyright (C) 2009 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
# Udev rules for device-mapper devices.
#
# These rules create a DM control node in /dev/(DM_DIR) directory.
# The rules also create nodes named dm-x (x is a number) in /dev
# directory and symlinks to these nodes with names given by
# the actual DM names. Some udev environment variables are set
# for use in later rules:
# DM_NAME - actual DM device's name
# DM_UUID - UUID set for DM device (blank if not specified)
# DM_SUSPENDED - suspended state of DM device (0 or 1)
# DM_UDEV_RULES_VSN - DM udev rules version
KERNEL=="device-mapper", NAME="(DM_DIR)/control"
SUBSYSTEM!="block", GOTO="dm_end"
KERNEL!="dm-[0-9]*", GOTO="dm_end"
(DM_EXEC_RULE)
# Device created, major and minor number assigned - "add" event generated.
# Table loaded - no event generated.
# Device resumed (or renamed) - "change" event generated.
# Device removed - "remove" event generated.
#
# The dm-X nodes are always created, even on "add" event, we can't suppress
# that (the node is created even earlier with devtmpfs). All the symlinks
# (e.g. /dev/mapper) are created in right time after a device has its table
# loaded and is properly resumed. For this reason, direct use of dm-X nodes
# is not recommended.
ACTION!="add|change", GOTO="dm_end"
# Decode udev control flags and set environment variables appropriately.
# These flags are encoded in DM_COOKIE variable that was introduced in
# kernel version 2.6.31. Therefore, we can use this feature with
# kernels >= 2.6.31 only. Cookie is not decoded for remove event.
ENV{DM_COOKIE}=="?*", IMPORT{program}="(DM_EXEC)/dmsetup udevflags $env{DM_COOKIE}"
# Rule out easy-to-detect inappropriate events first.
ENV{DISK_RO}=="1", GOTO="dm_disable"
# There is no cookie set nor any flags encoded in events not originating
# in libdevmapper so we need to detect this and try to behave correctly.
# For such spurious events, regenerate all flags from current udev database content
# (this information would normally be inaccessible for spurious ADD and CHANGE events).
activation: fix autoactivation to not trigger on each PV change Before, the pvscan --cache -aay was called on each ADD and CHANGE uevent (for a device that is not a device-mapper device) and each CHANGE event (for a PV that is a device-mapper device). This causes troubles with autoactivation in some cases as CHANGE event may originate from using the OPTION+="watch" udev rule that is defined in 60-persistent-storage.rules (part of the rules provided by udev directly) and it's used for all block devices (except fd*|mtd*|nbd*|gnbd*|btibm*|dm-*|md* devices). For example, the following sequence incorrectly activates the rest of LVs in a VG if one of the LVs in the VG is being removed: [root@rhel6-a ~]# pvcreate /dev/sda Physical volume "/dev/sda" successfully created [root@rhel6-a ~]# vgcreate vg /dev/sda Volume group "vg" successfully created [root@rhel6-a ~]# lvcreate -l1 vg Logical volume "lvol0" created [root@rhel6-a ~]# lvcreate -l1 vg Logical volume "lvol1" created [root@rhel6-a ~]# vgchange -an vg 0 logical volume(s) in volume group "vg" now active [root@rhel6-a ~]# lvs LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert lvol0 vg -wi------ 4.00m lvol1 vg -wi------ 4.00m [root@rhel6-a ~]# lvremove -ff vg/lvol1 Logical volume "lvol1" successfully removed [root@rhel6-a ~]# lvs LV VG Attr LSize Pool Origin Data% Move Log Cpy%Sync Convert lvol0 vg -wi-a---- 4.00m ...so the vg was deactivated, then lvol1 removed, and we end up with lvol1 removed (which is ok) BUT with lvol0 activated (which is wrong)!!! This is because after lvol1 removal, we need to write metadata to the underlying device /dev/sda and that causes the CHANGE event to be generated (because of the WATCH udev rule set on this device) and this causes the pvscan --cache -aay to be reevaluated. We have to limit this and call pvscan --cache -aay to autoactivate VGs/LVs only in these cases: --> if the *PV is not a dm device*, scan only after proper device addition (ADD event) and not with any other changes (CHANGE event) --> if the *PV is a dm device*, scan only after proper mapping activation (CHANGE event + the underlying PV in a state "just activated")
2012-12-21 13:34:48 +04:00
ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}="1", GOTO="dm_flags_done"
IMPORT{db}="DM_UDEV_DISABLE_DM_RULES_FLAG"
IMPORT{db}="DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG"
IMPORT{db}="DM_UDEV_DISABLE_DISK_RULES_FLAG"
IMPORT{db}="DM_UDEV_DISABLE_OTHER_RULES_FLAG"
IMPORT{db}="DM_UDEV_LOW_PRIORITY_FLAG"
IMPORT{db}="DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG"
IMPORT{db}="DM_UDEV_PRIMARY_SOURCE_FLAG"
IMPORT{db}="DM_UDEV_FLAG7"
IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG0"
IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG1"
IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG2"
IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG3"
IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG4"
IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG5"
IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG6"
IMPORT{db}="DM_SUBSYSTEM_UDEV_FLAG7"
IMPORT{db}="DM_UDEV_RULES_VSN"
LABEL="dm_flags_done"
# Normally, we operate on "change" events. But when coldplugging, there's an
# "add" event present. We have to recognize this and do our actions in this
# particular situation, too. Also, we don't want the nodes to be created
# prematurely on "add" events while not coldplugging. We check
# DM_UDEV_PRIMARY_SOURCE_FLAG to see if the device was activated correctly
# before and if not, we ignore the "add" event totally. This way we can support
# udev triggers generating "add" events (e.g. "udevadm trigger --action=add" or
# "echo add > /sys/block/<dm_device>/uevent"). The trigger with "add" event is
# also used at boot to reevaluate udev rules for all existing devices activated
# before (e.g. in initrd). If udev is used in initrd, we require the udev init
# script to not remove the existing udev database so we can reuse the information
# stored at the time of device activation in the initrd.
# The DM_ACTIVATION variable tells when any device stacked above should be
# (re)activated as well.
udev: also autoactivate on coldplug Commit 756bcabbfe297688ba240a880bc2b55265ad33f0 fixed autoactivation to not trigger on each uevent for a PV that appeared in the system most notably the events that are triggered artificially (udevadm trigger or as the result of the WATCH udev rule being applied that consequently generates CHANGE uevents). This fixed a situation in which VGs/LVs were activated when they should not. BUT we still need to care about the coldplug used at boot to retrigger the ADD events - the "udevadm trigger --action=add"! For non-DM-based PVs, this is already covered as for these we run the autoactivation on ADD event only. However, for DM-based PVs, we still need to run the autoactivation even for the artificial ADD event, reusing the udev DB content from previous proper CHANGE event that came with the DM device activation. Simply, this patch fixes a situation in which we run extra "udevadm trigger --action=add" (or echo add > /sys/block/<dev>/uevent) for DM-based PVs (cryptsetup devices, multipath devices, any other DM devices...). Without this patch, while using lvmetad + autoactivation, any VG/LV that has a DM-based PV and for which we do not call the activation directly, the VG/LV is not activated. For example a VG with an LV with root FS on it which is directly activated in initrd and then missing activation of the rest of the LVs in the VG because of unhandled uevent retrigger on boot after switching to root FS (the "coldplug"). (No WHATS_NEW here as this fixes the commit mentioned above and which was not released yet.)
2013-04-19 14:17:53 +04:00
ACTION!="add", GOTO="dm_no_coldplug"
ENV{DM_UDEV_RULES_VSN}!="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="dm_disable"
ENV{DM_ACTIVATION}="1"
LABEL="dm_no_coldplug"
# Putting it together, following table is used to recognize genuine and spurious events.
# N.B. Spurious events are generated based on use of the WATCH udev
# rule or by triggering an event manually by "udevadm trigger" call
# or by "echo <event_name> > /sys/block/dm-X/uevent".
#
# EVENT DM_UDEV_PRIMARY_SOURCE_FLAG DM_ACTIVATION
# ======================================================================
# add event (genuine) 0 0
# change event (genuine) 1 1
# add event (spurious)
# |_ dev still not active 0 0
# \_ dev already active 1 1
# change event (spurious)
# |_ dev still not active 0 0
# \_ dev already active 1 0
# "dm" sysfs subdirectory is available in newer versions of DM
# only (kernels >= 2.6.29). We have to check for its existence
# and use dmsetup tool instead to get the DM name, uuid and
# suspended state if the "dm" subdirectory is not present.
# The "suspended" item was added even later (kernels >= 2.6.31),
# so we also have to call dmsetup if the kernel version used
# is in between these releases.
TEST=="dm", ENV{DM_NAME}="$attr{dm/name}", ENV{DM_UUID}="$attr{dm/uuid}", ENV{DM_SUSPENDED}="$attr{dm/suspended}"
TEST!="dm", IMPORT{program}="(DM_EXEC)/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o name,uuid,suspended"
ENV{DM_SUSPENDED}!="?*", IMPORT{program}="(DM_EXEC)/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o suspended"
# dmsetup tool provides suspended state information in textual
# form with values "Suspended"/"Active". We translate it to
# 0/1 respectively to be consistent with sysfs values.
ENV{DM_SUSPENDED}=="Active", ENV{DM_SUSPENDED}="0"
ENV{DM_SUSPENDED}=="Suspended", ENV{DM_SUSPENDED}="1"
# This variable provides a reliable way to check that device-mapper
# rules were installed. It means that all needed variables are set
# by these rules directly so there's no need to acquire them again
# later. Other rules can alternate the functionality based on this
# fact (e.g. fallback to rules that behave correctly even without
# these rules installed). It also provides versioning for any
# possible future changes.
# VSN 1 - original rules
# VSN 2 - add support for synthesized events
ENV{DM_UDEV_RULES_VSN}="2"
ENV{DM_UDEV_DISABLE_DM_RULES_FLAG}!="1", ENV{DM_NAME}=="?*", SYMLINK+="(DM_DIR)/$env{DM_NAME}"
# We have to ignore further rule application for inappropriate events
# and devices. But still send the notification if cookie exists.
ENV{DM_UUID}=="mpath-?*", ENV{DM_ACTION}=="PATH_FAILED", GOTO="dm_disable"
ENV{DM_UUID}=="CRYPT-TEMP-?*", GOTO="dm_disable"
ENV{DM_UUID}!="?*", ENV{DM_NAME}=="temporary-cryptsetup-?*", GOTO="dm_disable"
# Avoid processing and scanning a DM device in the other (foreign)
# rules if it is in suspended state. However, we still keep 'disk'
# and 'DM subsystem' related rules enabled in this case.
ENV{DM_SUSPENDED}=="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
GOTO="dm_end"
LABEL="dm_disable"
ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}="1"
ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}="1"
ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1"
OPTIONS:="nowatch"
LABEL="dm_end"