diff options
Diffstat (limited to 'rules.d')
40 files changed, 1322 insertions, 0 deletions
diff --git a/rules.d/50-udev-default.rules.in b/rules.d/50-udev-default.rules.in new file mode 100644 index 0000000..af4f594 --- /dev/null +++ b/rules.d/50-udev-default.rules.in @@ -0,0 +1,125 @@ +# do not edit this file, it will be overwritten on update + +# run a command on remove events +ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}" +ACTION=="remove", GOTO="default_end" + +# The md driver increments diskseq *after* emitting 'change' uevent. +# Drop the line below if it is fixed on the kernel side. +SUBSYSTEM=="block", KERNEL=="md*", ENV{ID_IGNORE_DISKSEQ}="1" + +SUBSYSTEM=="virtio-ports", KERNEL=="vport*", ATTR{name}=="?*", SYMLINK+="virtio-ports/$attr{name}" + +# select "system RTC" or just use the first one +SUBSYSTEM=="rtc", ATTR{hctosys}=="1", SYMLINK+="rtc" +SUBSYSTEM=="rtc", KERNEL=="rtc0", SYMLINK+="rtc", OPTIONS+="link_priority=-100" + +SUBSYSTEM=="hidraw", IMPORT{builtin}="hwdb" + +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb" +ENV{MODALIAS}!="", IMPORT{builtin}="hwdb --subsystem=$env{SUBSYSTEM}" + +# Before c43ff248f94266cfc93e300a2d3d163ed805e55b, the following line in +# 60-drm.rules also sets ID_PATH for all pci, usb, and platform devices: +#### +# ACTION!="remove", SUBSYSTEM=="drm", SUBSYSTEMS=="pci|usb|platform", IMPORT{builtin}="path_id" +#### +# Unfortunately, some existing rules already rely on the unexpected behavior. +# To keep the backward compatibility, let's set ID_PATH for them. +SUBSYSTEM=="pci|usb|platform", IMPORT{builtin}="path_id" + +SUBSYSTEM=="net", IMPORT{builtin}="net_driver" + +ACTION!="add", GOTO="default_end" + +SUBSYSTEM=="tty", KERNEL=="ptmx", GROUP="tty", MODE="0666" +SUBSYSTEM=="tty", KERNEL=="tty", GROUP="tty", MODE="0666" +SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", GROUP="tty", MODE="0620" +SUBSYSTEM=="tty", KERNEL=="sclp_line[0-9]*", GROUP="tty", MODE="0620" +SUBSYSTEM=="tty", KERNEL=="ttysclp[0-9]*", GROUP="tty", MODE="0620" +SUBSYSTEM=="tty", KERNEL=="3270/tty[0-9]*", GROUP="tty", MODE="0620" +SUBSYSTEM=="vc", KERNEL=="vcs*|vcsa*", GROUP="tty" +KERNEL=="tty[A-Z]*[0-9]|ttymxc[0-9]*|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout" + +SUBSYSTEM=="mem", KERNEL=="mem|kmem|port", GROUP="kmem", MODE="0640" + +SUBSYSTEM=="input", GROUP="input" +SUBSYSTEM=="input", KERNEL=="js[0-9]*", MODE="0664" + +SUBSYSTEM=="video4linux", GROUP="video" +SUBSYSTEM=="graphics", GROUP="video" +SUBSYSTEM=="drm", KERNEL!="renderD*", GROUP="video" +SUBSYSTEM=="dvb", GROUP="video" +SUBSYSTEM=="media", GROUP="video" +SUBSYSTEM=="cec", GROUP="video" + +SUBSYSTEM=="drm", KERNEL=="renderD*", GROUP="render", MODE="{{GROUP_RENDER_MODE}}" +SUBSYSTEM=="kfd", GROUP="render", MODE="{{GROUP_RENDER_MODE}}" +SUBSYSTEM=="accel", GROUP="render", MODE="{{GROUP_RENDER_MODE}}" + +SUBSYSTEM=="misc", KERNEL=="sgx_enclave", GROUP="sgx", MODE="0660" +SUBSYSTEM=="misc", KERNEL=="sgx_vepc", GROUP="sgx", MODE="0660" + +# When using static_node= with non-default permissions, also update +# tmpfiles.d/static-nodes-permissions.conf.in to keep permissions synchronized. + +SUBSYSTEM=="sound", GROUP="audio", \ + OPTIONS+="static_node=snd/seq", OPTIONS+="static_node=snd/timer" + +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664" + +SUBSYSTEM=="firewire", TEST=="units", TEST=="model", \ + IMPORT{builtin}="hwdb 'ieee1394:node:ven$attr{vendor}mo$attr{model}units$attr{units}'" + +SUBSYSTEM=="firewire", TEST=="units", TEST!="model", \ + IMPORT{builtin}="hwdb 'ieee1394:node:ven$attr{vendor}units$attr{units}'" + +SUBSYSTEM=="firewire", TEST=="units", ENV{IEEE1394_UNIT_FUNCTION_MIDI}=="1", GROUP="audio" +SUBSYSTEM=="firewire", TEST=="units", ENV{IEEE1394_UNIT_FUNCTION_AUDIO}=="1", GROUP="audio" +SUBSYSTEM=="firewire", TEST=="units", ENV{IEEE1394_UNIT_FUNCTION_VIDEO}=="1", GROUP="video" + +KERNEL=="parport[0-9]*", GROUP="lp" +SUBSYSTEM=="printer", KERNEL=="lp*", GROUP="lp" +SUBSYSTEM=="ppdev", GROUP="lp" +KERNEL=="lp[0-9]*", GROUP="lp" +KERNEL=="irlpt[0-9]*", GROUP="lp" +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", GROUP="lp" + +SUBSYSTEM=="block", GROUP="disk" +SUBSYSTEM=="block", KERNEL=="sr[0-9]*", GROUP="cdrom" +SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", GROUP="cdrom" +KERNEL=="sch[0-9]*", GROUP="cdrom" +KERNEL=="pktcdvd[0-9]*", GROUP="cdrom" +KERNEL=="pktcdvd", GROUP="cdrom" + +SUBSYSTEM=="scsi_generic|scsi_tape", SUBSYSTEMS=="scsi", ATTRS{type}=="1|8", GROUP="tape" +SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="0", GROUP="disk" +KERNEL=="qft[0-9]*|nqft[0-9]*|zqft[0-9]*|nzqft[0-9]*|rawqft[0-9]*|nrawqft[0-9]*", GROUP="disk" +KERNEL=="loop-control", GROUP="disk", OPTIONS+="static_node=loop-control" +KERNEL=="btrfs-control", GROUP="disk" +KERNEL=="rawctl", GROUP="disk" +SUBSYSTEM=="raw", KERNEL=="raw[0-9]*", GROUP="disk" +SUBSYSTEM=="aoe", GROUP="disk", MODE="0220" +SUBSYSTEM=="aoe", KERNEL=="err", MODE="0440" + +KERNEL=="rfkill", MODE="0664" +KERNEL=="tun", MODE="0666", OPTIONS+="static_node=net/tun" + +KERNEL=="fuse", MODE="0666", OPTIONS+="static_node=fuse" + +# The static_node is required on s390x and ppc (they are using MODULE_ALIAS) +KERNEL=="kvm", GROUP="kvm", MODE="{{DEV_KVM_MODE}}", OPTIONS+="static_node=kvm" + +KERNEL=="vfio", MODE="0666", OPTIONS+="static_node=vfio/vfio" + +KERNEL=="vsock", MODE="0666" +KERNEL=="vhost-vsock", GROUP="kvm", MODE="{{DEV_KVM_MODE}}", OPTIONS+="static_node=vhost-vsock" + +KERNEL=="vhost-net", GROUP="kvm", MODE="{{DEV_KVM_MODE}}", OPTIONS+="static_node=vhost-net" + +KERNEL=="udmabuf", GROUP="kvm" + +SUBSYSTEM=="ptp", ATTR{clock_name}=="KVM virtual PTP", SYMLINK+="ptp_kvm" +SUBSYSTEM=="ptp", ATTR{clock_name}=="hyperv", SYMLINK+="ptp_hyperv" + +LABEL="default_end" diff --git a/rules.d/60-autosuspend.rules b/rules.d/60-autosuspend.rules new file mode 100644 index 0000000..ce31a92 --- /dev/null +++ b/rules.d/60-autosuspend.rules @@ -0,0 +1,22 @@ +# do not edit this file, it will be overwritten on update + +ACTION!="add", GOTO="autosuspend_end" + +# I2C rules +SUBSYSTEM=="i2c", ATTR{name}=="cyapa", \ + ATTR{power/control}="on", GOTO="autosuspend_end" + +# Enable autosuspend if hwdb says so. Here we are relying on +# the hwdb import done earlier based on MODALIAS. +ENV{ID_AUTOSUSPEND}=="1", TEST=="power/control", \ + ATTR{power/control}="auto" + +# Disable USB persist if hwdb says so. +ENV{ID_PERSIST}=="0", TEST=="power/persist", \ + ATTR{power/persist}="0" + +# Set up an autosuspend delay if hwdb say so +ENV{ID_AUTOSUSPEND_DELAY_MS}!="", TEST=="power/control", \ + ATTR{power/autosuspend_delay_ms}="$env{ID_AUTOSUSPEND_DELAY_MS}" + +LABEL="autosuspend_end" diff --git a/rules.d/60-block.rules b/rules.d/60-block.rules new file mode 100644 index 0000000..3134ab9 --- /dev/null +++ b/rules.d/60-block.rules @@ -0,0 +1,13 @@ +# do not edit this file, it will be overwritten on update + +# enable in-kernel media-presence polling +ACTION=="add", SUBSYSTEM=="module", KERNEL=="block", ATTR{parameters/events_dfl_poll_msecs}=="0", \ + ATTR{parameters/events_dfl_poll_msecs}="2000" + +# forward scsi device event to corresponding block device +ACTION=="change", SUBSYSTEM=="scsi", ENV{DEVTYPE}=="scsi_device", TEST=="block", ATTR{block/*/uevent}="change" + +# watch metadata changes, caused by tools closing the device node which was opened for writing +ACTION!="remove", SUBSYSTEM=="block", \ + KERNEL=="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*|ubi*|scm*|pmem*|nbd*|zd*", \ + OPTIONS+="watch" diff --git a/rules.d/60-cdrom_id.rules b/rules.d/60-cdrom_id.rules new file mode 100644 index 0000000..288f8ce --- /dev/null +++ b/rules.d/60-cdrom_id.rules @@ -0,0 +1,29 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="cdrom_end" +SUBSYSTEM!="block", GOTO="cdrom_end" +KERNEL!="sr[0-9]*|vdisk*|xvd*", GOTO="cdrom_end" +ENV{DEVTYPE}!="disk", GOTO="cdrom_end" + +# unconditionally tag device as CDROM +KERNEL=="sr[0-9]*", ENV{ID_CDROM}="1" + +# stop automatically any mount units bound to the device if the media eject +# button is pressed. +ENV{ID_CDROM}=="1", ENV{SYSTEMD_MOUNT_DEVICE_BOUND}="1" + +# media eject button pressed +ENV{DISK_EJECT_REQUEST}=="?*", RUN+="cdrom_id --eject-media $devnode", GOTO="cdrom_end" + +# import device and media properties and lock tray to +# enable the receiving of media eject button events +IMPORT{program}="cdrom_id --lock-media $devnode" + +# ejecting a CD does not remove the device node, so mark the systemd device +# unit as inactive while there is no medium; this automatically cleans up of +# stale mounts after ejecting +ENV{DISK_MEDIA_CHANGE}=="?*", ENV{ID_CDROM_MEDIA}!="?*", ENV{SYSTEMD_READY}="0" + +KERNEL=="sr0", SYMLINK+="cdrom", OPTIONS+="link_priority=-100" + +LABEL="cdrom_end" diff --git a/rules.d/60-dmi-id.rules b/rules.d/60-dmi-id.rules new file mode 100644 index 0000000..6c61ea2 --- /dev/null +++ b/rules.d/60-dmi-id.rules @@ -0,0 +1,14 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="dmi_end" +SUBSYSTEM!="dmi", GOTO="dmi_end" + +ENV{ID_SYS_VENDOR_IS_RUBBISH}!="1", ENV{ID_VENDOR}="$attr{sys_vendor}" +ENV{ID_SYSFS_ATTRIBUTE_MODEL}=="", ENV{ID_PRODUCT_NAME_IS_RUBBISH}!="1", ENV{ID_MODEL}="$attr{product_name}" +ENV{ID_SYSFS_ATTRIBUTE_MODEL}=="product_name", ENV{ID_MODEL}="$attr{product_name}" +ENV{ID_SYSFS_ATTRIBUTE_MODEL}=="product_version", ENV{ID_MODEL}="$attr{product_version}" +# fallback to board information +ENV{ID_VENDOR}=="", ENV{ID_VENDOR}="$attr{board_vendor}" +ENV{ID_MODEL}=="", ENV{ID_MODEL}="$attr{board_name}" + +LABEL="dmi_end" diff --git a/rules.d/60-drm.rules b/rules.d/60-drm.rules new file mode 100644 index 0000000..061b2a2 --- /dev/null +++ b/rules.d/60-drm.rules @@ -0,0 +1,11 @@ +# do not edit this file, it will be overwritten on update + +ACTION!="remove", SUBSYSTEM=="drm", SUBSYSTEMS=="pci|usb|platform", IMPORT{builtin}="path_id" + +# by-path +KERNEL=="card*", ENV{ID_PATH}=="?*", SYMLINK+="dri/by-path/$env{ID_PATH}-card" +KERNEL=="card*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="dri/by-path/$env{ID_PATH_WITH_USB_REVISION}-card" +KERNEL=="controlD*", ENV{ID_PATH}=="?*", SYMLINK+="dri/by-path/$env{ID_PATH}-control" +KERNEL=="controlD*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="dri/by-path/$env{ID_PATH_WITH_USB_REVISION}-control" +KERNEL=="renderD*", ENV{ID_PATH}=="?*", SYMLINK+="dri/by-path/$env{ID_PATH}-render" +KERNEL=="renderD*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="dri/by-path/$env{ID_PATH_WITH_USB_REVISION}-render" diff --git a/rules.d/60-evdev.rules b/rules.d/60-evdev.rules new file mode 100644 index 0000000..c97cdec --- /dev/null +++ b/rules.d/60-evdev.rules @@ -0,0 +1,30 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="evdev_end" +KERNEL!="event*", GOTO="evdev_end" + +# Execute the match patterns below, from least-to-most specific. + +# Device matching the modalias string (bustype, vendor, product, version, other properties) +IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=evdev:", \ + ENV{.HAVE_HWDB_PROPERTIES}="1" + +# AT keyboard matching by the machine's DMI data +DRIVERS=="atkbd", \ + IMPORT{builtin}="hwdb 'evdev:atkbd:$attr{[dmi/id]modalias}'", \ + ENV{.HAVE_HWDB_PROPERTIES}="1" + +# Device matching the input device name and the machine's DMI data +KERNELS=="input*", \ + IMPORT{builtin}="hwdb 'evdev:name:$attr{name}:$attr{[dmi/id]modalias}'", \ + ENV{.HAVE_HWDB_PROPERTIES}="1" + +# Device matching the input device name + properties + the machine's DMI data +KERNELS=="input*", \ + IMPORT{builtin}="hwdb 'evdev:name:$attr{name}:phys:$attr{phys}:ev:$attr{capabilities/ev}:$attr{[dmi/id]modalias}'", \ + ENV{.HAVE_HWDB_PROPERTIES}="1" + +ENV{.HAVE_HWDB_PROPERTIES}=="1", \ + IMPORT{builtin}="keyboard" + +LABEL="evdev_end" diff --git a/rules.d/60-fido-id.rules b/rules.d/60-fido-id.rules new file mode 100644 index 0000000..48c259e --- /dev/null +++ b/rules.d/60-fido-id.rules @@ -0,0 +1,14 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="fido_id_end" + +SUBSYSTEM=="hidraw", IMPORT{program}="fido_id" + +# Tag any form of security token as such +ENV{ID_SECURITY_TOKEN}=="1", TAG+="security-device" + +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0b????:*", ENV{ID_SMARTCARD_READER}="1" +# Tag any CCID device (i.e. Smartcard Reader) as security token +ENV{ID_SMARTCARD_READER}=="1", TAG+="security-device" + +LABEL="fido_id_end" diff --git a/rules.d/60-infiniband.rules b/rules.d/60-infiniband.rules new file mode 100644 index 0000000..da3eea6 --- /dev/null +++ b/rules.d/60-infiniband.rules @@ -0,0 +1,12 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="infiniband_end" +SUBSYSTEM!="infiniband_verbs", GOTO="infiniband_end" +KERNEL!="uverbs*", GOTO="infiniband_end" + +IMPORT{builtin}="path_id" + +ENV{ID_PATH}=="?*", SYMLINK+="infiniband/by-path/$env{ID_PATH}" +ATTR{ibdev}=="?*", SYMLINK+="infiniband/by-ibdev/uverbs-$attr{ibdev}" + +LABEL="infiniband_end" diff --git a/rules.d/60-input-id.rules b/rules.d/60-input-id.rules new file mode 100644 index 0000000..bb8a812 --- /dev/null +++ b/rules.d/60-input-id.rules @@ -0,0 +1,8 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="id_input_end" + +SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id" +SUBSYSTEM=="input", IMPORT{builtin}="hwdb --subsystem=input --lookup-prefix=id-input:modalias:" + +LABEL="id_input_end" diff --git a/rules.d/60-persistent-alsa.rules b/rules.d/60-persistent-alsa.rules new file mode 100644 index 0000000..466ab1c --- /dev/null +++ b/rules.d/60-persistent-alsa.rules @@ -0,0 +1,15 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="persistent_alsa_end" +SUBSYSTEM!="sound", GOTO="persistent_alsa_end" +KERNEL!="controlC[0-9]*", GOTO="persistent_alsa_end" + +SUBSYSTEMS=="usb", ENV{ID_MODEL}=="", IMPORT{builtin}="usb_id" +ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="?*", SYMLINK+="snd/by-id/$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_USB_INTERFACE_NUM}" +ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="", SYMLINK+="snd/by-id/$env{ID_BUS}-$env{ID_SERIAL}" + +IMPORT{builtin}="path_id" +ENV{ID_PATH}=="?*", SYMLINK+="snd/by-path/$env{ID_PATH}" +ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="snd/by-path/$env{ID_PATH_WITH_USB_REVISION}" + +LABEL="persistent_alsa_end" diff --git a/rules.d/60-persistent-input.rules b/rules.d/60-persistent-input.rules new file mode 100644 index 0000000..d02b46c --- /dev/null +++ b/rules.d/60-persistent-input.rules @@ -0,0 +1,46 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="persistent_input_end" +SUBSYSTEM!="input", GOTO="persistent_input_end" +SUBSYSTEMS=="bluetooth", ENV{ID_BUS}="bluetooth", GOTO="persistent_input_end" +# Bluetooth devices don't always have the bluetooth subsystem +ATTRS{id/bustype}=="0005", ENV{ID_BUS}="bluetooth", GOTO="persistent_input_end" +SUBSYSTEMS=="rmi4", ENV{ID_BUS}="rmi" +SUBSYSTEMS=="serio", ENV{ID_BUS}="i8042" + +SUBSYSTEMS=="usb", ENV{ID_BUS}=="", IMPORT{builtin}="usb_id" + +# determine class name for persistent symlinks +ENV{ID_INPUT_KEYBOARD}=="?*", ENV{.INPUT_CLASS}="kbd" +ENV{ID_INPUT_MOUSE}=="?*", ENV{.INPUT_CLASS}="mouse" +ENV{ID_INPUT_TOUCHPAD}=="?*", ENV{.INPUT_CLASS}="mouse" +ENV{ID_INPUT_TABLET}=="?*", ENV{.INPUT_CLASS}="mouse" +ENV{ID_INPUT_JOYSTICK}=="?*", ENV{.INPUT_CLASS}="joystick" +DRIVERS=="pcspkr", ENV{.INPUT_CLASS}="spkr" +ATTRS{name}=="*dvb*|*DVB*|* IR *", ENV{.INPUT_CLASS}="ir" + +# fill empty serial number +ENV{.INPUT_CLASS}=="?*", ENV{ID_SERIAL}=="", ENV{ID_SERIAL}="noserial" + +# by-id links +KERNEL=="mouse*|js*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="|00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-$env{.INPUT_CLASS}" +KERNEL=="mouse*|js*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="?*", ATTRS{bInterfaceNumber}!="00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$attr{bInterfaceNumber}-$env{.INPUT_CLASS}" +KERNEL=="event*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="|00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-event-$env{.INPUT_CLASS}" +KERNEL=="event*", ENV{ID_BUS}=="?*", ENV{.INPUT_CLASS}=="?*", ATTRS{bInterfaceNumber}=="?*", ATTRS{bInterfaceNumber}!="00", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$attr{bInterfaceNumber}-event-$env{.INPUT_CLASS}" +# allow empty class for USB devices, by appending the interface number +SUBSYSTEMS=="usb", ENV{ID_BUS}=="?*", KERNEL=="event*", ENV{.INPUT_CLASS}=="", ATTRS{bInterfaceNumber}=="?*", \ + SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-event-if$attr{bInterfaceNumber}" + +# by-path +SUBSYSTEMS=="pci|usb|platform|acpi", IMPORT{builtin}="path_id" +ENV{.INPUT_CLASS}=="?*", KERNEL=="mouse*|js*", ENV{ID_PATH}=="?*", SYMLINK+="input/by-path/$env{ID_PATH}-$env{.INPUT_CLASS}" +ENV{.INPUT_CLASS}=="?*", KERNEL=="mouse*|js*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="input/by-path/$env{ID_PATH_WITH_USB_REVISION}-$env{.INPUT_CLASS}" +ENV{.INPUT_CLASS}=="?*", KERNEL=="event*", ENV{ID_PATH}=="?*", SYMLINK+="input/by-path/$env{ID_PATH}-event-$env{.INPUT_CLASS}" +ENV{.INPUT_CLASS}=="?*", KERNEL=="event*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="input/by-path/$env{ID_PATH_WITH_USB_REVISION}-event-$env{.INPUT_CLASS}" +# allow empty class for platform, usb and i2c devices; platform supports only a single interface that way +SUBSYSTEMS=="usb|platform|i2c", KERNEL=="event*", ENV{.INPUT_CLASS}=="", ENV{ID_PATH}=="?*", \ + SYMLINK+="input/by-path/$env{ID_PATH}-event" +SUBSYSTEMS=="usb|platform|i2c", KERNEL=="event*", ENV{.INPUT_CLASS}=="", ENV{ID_PATH_WITH_USB_REVISION}=="?*", \ + SYMLINK+="input/by-path/$env{ID_PATH_WITH_USB_REVISION}-event" + +LABEL="persistent_input_end" diff --git a/rules.d/60-persistent-storage-mtd.rules b/rules.d/60-persistent-storage-mtd.rules new file mode 100644 index 0000000..bcf93b9 --- /dev/null +++ b/rules.d/60-persistent-storage-mtd.rules @@ -0,0 +1,12 @@ +# do not edit this file, it will be overwritten on update + +# persistent storage links: /dev/mtd/by-name + +ACTION=="remove", GOTO="persistent_storage_mtd_end" +SUBSYSTEM!="mtd", GOTO="persistent_storage_mtd_end" +KERNEL!="mtd[0-9]*", GOTO="persistent_storage_mtd_end" +KERNEL=="mtd[0-9]*ro", GOTO="persistent_storage_mtd_end" + +ATTR{name}=="?*", SYMLINK+="mtd/by-name/$attr{name}" + +LABEL="persistent_storage_mtd_end" diff --git a/rules.d/60-persistent-storage-tape.rules b/rules.d/60-persistent-storage-tape.rules new file mode 100644 index 0000000..0678d71 --- /dev/null +++ b/rules.d/60-persistent-storage-tape.rules @@ -0,0 +1,45 @@ +# do not edit this file, it will be overwritten on update + +# persistent storage links: /dev/tape/{by-id,by-path} + +ACTION=="remove", GOTO="persistent_storage_tape_end" +ENV{UDEV_DISABLE_PERSISTENT_STORAGE_RULES_FLAG}=="1", GOTO="persistent_storage_tape_end" + +# type 8 devices are "Medium Changers" +SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="8", GOTO="medium_changer_begin" +GOTO="medium_changer_end" + +LABEL="medium_changer_begin" + +IMPORT{program}="scsi_id --sg-version=3 --export --allowlisted -d $devnode" +ENV{ID_SERIAL}=="?*", SYMLINK+="tape/by-id/scsi-$env{ID_SERIAL} tape/by-id/scsi-$env{ID_SERIAL}-changer" + +# iSCSI devices from the same host have all the same ID_SERIAL, +# but additionally a property named ID_SCSI_SERIAL. +ENV{ID_SCSI_SERIAL}=="?*", SYMLINK+="tape/by-id/scsi-$env{ID_SCSI_SERIAL}" + +IMPORT{builtin}="path_id" +ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}-changer" +ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH_WITH_USB_REVISION}-changer" + +LABEL="medium_changer_end" + +SUBSYSTEM!="scsi_tape", GOTO="persistent_storage_tape_end" + +KERNEL=="st*[0-9]|nst*[0-9]", ATTRS{ieee1394_id}=="?*", ENV{ID_SERIAL}="$attr{ieee1394_id}", ENV{ID_BUS}="ieee1394" +KERNEL=="st*[0-9]|nst*[0-9]", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id" +KERNEL=="st*[0-9]|nst*[0-9]", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", KERNELS=="[0-9]*:*[0-9]", ENV{.BSG_DEV}="$root/bsg/$id" +KERNEL=="st*[0-9]|nst*[0-9]", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --allowlisted --export --device=$env{.BSG_DEV}", ENV{ID_BUS}="scsi" +KERNEL=="st*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}", OPTIONS+="link_priority=10" +KERNEL=="st*[0-9]", ENV{ID_SCSI_SERIAL}=="?*", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SCSI_SERIAL}" +KERNEL=="nst*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SERIAL}-nst" +KERNEL=="nst*[0-9]", ENV{ID_SCSI_SERIAL}=="?*", SYMLINK+="tape/by-id/$env{ID_BUS}-$env{ID_SCSI_SERIAL}-nst" + +# by-path (parent device path) +KERNEL=="st*[0-9]|nst*[0-9]", IMPORT{builtin}="path_id" +KERNEL=="st*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}" +KERNEL=="st*[0-9]", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH_WITH_USB_REVISION}" +KERNEL=="nst*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH}-nst" +KERNEL=="nst*[0-9]", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="tape/by-path/$env{ID_PATH_WITH_USB_REVISION}-nst" + +LABEL="persistent_storage_tape_end" diff --git a/rules.d/60-persistent-storage.rules.in b/rules.d/60-persistent-storage.rules.in new file mode 100644 index 0000000..17a9d08 --- /dev/null +++ b/rules.d/60-persistent-storage.rules.in @@ -0,0 +1,164 @@ +# do not edit this file, it will be overwritten on update + +# persistent storage links: /dev/disk/{by-id,by-uuid,by-label,by-path} +# scheme based on "Linux persistent device names", 2004, Hannes Reinecke <hare@suse.de> + +ACTION=="remove", GOTO="persistent_storage_end" +ENV{UDEV_DISABLE_PERSISTENT_STORAGE_RULES_FLAG}=="1", GOTO="persistent_storage_end" + +SUBSYSTEM!="block|ubi", GOTO="persistent_storage_end" +KERNEL!="loop*|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|nvme*|sd*|sr*|vd*|xvd*|bcache*|cciss*|dasd*|ubd*|ubi*|scm*|pmem*|nbd*|zd*", GOTO="persistent_storage_end" + +# ignore partitions that span the entire disk +TEST=="whole_disk", GOTO="persistent_storage_end" + +# For partitions import parent disk ID_* information, except ID_FS_*. +# +# This is particularly important on media where a filesystem superblock and +# partition table are found on the same level, e.g. common Linux distro ISO +# installation media. +# +# In the case where a partition device points to the same filesystem that +# was detected on the parent disk, the ID_FS_* information is already +# present on the partition devices as well as the parent, so no need to +# propagate it. In the case where the partition device points to a different +# filesystem, merging the parent ID_FS_ properties would lead to +# inconsistencies, so we avoid doing so. +ENV{DEVTYPE}=="partition", \ + IMPORT{parent}="ID_[!F]*", IMPORT{parent}="ID_", \ + IMPORT{parent}="ID_F[!S]*", IMPORT{parent}="ID_F", \ + IMPORT{parent}="ID_FS[!_]*", IMPORT{parent}="ID_FS" + +ENV{DEVTYPE}=="partition", ENV{.PART_SUFFIX}="-part%n" +ENV{DEVTYPE}!="partition", ENV{.PART_SUFFIX}="" + +# NVMe +KERNEL!="nvme*[0-9]n*[0-9]|nvme*[0-9]n*[0-9]p*[0-9]", GOTO="nvme_end" + +ATTRS{serial}=="?*", ENV{ID_SERIAL_SHORT}="$attr{serial}" +ATTRS{wwid}=="?*", ENV{ID_WWN}="$attr{wwid}" +ATTRS{model}=="?*", ENV{ID_MODEL}="$attr{model}" +ATTRS{firmware_rev}=="?*", ENV{ID_REVISION}="$attr{firmware_rev}" +ATTRS{nsid}=="?*", ENV{ID_NSID}="$attr{nsid}" + +ENV{ID_WWN}=="?*", SYMLINK+="disk/by-id/nvme-$env{ID_WWN}$env{.PART_SUFFIX}" + +# obsolete symlink with non-escaped characters, kept for backward compatibility +ENV{ID_MODEL}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_MODEL}!="*/*", ENV{ID_SERIAL_SHORT}!="*/*", \ + ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}$env{.PART_SUFFIX}" +# obsolete symlink that might get overridden on adding a new nvme controller, kept for backward compatibility +ENV{ID_MODEL}=="?*", ENV{ID_SERIAL_SHORT}=="?*", OPTIONS="string_escape=replace", \ + ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}$env{.PART_SUFFIX}" +ENV{ID_MODEL}=="?*", ENV{ID_SERIAL_SHORT}=="?*", ENV{ID_NSID}=="?*", OPTIONS="string_escape=replace", \ + ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}_$env{ID_NSID}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}$env{.PART_SUFFIX}" + +LABEL="nvme_end" + +# virtio-blk +KERNEL=="vd*", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}$env{.PART_SUFFIX}" + +# ATA +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", ATTRS{vendor}=="ATA", IMPORT{program}="ata_id --export $devnode" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_BUS}=="ata", ENV{ID_ATA_PERIPHERAL_DEVICE_TYPE}=="20", PROGRAM="scsi_id -u -g $devnode", \ + SYMLINK+="disk/by-id/scsi-$result$env{.PART_SUFFIX}" + +# ATAPI devices (SPC-3 or later) +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", ATTRS{type}=="5", ATTRS{scsi_level}=="[6-9]*", IMPORT{program}="ata_id --export $devnode" + +# Run ata_id on non-removable USB Mass Storage (SATA/PATA disks in enclosures) +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", ATTR{removable}=="0", SUBSYSTEMS=="usb", IMPORT{program}="ata_id --export $devnode" + +# Also import properties from usb_id for USB devices +KERNEL=="sd*[!0-9]|sr*", SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id" + +# SCSI devices +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --allowlisted -d $devnode", ENV{ID_BUS}="scsi" +KERNEL=="cciss*", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --allowlisted -d $devnode", ENV{ID_BUS}="cciss" + +KERNEL=="sd*|sr*|cciss*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}$env{.PART_SUFFIX}" +# Previously, ata_id in the above might not be able to retrieve attributes correctly, +# and properties from usb_id were used as a fallback. See issue #24921 and PR #24923. +# To keep backward compatibility, still we need to create symlinks based on USB serial. +# See issue #25179. +KERNEL=="sd*|sr*|cciss*", ENV{ID_USB_SERIAL}=="?*", SYMLINK+="disk/by-id/usb-$env{ID_USB_SERIAL}$env{.PART_SUFFIX}" + +# PMEM devices +KERNEL=="pmem*", ATTRS{uuid}=="?*", SYMLINK+="disk/by-id/pmem-$attr{uuid}$env{.PART_SUFFIX}" + +# FireWire +KERNEL=="sd*|sr*", ATTRS{ieee1394_id}=="?*", SYMLINK+="disk/by-id/ieee1394-$attr{ieee1394_id}$env{.PART_SUFFIX}" + +# MMC +KERNEL=="mmcblk[0-9]|mmcblk[0-9]p[0-9]*", SUBSYSTEMS=="mmc", GOTO="mmc_start" +GOTO="mmc_end" +LABEL="mmc_start" +ATTRS{name}=="?*", ENV{ID_NAME}="$attr{name}" +ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}" +ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}$env{.PART_SUFFIX}" +LABEL="mmc_end" + +# Memstick +KERNEL=="msblk[0-9]|mspblk[0-9]|msblk[0-9]p[0-9]|mspblk[0-9]p[0-9]", SUBSYSTEMS=="memstick", GOTO="memstick_start" +GOTO="memstick_end" +LABEL="memstick_start" +ATTRS{name}=="?*", ENV{ID_NAME}="$attr{name}" +ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}" +ENV{ID_NAME}=="?*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/memstick-$env{ID_NAME}_$env{ID_SERIAL}$env{.PART_SUFFIX}" +LABEL="memstick_end" + +# by-path +ENV{DEVTYPE}=="disk", DEVPATH!="*/virtual/*", IMPORT{builtin}="path_id" +ENV{DEVTYPE}=="disk", SUBSYSTEMS=="nvme-subsystem", IMPORT{builtin}="path_id" +KERNEL=="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-boot%n" +KERNEL=="mmcblk[0-9]boot[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH_WITH_USB_REVISION}-boot%n" +KERNEL!="mmcblk[0-9]boot[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}$env{.PART_SUFFIX}" +KERNEL!="mmcblk[0-9]boot[0-9]", ENV{ID_PATH_ATA_COMPAT}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH_ATA_COMPAT}$env{.PART_SUFFIX}" +KERNEL!="mmcblk[0-9]boot[0-9]", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH_WITH_USB_REVISION}$env{.PART_SUFFIX}" + +# legacy virtio-pci by-path links (deprecated) +KERNEL=="vd*", ENV{ID_PATH}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID_PATH}$env{.PART_SUFFIX}" +KERNEL=="vd*", ENV{ID_PATH_WITH_USB_REVISION}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID_PATH_WITH_USB_REVISION}$env{.PART_SUFFIX}" + +{% if HAVE_BLKID %} +# allow admin to disable probing the filesystem for slow devices like floppy disk drives +ENV{UDEV_DISABLE_PERSISTENT_STORAGE_BLKID_FLAG}=="1", GOTO="persistent_storage_blkid_probe_end" + +# probe filesystem metadata of optical drives which have a media inserted +KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="?*", \ + IMPORT{builtin}="blkid --hint=session_offset=$env{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}" +# single-session CDs do not have ID_CDROM_MEDIA_SESSION_LAST_OFFSET +KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="", \ + IMPORT{builtin}="blkid --noraid" + +# probe filesystem metadata of disks +KERNEL!="sr*|mmcblk[0-9]boot[0-9]", IMPORT{builtin}="blkid" + +LABEL="persistent_storage_blkid_probe_end" +{% endif %} + +# by-label/by-uuid links (filesystem metadata) +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|crypto", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}" + +# by-id (World Wide Name) +ENV{ID_WWN_WITH_EXTENSION}=="?*", SYMLINK+="disk/by-id/wwn-$env{ID_WWN_WITH_EXTENSION}$env{.PART_SUFFIX}" + +# by-partlabel/by-partuuid links (partition metadata) +ENV{ID_PART_ENTRY_UUID}=="?*", SYMLINK+="disk/by-partuuid/$env{ID_PART_ENTRY_UUID}" +ENV{ID_PART_ENTRY_SCHEME}=="gpt", ENV{ID_PART_ENTRY_NAME}=="?*", SYMLINK+="disk/by-partlabel/$env{ID_PART_ENTRY_NAME}" + +# by-diskseq link (if an app is told to open a path like this, they may parse +# the diskseq number from the path, then issue BLKGETDISKSEQ to verify they really got +# the right device, to access specific disks in a race-free fashion) +ENV{DISKSEQ}=="?*", ENV{ID_IGNORE_DISKSEQ}!="1", SYMLINK+="disk/by-diskseq/$env{DISKSEQ}$env{.PART_SUFFIX}" + +# Create symlinks that allow referencing loopback devices by their backing file's inode number +ENV{ID_LOOP_BACKING_DEVICE}!="", ENV{ID_LOOP_BACKING_INODE}!="", SYMLINK+="disk/by-loop-inode/$env{ID_LOOP_BACKING_DEVICE}-$env{ID_LOOP_BACKING_INODE}$env{.PART_SUFFIX}" + +# Similar, but uses the .lo_file_name field of the loopback device (note that +# this is basically just a free-form string passed from userspace to the kernel +# when the device is created, it is not necessarily a file system path like the +# "loop/backing_file" sysfs attribute, which is always an absolute path) +ENV{ID_LOOP_BACKING_FILENAME_ENC}!="", SYMLINK+="disk/by-loop-ref/$env{ID_LOOP_BACKING_FILENAME_ENC}$env{.PART_SUFFIX}" + +LABEL="persistent_storage_end" diff --git a/rules.d/60-persistent-v4l.rules b/rules.d/60-persistent-v4l.rules new file mode 100644 index 0000000..071650a --- /dev/null +++ b/rules.d/60-persistent-v4l.rules @@ -0,0 +1,22 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="persistent_v4l_end" +SUBSYSTEM!="video4linux", GOTO="persistent_v4l_end" +ENV{MAJOR}=="", GOTO="persistent_v4l_end" + +IMPORT{program}="v4l_id $devnode" + +SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id" +KERNEL=="video*", ENV{ID_SERIAL}=="?*", SYMLINK+="v4l/by-id/$env{ID_BUS}-$env{ID_SERIAL}-video-index$attr{index}" + +# check for valid "index" number +TEST!="index", GOTO="persistent_v4l_end" +ATTR{index}!="?*", GOTO="persistent_v4l_end" + +IMPORT{builtin}="path_id" +KERNEL=="video*|vbi*", ENV{ID_PATH}=="?*", SYMLINK+="v4l/by-path/$env{ID_PATH}-video-index$attr{index}" +KERNEL=="video*|vbi*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="v4l/by-path/$env{ID_PATH_WITH_USB_REVISION}-video-index$attr{index}" +KERNEL=="audio*", ENV{ID_PATH}=="?*", SYMLINK+="v4l/by-path/$env{ID_PATH}-audio-index$attr{index}" +KERNEL=="audio*", ENV{ID_PATH_WITH_USB_REVISION}=="?*", SYMLINK+="v4l/by-path/$env{ID_PATH_WITH_USB_REVISION}-audio-index$attr{index}" + +LABEL="persistent_v4l_end" diff --git a/rules.d/60-sensor.rules b/rules.d/60-sensor.rules new file mode 100644 index 0000000..09180b4 --- /dev/null +++ b/rules.d/60-sensor.rules @@ -0,0 +1,34 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="sensor_end" + +# device matching the sensor's label, name and the machine's DMI data for IIO devices +SUBSYSTEM=="iio", KERNEL=="iio*", SUBSYSTEMS=="usb|i2c|platform", ATTR{label}!="", \ + IMPORT{builtin}="hwdb 'sensor:$attr{label}:modalias:$attr{modalias}:$attr{[dmi/id]modalias}'", \ + GOTO="sensor_end" + +# Before Linux v6.0, cros-ec-accel used a non-standard 'location' sysfs file +SUBSYSTEM=="iio", KERNEL=="iio*", SUBSYSTEMS=="platform", \ + ATTR{name}=="cros-ec-accel|cros-ec-accel-legacy", ATTR{location}=="base", \ + IMPORT{builtin}="hwdb 'sensor:accel-base:modalias:$attr{modalias}:$attr{[dmi/id]modalias}'", \ + GOTO="sensor_end" + +SUBSYSTEM=="iio", KERNEL=="iio*", SUBSYSTEMS=="platform", \ + ATTR{name}=="cros-ec-accel|cros-ec-accel-legacy", ATTR{location}=="lid", \ + IMPORT{builtin}="hwdb 'sensor:accel-display:modalias:$attr{modalias}:$attr{[dmi/id]modalias}'", \ + GOTO="sensor_end" + +# device matching the sensor's name and the machine's DMI data for IIO devices +SUBSYSTEM=="iio", KERNEL=="iio*", SUBSYSTEMS=="usb|i2c|platform", \ + IMPORT{builtin}="hwdb 'sensor:modalias:$attr{modalias}:$attr{[dmi/id]modalias}'", \ + GOTO="sensor_end" + +SUBSYSTEM=="input", ENV{ID_INPUT_ACCELEROMETER}=="1", SUBSYSTEMS=="acpi", \ + IMPORT{builtin}="hwdb 'sensor:modalias:acpi:$attr{hid}:$attr{[dmi/id]modalias}'", \ + GOTO="sensor_end" + +SUBSYSTEM=="input", ENV{ID_INPUT_ACCELEROMETER}=="1", SUBSYSTEMS=="platform", \ + IMPORT{builtin}="hwdb 'sensor:modalias:platform:$id:$attr{[dmi/id]modalias}'", \ + GOTO="sensor_end" + +LABEL="sensor_end" diff --git a/rules.d/60-serial.rules b/rules.d/60-serial.rules new file mode 100644 index 0000000..0432122 --- /dev/null +++ b/rules.d/60-serial.rules @@ -0,0 +1,28 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="serial_end" +SUBSYSTEM!="tty", GOTO="serial_end" + +SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb" +SUBSYSTEMS=="pci", ENV{ID_BUS}=="", ENV{ID_BUS}="pci", \ + ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}", \ + IMPORT{builtin}="hwdb --subsystem=pci" + +# /dev/serial/by-path/, /dev/serial/by-id/ for USB devices +KERNEL!="ttyUSB[0-9]*|ttyACM[0-9]*", GOTO="serial_end" + +SUBSYSTEMS=="usb-serial", ENV{.ID_PORT}="$attr{port_number}" + +IMPORT{builtin}="path_id" +ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="", SYMLINK+="serial/by-path/$env{ID_PATH}" +ENV{ID_PATH_WITH_USB_REVISION}=="?*", ENV{.ID_PORT}=="", SYMLINK+="serial/by-path/$env{ID_PATH_WITH_USB_REVISION}" +ENV{ID_PATH}=="?*", ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-path/$env{ID_PATH}-port$env{.ID_PORT}" +ENV{ID_PATH_WITH_USB_REVISION}=="?*", ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-path/$env{ID_PATH_WITH_USB_REVISION}-port$env{.ID_PORT}" + +ENV{ID_BUS}=="", GOTO="serial_end" +ENV{ID_SERIAL}=="", GOTO="serial_end" +ENV{ID_USB_INTERFACE_NUM}=="", GOTO="serial_end" +ENV{.ID_PORT}=="", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}" +ENV{.ID_PORT}=="?*", SYMLINK+="serial/by-id/$env{ID_BUS}-$env{ID_SERIAL}-if$env{ID_USB_INTERFACE_NUM}-port$env{.ID_PORT}" + +LABEL="serial_end" diff --git a/rules.d/64-btrfs.rules.in b/rules.d/64-btrfs.rules.in new file mode 100644 index 0000000..039d759 --- /dev/null +++ b/rules.d/64-btrfs.rules.in @@ -0,0 +1,17 @@ +# do not edit this file, it will be overwritten on update + +SUBSYSTEM!="block", GOTO="btrfs_end" +ACTION=="remove", GOTO="btrfs_end" +ENV{ID_FS_TYPE}!="btrfs", GOTO="btrfs_end" +ENV{SYSTEMD_READY}=="0", GOTO="btrfs_end" + +# let the kernel know about this btrfs filesystem, and check if it is complete +IMPORT{builtin}="btrfs ready $devnode" + +# mark the device as not ready to be used by the system +ENV{ID_BTRFS_READY}=="0", ENV{SYSTEMD_READY}="0" + +# reconsider pending devices in case when multidevice volume awaits +ENV{ID_BTRFS_READY}=="1", RUN+="{{BINDIR}}/udevadm trigger -s block -p ID_BTRFS_READY=0" + +LABEL="btrfs_end" diff --git a/rules.d/70-camera.rules b/rules.d/70-camera.rules new file mode 100644 index 0000000..b87096e --- /dev/null +++ b/rules.d/70-camera.rules @@ -0,0 +1,9 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="camera_end" + +SUBSYSTEM=="video4linux", ENV{ID_BUS}="usb", \ + IMPORT{builtin}="hwdb 'camera:usb:v$env{ID_VENDOR_ID}p$env{ID_MODEL_ID}:name:$attr{name}:'", \ + GOTO="camera_end" + +LABEL="camera_end" diff --git a/rules.d/70-joystick.rules b/rules.d/70-joystick.rules new file mode 100644 index 0000000..b80d203 --- /dev/null +++ b/rules.d/70-joystick.rules @@ -0,0 +1,12 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="joystick_end" +ENV{ID_INPUT_JOYSTICK}=="", GOTO="joystick_end" +KERNEL!="event*", GOTO="joystick_end" + +# joystick:<bustype>:v<vid>p<pid>:name:<name>:* +KERNELS=="input*", ENV{ID_BUS}!="", \ + IMPORT{builtin}="hwdb 'joystick:$env{ID_BUS}:v$attr{id/vendor}p$attr{id/product}:name:$attr{name}:'", \ + GOTO="joystick_end" + +LABEL="joystick_end" diff --git a/rules.d/70-memory.rules b/rules.d/70-memory.rules new file mode 100644 index 0000000..f2610ff --- /dev/null +++ b/rules.d/70-memory.rules @@ -0,0 +1,8 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="memory_end" +SUBSYSTEM!="dmi", GOTO="memory_end" + +IMPORT{program}="dmi_memory_id" + +LABEL="memory_end" diff --git a/rules.d/70-mouse.rules b/rules.d/70-mouse.rules new file mode 100644 index 0000000..3ea743a --- /dev/null +++ b/rules.d/70-mouse.rules @@ -0,0 +1,18 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="mouse_end" +KERNEL!="event*", GOTO="mouse_end" +ENV{ID_INPUT_MOUSE}=="", GOTO="mouse_end" + +# mouse:<subsystem>:v<vid>p<pid>:name:<name>:* +KERNELS=="input*", ENV{ID_BUS}=="usb", \ + IMPORT{builtin}="hwdb 'mouse:$env{ID_BUS}:v$attr{id/vendor}p$attr{id/product}:name:$attr{name}:'", \ + GOTO="mouse_end" +KERNELS=="input*", ENV{ID_BUS}=="bluetooth", \ + IMPORT{builtin}="hwdb 'mouse:$env{ID_BUS}:v$attr{id/vendor}p$attr{id/product}:name:$attr{name}:'", \ + GOTO="mouse_end" +DRIVERS=="psmouse", SUBSYSTEMS=="serio", \ + IMPORT{builtin}="hwdb 'mouse:ps2::name:$attr{device/name}:'", \ + GOTO="mouse_end" + +LABEL="mouse_end" diff --git a/rules.d/70-power-switch.rules b/rules.d/70-power-switch.rules new file mode 100644 index 0000000..3fb954a --- /dev/null +++ b/rules.d/70-power-switch.rules @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +ACTION=="remove", GOTO="power_switch_end" + +SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_SWITCH}=="1", TAG+="power-switch" +SUBSYSTEM=="input", KERNEL=="event*", ENV{ID_INPUT_KEY}=="1", TAG+="power-switch" + +LABEL="power_switch_end" diff --git a/rules.d/70-touchpad.rules b/rules.d/70-touchpad.rules new file mode 100644 index 0000000..7bede02 --- /dev/null +++ b/rules.d/70-touchpad.rules @@ -0,0 +1,13 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="touchpad_end" +ENV{ID_INPUT}=="", GOTO="touchpad_end" +ENV{ID_INPUT_TOUCHPAD}=="", GOTO="touchpad_end" +KERNEL!="event*", GOTO="touchpad_end" + +# touchpad:<subsystem>:v<vid>p<pid>:name:<name>:* +KERNELS=="input*", ENV{ID_BUS}!="", \ + IMPORT{builtin}="hwdb 'touchpad:$env{ID_BUS}:v$attr{id/vendor}p$attr{id/product}:name:$attr{name}:'", \ + GOTO="touchpad_end" + +LABEL="touchpad_end" diff --git a/rules.d/70-uaccess.rules.in b/rules.d/70-uaccess.rules.in new file mode 100644 index 0000000..b82ce04 --- /dev/null +++ b/rules.d/70-uaccess.rules.in @@ -0,0 +1,100 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +ACTION=="remove", GOTO="uaccess_end" +ENV{MAJOR}=="", GOTO="uaccess_end" + +# PTP/MTP protocol devices, cameras, portable media players +SUBSYSTEM=="usb", ENV{ID_USB_INTERFACES}=="*:060101:*", TAG+="uaccess" + +# Digicams with proprietary protocol +ENV{ID_GPHOTO2}=="?*", TAG+="uaccess" + +# SCSI and USB scanners +ENV{libsane_matched}=="yes", TAG+="uaccess" + +# HPLIP devices (necessary for ink level check and HP tool maintenance) +ENV{ID_HPLIP}=="1", TAG+="uaccess" + +# optical drives +SUBSYSTEM=="block", ENV{ID_CDROM}=="1", TAG+="uaccess" +SUBSYSTEM=="scsi_generic", SUBSYSTEMS=="scsi", ATTRS{type}=="4|5", TAG+="uaccess" + +# Sound devices +SUBSYSTEM=="sound", TAG+="uaccess", \ + OPTIONS+="static_node=snd/timer", OPTIONS+="static_node=snd/seq" + +# Webcams, frame grabber, TV cards +SUBSYSTEM=="video4linux", TAG+="uaccess" +SUBSYSTEM=="dvb", TAG+="uaccess" +SUBSYSTEM=="media", TAG+="uaccess" + +# industrial cameras, some webcams, camcorders, set-top boxes, TV sets, audio devices, and more +SUBSYSTEM=="firewire", TEST=="units", ENV{IEEE1394_UNIT_FUNCTION_MIDI}=="1", TAG+="uaccess" +SUBSYSTEM=="firewire", TEST=="units", ENV{IEEE1394_UNIT_FUNCTION_AUDIO}=="1", TAG+="uaccess" +SUBSYSTEM=="firewire", TEST=="units", ENV{IEEE1394_UNIT_FUNCTION_VIDEO}=="1", TAG+="uaccess" + +# DRI video devices +SUBSYSTEM=="drm", KERNEL=="card*", TAG+="uaccess" +{% if GROUP_RENDER_UACCESS %} +# DRI render nodes +SUBSYSTEM=="drm", KERNEL=="renderD*", TAG+="uaccess" +{% endif %} +{% if DEV_KVM_UACCESS %} +# KVM +SUBSYSTEM=="misc", KERNEL=="kvm", TAG+="uaccess" +{% endif %} + +# smart-card readers +ENV{ID_SMARTCARD_READER}=="?*", TAG+="uaccess" + +# (USB) authentication devices +ENV{ID_SECURITY_TOKEN}=="?*", TAG+="uaccess" + +# PDA devices +ENV{ID_PDA}=="?*", TAG+="uaccess" + +# Programmable remote control +ENV{ID_REMOTE_CONTROL}=="1", TAG+="uaccess" + +# joysticks +SUBSYSTEM=="input", ENV{ID_INPUT_JOYSTICK}=="?*", TAG+="uaccess" + +# color measurement devices +ENV{COLOR_MEASUREMENT_DEVICE}=="?*", TAG+="uaccess" + +# DDC/CI device, usually high-end monitors such as the DreamColor +ENV{DDC_DEVICE}=="?*", TAG+="uaccess" + +# media player raw devices (for user-mode drivers, Android SDK, etc.) +SUBSYSTEM=="usb", ENV{ID_MEDIA_PLAYER}=="?*", TAG+="uaccess" + +# software-defined radio communication devices +ENV{ID_SOFTWARE_RADIO}=="?*", TAG+="uaccess" + +# 3D printers, CNC machines, laser cutters, 3D scanners, etc. +ENV{ID_MAKER_TOOL}=="?*", TAG+="uaccess" + +# Protocol analyzers +ENV{ID_SIGNAL_ANALYZER}=="?*", ENV{DEVTYPE}=="usb_device", TAG+="uaccess" +ENV{ID_SIGNAL_ANALYZER}=="?*", KERNEL=="ttyACM[0-9]*", TAG+="uaccess" + +# rfkill / radio killswitches +KERNEL=="rfkill", SUBSYSTEM=="misc", TAG+="uaccess" + +# AV production controllers +# Most of these devices use HID for the knobs, faders, buttons, encoders, and jog wheels. +SUBSYSTEM=="hidraw", ENV{ID_AV_PRODUCTION_CONTROLLER}=="1", TAG+="uaccess" + +# Some devices use vendor defined protocols on USB Bulk endpoints for controllers. +# Other devices transfer graphics to screens on the device through USB Bulk endpoints. +# This also allows accessing HID devices with the libusb backend of hidapi. +SUBSYSTEM=="usb", ENV{ID_AV_PRODUCTION_CONTROLLER}=="1", TAG+="uaccess" + +LABEL="uaccess_end" diff --git a/rules.d/71-seat.rules.in b/rules.d/71-seat.rules.in new file mode 100644 index 0000000..1fd7ec2 --- /dev/null +++ b/rules.d/71-seat.rules.in @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +ACTION=="remove", GOTO="seat_end" + +TAG=="uaccess", SUBSYSTEM!="sound", TAG+="seat" +SUBSYSTEM=="sound", KERNEL=="card*", TAG+="seat" +SUBSYSTEM=="input", KERNEL=="input*", TAG+="seat" +SUBSYSTEM=="graphics", KERNEL=="fb[0-9]*", TAG+="seat" + +# Assign keyboard and LCD backlights to the seat +SUBSYSTEM=="leds", TAG+="seat" +SUBSYSTEM=="backlight", TAG+="seat" + +# Allow efifb / uvesafb to be a master if KMS is disabled +SUBSYSTEM=="graphics", KERNEL=="fb[0-9]", IMPORT{cmdline}="nomodeset", TAG+="master-of-seat" + +# Allow any PCI graphics device to be a master and synthesize a seat if KMS +# is disabled and the kernel doesn't have a driver that would work with this device. +SUBSYSTEM=="pci", ENV{ID_PCI_CLASS_FROM_DATABASE}=="Display controller", \ + ENV{DRIVER}=="", IMPORT{cmdline}="nomodeset", TAG+="seat", TAG+="master-of-seat" + +# Synthesize a seat for graphic devices without DRM and that fall back to fb +# device instead. Such HWs are listed in hwdb. +SUBSYSTEM=="graphics", KERNEL=="fb[0-9]*", ATTRS{modalias}=="?*", IMPORT{builtin}="hwdb fb:$attr{modalias}" +ENV{ID_TAG_MASTER_OF_SEAT}=="1", TAG+="master-of-seat" + +SUBSYSTEM=="drm", KERNEL=="card[0-9]*", TAG+="seat", TAG+="master-of-seat" + +# Allow individual USB ports to be assigned to a seat +SUBSYSTEM=="usb", ATTR{bDeviceClass}=="00", TAG+="seat" + +# Allow USB hubs (and all downstream ports) to be assigned to a seat +SUBSYSTEM=="usb", ATTR{bDeviceClass}=="09", TAG+="seat" + +# 'Plugable' USB hub, sound, network, graphics adapter +SUBSYSTEM=="usb", ATTR{idVendor}=="2230", ATTR{idProduct}=="000[13]", ENV{ID_AUTOSEAT}="1" + +# qemu (version 2.4+) has a PCI-PCI bridge (-device pci-bridge-seat) to group +# devices belonging to one seat. See: +# http://git.qemu.org/?p=qemu.git;a=blob;f=docs/multiseat.txt +SUBSYSTEM=="pci", ATTR{vendor}=="0x1b36", ATTR{device}=="0x000a", TAG+="seat", ENV{ID_AUTOSEAT}="1" + +# Mimo 720, with integrated USB hub, displaylink graphics, and e2i +# touchscreen. This device carries no proper VID/PID in the USB hub, +# but it does carry good ID data in the graphics component, hence we +# check it from the parent. There's a bit of a race here however, +# given that the child devices might not exist yet at the time this +# rule is executed. To work around this we'll trigger the parent from +# the child if we notice that the parent wasn't recognized yet. + +# Match parent +{% raw -%} +SUBSYSTEM=="usb", ATTR{idVendor}=="058f", ATTR{idProduct}=="6254", \ + ATTR{%k.2/idVendor}=="17e9", ATTR{%k.2/idProduct}=="401a", ATTR{%k.2/product}=="mimo inc", \ + ENV{ID_AUTOSEAT}="1", ENV{ID_AVOID_LOOP}="1" +{% endraw %} + +# Match child, look for parent's ID_AVOID_LOOP +SUBSYSTEM=="usb", ATTR{idVendor}=="17e9", ATTR{idProduct}=="401a", ATTR{product}=="mimo inc", \ + ATTR{../idVendor}=="058f", ATTR{../idProduct}=="6254", \ + IMPORT{parent}="ID_AVOID_LOOP" + +# Match child, retrigger parent +SUBSYSTEM=="usb", ATTR{idVendor}=="17e9", ATTR{idProduct}=="401a", ATTR{product}=="mimo inc", \ + ATTR{../idVendor}=="058f", ATTR{../idProduct}=="6254", \ + ENV{ID_AVOID_LOOP}=="", \ + RUN+="{{BINDIR}}/udevadm trigger --parent-match=%p/.." + +TAG=="seat", ENV{ID_PATH}=="", IMPORT{builtin}="path_id" +TAG=="seat", ENV{ID_FOR_SEAT}=="", ENV{ID_PATH_TAG}!="", ENV{ID_FOR_SEAT}="$env{SUBSYSTEM}-$env{ID_PATH_TAG}" + +SUBSYSTEM=="input", ATTR{name}=="Wiebetech LLC Wiebetech", RUN+="{{BINDIR}}/loginctl lock-sessions" + +LABEL="seat_end" diff --git a/rules.d/73-seat-late.rules.in b/rules.d/73-seat-late.rules.in new file mode 100644 index 0000000..7cda2b0 --- /dev/null +++ b/rules.d/73-seat-late.rules.in @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +ACTION=="remove", GOTO="seat_late_end" + +ENV{ID_SEAT}=="", ENV{ID_AUTOSEAT}=="1", ENV{ID_FOR_SEAT}!="", ENV{ID_SEAT}="seat-$env{ID_FOR_SEAT}" +ENV{ID_SEAT}=="", IMPORT{parent}="ID_SEAT" + +ENV{ID_SEAT}!="", TAG+="$env{ID_SEAT}" +{% if HAVE_ACL %} +TAG=="uaccess", ENV{MAJOR}!="", RUN{builtin}+="uaccess" +{% endif %} + +LABEL="seat_late_end" diff --git a/rules.d/75-net-description.rules b/rules.d/75-net-description.rules new file mode 100644 index 0000000..7e62f8b --- /dev/null +++ b/rules.d/75-net-description.rules @@ -0,0 +1,14 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="net_end" +SUBSYSTEM!="net", GOTO="net_end" + +IMPORT{builtin}="net_id" + +SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb" +SUBSYSTEMS=="usb", GOTO="net_end" + +SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}" +SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci" + +LABEL="net_end" diff --git a/rules.d/75-probe_mtd.rules b/rules.d/75-probe_mtd.rules new file mode 100644 index 0000000..8848aee --- /dev/null +++ b/rules.d/75-probe_mtd.rules @@ -0,0 +1,7 @@ +# do not edit this file, it will be overwritten on update + +ACTION!="add", GOTO="mtd_probe_end" + +KERNEL=="mtd*ro", IMPORT{program}="mtd_probe $devnode" + +LABEL="mtd_probe_end" diff --git a/rules.d/78-sound-card.rules b/rules.d/78-sound-card.rules new file mode 100644 index 0000000..f2fc277 --- /dev/null +++ b/rules.d/78-sound-card.rules @@ -0,0 +1,96 @@ +# do not edit this file, it will be overwritten on update + +SUBSYSTEM!="sound", GOTO="sound_end" + +ACTION=="add|change", KERNEL=="controlC*", ATTR{../uevent}="change" +ACTION!="change", GOTO="sound_end" + +# Ok, we probably need a little explanation here for what the two lines above +# are good for. +# +# The story goes like this: when ALSA registers a new sound card it emits a +# series of 'add' events to userspace, for the main card device and for all the +# child device nodes that belong to it. udev relays those to applications, +# however only maintains the order between father and child, but not between +# the siblings. The control device node creation can be used as synchronization +# point. All other devices that belong to a card are created in the kernel +# before it. However unfortunately due to the fact that siblings are forwarded +# out of order by udev this fact is lost to applications. +# +# OTOH before an application can open a device it needs to make sure that all +# its device nodes are completely created and set up. +# +# As a workaround for this issue we have added the udev rule above which will +# generate a 'change' event on the main card device from the 'add' event of the +# card's control device. Due to the ordering semantics of udev this event will +# only be relayed after all child devices have finished processing properly. +# When an application needs to listen for appearing devices it can hence look +# for 'change' events only, and ignore the actual 'add' events. +# +# When the application is initialized at the same time as a device is plugged +# in it may need to figure out if the 'change' event has already been triggered +# or not for a card. To find that out we store the flag environment variable +# SOUND_INITIALIZED on the device which simply tells us if the card 'change' +# event has already been processed. + +KERNEL!="card*", GOTO="sound_end" + +ENV{SOUND_INITIALIZED}="1" + +IMPORT{builtin}="hwdb" +SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id" +SUBSYSTEMS=="usb", GOTO="skip_pci" + +SUBSYSTEMS=="firewire", ATTRS{guid}=="?*", \ + ENV{ID_BUS}="firewire", ENV{ID_SERIAL}="$attr{guid}", ENV{ID_SERIAL_SHORT}="$attr{guid}", \ + ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{model}", \ + ENV{ID_VENDOR}="$attr{vendor_name}", ENV{ID_MODEL}="$attr{model_name}" +SUBSYSTEMS=="firewire", GOTO="skip_pci" + +SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}" +SUBSYSTEMS=="pci", GOTO="skip_pci" + +# If we reach here, the device nor any of its parents are USB/PCI/firewire bus devices. +# If we now find a parent that is a platform device, assume that we're working with +# an internal sound card. +SUBSYSTEMS=="platform", ENV{SOUND_FORM_FACTOR}="internal", GOTO="sound_end" + +LABEL="skip_pci" + +# Define ID_ID if ID_BUS and ID_SERIAL are set. This will work for both +# USB and firewire. +ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="?*", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_USB_INTERFACE_NUM}" +ENV{ID_SERIAL}=="?*", ENV{ID_USB_INTERFACE_NUM}=="", ENV{ID_ID}="$env{ID_BUS}-$env{ID_SERIAL}" + +IMPORT{builtin}="path_id" + +# The values used here for $SOUND_FORM_FACTOR and $SOUND_CLASS should be kept +# in sync with those defined for PulseAudio's src/pulse/proplist.h +# PA_PROP_DEVICE_FORM_FACTOR, PA_PROP_DEVICE_CLASS properties. + +# If the first PCM device of this card has the pcm class 'modem', then the card is a modem +ATTR{pcmC%nD0p/pcm_class}=="modem", ENV{SOUND_CLASS}="modem", GOTO="sound_end" + +# Identify cards on the internal PCI bus as internal +SUBSYSTEMS=="pci", DEVPATH=="*/0000:00:??.?/sound/*", ENV{SOUND_FORM_FACTOR}="internal", GOTO="sound_end" + +# Devices that also support Image/Video interfaces are most likely webcams +SUBSYSTEMS=="usb", ENV{ID_USB_INTERFACES}=="*:0e????:*", ENV{SOUND_FORM_FACTOR}="webcam", GOTO="sound_end" + +# Matching on the model strings is a bit ugly, I admit +ENV{ID_MODEL}=="*[Ss]peaker*", ENV{SOUND_FORM_FACTOR}="speaker", GOTO="sound_end" +ENV{ID_MODEL_FROM_DATABASE}=="*[Ss]peaker*", ENV{SOUND_FORM_FACTOR}="speaker", GOTO="sound_end" + +ENV{ID_MODEL}=="*[Hh]eadphone*", ENV{SOUND_FORM_FACTOR}="headphone", GOTO="sound_end" +ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]eadphone*", ENV{SOUND_FORM_FACTOR}="headphone", GOTO="sound_end" + +ENV{ID_MODEL}=="*[Hh]eadset*", ENV{SOUND_FORM_FACTOR}="headset", GOTO="sound_end" +ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]eadset*", ENV{SOUND_FORM_FACTOR}="headset", GOTO="sound_end" + +ENV{ID_MODEL}=="*[Hh]andset*", ENV{SOUND_FORM_FACTOR}="handset", GOTO="sound_end" +ENV{ID_MODEL_FROM_DATABASE}=="*[Hh]andset*", ENV{SOUND_FORM_FACTOR}="handset", GOTO="sound_end" + +ENV{ID_MODEL}=="*[Mm]icrophone*", ENV{SOUND_FORM_FACTOR}="microphone", GOTO="sound_end" +ENV{ID_MODEL_FROM_DATABASE}=="*[Mm]icrophone*", ENV{SOUND_FORM_FACTOR}="microphone", GOTO="sound_end" + +LABEL="sound_end" diff --git a/rules.d/80-drivers.rules b/rules.d/80-drivers.rules new file mode 100644 index 0000000..4bf942f --- /dev/null +++ b/rules.d/80-drivers.rules @@ -0,0 +1,13 @@ +# do not edit this file, it will be overwritten on update + +ACTION!="add", GOTO="drivers_end" + +ENV{MODALIAS}=="?*", RUN{builtin}+="kmod load" +SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="SD", RUN{builtin}+="kmod load tifm_sd" +SUBSYSTEM=="tifm", ENV{TIFM_CARD_TYPE}=="MS", RUN{builtin}+="kmod load tifm_ms" +SUBSYSTEM=="memstick", RUN{builtin}+="kmod load ms_block mspro_block" +SUBSYSTEM=="i2o", RUN{builtin}+="kmod load i2o_block" +SUBSYSTEM=="module", KERNEL=="parport_pc", RUN{builtin}+="kmod load ppdev" +KERNEL=="mtd*ro", ENV{MTD_FTL}=="smartmedia", RUN{builtin}+="kmod load sm_ftl" + +LABEL="drivers_end" diff --git a/rules.d/80-net-setup-link.rules b/rules.d/80-net-setup-link.rules new file mode 100644 index 0000000..bafc3fb --- /dev/null +++ b/rules.d/80-net-setup-link.rules @@ -0,0 +1,13 @@ +# do not edit this file, it will be overwritten on update + +SUBSYSTEM!="net", GOTO="net_setup_link_end" + +IMPORT{builtin}="path_id" + +ACTION=="remove", GOTO="net_setup_link_end" + +IMPORT{builtin}="net_setup_link" + +NAME=="", ENV{ID_NET_NAME}!="", NAME="$env{ID_NET_NAME}" + +LABEL="net_setup_link_end" diff --git a/rules.d/81-net-dhcp.rules b/rules.d/81-net-dhcp.rules new file mode 100644 index 0000000..2ef25ba --- /dev/null +++ b/rules.d/81-net-dhcp.rules @@ -0,0 +1,14 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="net_dhcp_end" +SUBSYSTEM!="net", GOTO="net_dhcp_end" + +# Network interfaces requiring DHCPOFFER messages to be broadcast +# must set ID_NET_DHCP_BROADCAST to "1". This property will be +# checked by the networkd DHCP4 client to set the DHCP option + +# s390 ccwgroup interfaces in layer3 mode need broadcast DHCPOFFER +# using the link driver to detect this condition +ENV{ID_NET_DRIVER}=="qeth_l3", ENV{ID_NET_DHCP_BROADCAST}="1" + +LABEL="net_dhcp_end" diff --git a/rules.d/82-net-auto-link-local.rules b/rules.d/82-net-auto-link-local.rules new file mode 100644 index 0000000..88ac7bc --- /dev/null +++ b/rules.d/82-net-auto-link-local.rules @@ -0,0 +1,15 @@ +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="net_link_local_end" +SUBSYSTEM!="net", GOTO="net_link_local_end" + +# Network interfaces for which only Link-Local communication (i.e. IPv4LL, …) +# makes sense, because they almost certainy will point to another host, not an +# internet router. + +# (Note: matches against VID/PID go into 82-net-auto-link-local.hwdb instead) + +# Thunderbolt host-to-host connections +DRIVERS=="thunderbolt-net", ENV{ID_NET_AUTO_LINK_LOCAL_ONLY}="1" + +LABEL="net_link_local_end" diff --git a/rules.d/90-iocost.rules b/rules.d/90-iocost.rules new file mode 100644 index 0000000..34311de --- /dev/null +++ b/rules.d/90-iocost.rules @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +SUBSYSTEM!="block", GOTO="iocost_end" +ENV{DEVTYPE}!="disk", GOTO="iocost_end" +ACTION=="remove", GOTO="iocost_end" + +ENV{.MODEL}="" +ENV{ID_MODEL}!="", ENV{.MODEL}="$env{ID_MODEL}" +ENV{ID_MODEL_FROM_DATABASE}!="", ENV{.MODEL}="$env{ID_MODEL_FROM_DATABASE}" + +ENV{.MODEL}!="", IMPORT{builtin}="hwdb 'block::name:$env{.MODEL}:fwrev:$env{ID_REVISION}:'" + +ENV{IOCOST_SOLUTIONS}!="", RUN+="iocost apply $env{DEVNAME}" + +LABEL="iocost_end" diff --git a/rules.d/90-vconsole.rules.in b/rules.d/90-vconsole.rules.in new file mode 100644 index 0000000..bc7f8a1 --- /dev/null +++ b/rules.d/90-vconsole.rules.in @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +# Each vtcon keeps its own state of fonts. +# +ACTION=="add", SUBSYSTEM=="vtconsole", KERNEL=="vtcon*", RUN+="{{SYSTEMCTL_BINARY_PATH}} --no-block restart systemd-vconsole-setup.service" diff --git a/rules.d/99-systemd.rules.in b/rules.d/99-systemd.rules.in new file mode 100644 index 0000000..a99eab9 --- /dev/null +++ b/rules.d/99-systemd.rules.in @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +ACTION=="remove", GOTO="systemd_end" + +SUBSYSTEM=="tty", KERNEL=="tty[a-zA-Z]*|hvc*|xvc*|hvsi*|ttysclp*|sclp_line*|3270/tty[0-9]*", TAG+="systemd" +KERNEL=="vport*", TAG+="systemd" + +SUBSYSTEM=="ptp", TAG+="systemd" + +SUBSYSTEM=="ubi", TAG+="systemd" + +SUBSYSTEM=="block", TAG+="systemd" + +# We can't make any conclusions about suspended DM devices so let's just import previous SYSTEMD_READY state and skip other rules +SUBSYSTEM=="block", ENV{DM_SUSPENDED}=="1", IMPORT{db}="SYSTEMD_READY" +SUBSYSTEM=="block", ENV{DM_SUSPENDED}=="1", GOTO="systemd_end" + +SUBSYSTEM=="block", ACTION=="add", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}=="1", ENV{SYSTEMD_READY}="0" + +# Ignore encrypted devices with no identified superblock on it, since +# we are probably still calling mke2fs or mkswap on it. +SUBSYSTEM=="block", ENV{DM_UUID}=="CRYPT-*", ENV{ID_PART_TABLE_TYPE}=="", ENV{ID_FS_USAGE}=="", ENV{SYSTEMD_READY}="0" + +# Explicitly set SYSTEMD_READY=1 for DM devices that don't have it set yet, so that we always have something to import above +SUBSYSTEM=="block", ENV{DM_UUID}=="?*", ENV{SYSTEMD_READY}=="", ENV{SYSTEMD_READY}="1" + +# add symlink to GPT root disk +SUBSYSTEM=="block", ENV{ID_PART_GPT_AUTO_ROOT}=="1", ENV{ID_FS_TYPE}!="crypto_LUKS", SYMLINK+="gpt-auto-root" +SUBSYSTEM=="block", ENV{ID_PART_GPT_AUTO_ROOT}=="1", ENV{ID_FS_TYPE}=="crypto_LUKS", SYMLINK+="gpt-auto-root-luks" +SUBSYSTEM=="block", ENV{DM_UUID}=="CRYPT-*", ENV{DM_NAME}=="root", SYMLINK+="gpt-auto-root" + +# Ignore raid devices that are not yet assembled and started +SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", TEST!="md/array_state", ENV{SYSTEMD_READY}="0" +SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", KERNEL=="md*", ATTR{md/array_state}=="|clear|inactive", ENV{SYSTEMD_READY}="0" + +# Ignore loop devices that don't have any file attached +SUBSYSTEM=="block", KERNEL=="loop[0-9]*", ENV{DEVTYPE}=="disk", TEST!="loop/backing_file", ENV{SYSTEMD_READY}="0" + +# Ignore nbd devices until the PID file exists (which signals a connected device) +SUBSYSTEM=="block", KERNEL=="nbd*", ENV{DEVTYPE}=="disk", TEST!="pid", ENV{SYSTEMD_READY}="0" + +# We need a hardware independent way to identify network devices. We +# use the /sys/subsystem/ path for this. Kernel "bus" and "class" names +# should be treated as one namespace, like udev handles it. This is mostly +# just an identification string for systemd, so whether the path actually is +# accessible or not does not matter as long as it is unique and in the +# filesystem namespace. + +SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/net/devices/$name" +SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/bluetooth/devices/%k", \ + ENV{SYSTEMD_WANTS}+="bluetooth.target", ENV{SYSTEMD_USER_WANTS}+="bluetooth.target" + +ENV{ID_SMARTCARD_READER}=="?*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="smartcard.target", ENV{SYSTEMD_USER_WANTS}+="smartcard.target" +SUBSYSTEM=="sound", KERNEL=="controlC*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sound.target", ENV{SYSTEMD_USER_WANTS}+="sound.target" + +SUBSYSTEM=="printer", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target", ENV{SYSTEMD_USER_WANTS}+="printer.target" +SUBSYSTEM=="usb", KERNEL=="lp*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target", ENV{SYSTEMD_USER_WANTS}+="printer.target" +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target", ENV{SYSTEMD_USER_WANTS}+="printer.target" + +SUBSYSTEM=="udc", TAG+="systemd", ENV{SYSTEMD_WANTS}+="usb-gadget.target" + +# Apply sysctl variables to network devices (and only to those) as they appear. +ACTION=="add", SUBSYSTEM=="net", KERNEL!="lo", RUN+="{{LIBEXECDIR}}/systemd-sysctl --prefix=/net/ipv4/conf/$name --prefix=/net/ipv4/neigh/$name --prefix=/net/ipv6/conf/$name --prefix=/net/ipv6/neigh/$name" + +{% if ENABLE_BACKLIGHT %} +# Pull in backlight save/restore for all backlight devices and +# keyboard backlights +SUBSYSTEM=="backlight", TAG+="systemd", IMPORT{builtin}="path_id", ENV{SYSTEMD_WANTS}+="systemd-backlight@backlight:$name.service" +SUBSYSTEM=="leds", KERNEL=="*kbd_backlight*", TAG+="systemd", IMPORT{builtin}="path_id", ENV{SYSTEMD_WANTS}+="systemd-backlight@leds:$name.service" +{% endif %} + +# Pull in rfkill save/restore for all rfkill devices +SUBSYSTEM=="rfkill", ENV{SYSTEMD_RFKILL}="1" +SUBSYSTEM=="rfkill", IMPORT{builtin}="path_id" +SUBSYSTEM=="misc", KERNEL=="rfkill", TAG+="systemd", ENV{SYSTEMD_WANTS}+="systemd-rfkill.socket" + +# Asynchronously mount file systems implemented by these modules as soon as they are loaded. +SUBSYSTEM=="module", KERNEL=="fuse", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sys-fs-fuse-connections.mount" +SUBSYSTEM=="module", KERNEL=="configfs", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sys-kernel-config.mount" + +LABEL="systemd_end" diff --git a/rules.d/README b/rules.d/README new file mode 100644 index 0000000..08edb4d --- /dev/null +++ b/rules.d/README @@ -0,0 +1,8 @@ +Files in this directory contain configuration for systemd-udevd.service, a +daemon that manages symlinks to device nodes, permissions of devices nodes, +emits device events for userspace, and renames network interfaces. + +See man:udev(7) for an overview of the configuration file format, and +man:systemd-udevd.service(8) for a description of service itself. + +Use 'systemd-analyze cat-config udev/rules.d' to display the effective config. diff --git a/rules.d/meson.build b/rules.d/meson.build new file mode 100644 index 0000000..3040fae --- /dev/null +++ b/rules.d/meson.build @@ -0,0 +1,83 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +install_data( + 'README', + install_dir : udevrulesdir) + +rules = [ + [files('60-autosuspend.rules', + '60-block.rules', + '60-cdrom_id.rules', + '60-dmi-id.rules', + '60-drm.rules', + '60-evdev.rules', + '60-fido-id.rules', + '60-infiniband.rules', + '60-input-id.rules', + '60-persistent-alsa.rules', + '60-persistent-input.rules', + '60-persistent-storage-mtd.rules', + '60-persistent-storage-tape.rules', + '60-persistent-v4l.rules', + '60-sensor.rules', + '60-serial.rules', + '70-camera.rules', + '70-joystick.rules', + '70-mouse.rules', + '70-touchpad.rules', + '75-net-description.rules', + '75-probe_mtd.rules', + '78-sound-card.rules', + '80-net-setup-link.rules', + '81-net-dhcp.rules', + '90-iocost.rules', + )], + + [files('80-drivers.rules'), + conf.get('HAVE_KMOD') == 1], + + [files('70-memory.rules'), + conf.get('HAVE_DMI') == 1], + + [files('70-power-switch.rules'), + enable_logind], +] + +all_rules = [] + +foreach tuple : rules + if tuple.length() == 1 or tuple[1] + install_data(tuple[0], + install_dir : udevrulesdir) + all_rules += tuple[0] + endif +endforeach + +rules_in = [ + ['50-udev-default.rules'], + ['60-persistent-storage.rules'], + ['64-btrfs.rules'], + ['99-systemd.rules'], + + ['70-uaccess.rules', enable_logind and conf.get('HAVE_ACL') == 1], + ['71-seat.rules', enable_logind], + ['73-seat-late.rules', enable_logind], + + ['90-vconsole.rules', conf.get('ENABLE_VCONSOLE') == 1], +] + +foreach tuple : rules_in + want = tuple.length() == 1 or tuple[1] + + rule = custom_target( + tuple[0], + input : tuple[0] + '.in', + output: tuple[0], + command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'], + install : want, + install_dir : udevrulesdir) + + if want + all_rules += rule + endif +endforeach |