GNU/Linux >> Tutoriels Linux >  >> Linux

Une introduction à Udev :le sous-système Linux pour la gestion des événements de périphérique

Udev est le sous-système Linux qui fournit à votre ordinateur les événements de périphérique. En clair, cela signifie que c'est le code qui détecte quand vous avez des choses branchées sur votre ordinateur, comme une carte réseau, des disques durs externes (y compris des clés USB), des souris, des claviers, des joysticks et des manettes de jeu, des lecteurs de DVD-ROM, etc. sur. Cela en fait un utilitaire potentiellement utile, et il est suffisamment bien exposé pour qu'un utilisateur standard puisse le scripter manuellement pour faire des choses comme effectuer certaines tâches lorsqu'un certain disque dur est branché.

Cet article vous apprend à créer un script udev déclenché par un événement udev, tel que brancher une clé USB spécifique. Une fois que vous avez compris le processus de travail avec udev, vous pouvez l'utiliser pour faire toutes sortes de choses, comme charger un pilote spécifique lorsqu'une manette de jeu est connectée ou effectuer une sauvegarde automatique lorsque vous connectez votre lecteur de sauvegarde.

Un script de base

La meilleure façon de travailler avec udev est en petits morceaux. N'écrivez pas tout le script à l'avance, mais commencez plutôt par quelque chose qui confirme simplement qu'udev déclenche un événement personnalisé.

En fonction de votre objectif pour votre script, vous ne pouvez pas garantir que vous verrez jamais les résultats d'un script de vos propres yeux, alors assurez-vous que votre script enregistre qu'il a été déclenché avec succès. L'emplacement habituel des fichiers journaux est dans /var répertoire, mais il s'agit principalement du domaine de l'utilisateur root. Pour tester, utilisez /tmp , qui est accessible aux utilisateurs normaux et est généralement nettoyé lors d'un redémarrage.

Ouvrez votre éditeur de texte préféré et saisissez ce script simple :

#!/usr/bin/bash

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

Placez ceci dans /usr/local/bin ou un tel endroit dans le chemin exécutable par défaut. Appelez-le trigger.sh et, bien sûr, rendez-le exécutable avec chmod +x .

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

Ce script n'a rien à voir avec udev. Lorsqu'il s'exécute, le script place un horodatage dans le fichier /tmp/udev.log . Testez le script vous-même :

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

L'étape suivante consiste à faire en sorte qu'udev déclenche le script.

Identification unique de l'appareil

Pour que votre script soit déclenché par un événement de périphérique, udev doit savoir dans quelles conditions il doit appeler le script. Dans la vraie vie, vous pouvez identifier une clé USB par sa couleur, le fabricant et le fait que vous venez de la brancher sur votre ordinateur. Votre ordinateur, cependant, a besoin d'un ensemble de critères différent.

Udev identifie les appareils par des numéros de série, des fabricants et même des numéros d'identification de fournisseur et d'identification de produit. Comme il s'agit du début de la durée de vie de votre script udev, soyez aussi large, non spécifique et inclusif que possible. En d'autres termes, vous voulez d'abord intercepter presque tous les événements udev valides pour déclencher votre script.

Avec le moniteur udevadm commande, vous pouvez accéder à udev en temps réel et voir ce qu'il voit lorsque vous branchez différents appareils. Devenez root et essayez-le.

$ su
# moniteur udevadm

La fonction de surveillance imprime les événements reçus pour :

  • UDEV :l'événement envoyé par udev après le traitement de la règle
  • KERNEL :l'uevent du noyau

Avec moniteur udevadm en cours d'exécution, branchez une clé USB et regardez toutes sortes d'informations s'afficher sur votre écran. Notez que le type d'événement est un ADD un événement. C'est un bon moyen d'identifier le type d'événement que vous souhaitez.

