LINUX.ORG.RU

udev собрать симлинк на основе атрибутов

 , , ,


0

4

При подключении переходников USB-UART они именуются /dev/ttyUSB0, /dev/ttyACM50 и т.д. Хотелось бы дать им более осмысленные имена. Для этого написал правило udev’а:

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", PROGRAM="/bin/bash -c \"ls /dev | grep tty_ft232r_ | wc -l \"", SYMLINK+="tty_ft232r_%c"

Потом подключаю свое самодельное устройство, которое выглядит как сдвоенный переходник, причем назначения у «частей» переходника разные и описываются именем интерфейса. Это тоже решаемо:

SUBSYSTEM=="tty", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05df" ENV{CONNECTED_vusb}="yes"
ENV{CONNECTED_vusb}=="yes", SUBSYSTEM=="tty", ATTRS{interface}=="term_cdc", PROGRAM="/bin/bash -c \"ls /dev | grep tty_TERM_CDC_ | wc -l \"", SYMLINK+="tty_TERM_CDC_%c"
ENV{CONNECTED_vusb}=="yes", SUBSYSTEM=="tty", ATTRS{interface}=="term", PROGRAM="/bin/bash -c \"ls /dev | grep tty_TERM_ | wc -l \"", SYMLINK+="tty_TERM_%c

Но мне не понравилось указывать имя симлинка в двух местах для каждого устройства: при подсчете количества и при собственно формировании симлинка. Интуитивно кажется, что должно быть решение.

Если у устройства уже есть атрибут ATTRS{interface} с нормальным текстовым описанием, нельзя ли его как-то подставить его в симлинк?

Если у устройства уже есть атрибут ATTRS{interface} с нормальным текстовым описанием, нельзя ли его как-то подставить его в симлинк?

SYMLINK+="foobar-$attr{interface}"?

man udev, ну ё-моё.

intelfx ★★★★★ ()
Ответ на: комментарий от intelfx

SYMLINK+=«foobar-$attr{interface}»?

man udev, ну ё-моё.

А самому проверить перед отправкой «совета»? Если бы все было так просто, я бы тему не создавал.

COKPOWEHEU ()
Ответ на: комментарий от intelfx

В udev, очевидно, не работает, где же еще. Вместо переменной подставляет пустоту.

Мне не на чем проверять.

Но не высказать свое невероятно ценное вкупе с обвинением в безграмотности мнение было ну никак нельзя.

COKPOWEHEU ()
Ответ на: комментарий от COKPOWEHEU

не высказать свое невероятно ценное

Ты пришёл на форум с вопросом, алё. На форумах, если тебе не известно, знающие люди отвечают на вопросы незнающих. Поэтому да, невероятно ценное.

вкупе с обвинением в безграмотности

Так ты не потрудился даже указать, где конкретно у тебя возникла проблема и какие методы её решения ты уже попробовал. Ни тогда, ни сейчас.

Вместо переменной подставляет пустоту.

Ну потому что надо руки из жопы достать.

Мы ведь не в Job. Я ответил на твой вопрос (используя всю информацию о твоей проблеме, которую ты соизволил сообщить), а прочитать в мане про семантику ATTRS и $attr, и в частности как именно при подстановке атрибута выбирается родительское устройство — это, извини, уже твоя задача. И может быть я бы и с ней тебе помог, если бы ты не начал хамить.


Вот не поленился, раскопал в шкафу железку с тремя UART’ами, написал правило, всё работает. Мой первоначальный совет на 100% валиден, именно в той формулировке, в которой он был дан. Ты должен мне эти пятнадцать минут жизни обратно.

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 3)
Ответ на: комментарий от intelfx

Ты пришёл на форум с вопросом, алё. На форумах, если тебе не известно, знающие люди отвечают на вопросы незнающих. Поэтому да, невероятно ценное.

Да ну? И в чем же ценность этого замечания, что нового я или другой форумчанин из него узнал? Что чтобы обосрать оппонента не нужно даже попытаться вникнуть прочитать его вопрос? Так это и так все знали.

Я ответил на твой вопрос (используя всю информацию о твоей проблеме, которую ты соизволил сообщить)

Нет, не ответил.

Если информации недостаточно, надо или явно написать чего не хватает или, если лень спрашивать, попытаться додумать.

Вот не поленился, раскопал в шкафу железку с тремя UART’ами, написал правило, всё работает. Мой первоначальный совет на 100% валиден, именно в той формулировке, в которой он был дан.

Первоначальный совет добавить $attr{interface} дает правило

SUBSYSTEM=="tty", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05df", SYMLINK+="tty_$attr{interface}"

Закономерный результат:

lrwxrwxrwx  1 root root               7 апр 11 20:13 tty_ -> ttyACM0

Как и говорилось сначала: вместо $attr{interface} подставляется пустота.

