GNU/Linux >> Linux Esercitazione >  >> Linux

Un'introduzione a Udev:il sottosistema Linux per la gestione degli eventi del dispositivo

Udev è il sottosistema Linux che fornisce al tuo computer gli eventi del dispositivo. In parole povere, ciò significa che è il codice che rileva quando hai elementi collegati al computer, come una scheda di rete, dischi rigidi esterni (incluse chiavette USB), mouse, tastiere, joystick e gamepad, unità DVD-ROM e così via su. Ciò la rende un'utilità potenzialmente utile ed è sufficientemente esposto che un utente standard può eseguirne manualmente uno script per eseguire operazioni come l'esecuzione di determinate attività quando un determinato disco rigido è collegato.

Questo articolo spiega come creare uno script udev attivato da alcuni eventi udev, come il collegamento di una chiavetta USB specifica. Una volta compreso il processo per lavorare con udev, puoi usarlo per fare qualsiasi cosa, come caricare un driver specifico quando è collegato un gamepad o eseguire un backup automatico quando colleghi l'unità di backup.

Uno script di base

Il modo migliore per lavorare con udev è in piccoli pezzi. Non scrivere l'intero script in anticipo, ma iniziare con qualcosa che conferma semplicemente che udev attiva un evento personalizzato.

A seconda del tuo obiettivo per il tuo script, non puoi garantire che vedrai mai i risultati di uno script con i tuoi occhi, quindi assicurati che lo script registri che è stato attivato correttamente. La posizione normale per i file di registro è in /var directory, ma è principalmente il dominio dell'utente root. Per il test, usa /tmp , che è accessibile da utenti normali e di solito viene ripulito con un riavvio.

Apri il tuo editor di testo preferito e inserisci questo semplice script:

#!/usr/bin/bash

/usr/bin/date >> /tmp/udev.log

Inseriscilo in /usr/local/bin o un posto simile nel percorso eseguibile predefinito. Chiamalo trigger.sh e, ovviamente, rendilo eseguibile con chmod +x .

$ sudo mv trigger.sh /usr/local/bin
$ sudo chmod +x /usr/local/bin/trigger.sh

Questo script non ha nulla a che fare con udev. Quando viene eseguito, lo script inserisce un timestamp nel file /tmp/udev.log . Prova tu stesso lo script:

$ /usr/local/bin/trigger.sh
$ cat /tmp/udev.log
Tue Oct 31 01:05:28 NZDT 2035

Il passaggio successivo è fare in modo che udev attivi lo script.

Identificazione univoca del dispositivo

Affinché il tuo script venga attivato da un evento del dispositivo, udev deve sapere in quali condizioni dovrebbe chiamare lo script. Nella vita reale, puoi identificare una chiavetta USB dal colore, dal produttore e dal fatto che l'hai appena collegata al computer. Il tuo computer, tuttavia, necessita di un diverso insieme di criteri.

Udev identifica i dispositivi in ​​base a numeri di serie, produttori e persino ID fornitore e numeri ID prodotto. Poiché questo è all'inizio della durata della vita del tuo script udev, sii il più ampio, non specifico e inclusivo possibile. In altre parole, vuoi prima catturare quasi tutti gli eventi udev validi per attivare il tuo script.

Con il monitor udevadm comando, puoi attingere a udev in tempo reale e vedere cosa vede quando colleghi dispositivi diversi. Diventa root e provalo.

$ su
# udevadm monitor

La funzione di monitoraggio stampa gli eventi ricevuti per:

  • UDEV:l'evento che udev invia dopo l'elaborazione della regola
  • KERNEL:il kernel uevent

Con udevadm monitor in esecuzione, collega una chiavetta USB e osserva come tutti i tipi di informazioni vengono riversate sullo schermo. Nota che il tipo di evento è un AGGIUNGI evento. È un buon modo per identificare il tipo di evento che desideri.

Il monitor udevadm comando fornisce molte buone informazioni, ma puoi vederle con una formattazione più carina con il comando udevadm info , supponendo che tu sappia dove si trova attualmente la tua chiavetta USB nel tuo /dev albero. In caso contrario, scollega e ricollega la chiavetta USB, quindi emetti immediatamente questo comando:

