Regra do udev para atribuir links simbólicos conhecidos para dispositivos seriais USB idênticos

8

Eu tenho dois (e possivelmente no futuro, mais) dispositivos seriais USB que são idênticos (até o número de série, infelizmente) - eles são realmente mineiros BTC. Atualmente, eles terminam como ttyUSBXonde X é 0, 1 ou 2, pois também há outro dispositivo serial USB não relacionado (que não precisa se preocupar aqui).

Eu gostaria de escrever uma regra do udev que os atribua a nomes previsíveis /dev, como /dev/miner0onde o zero é um número inteiro crescente. Eu não ligo para qual deles acaba como qual, mas preciso que eles estejam dentro de um intervalo previsível que não mude.

Atualmente eu tenho isso:

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

Isso é bem próximo, pois acabo com nomes como eu quero. O único problema é que, uma vez que os mineradores e o terceiro dispositivo podem aparecer em uma ordem aleatória, eu posso acabar com dois de miner0, miner1e miner2, mas nunca sei quais deles (sem olhar manualmente). Se eu adicionar mais dispositivos seriais usb não mineradores (o que é uma possibilidade), isso agravará o problema.

Eu tinha encontrado uma referência à %equal parecia exatamente o que eu queria, mas parece não existir mais .

Como posso dar nomes previsíveis a esses dispositivos? Eu preferiria não amarrá-los à sua localização no barramento USB também, se possível.


Mais informações / antecedentes

Vale ressaltar que não sou tão incomodado com o nome, apenas com o fato de serem conhecidos e imutáveis, mesmo se / quando o dispositivo for conectado a um soquete USB diferente. Eu simplesmente esqueceria a coisa toda do udev e usaria as entradas /dev/serial/by-id, mas como elas têm o mesmo número de série, há apenas uma delas lá!

Também vale a pena mencionar que a razão para fazer isso é que o software de mineração precisa receber uma lista de dispositivos para sondar e encontrar. Eu posso fazer tudo (basicamente encontra todos os mineiros válidos no ttyUSB*intervalo), mas isso irrita o dispositivo não mineiro. Por isso, preciso dos nomes dos mineiros conhecidos com antecedência, para que eu possa configurá-lo para usar apenas esses. Infelizmente, ele não aceita um curinga (portanto, apenas dizer a ele para usar /dev/miner*parece estar fora de questão), daí esse problema.

Mark Embling
fonte
2
(comentando a partir de um telefone, para que eu não possa olhar): Dê uma olhada no código da sua distro que lida com links / dev / cdrom etc. Você deve poder passar o dedo nessa abordagem. Ele usa um arquivo para persistir alterações, mas provavelmente pode retirá-lo ou usar um arquivo limpo na inicialização.
derobert
Obrigado, esse foi um bom pensamento que não me ocorreu. Acabei de investigar e parece realmente bastante complexo. Eu acho que pode ser muito esforço dado o problema atual, mas talvez algo que eu verificaria se estivesse lidando com dezenas de dispositivos em vez de números únicos.
Mark Embling
Fiz uma pausa e dei outra olhada e é desconcertante. Vejo que ele persiste em um arquivo e você tem razão em não querer isso. No entanto, não consigo descobrir a lógica de como está a descobrir o próximo disponível, pois parece estar lendo o arquivo antes de ser escrito e depois escrevendo depois de ter usado a saída. Totalmente desconcertante. E os scripts do bash não são os mais fáceis de seguir na melhor das hipóteses.
Mark Embling
A maioria dos softwares Unix não aceita curingas, o shell é usado para expandi-los. Você pode usar outra ferramenta para expandir os curingas.
Ctrl-alt-delor
@richard Eu não tenho certeza. Dado o que recebi da resposta abaixo, não é essencial, pois tenho uma sequência sensata à qual adiciono manualmente os sinalizadores no script que inicia o software. No entanto, idealmente, para resolver essa parte também, eu precisaria ir do curinga (que seria parecido /dev/btcminer/*) para uma lista como esta: -S /dev/btcminer/0 -S /dev/btcminer/1 <and so on if present>quais são os parâmetros que o software utiliza.
Mark Embling

Respostas:

4

Isso não foi testado em combinação:

Adicione uma regra do udev IMPORT{program}="/usr/local/sbin/unique-num /run/miner-counter 0 MINER_NUM"para seus mineiros.

Então você pode usar um script de shell simples, algo como este programa um tanto testado:

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

Em seguida, você pode usar essa variável de ambiente udev para nomear seus mineiros.

derobert
fonte
Isso ajudou imensamente, obrigado. Ajustei um pouco para que o programa retornasse apenas o número (e pegue apenas os dois primeiros argumentos) e o usei na opção PROGRAM na minha regra do udev, cuja saída são eles usados ​​para criar o nome do link simbólico. Agora eu tenho /dev/btcminer/0e /dev/btcminer/1qual é (uma versão ligeiramente aprimorada) do que eu estava procurando. Obrigado por isso! :-)
Mark Embling
Também devo mencionar que eu tive que mudar o shebang #!/bin/bashtambém. Por alguma razão, shalegou que houve um erro de sintaxe ("palavra inesperada"). Não sei por que ou o que shestá sob o Ubuntu, mas isso resolveu.
Mark Embling
1
@MarkEmbling Parece que o SUS exige apenas números de até 9 para suporte. Então, se você alterar esses dois 16s para 9s, funcionará /bin/sh. Pelo menos com traço. (/ bin / sh neste sistema é bash por algum motivo)
derobert
Perfeito, agora funciona perfeitamente com / bin / sh. Mais uma vez obrigado por isso, eu aprendi muito nos últimos dias. Nunca toquei em udev antes de ontem :-) #
58275 Mark Embling
2

A pergunta já tem uma resposta aceita, mas decidi compartilhar minha variação da solução fornecida pela derobert .

Meus requisitos eram um pouco diferentes - além de fornecer números de índice "incrementais" para novos dispositivos - eu queria recuperar os números de índice cedidos por dispositivos removidos do sistema.

A regra do udev para configurar a variável de ambiente seria algo como isto:

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

Na minha solução, eu não uso um arquivo para acompanhar o índice, simplesmente faço um loop sobre o existente e encontre o primeiro índice disponível:

/usr/local/sbin/unique-num roteiro:

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

Obviamente, isso imprimirá o nome do var com o primeiro índice disponível, por exemplo, se estes já existe:

miner0
miner1
miner2

e depois miner1é desconectado do sistema - somos deixados com:

miner0
miner2

A execução do script retornará:

MINER_NUM=1

... como este é agora o primeiro índice disponível .

dtmland
fonte