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 ★★★★★
()
Ответ на: комментарий от intelfx

То есть к сути мы так и не перейдем. Ладно, хоть за «заклинание» спасибо, даже если не знаете откуда оно взялось.

COKPOWEHEU
() автор топика
Ответ на: комментарий от 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 ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.