Le moniteur udevadm La commande fournit beaucoup de bonnes informations, mais vous pouvez les voir avec un formatage plus joli avec la commande udevadm info , en supposant que vous sachiez où se trouve actuellement votre clé USB dans votre /dev arbre. Si ce n'est pas le cas, débranchez et rebranchez votre clé USB, puis lancez immédiatement cette commande :

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

Si cette commande a renvoyé sdb :sdb1 , par exemple, vous savez que le noyau a attribué à votre clé USB le sdb étiquette.

Alternativement, vous pouvez utiliser le lsblk commande pour voir tous les lecteurs connectés à votre système, y compris leurs tailles et leurs partitions.

Maintenant que vous avez défini l'emplacement de votre lecteur dans votre système de fichiers, vous pouvez afficher les informations udev sur ce périphérique avec cette commande :

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

Cela renvoie beaucoup d'informations. Concentrez-vous sur le premier bloc d'informations pour l'instant.

Votre travail consiste à sélectionner les parties du rapport d'udev sur un appareil qui sont les plus uniques à cet appareil, puis à dire à udev de déclencher votre script lorsque ces attributs uniques sont détectés.

Les infos udevadm traite les rapports sur un périphérique (spécifié par le chemin du périphérique), puis "parcourt" la chaîne des périphériques parents. Pour chaque périphérique trouvé, il imprime tous les attributs possibles à l'aide d'un format clé-valeur. Vous pouvez composer une règle à faire correspondre en fonction des attributs d'un appareil et des attributs d'un seul appareil parent.

en regardant l'appareil '/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{amovible}=="1"
  ATTR{blah}=="blah"

Une règle udev doit contenir un attribut d'un seul appareil parent.

Les attributs parents sont des éléments qui décrivent un appareil au niveau le plus élémentaire, comme c'est quelque chose qui a été branché sur un port physique ou c'est quelque chose avec une taille ou il s'agit d'un périphérique amovible .

