udev regra para atribuir links simbólicos conhecidos para dispositivos seriais idênticos usb

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, na verdade, mineiros BTC. Atualmente eles acabam em ttyUSBX , onde X é 0, 1 ou 2, já que há outro dispositivo serial USB não relacionado (que não precisa se preocupar aqui).

Eu gostaria de escrever uma regra do udev que irá atribuir-lhes nomes previsíveis dentro de /dev , como /dev/miner0 , onde o zero é um inteiro de incremento. Eu não me importo com qual deles acaba sendo o que, mas eu preciso que eles estejam dentro de uma faixa previsível que não irá mudar.

Atualmente, tenho isto:

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, como os mineiros e o terceiro dispositivo podem aparecer em uma ordem aleatória, posso acabar com dois miner0 , miner1 e miner2 , mas nunca sei quais (sem olhar manualmente) . Se eu adicionar mais dispositivos seriais USB não-mineiros (o que é uma possibilidade), isso vai agravar o problema.

Eu encontrei referência para %e , que parecia ter feito exatamente o que eu queria, mas parece não existir mais .

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

Mais informações / histórico

Vale a pena mencionar que não estou tão incomodado com os nomes, apenas que eles são conhecidos e imutáveis mesmo quando o dispositivo é plugado em um soquete USB diferente. Eu simplesmente esqueceria toda a coisa do udev e usaria entradas em /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 o motivo para fazer isso é que o software de mineração precisa receber uma lista de dispositivos para sondar e localizar. Eu posso apenas fazer tudo (basicamente apenas encontra todos os mineradores válidos no intervalo ttyUSB* ), mas isso incomoda o dispositivo não-mineiro. Então eu preciso dos nomes dos mineiros conhecidos antes do tempo para que eu possa configurá-lo para usar apenas aqueles. Infelizmente, ele não aceita um caractere curinga (por isso, apenas dizer para usar /dev/miner* parece estar fora de questão), daí o problema.

    
por Mark Embling 14.12.2013 / 13:32

2 respostas

4

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

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

Então você poderia usar um script de shell simples, algo como este programa um pouco 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"

Então você pode usar essa variável de ambiente do udev para nomear seus mineiros.

    
por 15.12.2013 / 07:15
2

A pergunta já tem uma resposta aceita, mas decidi compartilhar minha variação da solução fornecida por < href="https://unix.stackexchange.com/users/977/derobert"> derobert .

Minhas exigências eram um pouco diferentes - além de fornecer números de índice "incrementados" para novos dispositivos - eu queria readquirir números de índice que foram abandonados por dispositivos que foram 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, eu simplesmente faço um loop sobre as <-href="/ questions / tagged / symlink" class="post-tag" title="show questions existentes marcou 'symlink' "> symlink e encontre o primeiro índice disponível:

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

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

Isso, é claro, imprimirá o var-name com o primeiro índice disponível, por exemplo, se esses symlink já existe:

miner0
miner1
miner2

e, em seguida, miner1 é separado do sistema - ficamos com:

miner0
miner2

A execução do script retornará:

MINER_NUM=1

... pois agora é o primeiro índice disponível .

    
por 03.04.2015 / 00:50