Правило udev для назначения известных символических ссылок для идентичных последовательных USB-устройств

8

У меня есть два (и, возможно, в будущем, больше) последовательных USB-устройства, которые идентичны (вплоть до серийного номера, к сожалению) - на самом деле это майнеры BTC. В настоящее время они заканчиваются тем, что ttyUSBXгде X равен 0, 1 или 2, так как есть и другое не связанное последовательное USB-устройство (о котором здесь не нужно беспокоиться).

Я хотел бы написать правило udev, которое будет присваивать им предсказуемые имена /dev, например, /dev/miner0где ноль - увеличивающееся целое число. Мне все равно, кто из них в итоге окажется, но мне нужно, чтобы они находились в предсказуемом диапазоне, который не изменится.

В настоящее время у меня есть это:

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

Это довольно близко, так как я получаю имена, которые хочу. Единственная проблема заключается в том, что майнеры и третье устройство иногда могут отображаться в случайном порядке, у меня может получиться два из miner0, miner1и miner2, но я никогда не знаю, какие два (без просмотра вручную). Если я добавлю больше не майнерских устройств с последовательным интерфейсом USB (что возможно), это усугубит проблему.

Я нашел ссылку, %eкоторая выглядела так, как будто она сделала именно то, что я хотел, но , похоже , она больше не существует .

Как я могу дать этим устройствам предсказуемые имена? Я бы предпочел не привязывать их к их расположению на шине USB, если это возможно.


Дополнительная информация / справочная информация

Стоит отметить, что меня не очень беспокоит, какие имена есть, просто они известны и неизменны, даже если / когда устройство подключено к другому USB-разъему. Я бы просто забыл всю вещь об udev и использовал бы записи /dev/serial/by-id, но поскольку они имеют одинаковый серийный номер, там только один из них!

Стоит также упомянуть, что причина для этого заключается в том, что программное обеспечение для майнинга должно иметь список устройств для поиска и поиска. Я могу просто сделать все (в основном он находит всех допустимых майнеров в ttyUSB*диапазоне), но это раздражает не майнерское устройство. Поэтому мне нужны заранее известные имена майнеров, чтобы я мог настроить их на использование только этих. К сожалению, он не примет подстановочный знак (так что просто сказать, что его использовать не /dev/miner*может быть и речи), следовательно, эта проблема.

Марк Эмблинг
источник
2
(комментируя с телефона, поэтому я не могу посмотреть): взгляните на код вашего дистрибутива, который обрабатывает ссылки / dev / cdrom и т. д. Вы должны иметь возможность использовать этот подход. Он использует файл для сохранения изменений, но может удалить его или использовать один, очищенный при загрузке.
Дероберт
Спасибо, это была хорошая мысль, которая не пришла мне в голову. Я только что посмотрел на это, и это кажется довольно сложным. Я думаю, что это может быть слишком много усилий, учитывая текущую проблему, но, возможно, я бы посмотрел, если бы имел дело с десятками устройств, а не с однозначными числами.
Марк Эмблинг
Был перерыв, еще раз посмотрел, и это сбивает с толку. Я вижу, что это сохраняется в файл, и вы правы в том, что я бы этого не хотел. Я не могу понять логику того, как он вычисляет следующий доступный, хотя он, кажется, читает файл перед его записью и затем записывает в него после того, как он использовал вывод. Совершенно сбивает с толку. И скрипты bash - не самый простой способ следовать в лучшие времена.
Марк Эмблинг
Большинство программного обеспечения Unix не принимает подстановочные знаки, оболочка используется для их расширения. Можете ли вы использовать другой инструмент для расширения подстановочных знаков.
Ctrl-Alt-Delor
@ Richard Я не уверен. Учитывая то, что я получил из приведенного ниже ответа, это не существенно, поскольку у меня есть разумная последовательность, для которой я вручную добавляю флаги в скрипт, запускающий программное обеспечение. Однако в идеале, чтобы решить и эту часть, мне нужно перейти от подстановочного знака (который будет выглядеть /dev/btcminer/*) к списку, подобному следующему: -S /dev/btcminer/0 -S /dev/btcminer/1 <and so on if present>какие параметры принимает программное обеспечение.
Марк Эмблинг

Ответы:

4

Это не проверено в комбинации:

Добавьте правило udev IMPORT{program}="/usr/local/sbin/unique-num /run/miner-counter 0 MINER_NUM"для ваших майнеров.

Тогда вы можете использовать простой сценарий оболочки, что-то вроде этой несколько протестированной программы:

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

Затем вы можете использовать эту переменную окружения udev для именования ваших майнеров.

derobert
источник
Это очень помогло, спасибо. Я немного подправил его, чтобы программа возвращала только число (и принимает только первые два аргумента), а затем использовал его из опции PROGRAM в моем правиле udev, вывод которого используется для создания имени символической ссылки. У меня сейчас есть /dev/btcminer/0и /dev/btcminer/1что (слегка подправленная версия), что я был после. Спасибо за это! :-)
Марк Эмблинг
Я должен также упомянуть, что я должен был также изменить шебанг #!/bin/bash. По какой-то причине shутверждал , что произошла синтаксическая ошибка («неожиданное слово»). Не знаю почему или что shнаходится под Ubuntu, но это решило это.
Марк Эмблинг
1
@MarkEbing Оказывается, для поддержки SUS требуются только цифры до 9. Так что если вы поменяете эти две 16s на 9s, то это сработает /bin/sh. По крайней мере, с тире. (/ bin / sh в этой системе по какой-то причине является bash)
derobert
Это прекрасно, теперь он отлично работает с / bin / sh. Еще раз спасибо за это, я многому научился за последние пару дней. Никогда не трогал udev вообще до вчерашнего дня :-)
Марк Эмблинг
2

На этот вопрос уже есть принятый ответ, но я решил поделиться своим вариантом решения, предложенным Деробертом .

Мои требования были немного другими - в дополнение к предоставлению «увеличивающихся» индексных номеров для новых устройств - я хотел получить заново индексные номера, которые были выданы устройствами, которые были удалены из системы.

Правило udev для установки переменной окружения будет выглядеть примерно так:

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

В моем решении я не использую файл для отслеживания индекса, я просто перебираю существующий и найдите первый доступный индекс:

/usr/local/sbin/unique-num сценарий:

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

Это, конечно, напечатает имя переменной с первым доступным индексом, например, если они уже существует:

miner0
miner1
miner2

а затем miner1отсоединяется от системы - у нас остается:

miner0
miner2

Запуск скрипта вернет:

MINER_NUM=1

... так как теперь это первый доступный индекс .

dtmland
источник