Pagina 1 di 1

Udev: eseguire comando alla connessione di un device

Inviato: mer 16 set 2009, 15:11
da anycolouryoulike
Ho un card reader che richiede un comando per essere riconosciuto (lo stesso di cui si parla qui: http://lkml.org/lkml/2009/5/25/368).
Ho creato questa regola:

Codice: Seleziona tutto

$ cat /etc/udev/rules.d/99-card-reader.rules
KERNEL=="sdc", SUBSYSTEM=="block", ACTION=="add", RUN+="sleep 10; blockdev --rereadpt /dev/sdc"
Ma non funziona.
Il device dovrebbe essere questo:

Codice: Seleziona tutto

$ udevadm info -a -p /sys/block/sdc

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:1d.7/usb1/1-8/1-8:1.0/host10/target10:0:0/10:0:0:0/block/sdc':
    KERNEL=="sdc"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{range}=="16"
    ATTR{ext_range}=="256"
    ATTR{removable}=="1"
    ATTR{ro}=="0"
    ATTR{size}=="7812096"
    ATTR{alignment_offset}=="0"
    ATTR{capability}=="53"
    ATTR{stat}=="      36      239     2200      260        0        0        0        0        0      213      260"

  looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host10/target10:0:0/10:0:0:0':
    KERNELS=="10:0:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS=="sd"
    ATTRS{device_blocked}=="0"
    ATTRS{type}=="0"
    ATTRS{scsi_level}=="0"
    ATTRS{vendor}=="Generic "
    ATTRS{model}=="                "
    ATTRS{rev}=="6000"
    ATTRS{state}=="running"
    ATTRS{timeout}=="30"
    ATTRS{iocounterbits}=="32"
    ATTRS{iorequest_cnt}=="0xd7"
    ATTRS{iodone_cnt}=="0xd7"
    ATTRS{ioerr_cnt}=="0x3"
    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:1d.7/usb1/1-8/1-8:1.0/host10/target10:0:0':
    KERNELS=="target10:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS==""

  looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host10':
    KERNELS=="host10"
    SUBSYSTEMS=="scsi"
    DRIVERS==""

  looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0':
    KERNELS=="1-8: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:v090Cp6000d0100dc00dsc00dp00ic08isc06ip50"
    ATTRS{supports_autosuspend}=="0"

  looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1/1-8':
    KERNELS=="1-8"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="80"
    ATTRS{bMaxPower}=="500mA"
    ATTRS{urbnum}=="716"
    ATTRS{idVendor}=="090c"
    ATTRS{idProduct}=="6000"
    ATTRS{bcdDevice}=="0100"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="5"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Generic       ,   . "
    ATTRS{product}=="USB2.0 Card Reader  "
    ATTRS{serial}=="0000001       "

  looking at parent device '/devices/pci0000:00/0000:00:1d.7/usb1':
    KERNELS=="usb1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}=="  0mA"
    ATTRS{urbnum}=="83"
    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}=="1"
    ATTRS{devnum}=="1"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="8"
    ATTRS{quirks}=="0x0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Linux 2.6.31 ehci_hcd"
    ATTRS{product}=="EHCI Host Controller"
    ATTRS{serial}=="0000:00:1d.7"
    ATTRS{authorized_default}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:1d.7':
    KERNELS=="0000:00:1d.7"
    SUBSYSTEMS=="pci"
    DRIVERS=="ehci_hcd"
    ATTRS{vendor}=="0x8086"
    ATTRS{device}=="0x27cc"
    ATTRS{subsystem_vendor}=="0x1043"
    ATTRS{subsystem_device}=="0x8179"
    ATTRS{class}=="0x0c0320"
    ATTRS{irq}=="20"
    ATTRS{local_cpus}=="3"
    ATTRS{local_cpulist}=="0-1"
    ATTRS{modalias}=="pci:v00008086d000027CCsv00001043sd00008179bc0Csc03i20"
    ATTRS{enable}=="1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{msi_bus}==""
    ATTRS{companion}==""

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""

Qualche idea?
Grazie

Re: Udev: eseguire comando alla connessione di un device

Inviato: mer 16 set 2009, 16:03
da targzeta
Non dare per scontato che venga visto sempre come sdc. Inoltre è meglio fare un entry più specifica, altrimenti quel comando viene eseguito anche se ci metti una pennina.
Ancora, indica la creazione di un link simbolico, così ti riferisci sempre a lui quando vuoi indicare la tua scheda.

