Rozpracowuję powoli działanie UDEV i jego reguł. Wprowadzenie do mojego problemu będzie trochę długie.
Po zmianie reguły lub dodaniu nowej potrzebne jest odczytanie na nowo reguł
oraz wysłanie zdarzenia
add na poziomie jądra (być może da się to jeszcze inaczej zrobić).
Do tego drugiego służy polecenie
udevadm trigger (udevtrigger przed wersją 117). Odpalone bez dodatkowych opcji wyzwala zdarzenia dla wszystkich wykrytych przez jądro urządzeń.
To jednak trwa kilkanaście sekund do kilku minut i potrafi zawiesić działanie systemu (musiałem odczekać cierpliwie nawet te parę minut). Chciałbym znaleźć opcje, które pozwolą mi
wyzwolić zdarzenie add tylko dla wybranego urządzenia, a nie wysyłać go dla całej masy.
Pewnym ograniczeniem jest opcja
--subsystem-match, ale najpierw przedstawię sytuację.
Napisałem sobie regułę tworzącą link do /dev/sda1
KERNEL=="sda1", \\
NAME="%k", \\
ATTRS{serial}=="0000000272",\\
SYMLINK+="pendr2-eqe"
i chciałbym wyzwolić zdarzenie tylko dla tego urządzenia. Oczywiście po zapisaniu reguły odświeżam bazę:
udevadm control --reload_rules
arctgx # udevadm info --attribute-walk --name=sda1
Udevinfo 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 '/block/sda/sda1':
KERNEL=="sda1"
SUBSYSTEM=="block"
DRIVER==""
ATTR{start}=="63"
ATTR{size}=="979902"
ATTR{stat}==" 80 2071 4080 376 0 0 0 0 0 244 376"
looking at parent device '/block/sda':
KERNELS=="sda"
SUBSYSTEMS=="block"
DRIVERS==""
ATTRS{range}=="16"
ATTRS{removable}=="1"
ATTRS{size}=="984576"
ATTRS{capability}=="13"
ATTRS{stat}==" 108 2110 4616 434 0 0 0 0 0 287 434"
looking at parent device '/devices/pci0000:00/0000:00:10.3/usb2/2-5/2-5:1.0/host1/target1:0:0/1:0:0:0':
KERNELS=="1:0:0:0"
SUBSYSTEMS=="scsi"
DRIVERS=="sd"
ATTRS{device_blocked}=="0"
ATTRS{type}=="0"
ATTRS{scsi_level}=="3"
ATTRS{vendor}=="Kingston"
ATTRS{model}=="DataTraveler 2.0"
ATTRS{rev}=="1.00"
ATTRS{state}=="running"
ATTRS{timeout}=="30"
ATTRS{iocounterbits}=="32"
ATTRS{iorequest_cnt}=="0x3caf"
ATTRS{iodone_cnt}=="0x3caf"
ATTRS{ioerr_cnt}=="0x1"
ATTRS{modalias}=="scsi:t-0x00"
ATTRS{evt_media_change}=="0"
ATTRS{queue_depth}=="1"
ATTRS{queue_type}=="none"
ATTRS{max_sectors}=="240"
looking at parent device '/devices/pci0000:00/0000:00:10.3/usb2/2-5/2-5:1.0/host1/target1:0:0':
KERNELS=="target1:0:0"
SUBSYSTEMS==""
DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:10.3/usb2/2-5/2-5:1.0/host1':
KERNELS=="host1"
SUBSYSTEMS==""
DRIVERS==""
looking at parent device '/devices/pci0000:00/0000:00:10.3/usb2/2-5/2-5:1.0':
KERNELS=="2-5:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="usb-storage"
ATTRS{bInterfaceNumber}=="00"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bNumEndpoints}=="02"
ATTRS{bInterfaceClass}=="08"
ATTRS{bInterfaceSubClass}=="06"
ATTRS{bInterfaceProtocol}=="50"
ATTRS{modalias}=="usb:v0951p1603d0200dc00dsc00dp00ic08isc06ip50"
looking at parent device '/devices/pci0000:00/0000:00:10.3/usb2/2-5':
KERNELS=="2-5"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{configuration}==""
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bmAttributes}=="80"
ATTRS{bMaxPower}==" 50mA"
ATTRS{urbnum}=="31674"
ATTRS{idVendor}=="0951"
ATTRS{idProduct}=="1603"
ATTRS{bcdDevice}=="0200"
ATTRS{bDeviceClass}=="00"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bNumConfigurations}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{speed}=="480"
ATTRS{busnum}=="2"
ATTRS{devnum}=="3"
ATTRS{version}==" 2.00"
ATTRS{maxchild}=="0"
ATTRS{quirks}=="0x0"
ATTRS{authorized}=="1"
ATTRS{manufacturer}=="Kingston"
ATTRS{product}=="DataTraveler 2.00000000272"
ATTRS{serial}=="0000000272"
looking at parent device '/devices/pci0000:00/0000:00:10.3/usb2':
KERNELS=="usb2"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{configuration}==""
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bmAttributes}=="e0"
ATTRS{bMaxPower}==" 0mA"
ATTRS{urbnum}=="71"
ATTRS{idVendor}=="1d6b"
ATTRS{idProduct}=="0002"
ATTRS{bcdDevice}=="0206"
ATTRS{bDeviceClass}=="09"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{bNumConfigurations}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{speed}=="480"
ATTRS{busnum}=="2"
ATTRS{devnum}=="1"
ATTRS{version}==" 2.00"
ATTRS{maxchild}=="6"
ATTRS{quirks}=="0x0"
ATTRS{authorized}=="1"
ATTRS{manufacturer}=="Linux 2.6.26.3-rt5-4 ehci_hcd"
ATTRS{product}=="EHCI Host Controller"
ATTRS{serial}=="0000:00:10.3"
ATTRS{authorized_default}=="1"
looking at parent device '/devices/pci0000:00/0000:00:10.3':
KERNELS=="0000:00:10.3"
SUBSYSTEMS=="pci"
DRIVERS=="ehci_hcd"
ATTRS{vendor}=="0x1106"
ATTRS{device}=="0x3104"
ATTRS{subsystem_vendor}=="0x1462"
ATTRS{subsystem_device}=="0x7120"
ATTRS{class}=="0x0c0320"
ATTRS{irq}=="21"
ATTRS{local_cpus}=="1"
ATTRS{local_cpulist}=="0"
ATTRS{modalias}=="pci:v00001106d00003104sv00001462sd00007120bc0Csc03i20"
ATTRS{enable}=="1"
ATTRS{broken_parity_status}=="0"
ATTRS{msi_bus}==""
looking at parent device '/devices/pci0000:00':
KERNELS=="pci0000:00"
SUBSYSTEMS==""
DRIVERS==""
Polecenie
arctgx# udevadm trigger --verbose --subsystem-match=block
/block/hda
/block/hda/hda1
/block/hda/hda2
/block/hda/hda3
/block/hda/hda4
/block/hda/hda5
/block/hda/hda6
/block/hda/hda7
/block/hda/hda8
/block/hdc
/block/ram0
/block/ram1
/block/ram10
/block/ram11
/block/ram12
/block/ram13
/block/ram14
/block/ram15
/block/ram2
/block/ram3
/block/ram4
/block/ram5
/block/ram6
/block/ram7
/block/ram8
/block/ram9
/block/sda
/block/sda/sda1
/class/bdi/1:0
/class/bdi/1:1
/class/bdi/1:10
/class/bdi/1:11
/class/bdi/1:12
/class/bdi/1:13
/class/bdi/1:14
/class/bdi/1:15
/class/bdi/1:2
/class/bdi/1:3
/class/bdi/1:4
/class/bdi/1:5
/class/bdi/1:6
/class/bdi/1:7
/class/bdi/1:8
/class/bdi/1:9
/class/bdi/22:0
/class/bdi/3:0
/class/bdi/8:0
daje pewne ograniczenie, ale, jak widać, jest nadal niedokładne, bo sieje ueventami dla reszty urządzeń blokowych. W dodatku niezbyt bezpieczne ze względu na wiechy. Opcja
--attr-match wydaje się naturalnym rozwiązaniem, ale nie potrafię jej poprawnie użyć. Próbowałem np.
udevadm trigger --verbose --subsystem-match=block --attr-match=size="979902"
ale to nie wyzwala zdarzenia "add" dla sda1. Kombinowałem z cudzysłowami w różnych miejscach tego warunku i nic.
Cel mogę osiągnąć ręcznie: polecenie
echo add >/sys/block/sda/sda1/uevent
wyzwala zdarzenie tylko tam gdzie trzeba, ale mimo to chciałbym zrobić to za pomocą narzędzi UDEV.
P.S. Sprawdzam rzecz za pomocą
udevadm monitor, wspomnianej opcji --verbose oraz zwykłego spojrzenia czy link powstał.
P.S.2. Podręcznik pokazuje składnię
--attr-match=attribute=value, a polecenie
udevadm trigger --help -
--attr-match=]>. Ale skąd to "file"...
P.S.3. Lektury:
1.
man udevadm2.
Documentation/sysfs-rules.txt w źródłach jądra
3.
http://www.disa.nu/pub/doc/sles10/usr/share/doc/manual/sles-admin_en/sec.udev.boot.html4.
http://dug.net.pl/texty/udev.pdf - stary dobry artykuł po polsku
5. do wypełnienia - dobre i działające przykłady użycia --attr-match.