Но, может быть, многомудрый @intelfx имел в виду подставить уже после фильтра vid:pid:

SUBSYSTEM=="tty", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05df" ENV{CONNECTED_vusb}="yes"
ENV{CONNECTED_vusb}=="yes", SUBSYSTEM=="tty", ATTRS{interface}=="progr", SYMLINK+="tty_$attr{interface}"

Так оно работает. Но если сравнение интерфейса из условий убрать:

SUBSYSTEM=="tty", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05df" ENV{CONNECTED_vusb}="yes"
ENV{CONNECTED_vusb}=="yes", SUBSYSTEM=="tty", SYMLINK+="tty_$attr{interface}"

То внезапно снова не работает.

И где же тут хваленое решение задачи, на которое многомудрый @intelfx потратил целых 15 минут жизни? Если бы ручное прописывание интерфейсов меня устраивало, я бы эту тему не создавал.

И может быть я бы и с ней тебе помог, если бы ты не начал хамить.

А, это стиль ведения дискуссии такой: начать с хамства, а когда ответят тем же, гордо задрать нос и не отвечать, мол мне нахамили.

COKPOWEHEU ()
Ответ на: комментарий от COKPOWEHEU

Так оно работает.

Если честно, когда я это увидел, удивился почему это не работало у меня, и хотел извиниться. Но нет, как оказалось, исходную задачу оно не решает, и извиняться мне не за что.

COKPOWEHEU ()
Ответ на: комментарий от COKPOWEHEU

Первоначальный совет добавить $attr{interface} дает правило

<…>

Как и говорилось сначала: вместо $attr{interface} подставляется пустота.

Потому что, как я уже сказал, надо достать руки из жопы, включить думалку и соизволить заглянуть в ман (на который я указал во всё том же первом ответе), чтобы изучить семантику $attr.

А, это стиль ведения дискуссии такой: начать с хамства

Укажи, пожалуйста, где я «начал с хамства».

intelfx ★★★★★ ()
Ответ на: комментарий от intelfx

А семантика такова, что вместо $attr подставляется либо значение атрибута текущего устройства, либо значение атрибута того родительского устройства, которое было найдено во время обработки условия ATTRS{}, если таковое было. При этом нужно также иметь в виду, что во время обработки одного правила все условия ATTRS{} обязаны сработать на одном и том же уровне.

Ну а поскольку idProduct/idVendor и interface лежат на разных уровнях вложенности, то нужно сделать небольшой танец и разбить правило на два:

ACTION!="remove", SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", GOTO="found"
GOTO="end"
LABEL="found"
ATTRS{interface}=="?*", SYMLINK+="uarts/$attr{interface}"
LABEL="end"
intelfx ★★★★★ ()
Ответ на: комментарий от intelfx

Ну а поскольку idProduct/idVendor и interface лежат на разных уровнях вложенности, то нужно сделать небольшой танец и разбить правило на два:

Это мне известно и было сделано еще в первом посте, только другим способом - заведением переменной ENV{CONNECTED_vusb}=«yes»

ATTRS{interface}=="?*"

А вот это помогло, спасибо. Интересно, что для более «верхних» атрибутов (положение на шине, имя драйвера) это не нужно. Даже сейчас, зная, что решение есть, не могу найти его в man'е.

COKPOWEHEU ()
Ответ на: комментарий от COKPOWEHEU

Интересно, что для более «верхних» атрибутов (положение на шине, имя драйвера) это не нужно.

Потому что они существуют на текущем уровне, а не на родительском.

Даже сейчас, зная, что решение есть, не могу найти его в man’е.

       $attr{file}, %s{file}
           The value of a sysfs attribute found at the device where all
           keys of the rule have matched. If the matching device does
           not have such an attribute, and a previous KERNELS,
           SUBSYSTEMS, DRIVERS, or ATTRS test selected a parent device,
           then the attribute from that parent device is used.
intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

Потому что они существуют на текущем уровне, а не на родительском.

$attr{file}, %s{file}

Имеется в виду, что они подставляются потому что хоть на текущем уровне их нет, но они приходят из верхнего?

Даже сейчас, зная, что решение есть, не могу найти его в man’е.

Вопрос в том, почему интерфейсу необходим шаблон сравнения (пусть и "?*"), хотя родительские атрибуты подхватываются и так.

То есть единственное, чего не хватало в моем решении - этого несчастного сравнения, и я не вижу в man'е строчки, где бы это пояснялось.

SUBSYSTEM=="tty", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05df" ENV{CONNECTED_vusb}="yes"

Вот так (вариант из 1-го поста) не работает:

ENV{CONNECTED_vusb}=="yes", SUBSYSTEM=="tty", PROGRAM="/bin/bash -c \"ls /dev | grep tty_TERM_CDC_ | wc -l \"", SYMLINK+="tty_$attr{interface}_%c"