Generalmente gli errori più frequenti nelle regole di udev sono trovare la giusta sequenza di && che indicizzano ciò che si vuole. Per prima cosa, mettici solo la creazione del link simbolico e poi controlla che venga creato, se viene creato allora mettici anche l'esecuzione del programma.
In sostanza io farei una cosa del tipo:

Codice: Seleziona tutto

KERNEL=="sd?", ATTRS{idVendor}=="090c", ATTRS{idProduct}=="6000", SYMLINK+="mia_scheda"
Quindi, senza fare altro (non c'è bisogno di riavviare udevd per intenderci) inserisci la scheda e controlla che ti sia stato correttamente creato il link /dev/mia_scheda.
Se il link viene creato prova quindi ad eseguire il programma, potrebbe anche darsi che ci sia un errore nell'ambiente, sei sicuro che la variabile PATH sia settata nell'ambiente di udevd? Io non ricordo ora, comunque ti converrebbe in ogni caso dare l'intero path dei comandi che vuoi eseguire.

Se il link non viene creato, usa:

Codice: Seleziona tutto

udevadm monitor
per monitorare gli eventi che seguono l'inserzione della scheda.

Facci sapere,
Emanuele

Re: Udev: eseguire comando alla connessione di un device

Inviato: mer 16 set 2009, 17:36
da anycolouryoulike
spina ha scritto:Non dare per scontato che venga visto sempre come sdc. Inoltre è meglio fare un entry più specifica, altrimenti quel comando viene eseguito anche se ci metti una pennina.
Si lo so, alla fine ho provato sdc perché non ne funzionava nessuna...
spina ha scritto:Generalmente gli errori più frequenti nelle regole di udev sono trovare la giusta sequenza di && che indicizzano ciò che si vuole. Per prima cosa, mettici solo la creazione del link simbolico e poi controlla che venga creato, se viene creato allora mettici anche l'esecuzione del programma.
In sostanza io farei una cosa del tipo:

Codice: Seleziona tutto

KERNEL=="sd?", ATTRS{idVendor}=="090c", ATTRS{idProduct}=="6000", SYMLINK+="mia_scheda"
Quindi, senza fare altro (non c'è bisogno di riavviare udevd per intenderci) inserisci la scheda e controlla che ti sia stato correttamente creato il link /dev/mia_scheda.
Così funziona:

Codice: Seleziona tutto

$ cat /etc/udev/rules.d/99-card-reader.rules
KERNEL=="sd?", ATTRS{idVendor}=="090c", ATTRS{idProduct}=="6000", ACTION=="add", SYMLINK+="cardreader", RUN+="/usr/bin/cardreader"
Senza ACTION=="add" si crea un loop infinito:

Codice: Seleziona tutto

[10155.794015]  sdc: sdc1
[10163.885566] sd 33:0:0:0: [sdc] Assuming drive cache: write through
[10163.885570]  sdc: sdc1
[10171.991242] sd 33:0:0:0: [sdc] Assuming drive cache: write through
[10171.991246]  sdc: sdc1
[10180.100060] sd 33:0:0:0: [sdc] Assuming drive cache: write through
[10180.100065]  sdc: sdc1
[10188.218680] sd 33:0:0:0: [sdc] Assuming drive cache: write through
[10188.218685]  sdc: sdc1
[10196.306404] sd 33:0:0:0: [sdc] Assuming drive cache: write through
[10196.306408]  sdc: sdc1
[10204.421708] sd 33:0:0:0: [sdc] Assuming drive cache: write through
[10204.421713]  sdc: sdc1
[10212.532827] sd 33:0:0:0: [sdc] Assuming drive cache: write through
[10212.532831]  sdc: sdc1
[10220.648061] sd 33:0:0:0: [sdc] Assuming drive cache: write through
/usr/bin/cardreader è:

Codice: Seleziona tutto

$ cat /usr/bin/cardreader
#!/bin/sh
/usr/bin/sleep 8
/sbin/blockdev --rereadpt /dev/cardreader
Senza il path assoluto non funziona.
spina ha scritto:Se il link viene creato prova quindi ad eseguire il programma, potrebbe anche darsi che ci sia un errore nell'ambiente, sei sicuro che la variabile PATH sia settata nell'ambiente di udevd? Io non ricordo ora, comunque ti converrebbe in ogni caso dare l'intero path dei comandi che vuoi eseguire.
Infatti era proprio lì il problema.
Credo che non riconosca neanche il punto e virgola, da quello che ho potuto sperimentare (in effetti non è una shell).

Grazie mille dell'aiuto!
Ora funziona perfettamente!

Re: Udev: eseguire comando alla connessione di un device

Inviato: mer 16 set 2009, 17:47
da anycolouryoulike
Ho notato che il link simbolico non viene rimosso, ma (credo) non è di nessun disturbo.
Grazie ancora!

Re: Udev: eseguire comando alla connessione di un device

Inviato: mer 16 set 2009, 18:10
da targzeta
anycolouryoulike ha scritto:Ho notato che il link simbolico non viene rimosso, ma (credo) non è di nessun disturbo...
Puoi investigare. Per distrubare non dovrebbe disturbare nessuno, ma rimane lì e non punta a niente?
Potrebbe essere l'ACTION. Normalmente mettendoci una regola opposta dovrebbe bastare, quella con ACTION="remove" (controlla con udevadm monitor se viene inviato questo evento alla rimozione della scheda).
Se è l'ACTION che disturba, puoi optare per la soluzione più pulita di creare due regole una, senza ACTION per la sola creazione del link e l'altra con ACTION per l'esecuzione del programma.

Strano anche il fatto che vada in un loop infinto, forse è così proprio perchè hai bisogno di eseguire quei due comani? udevadm monitor cosa ti da, un sacco di eventi finchè non viengono eseguiti i due comandi?

Emanuele

Re: Udev: eseguire comando alla connessione di un device

Inviato: gio 17 set 2009, 14:18
da anycolouryoulike
spina ha scritto:
anycolouryoulike ha scritto:Ho notato che il link simbolico non viene rimosso, ma (credo) non è di nessun disturbo...
Puoi investigare. Per distrubare non dovrebbe disturbare nessuno, ma rimane lì e non punta a niente?
Potrebbe essere l'ACTION. Normalmente mettendoci una regola opposta dovrebbe bastare, quella con ACTION="remove" (controlla con udevadm monitor se viene inviato questo evento alla rimozione della scheda).
Se è l'ACTION che disturba, puoi optare per la soluzione più pulita di creare due regole una, senza ACTION per la sola creazione del link e l'altra con ACTION per l'esecuzione del programma.

Strano anche il fatto che vada in un loop infinto, forse è così proprio perchè hai bisogno di eseguire quei due comani? udevadm monitor cosa ti da, un sacco di eventi finchè non viengono eseguiti i due comandi?

Emanuele
Da quello che ho capito questo lettore è un pò scandente, perché praticamente non risponde correttamente alla prima chiamata del kernel, e quel comando serve proprio a farlo "rileggere" dal kernel una volta che si è "assestato" (le informazioni dettagliate le trovi al link che ho postato prima, io ho capito giusto il senso).
Quindi credo che una volta riletto, udev lo veda un'altra volta, e rilanci lo script, e così via.
Questo è l'output di udevadm monitor durante il loop:

Codice: Seleziona tutto

KERNEL[1253187819.556594] change   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc (block)
KERNEL[1253187819.556630] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
UDEV  [1253187819.557108] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc (block)
KERNEL[1253187827.607735] remove   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
KERNEL[1253187827.609684] change   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc (block)
KERNEL[1253187827.609827] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
UDEV  [1253187827.610564] change   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc (block)
UDEV  [1253187827.655862] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
UDEV  [1253187827.657037] remove   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
KERNEL[1253187835.724721] remove   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
KERNEL[1253187835.726627] change   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc (block)
KERNEL[1253187835.726658] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
UDEV  [1253187835.727152] change   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc (block)
UDEV  [1253187835.760872] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
UDEV  [1253187835.763630] remove   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
KERNEL[1253187843.846659] remove   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
KERNEL[1253187843.848486] change   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc (block)
KERNEL[1253187843.848507] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
UDEV  [1253187843.848996] change   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc (block)
UDEV  [1253187843.884135] add      /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
UDEV  [1253187843.885262] remove   /devices/pci0000:00/0000:00:1d.7/usb1/1-7/1-7:1.0/host10/target10:0:0/10:0:0:0/block/sdc/sdc1 (block)
Anzi riprovando adesso a computer riavviato, vedo che il link manco lo crea. O meglio lo crea, perché lo script viene lanciato e funziona, ma evidentemente con quel comando cambia il device e viene eliminato.
È un pò incasinata come cosa ma almeno non butto il lettore...
Grazie ancora!