règle udev pour attribuer des liens symboliques connus pour des périphériques série USB identiques

8

J'ai deux (et peut-être à l'avenir, plus) des périphériques série USB qui sont identiques (jusqu'au numéro de série, malheureusement) - ce sont en fait des mineurs BTC. Actuellement, ils finissent comme ttyUSBXoù X est 0, 1 ou 2, car il existe également un autre périphérique série USB non lié (qui ne doit pas être inquiété ici).

Je voudrais écrire une règle udev qui leur attribuera des noms prévisibles /dev, comme /dev/miner0où le zéro est un entier incrémenté. Peu m'importe lequel finit par lequel, mais j'ai besoin qu'ils soient dans une plage prévisible qui ne changera pas.

Actuellement, j'ai ceci:

SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="miner%n"

C'est assez proche, car je me retrouve avec des noms comme je veux. Le seul problème est, puisque les mineurs et le troisième appareil peuvent parfois apparaître dans un ordre aléatoire, je pourrais me retrouver avec deux miner0, miner1et miner2, mais je ne sais jamais lesquels (sans chercher manuellement). Si j'ajoute des périphériques série USB non mineurs (ce qui est une possibilité), cela aggravera le problème.

J'avais trouvé une référence à %equi semblait faire exactement ce que je voulais, mais cela ne semble plus exister .

Comment donner à ces appareils des noms prévisibles? Je préfère ne pas les lier à leur emplacement sur le bus USB aussi bien que possible.


Informations complémentaires / contexte

Il convient de mentionner que les noms ne me dérangent pas, juste qu'ils soient connus et inchangés même si / lorsque l'appareil est branché sur une autre prise USB. J'oublierais simplement le tout udev et j'utiliserais des entrées dans /dev/serial/by-id, mais comme ils ont le même numéro de série, il n'y en a qu'un!

Il convient également de mentionner que la raison de cette opération est que le logiciel de minage doit recevoir une liste d'appareils à rechercher et à détecter. Je peux simplement tout faire (il ne trouve essentiellement que tous les mineurs valides de la ttyUSB*gamme), mais cela ennuie l'appareil non mineur. J'ai donc besoin des noms des mineurs connus à l'avance afin de pouvoir le configurer pour utiliser uniquement ceux-ci. Malheureusement, il n'acceptera pas de caractère générique (il /dev/miner*est donc hors de question de simplement lui dire d'utiliser ), d'où ce problème.

