以下是我尝试使用 udev 规则实现的功能。也许我需要多个。
我有一张插入 USB 适配器的 micro-SD 卡。此卡有多个分区。我希望/dev/sdcard
在插入卡时有一个指向卡根目录的目录。我还希望将设备的组设置为特定组。
所以我的卡可能有/dev/sdd
,,/dev/sdd1
/dev/sdd2
我想/dev/sdcard
指出/dev/sdd
这是我目前正在使用的规则。
ATTRS{removable}=="1",SUBSYSTEMS=="block",SYMLINK+="sdcard",GROUP="rawdisk"
我目前看到 组已/dev/sdd
正确更改为rawdisk
。
$ ls -la /dev/sdd
brw-rw---- 1 root rawdisk 8, 48 Apr 19 14:51 /dev/sdd
然而,/dev/sdcard
指向/dev/sdd2
而不是/dev/sdd
$ ls -la /dev/sdcard
lrwxrwxrwx 1 root root 4 Apr 19 14:51 /dev/sdcard -> sdd2
移除卡并不会移除/dev/sdcard
$ udevadm info --name=/dev/sdd --attribute-walk
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.1/host4/target4:0:0/4:0:0:2/block/sdd':
KERNEL=="sdd"
SUBSYSTEM=="block"
DRIVER==""
ATTR{ro}=="0"
ATTR{size}=="0"
ATTR{stat}==" 3815 2182 44808 49392 16 0 128 2028 0 28516 51416"
ATTR{range}=="16"
ATTR{discard_alignment}=="0"
ATTR{events}=="media_change"
ATTR{ext_range}=="256"
ATTR{events_poll_msecs}=="2000"
ATTR{alignment_offset}=="0"
ATTR{inflight}==" 0 0"
ATTR{removable}=="1"
ATTR{capability}=="51"
ATTR{events_async}==""
looking at parent device '/devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.1/host4/target4:0:0/4:0:0:2':
KERNELS=="4:0:0:2"
SUBSYSTEMS=="scsi"
DRIVERS=="sd"
ATTRS{rev}=="1.00"
ATTRS{type}=="0"
ATTRS{scsi_level}=="0"
ATTRS{model}=="SD/MMC "
ATTRS{state}=="running"
ATTRS{queue_type}=="none"
ATTRS{iodone_cnt}=="0x2ad5"
ATTRS{iorequest_cnt}=="0x2ad5"
ATTRS{device_busy}=="0"
ATTRS{evt_capacity_change_reported}=="0"
ATTRS{timeout}=="30"
ATTRS{evt_media_change}=="0"
ATTRS{max_sectors}=="240"
ATTRS{ioerr_cnt}=="0xf6"
ATTRS{queue_depth}=="1"
ATTRS{vendor}=="Generic-"
ATTRS{evt_soft_threshold_reached}=="0"
ATTRS{device_blocked}=="0"
ATTRS{evt_mode_parameter_change_reported}=="0"
ATTRS{evt_lun_change_reported}=="0"
ATTRS{evt_inquiry_change_reported}=="0"
ATTRS{dh_state}=="detached"
ATTRS{iocounterbits}=="32"
ATTRS{inquiry}==""
ATTRS{eh_timeout}=="10"
looking at parent device '/devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.1/host4/target4:0:0':
KERNELS=="target4:0:0"
SUBSYSTEMS=="scsi"
DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.1/host4':
KERNELS=="host4"
SUBSYSTEMS=="scsi"
DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:0b.0/usb1/1-1/1-1:1.1':
KERNELS=="1-1:1.1"
SUBSYSTEMS=="usb"
DRIVERS=="usb-storage"
ATTRS{bInterfaceClass}=="08"
ATTRS{bInterfaceSubClass}=="06"
ATTRS{bInterfaceProtocol}=="50"
ATTRS{bNumEndpoints}=="02"
ATTRS{authorized}=="1"
ATTRS{supports_autosuspend}=="1"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceNumber}=="01"
ATTRS{interface}=="Bulk-In, Bulk-Out, Interface"
looking at parent device '/devices/pci0000:00/0000:00:0b.0/usb1/1-1':
KERNELS=="1-1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{devpath}=="1"
ATTRS{idVendor}=="0bda"
ATTRS{speed}=="480"
ATTRS{bNumInterfaces}==" 2"
ATTRS{bConfigurationValue}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{busnum}=="1"
ATTRS{devnum}=="3"
ATTRS{configuration}=="CARD READER"
ATTRS{bMaxPower}=="500mA"
ATTRS{authorized}=="1"
ATTRS{bmAttributes}=="80"
ATTRS{bNumConfigurations}=="1"
ATTRS{maxchild}=="0"
ATTRS{bcdDevice}=="6123"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{quirks}=="0x0"
ATTRS{serial}=="20070818000000000"
ATTRS{version}==" 2.00"
ATTRS{urbnum}=="126995"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="Generic"
ATTRS{removable}=="unknown"
ATTRS{idProduct}=="0161"
ATTRS{bDeviceClass}=="00"
ATTRS{product}=="USB2.0-CRW"
looking at parent device '/devices/pci0000:00/0000:00:0b.0/usb1':
KERNELS=="usb1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{devpath}=="0"
ATTRS{idVendor}=="1d6b"
ATTRS{speed}=="480"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{authorized_default}=="1"
ATTRS{busnum}=="1"
ATTRS{devnum}=="1"
ATTRS{configuration}==""
ATTRS{bMaxPower}=="0mA"
ATTRS{authorized}=="1"
ATTRS{bmAttributes}=="e0"
ATTRS{bNumConfigurations}=="1"
ATTRS{maxchild}=="12"
ATTRS{interface_authorized_default}=="1"
ATTRS{bcdDevice}=="0404"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{quirks}=="0x0"
ATTRS{serial}=="0000:00:0b.0"
ATTRS{version}==" 2.00"
ATTRS{urbnum}=="101"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="Linux 4.4.0-116-generic ehci_hcd"
ATTRS{removable}=="unknown"
ATTRS{idProduct}=="0002"
ATTRS{bDeviceClass}=="09"
ATTRS{product}=="EHCI Host Controller"
looking at parent device '/devices/pci0000:00/0000:00:0b.0':
KERNELS=="0000:00:0b.0"
SUBSYSTEMS=="pci"
DRIVERS=="ehci-pci"
ATTRS{irq}=="19"
ATTRS{subsystem_vendor}=="0x0000"
ATTRS{broken_parity_status}=="0"
ATTRS{class}=="0x0c0320"
ATTRS{companion}==""
ATTRS{driver_override}=="(null)"
ATTRS{consistent_dma_mask_bits}=="32"
ATTRS{dma_mask_bits}=="32"
ATTRS{local_cpus}=="f"
ATTRS{device}=="0x265c"
ATTRS{uframe_periodic_max}=="100"
ATTRS{enable}=="1"
ATTRS{msi_bus}=="1"
ATTRS{local_cpulist}=="0-3"
ATTRS{vendor}=="0x8086"
ATTRS{subsystem_device}=="0x0000"
ATTRS{numa_node}=="-1"
ATTRS{d3cold_allowed}=="0"
looking at parent device '/devices/pci0000:00':
KERNELS=="pci0000:00"
SUBSYSTEMS==""
DRIVERS==""
答案1
该规则过于通用,匹配所有节点 /dev/sdd、/dev/sdd1、/dev/sdd2。它匹配块设备及其分区节点。
因此 udev:
- 创建符号链接 /dev/sdcard → /dev/sdd
- 并快速将其替换为 /dev/sdcard → /dev/sdd1
- 然后再次使用 /dev/sdcard → /dev/sdd2
按照此规则查看:
ATTR{removable}=="1",SUBSYSTEM=="block",DRIVERS=="sd",SYMLINK+="sdcard",GROUP="rawdisk"
注意,我用 SUBSYSTEM、ATTR 替换了 SUBSYSTEMS、ATTRS。