regla udev para asignar enlaces simbólicos conocidos para dispositivos serie USB idénticos

8

Tengo dos (y posiblemente en el futuro, más) dispositivos serie USB que son idénticos (hasta el número de serie, desafortunadamente), en realidad son mineros de BTC. Actualmente terminan ttyUSBXdonde X es 0, 1 o 2, ya que también hay otro dispositivo serie USB no relacionado (que no debe preocuparse aquí).

Me gustaría escribir una regla udev que les asigne nombres predecibles dentro /dev, como /dev/miner0donde el cero es un número entero incremental. No me importa cuál de ellos termine como cuál, pero sí necesito que estén dentro de un rango predecible que no cambie.

Actualmente tengo esto:

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

Esto está bastante cerca, ya que termino con nombres como quiero. El único problema es que, dado que los mineros y el tercer dispositivo a veces pueden aparecer en un orden aleatorio, podría terminar con dos de miner0, miner1y miner2, pero nunca sé cuáles dos (sin mirar manualmente). Si agrego más dispositivos serie USB no mineros (que es una posibilidad), agravará el problema.

Había encontrado una referencia a lo %eque parecía que hacía exactamente lo que quería, pero parece que ya no existe .

¿Cómo podría darles a estos dispositivos nombres predecibles? Preferiría no vincularlos a su ubicación en el bus USB también si es posible.


Más información / antecedentes

Vale la pena mencionar que no me preocupan los nombres, solo que sean conocidos e inmutables incluso si / cuando el dispositivo se conecta a una toma USB diferente. Simplemente olvidaría todo el asunto de udev y usaría entradas /dev/serial/by-id, pero como tienen el mismo número de serie, ¡solo hay una de ellas allí!

También vale la pena mencionar que la razón para hacer esto es que el software de minería necesita una lista de dispositivos para sondear y encontrar. Solo puedo hacer que haga todo (básicamente solo encuentra a todos los mineros válidos en el ttyUSB*rango), pero eso molesta al dispositivo que no es minero. Por lo tanto, necesito los nombres de los mineros conocidos de antemano para poder configurarlos para usar solo esos. Lamentablemente, no aceptará un comodín (por lo tanto, simplemente decirle que lo use /dev/miner*parece estar fuera de discusión), de ahí este problema.

Mark Embling
fuente
2
(comentando desde un teléfono, así que no puedo mirar): Eche un vistazo al código de su distribución que maneja enlaces / dev / cdrom, etc. Debería poder deslizar ese enfoque. Utiliza un archivo para persistir los cambios, pero es probable que pueda eliminarlo o usar uno borrado en el arranque.
derobert
Gracias, fue un buen pensamiento que no se me ocurrió. Sin embargo, acabo de investigarlo y parece realmente bastante complejo. Creo que podría ser demasiado esfuerzo dado el problema actual, pero tal vez algo que miraría si estuviera tratando con decenas de dispositivos en lugar de figuras únicas.
Mark Embling
Tomé un descanso y eché otro vistazo y es desconcertante. Veo que persiste en un archivo y tienes razón en que no quisiera eso. Sin embargo, no puedo entender la lógica de cómo está descubriendo el próximo disponible, ya que parece estar leyendo el archivo antes de escribirlo y luego escribirle después de usar la salida. Completamente desconcertante. Y los scripts de bash no son los más fáciles de seguir en el mejor de los casos.
Mark Embling
La mayoría del software de Unix no toma comodines, el shell se usa para expandirlos. ¿Puedes usar otra herramienta para expandir los comodines?
ctrl-alt-delor
@richard No estoy seguro. Dado lo que obtuve de la respuesta a continuación, no es esencial, ya que tengo una secuencia sensible para la cual agrego manualmente las banderas en el script que inicia el software. Sin embargo, idealmente para resolver esta parte también, necesitaría ir del comodín (que se vería así /dev/btcminer/*) a una lista como esta: -S /dev/btcminer/0 -S /dev/btcminer/1 <and so on if present>cuáles son los parámetros que toma el software.
Mark Embling

Respuestas:

4

Esto no se ha probado en combinación:

Agregue una regla udev IMPORT{program}="/usr/local/sbin/unique-num /run/miner-counter 0 MINER_NUM"para sus mineros.

Entonces podría usar un script de shell simple, algo como este programa algo probado:

#!/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"

Luego puede usar esa variable de entorno udev para nombrar a sus mineros.

derobert
fuente
Esto ayudó inmensamente, gracias. Lo modifiqué un poco para que el programa devuelva solo el número (y tome solo los dos primeros argumentos) y luego lo usé desde la opción PROGRAMA en mi regla udev, cuyo resultado se usa para hacer el nombre del enlace simbólico. Ahora tengo /dev/btcminer/0y /dev/btcminer/1cuál es (una versión ligeramente modificada de) lo que estaba buscando. ¡Gracias por esto! :-)
Mark Embling
También debo mencionar que también tuve que cambiar el shebang #!/bin/bash. Por alguna razón, shafirmó que hubo un error de sintaxis ("palabra inesperada"). No sé por qué o qué shhay bajo Ubuntu, pero eso lo resolvió.
Mark Embling
1
@MarkEmbling Resulta que SUS solo requiere que se admitan números hasta el 9. Entonces, si cambias esos dos 16s a 9s, entonces funcionará /bin/sh. Al menos con guión. (/ bin / sh en este sistema es bash por alguna razón)
derobert
Eso es perfecto, ahora funciona perfectamente con / bin / sh. Gracias de nuevo por esto, he aprendido mucho en los últimos días. Nunca toqué udev en absoluto antes de ayer :-)
Mark Embling
2

La pregunta ya tiene una respuesta aceptada, pero decidí compartir mi variación de la solución provista por derobert .

Mis requisitos eran ligeramente diferentes, además de proporcionar números de índice "incrementales" a los nuevos dispositivos, quería volver a adquirir números de índice que fueron dados por dispositivos que se han eliminado del sistema.

La regla de udev para configurar la variable de entorno se vería así:

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

En mi solución, no uso un archivo para realizar un seguimiento del índice, simplemente hago un bucle sobre el existente y encuentre el primer índice disponible:

/usr/local/sbin/unique-num guión:

#!/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

Esto, por supuesto, imprimirá el nombre de var con el primer índice disponible, por ejemplo si estos ya existe:

miner0
miner1
miner2

y luego miner1se separa del sistema, nos quedamos con:

miner0
miner2

La ejecución del script devolverá:

MINER_NUM=1

... ya que este es el primer índice disponible .

dtmland
fuente