А вот так - работает:

ENV{CONNECTED_vusb}=="yes", SUBSYSTEM=="tty", ATTRS{interface}=="?*", PROGRAM="/bin/bash -c \"ls /dev | grep tty_$attr{interface}_ | wc -l \"", SYMLINK+="tty_$attr{interface}_%c"

COKPOWEHEU ()
Последнее исправление: COKPOWEHEU (всего исправлений: 1)
Ответ на: комментарий от intelfx

Значение атрибута sysfs, найденное на устройстве, где совпали все ключи правила. Если соответствующее устройство не имеет такого атрибута, а в предыдущем тесте ЯДРА, ПОДСИСТЕМЫ, ДРАЙВЕРЫ или ATTRS было выбрано родительское устройство, то используется атрибут этого родительского устройства. (c) гуглоперевод

Я тебе её только что процитировал.

Тут написано, что если атрибут не найден на текущем уровне, он будет искаться на родительском. Где тут про необходимость шаблона?

COKPOWEHEU ()
Ответ на: комментарий от COKPOWEHEU

На каком родительском? Ответь себе на этот вопрос. По возможности пользуясь оригиналом мана, а не гуглопереводом.

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от COKPOWEHEU
  1. А ты в курсе, что interface и idVendor/idProduct определены на разных уровнях вложенности? Загляни в sysfs, посмотри.

  2. Подумай ещё раз. Я не просто так сказал, что правило должно быть разбито на два. У этого действия есть вполне конкретный смысл, до которого ты не допёр (а просто так совпало).

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 2)
Ответ на: комментарий от intelfx

А ты в курсе, что interface и idVendor/idProduct определены на разных уровнях вложенности?

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

USB-устройства бывают составными, у них общие vid:pid, class/subclass/protocol. Но внутри прописывается несколько «под-устройств», у каждого из которых свои class/subclass/protocol, конечные точки. А строковые описания привязываются к частям дескрипторов. К DeviceDescriptor привязываются iManufacturer, iProduct - они относятся к устройству вцелом. А внутри ConfigurationDescriptor - iInterface, iFunction, они относятся к под-устройствам.

COKPOWEHEU ()
Ответ на: комментарий от COKPOWEHEU

Повторяю

Как из этого следует необходимость прописывать шаблон перед чтением переменной?

Повторяю:

семантика такова, что вместо $attr подставляется либо значение атрибута текущего устройства, либо значение атрибута того родительского устройства, которое было найдено во время обработки условия ATTRS{}, если таковое было. При этом нужно также иметь в виду, что во время обработки одного правила все условия ATTRS{} обязаны сработать на одном и том же уровне.

$attr{file}, %s{file}

The value of a sysfs attribute found at the device where all keys of the rule have matched. If the matching device does not have such an attribute, and a previous KERNELS, SUBSYSTEMS, DRIVERS, or ATTRS test selected a parent device, then the attribute from that parent device is used.

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

Хорошо.

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

Почему на одном и том же уровне attr{interface} определен только если в той же строчке он был упомянут в условии сравнения? Или из-за добавления несчастного ATTRS{interface}==«?*» уровень меняется?

COKPOWEHEU ()
Ответ на: комментарий от COKPOWEHEU

Мы «перешли к сути» уже очень давно. Как объяснить так, чтобы стало ещё понятнее, я не знаю. Удачи.

intelfx ★★★★★ ()
Ответ на: комментарий от COKPOWEHEU

Интересное предположение. Я отлично знаю, откуда что взялось, а вам уж придётся довольствоваться «заклинаниями», видимо, если с пониманием письменной информации проблемы :) Ну не беда, в индустрии сейчас таких, как вы, полно.

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

Я отлично знаю, откуда что взялось

Но объяснить не можете. Значит, далеко не все понятно.

COKPOWEHEU ()

Я пытался как-то тоже дать внятные имена двум преобразователям usb-rs485. Специально купил два разных, добавил правило:

# Rule for my USB-RS485 converters
# I want to distinct between them.
#
# command to get attributes: sudo udevadm info -a -n /dev/ttyUSB0
#
# cp210x converter with serial number 0001
SUBSYSTEM=="tty",  ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ATTRS{serial}=="0001", SYMLINK+="ttyUSB_RS485_0"

# FT232R converter with serial number 00000000 (fake?)
SUBSYSTEM=="tty",  ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="ttyUSB_RS485_1"

И нифига. Не появляются симлинки. Так и мучаюсь - отключаю оба, потом втыкаю в правильной последовательности.

Beewek ()
Последнее исправление: Beewek (всего исправлений: 1)
Ответ на: комментарий от Beewek

О как! Пожаловался - и сразу заработало :-)

Осталось понять, о чём была речь в этой теме :-)))

Beewek ()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.