This is an attempt at generic device mapper rules file. Both lvm and manually (dmsetup) created devices are supported. The rules file depends only on lvm and dmsetup binaries. Standard /dev/disk/* symlinks are created at the end, with additional /dev/disk/by-id/dm-uuid-* symlinks (by device's uuid, not filesystem's one).
KERNEL=="device-mapper", NAME="mapper/control", GOTO="dm_end" ACTION!="add|change", GOTO="dm_end" SUBSYSTEM!="block", GOTO="dm_end" KERNEL!="dm*", GOTO="dm_end" # First get the name from dmsetup - it can be fed to lvs for parsing PROGRAM="/sbin/dmsetup info -c --noheadings -o name -j%M -m%m", ENV{DM_NAME}="%c" ENV{DM_NAME}!="?*", GOTO="dm_end" ENV{DM_NAME}=="?*", NAME="mapper/$env{DM_NAME}" # Try to get volume group name # - lvs always indents first field with 2 spaces (thus %c{2}) # - note, that node doesn't have to exist, and it would fail if $tempnode was used PROGRAM="/sbin/lvm lvs --ignorelockingfailure --noheadings -o vg_name /dev/mapper/$env{DM_NAME}", ENV{LVM_VGN}="%c{2}" ENV{LVM_VGN}!="?*", GOTO="dm_finalize" PROGRAM="/sbin/lvm lvs --ignorelockingfailure --noheadings -o lv_name /dev/mapper/$env{DM_NAME}", ENV{LVM_LVN}="%c{2}" ENV{LVM_LVN}!="?*", GOTO="dm_finalize" SYMLINK+="$env{LVM_VGN}/$env{LVM_LVN}" LABEL="dm_finalize" # /disk/* symlinks PROGRAM="/sbin/dmsetup info -c --noheadings -o uuid -j%M -m%m", SYMLINK+="disk/by-id/dm-uuid-%c" IMPORT{program}="vol_id --export $tempnode" ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}" ENV{ID_FS_USAGE}=="filesystem|other", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}" LABEL="dm_end"