Mark Embling
la source
2
(commentant depuis un téléphone, donc je ne peux pas regarder): Jetez un œil au code de votre distribution qui gère les liens / dev / cdrom, etc. Vous devriez être capable de glisser cette approche. Il utilise un fichier pour conserver les modifications, mais peut probablement le supprimer ou en utiliser un effacé au démarrage.
derobert
Merci, c'était une bonne idée qui ne m'est pas venue à l'esprit. Je viens de m'y intéresser et cela semble vraiment assez complexe. Je pense que cela pourrait être trop d'effort compte tenu du problème actuel, mais peut-être quelque chose que j'examinerais si j'avais affaire à des dizaines d'appareils plutôt qu'à des chiffres uniques.
Mark Embling
J'ai fait une pause et jeté un autre coup d'oeil et c'est déconcertant. Je vois que cela persiste dans un fichier et vous avez raison, je ne voudrais pas cela. Je ne peux pas comprendre la logique de la façon dont il comprend le prochain disponible, car il semble lire le fichier avant son écriture, puis y écrire après son utilisation de la sortie. Tout à fait déroutant. Et les scripts bash ne sont pas les plus faciles à suivre dans le meilleur des cas.
Mark Embling
La plupart des logiciels Unix ne prennent pas de caractères génériques, le shell est utilisé pour les développer. Pouvez-vous utiliser un autre outil pour développer les caractères génériques.
ctrl-alt-delor
@richard, je ne suis pas sûr. Compte tenu de ce que j'ai de la réponse ci-dessous, ce n'est pas essentiel car j'ai une séquence sensée pour laquelle j'ajoute manuellement les drapeaux dans le script qui lance le logiciel. Cependant, idéalement, pour résoudre cette partie aussi, je devrais passer du caractère générique (qui ressemblerait à /dev/btcminer/*) à une liste comme celle-ci: -S /dev/btcminer/0 -S /dev/btcminer/1 <and so on if present>quels sont les paramètres que le logiciel prend.
Mark Embling

Réponses:

4

Ceci n'est pas testé en combinaison:

Ajoutez une règle udev à IMPORT{program}="/usr/local/sbin/unique-num /run/miner-counter 0 MINER_NUM"vos mineurs.

Ensuite, vous pouvez utiliser un simple script shell, quelque chose comme ce programme quelque peu testé:

#!/bin/sh

if [ $# -ne 3 ]; then
    echo "Usage: $0 data-file initial var-name" >&2
    exit 1
fi

datfile="$1"
lockfile="$1.lck"
initial=$2
key="$3"

(
    flock -x 9
    num=$initial
    if [ -e "$datfile" ]; then
        read -r num < "$datfile"
    fi

    next=`expr $num + 1`;
    echo $next > "$datfile"

    echo "$key=$num"
) 9> "$lockfile"

Ensuite, vous pouvez utiliser cette variable d'environnement udev pour nommer vos mineurs.

derobert
la source
Cela a énormément aidé, merci. Je l'ai légèrement modifié pour que le programme renvoie juste le numéro (et ne prend que les deux premiers arguments), puis je l'ai utilisé à partir de l'option PROGRAM dans ma règle udev, dont la sortie est utilisée pour créer le nom du lien symbolique. J'ai maintenant /dev/btcminer/0et /dev/btcminer/1qui est (une version légèrement modifiée de) ce que je recherchais. Merci pour cela! :-)
Mark Embling
Je dois également mentionner que je devais également changer le shebang #!/bin/bash. Pour une raison quelconque, a shaffirmé qu'il y avait une erreur de syntaxe ("mot inattendu"). Je ne sais pas pourquoi ni ce qui shest sous Ubuntu, mais cela l'a résolu.
Mark Embling
1
@MarkEmbling Il s'avère que SUS ne nécessite que des nombres jusqu'à 9 pour être pris en charge. Donc, si vous changez ces deux 16s en 9s, cela fonctionnera /bin/sh. Au moins avec tiret. (/ bin / sh sur ce système est bash pour une raison quelconque)
derobert
C'est parfait, cela fonctionne maintenant parfaitement avec / bin / sh. Merci encore pour cela, j'ai beaucoup appris ces derniers jours. Jamais touché udev avant hier :-)
Mark Embling
2

La question a déjà une réponse acceptée, mais j'ai décidé de partager ma variation de la solution fournie par derobert .

Mes exigences étaient légèrement différentes - en plus de fournir des numéros d'index «incrémentés» aux nouveaux appareils - je voulais réacquérir les numéros d'index qui ont été abandonnés par les appareils qui ont été supprimés du système.

La règle udev pour configurer la variable d'environnement ressemblerait à ceci:

IMPORT{program}="/usr/local/sbin/unique-num /dev miner MINER_NUM"

Dans ma solution, je n'utilise pas de fichier pour garder la trace de l'index, je boucle simplement sur l'existant et trouvez le premier index disponible:

/usr/local/sbin/unique-num scénario:

#!/bin/bash

if [ $# -ne 3 ]; then
    echo "Usage: $0 location prefix var-name" >&2
    exit 1
fi

location="$1"
prefix="$2"
key="$3"

needindex=1
index=0

while [ $needindex -eq 1 ]
do
        if [ ! -e $location/$prefix$index ]; then
                needindex=0
                echo "$key=$index"
        else
                (( index++ ))
        fi
done

Bien sûr, cela imprimera le nom de la variable avec le premier index disponible, par exemple si ceux-ci existe déjà:

miner0
miner1
miner2

puis miner1se détache du système - il nous reste:

miner0
miner2

L'exécution du script renverra:

MINER_NUM=1

... car il s'agit désormais du premier index disponible .

dtmland
la source