$ su -c 'dmesg | tail | fgrep -i sd*'

Se quel comando ha restituito sdb:sdb1 , ad esempio, sai che il kernel ha assegnato alla tua chiavetta USB sdb etichetta.

In alternativa, puoi utilizzare lsblk comando per vedere tutte le unità collegate al tuo sistema, comprese le loro dimensioni e partizioni.

Ora che hai stabilito dove si trova la tua unità nel tuo filesystem, puoi visualizzare le informazioni udev su quel dispositivo con questo comando:

# udevadm info -a -n /dev/sdb | less

Questo restituisce molte informazioni. Concentrati sul primo blocco di informazioni per ora.

Il tuo compito è selezionare le parti del rapporto di udev su un dispositivo che sono più unici per quel dispositivo, quindi dire a udev di attivare il tuo script quando vengono rilevati quegli attributi univoci.

Le informazioni udevadm elabora i rapporti su un dispositivo (specificato dal percorso del dispositivo), quindi "cammina" lungo la catena dei dispositivi principali. Per ogni dispositivo trovato, stampa tutti i possibili attributi utilizzando un formato chiave-valore. Puoi comporre una regola da abbinare in base agli attributi di un dispositivo più gli attributi di un unico dispositivo principale.

looking at device '/devices/000:000/blah/blah//block/sdb':
  KERNEL=="sdb"
  SUBSYSTEM=="block"
  DRIVER==""
  ATTR{ro}=="0"
  ATTR{size}=="125722368"
  ATTR{stat}==" 2765 1537 5393"
  ATTR{range}=="16"
  ATTR{discard\_alignment}=="0"
  ATTR{removable}=="1"
  ATTR{blah}=="blah"

Una regola udev deve contenere un attributo da un unico dispositivo padre.

Gli attributi principali sono elementi che descrivono un dispositivo dal livello più elementare, ad esempio è qualcosa che è stato collegato a una porta fisica o è qualcosa con una dimensione o questo è un dispositivo rimovibile .

Dal momento che l'etichetta KERNEL di sdb può cambiare a seconda di quante altre unità sono state collegate prima di collegare quella chiavetta USB, questo non è l'attributo padre ottimale per una regola udev. Tuttavia, funziona per un proof of concept, quindi potresti usarlo. Un candidato ancora migliore è l'attributo SUBSYSTEM, che identifica che si tratta di un dispositivo di sistema "a blocchi" (motivo per cui lsblk comando elenca il dispositivo).

Apri un file chiamato 80-local.rules in /etc/udev/rules.d e inserisci questo codice:

SUBSYSTEM=="block", ACTION=="add", RUN+="/usr/local/bin/trigger.sh"

Salva il file, scollega la chiavetta USB di prova e riavvia.

Aspetta, riavvia su una macchina Linux?

In teoria, puoi semplicemente emettere udevadm control --reload , che dovrebbe caricare tutte le regole, ma in questa fase del gioco è meglio eliminare tutte le variabili. Udev è abbastanza complesso e non vuoi stare sdraiato a letto tutta la notte chiedendoti se quella regola non ha funzionato a causa di un errore di sintassi o se avresti dovuto riavviare. Quindi riavvia indipendentemente da ciò che ti dice il tuo orgoglio POSIX.

Quando il tuo sistema è di nuovo online, passa a una console di testo (con Ctl+Alt+F3 o simile) e collega la chiavetta USB. Se stai eseguendo un kernel recente, probabilmente vedrai un sacco di output nella tua console quando colleghi l'unità. Se viene visualizzato un messaggio di errore come Impossibile eseguire / noi /local/bin/trigger.sh , probabilmente hai dimenticato di rendere eseguibile lo script. Altrimenti, si spera che tutto ciò che vedi è che un dispositivo è stato collegato, ha ricevuto una sorta di assegnazione del dispositivo del kernel e così via.

Ora, il momento della verità:

$ cat /tmp/udev.log
Tue Oct 31 01:35:28 NZDT 2035