Depuis le label KERNEL de sdb peut changer en fonction du nombre d'autres lecteurs connectés avant de brancher cette clé USB, ce n'est pas l'attribut parent optimal pour une règle udev. Cependant, cela fonctionne pour une preuve de concept, vous pouvez donc l'utiliser. Un candidat encore meilleur est l'attribut SUBSYSTEM, qui identifie qu'il s'agit d'un périphérique système "bloc" (c'est pourquoi le lsblk commande répertorie le périphérique).

Ouvrez un fichier appelé 80-local.rules dans /etc/udev/rules.d et saisissez ce code :

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

Enregistrez le fichier, débranchez votre clé USB de test et redémarrez.

Attendez, redémarrez sur une machine Linux ?

Théoriquement, vous pouvez simplement émettre udevadm control --reload , qui devrait charger toutes les règles, mais à ce stade du jeu, il est préférable d'éliminer toutes les variables. Udev est suffisamment complexe et vous ne voulez pas rester allongé au lit toute la nuit à vous demander si cette règle n'a pas fonctionné à cause d'une erreur de syntaxe ou si vous auriez simplement dû redémarrer. Alors redémarrez indépendamment de ce que votre fierté POSIX vous dit.

Lorsque votre système est de nouveau en ligne, passez à une console texte (avec Ctl+Alt+F3 ou similaire) et branchez votre clé USB. Si vous utilisez un noyau récent, vous verrez probablement un tas de sorties dans votre console lorsque vous branchez le lecteur. Si vous voyez un message d'erreur tel que Impossible d'exécuter / usr /local/bin/trigger.sh , vous avez probablement oublié de rendre le script exécutable. Sinon, tout ce que vous voyez, espérons-le, c'est qu'un périphérique a été branché, qu'il a reçu une sorte d'affectation de périphérique du noyau, etc.

Maintenant, le moment de vérité :

$ cat /tmp/udev.log
Mar 31 octobre 01:35:28 NZDT 2035

Si vous voyez une date et une heure très récentes renvoyées par /tmp/udev.log , udev a correctement déclenché votre script.

Raffiner la règle en quelque chose d'utile

Le problème avec cette règle est qu'elle est très générique. Brancher une souris, une clé USB ou la clé USB de quelqu'un d'autre déclenchera votre script sans discernement. Il est maintenant temps de commencer à vous concentrer sur la clé USB exacte sur laquelle vous souhaitez déclencher votre script.

Une façon de procéder consiste à utiliser l'ID du fournisseur et l'ID du produit. Pour obtenir ces numéros, vous pouvez utiliser le lsusb commande.

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

Dans cet exemple, le 03f0:3307 avant TyCoon Corp. désigne les attributs idVendor et idProduct. Vous pouvez également voir ces chiffres dans la sortie de udevadm info -a -n /dev/sdb | vendeur grep , mais je trouve la sortie de lsusb un peu plus agréable pour les yeux.

Vous pouvez maintenant inclure ces attributs dans votre règle.

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

Testez ceci (oui, vous devriez toujours redémarrer, juste pour vous assurer que vous obtenez de nouvelles réactions d'udev), et cela devrait fonctionner comme avant, seulement maintenant si vous branchez, disons, une clé USB fabriquée par une autre société (donc avec un idVendor différent) ou une souris ou une imprimante, le script ne se déclenchera pas.

Continuez à ajouter de nouveaux attributs pour vous concentrer davantage sur celui-là un clé USB unique que vous souhaitez déclencher votre script. Utilisation de udevadm info -a -n /dev/sdb , vous pouvez obtenir des informations telles que le nom du fournisseur, parfois un numéro de série ou le nom du produit, etc.

Pour votre propre santé mentale, assurez-vous d'ajouter un seul nouvel attribut à la fois. La plupart des erreurs que j'ai commises (et que j'ai vu d'autres personnes en ligne faire) consistent à ajouter un tas d'attributs à leur règle udev et à me demander pourquoi cela ne fonctionne plus. Tester les attributs un par un est le moyen le plus sûr de s'assurer qu'udev peut identifier votre appareil avec succès.

Sécurité

Cela soulève les problèmes de sécurité liés à l'écriture de règles udev pour faire automatiquement quelque chose lorsqu'un lecteur est branché. Sur mes machines, je n'ai même pas activé le montage automatique, et pourtant cet article propose des scripts et des règles qui exécutent des commandes juste en avoir quelque chose de branché.

Deux choses à garder à l'esprit ici.

  1. Concentrez vos règles udev une fois qu'elles fonctionnent afin qu'elles déclenchent des scripts uniquement quand vous le voulez vraiment. L'exécution d'un script qui copie aveuglément des données vers ou depuis votre ordinateur est une mauvaise idée au cas où quelqu'un portant la même marque de clé USB la brancherait dans votre boîtier.
  2. N'écrivez pas votre règle et vos scripts udev et oubliez-les. Je sais quels ordinateurs ont mes règles udev dessus, et ces boîtes sont le plus souvent mes ordinateurs personnels, pas ceux que j'emmène à des conférences ou que j'ai dans mon bureau au travail. Plus un ordinateur est "social", moins il est susceptible d'être soumis à une règle udev susceptible de faire en sorte que mes données se retrouvent sur l'appareil de quelqu'un d'autre ou les données ou les logiciels malveillants de quelqu'un d'autre sur mon appareil.

En d'autres termes, comme pour une grande partie de la puissance fournie par un système GNU, il est de votre devoir d'être attentif à la manière dont vous utilisez cette puissance. Si vous en abusez ou ne le traitez pas avec respect, cela pourrait très bien tourner mal.

Udev dans le monde réel

Maintenant que vous pouvez confirmer que votre script est déclenché par udev, vous pouvez porter votre attention sur la fonction du script. Pour le moment, il est inutile, ne faisant rien de plus que de consigner le fait qu'il a été exécuté.

J'utilise udev pour déclencher des sauvegardes automatisées de mes clés USB. L'idée est que les copies maîtresses de mes documents actifs se trouvent sur ma clé USB (puisqu'elle va partout où je vais et peut être travaillée à tout moment), et ces documents maîtres sont sauvegardés sur mon ordinateur chaque fois que je branche la clé sur cette machine. En d'autres termes, mon ordinateur est le lecteur de sauvegarde et mes données de production sont mobiles. Le code source est disponible, alors n'hésitez pas à consulter le code d'attachup pour d'autres exemples de contraintes de vos tests udev.

Puisque c'est ce que j'utilise le plus pour udev, c'est l'exemple que j'utiliserai ici, mais udev peut saisir beaucoup d'autres choses, comme les manettes de jeu (ceci est utile sur les systèmes qui ne sont pas configurés pour charger le module xboxdrv lorsqu'une manette de jeu est connecté) et les caméras et les microphones (utiles pour définir les entrées lorsqu'un micro spécifique est connecté), alors sachez que c'est bon pour beaucoup plus que cet exemple.

Une version simple de mon système de sauvegarde est un processus à deux commandes :

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

La première ligne détecte ma clé USB avec les attributs déjà discutés, puis attribue à la clé USB un lien symbolique dans l'arborescence des périphériques. Le lien symbolique qu'il attribue est safety%n . Le %n est une macro udev qui se résout en quel que soit le numéro que le noyau donne au périphérique , tels que sdb1, sdb2, sdb3, etc. Alors %n serait le 1 ou le 2 ou le 3.

Cela crée un lien symbolique dans l'arborescence de développement, de sorte qu'il n'interfère pas avec le processus normal de connexion d'un périphérique. Cela signifie que si vous utilisez un environnement de bureau qui aime monter automatiquement les périphériques, vous ne lui causerez aucun problème.

La deuxième ligne exécute le script.

Mon script de sauvegarde ressemble à ceci :

#!/usr/bin/bash

mount /dev/safety1 /mnt/hd
sleep 2
rsync -az /mnt/hd/ /home/seth /sauvegardes/ &&démonter /dev/safety1

Le script utilise le lien symbolique, ce qui évite la possibilité qu'udev nomme le lecteur quelque chose d'inattendu (par exemple, si j'ai déjà une clé USB appelée DISK branchée sur mon ordinateur et que je branche mon autre clé USB également appelée DISK, la seconde sera étiqueté DISK_, ce qui déjouerait mon script). Il monte sécurité1 (la première partition du lecteur) à mon point de montage préféré de /mnt/hd .

Une fois monté en toute sécurité, il utilise rsync pour sauvegarder le lecteur dans mon dossier de sauvegarde (mon script actuel utilise rdiff-backup, et le vôtre peut utiliser la solution de sauvegarde automatisée que vous préférez).

Udev est votre développeur

Udev est un système très flexible et vous permet de définir des règles et des fonctions d'une manière que peu d'autres systèmes osent fournir aux utilisateurs. Apprenez-le et utilisez-le, et profitez de la puissance de POSIX.

Cet article s'appuie sur le contenu du manuel Slackermedia, qui est sous licence GNU Free Documentation License 1.3.


Linux
  1. 8 conseils pour la ligne de commande Linux

  2. Introduction à la commande Linux chown

  3. Introduction à la commande alternatives sous Linux

  4. Apprivoiser la commande tar :conseils pour gérer les sauvegardes sous Linux

  5. 8 sous-commandes Linux virsh pour la gestion des machines virtuelles sur la ligne de commande

Une introduction à l'émulateur de terminal DomTerm pour Linux

Introduction au système de fichiers Linux

GalliumOS :la distribution Linux pour les Chromebooks

Introduction à la gestion des conteneurs Linux

Une introduction rapide au système de fichiers Linux pour les utilisateurs de Windows.

Le guide ultime du sous-système Windows pour Linux (Windows WSL)