Se vedi una data e un'ora molto recenti restituite da /tmp/udev.log , udev ha attivato correttamente il tuo script.

Perfezionare la regola in qualcosa di utile

Il problema con questa regola è che è molto generica. Collegare un mouse, una chiavetta USB o la chiavetta USB di qualcun altro attiverà indiscriminatamente lo script. Ora è il momento di iniziare a concentrarti sull'esatta chiavetta USB su cui desideri attivare lo script.

Un modo per farlo è con l'ID fornitore e l'ID prodotto. Per ottenere questi numeri, puoi utilizzare lsusb comando.

$ lsusb
Bus 001 Device 002: ID 8087:0024 Slacker Corp. Hub
Bus 002 Device 002: ID 8087:0024 Slacker Corp. Hub
Bus 003 Device 005: ID 03f0:3307 TyCoon Corp.
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 hub
Bus 001 Device 003: ID 13d3:5165 SBo Networks

In questo esempio, 03f0:3307 prima di TyCoon Corp. denota gli attributi idVendor e idProduct. Puoi anche vedere questi numeri nell'output di udevadm info -a -n /dev/sdb | fornitore di grep , ma trovo l'output di lsusb un po' più facile per gli occhi.

Ora puoi includere questi attributi nella tua regola.

SUBSYSTEM=="block", ATTRS{idVendor}=="03f0", ACTION=="add", RUN+="/usr/local/bin/thumb.sh"

Provalo (sì, dovresti comunque riavviare, solo per assicurarti di ricevere nuove reazioni da udev) e dovrebbe funzionare come prima, solo ora se colleghi, ad esempio, una chiavetta USB prodotta da un'altra azienda (quindi con un idVendor diverso) o un mouse o una stampante, lo script non verrà attivato.

Continua ad aggiungere nuovi attributi per concentrarti ulteriormente su quello uno chiavetta USB unica che desideri attivare il tuo script. Utilizzo di udevadm info -a -n /dev/sdb , puoi scoprire cose come il nome del fornitore, a volte un numero di serie o il nome del prodotto e così via.

Per la tua sanità mentale, assicurati di aggiungere solo un nuovo attributo alla volta. La maggior parte degli errori che ho commesso (e ho visto fare altre persone online) è di inserire un sacco di attributi nella loro regola udev e chiedermi perché la cosa non funziona più. Testare gli attributi uno per uno è il modo più sicuro per garantire che udev possa identificare correttamente il tuo dispositivo.

Sicurezza

Ciò solleva i problemi di sicurezza della scrittura di regole udev per eseguire automaticamente qualcosa quando un'unità è collegata. Sulle mie macchine, non ho nemmeno attivato il montaggio automatico, eppure questo articolo propone script e regole che eseguono comandi semplicemente avere qualcosa collegato.

Due cose da tenere a mente qui.

  1. Concentra le tue regole udev una volta che le hai attive in modo che attivino gli script solo quando vuoi davvero che lo facciano. L'esecuzione di uno script che copia alla cieca i dati da o verso il tuo computer è una cattiva idea nel caso in cui qualcuno che abbia la stessa marca di chiavetta USB la colleghi alla tua scatola.
  2. Non scrivere la tua regola udev e gli script e dimenticarli. So quali computer hanno le mie regole udev e quelle scatole sono spesso i miei personal computer, non quelli che porto in giro alle conferenze o che ho nel mio ufficio al lavoro. Più un computer è "sociale", meno è probabile che venga applicata una regola udev che potrebbe potenzialmente portare i miei dati a finire sul dispositivo di qualcun altro o i dati di qualcun altro o malware sul mio dispositivo.

In altre parole, come per gran parte della potenza fornita da un sistema GNU, è tuo compito essere consapevole di come stai esercitando tale potenza. Se ne abusi o non tratti con rispetto, potrebbe benissimo andare terribilmente storto.

Udev nel mondo reale

Ora che puoi confermare che il tuo script è attivato da udev, puoi rivolgere la tua attenzione alla funzione dello script. In questo momento, è inutile, non fa altro che registrare il fatto che è stato eseguito.

Uso udev per attivare i backup automatici delle mie pen drive. L'idea è che le copie master dei miei documenti attivi siano sulla mia chiavetta (dal momento che va ovunque io vada e potrebbe essere lavorato in qualsiasi momento), e quei documenti master vengono salvati sul mio computer ogni volta che collego l'unità quella macchina. In altre parole, il mio computer è l'unità di backup ei miei dati di produzione sono mobili. Il codice sorgente è disponibile, quindi sentiti libero di guardare il codice di allegato per ulteriori esempi su come vincolare i tuoi test udev.

Dato che è quello che uso di più udev, è l'esempio che userò qui, ma udev può prendere molte altre cose, come i gamepad (questo è utile su sistemi che non sono impostati per caricare il modulo xboxdrv quando un gamepad è collegato) e videocamere e microfoni (utili per impostare gli ingressi quando è collegato un microfono specifico), quindi renditi conto che va bene per molto di più di questo esempio.

Una versione semplice del mio sistema di backup è un processo a due comandi:

SUBSYSTEM=="block", ATTRS{idVendor}=="03f0", ACTION=="add", SYMLINK+="safety%n"
SUBSYSTEM=="block", ATTRS{idVendor}=="03f0", ACTION=="add", RUN+="/usr/local/bin/trigger.sh"

La prima riga rileva la mia chiavetta USB con gli attributi già discussi, quindi assegna alla chiavetta un collegamento simbolico all'interno dell'albero del dispositivo. Il collegamento simbolico che assegna è safety%n . Il %n è una macro udev che si risolve in qualunque numero il kernel assegna al dispositivo , come sdb1, sdb2, sdb3 e così via. Quindi %n sarebbe l'1 o il 2 o il 3.

Questo crea un collegamento simbolico nell'albero di sviluppo, quindi non interferisce con il normale processo di collegamento di un dispositivo. Ciò significa che se utilizzi un ambiente desktop a cui piace montare automaticamente i dispositivi, non causerai problemi.

La seconda riga esegue lo script.

Il mio script di backup è simile a questo:

#!/usr/bin/bash

mount /dev/safety1 /mnt/hd
sleep 2
rsync -az /mnt/hd/ /home/seth/backups/ && umount /dev/safety1

Lo script utilizza il collegamento simbolico, che evita la possibilità di udev nominare l'unità in modo imprevisto (ad esempio, se ho già una chiavetta USB chiamata DISK collegata al mio computer e collego l'altra chiavetta USB chiamata anche DISK, la seconda sarà etichettato DISK_, il che sventerebbe il mio script). Monta sicurezza1 (la prima partizione dell'unità) nel mio punto di montaggio preferito di /mnt/hd .

Una volta montato in sicurezza, utilizza rsync per eseguire il backup dell'unità nella mia cartella di backup (il mio script effettivo utilizza rdiff-backup e il tuo può utilizzare qualsiasi soluzione di backup automatizzata che preferisci).

Udev è il tuo sviluppatore

Udev è un sistema molto flessibile e consente di definire regole e funzioni in modi che pochi altri sistemi osano fornire agli utenti. Imparalo e usalo e goditi la potenza di POSIX.

Questo articolo si basa sui contenuti dello Slackermedia Handbook, che è concesso in licenza in base alla GNU Free Documentation License 1.3.


Linux
  1. 8 suggerimenti per la riga di comando di Linux

  2. Introduzione al comando chown di Linux

  3. Introduzione al comando alternatives in Linux

  4. Addomesticare il comando tar:suggerimenti per la gestione dei backup in Linux

  5. 8 sottocomandi Linux virsh per la gestione delle VM sulla riga di comando

Un'introduzione all'emulatore di terminale DomTerm per Linux

Introduzione al file system Linux

GalliumOS:la distribuzione Linux per i Chromebook

Introduzione alla gestione dei container Linux

Una rapida introduzione al filesystem Linux per gli utenti Windows.

La guida definitiva al sottosistema Windows per Linux (Windows WSL)