Подключение сканеров, принтеров и др. при помощи usbip в thinstation 5
Если достаточно пробросить одно устройство с тонкого клиента на сервер, то можно попробовать софтину из этого поста на форуме.
Ну а если чем то она не устраивает, то поехали дальше.
Итак, начнём с самого главного. Серверная часть этого пакета лежит в ядре в виде модулей. Скажу больше, вам не нужно перекомпилировать ядро в thinstation, потому как они уже включены по-умолчанию, это три модуля usbip-core.ko, usbip-host.ko и vhci-hcd.ko. Для того, чтобы эти модули были собраны в ваш образ вам необходимо добавить эти модули в build.conf вручную тремя строчками, потому что эти модули вспомогательные и не учтутся скриптом hwlister.sh:
( HTML ломает некоторые знаки. Для точного копирования команд справа от листинга есть кнопка <>)
Теперь нам необходима клиентская часть, несмотря на то, что наш ТК выступает в роли сервера. Клиентская часть находится всё в том же ядре, только в userspace части. Для этого нам понадобятся исходники нашего ядра. Итак, скачиваем их:
После применения патчей прерываем компиляцию, нажав Ctrl+C
Теперь нам необходимо скомпилировать клиентскую часть вручную - она не собирается вместе с остальным ядром, но для начала мы проведём несколько манипуляций.
Итак, перейдём в каталог с исходниками клиентской части (обратите внимание на версию ядра, она скорее всего уже будет иная):
Находим файл configure.ac и меняем в строке указания версии значение 0x00000111 на 0x00000106
AC_DEFINE([USBIP_VERSION], [0x00000106], [binary-coded decimal version number])
Теперь перейдём в каталог src
и добавим в шапку файла usbip_network.h следующие директивы
Редактировать не обязательно в chroot-окружении, пользуйтесь любым удобным редактором (mc, vi ...), а вот команды выполнять в chroot.
Все манипуляции проведены, теперь приступим к сборке пакета. Выйдем на ступень вверх из каталога src и выполним все необходимые процедуры:
Параметром exec-prefix я указал установщику положить библиотеки и бинарники в каталог, где лежат все пакеты, которые могут быть добавлены через параметр package файла build.conf. Перейдём в этот каталог и посмотрим содержимое:
Переименуем каталог sbin в bin(точнее переместим):
Создадим в корне нашего пакета файл dependencies и добавим туда слово ids и base, чтобы наш пакет зависел от базовых утилит(они нам понадобятся в дальнейшем) и :
CTRL+d - это сочетание клавиш, которое необходимо нажать после набора слова ids.
И добавим в файл build.conf параметр:
Теперь нам осталось совсем немного до того момента, как мы сможем закинуть наш пакет в образ и заставить его работать.
Перед нами стоит задача довести процедуру связывания устройств с сервисом usbip до автоматизма, иными словами, при подключении нового устройства или смена порта подключения наше устройство автоматически "мапилось" через usbip, без выковыривания нужных параметров usbip и дополнительной пересборки образа. В этом нам поможет udev - менеджер устройств. У нас возникает только один нюанс - средствами udev невозможно различить устройства по типам - принтеры, сканеры, накопители, hid-устройства и т.д., а это важно, потому что нам не нужно "прокидывать" мышку на сервер через usbip, тем более что устройство становится полностью недоступным для ТК после подключения к нему клиентом usbip. Выход в данной ситуации может быть следующим - перечислить в правилах производителя устройства(т.н. вендор) и, соответственно, таким образом различать устройства. Ну что ж, воплотим слова в жизнь.
В каталоге /ts/build/packages/usbip/lib/udev/rules.d мы создадим своё проавило 99-usbip.rules (всё должно быть в одной строке!):
Немного расшифрую смысл написанного. Первые три параметра(ACTION и два ENV) действуют по принципу логического И, т.е. при добавлении устройства (ACTION=="add") usb (ENV{ID_BUS}=="usb") производителя Samsung (ENV{ID_VENDOR}=="Samsung") должна выполнятся команда (RUN+="usbip_bind %E{ID_VENDOR_ID} %E{ID_MODEL_ID}"). Таким образом, если вам нужны ещё устройства, например, Canon, Hewlett-Packard, Epson и др., то вам нужно в этом же файле создать точно такие строки, только в ENV{ID_VENDOR} указать нужного вам производителя. Следует заметить, что название производителя не может быть взято "с потолка", его можно посмотреть, например, выполнив команду udevadm monitor --env | grep ID_VENDOR, подключившись к ТК по telnet или ssh, и подключив ваше устройство(после выполнения команды).
Как вы могли заметить, в параметре RUN присутствует usbip_bind. Это скрипт, который автоматически подвязывает наше устройство на usbip, при этом нам не нужно будет заботится об особых параметрах, которые передаются команде usbip - это всё за нас будет делать наш скрипт. Этот скрипт мы положем в /ts/5.1/packages/usbip/bin. Итак, создадим скрипт, дадим права на выполнение и заполним его:
Рассмотрим этот скрипт подробнее. Параметр BUSID - это необходимый параметр команды usbip, его мы вычисляем автоматически с помощью параметров ID_VENDOR_ID и ID_MODEL_ID(они передаются параметрами в скрипт из нашего правила udev). Далее, как вы видите, идет условный оператор if. Всё дело в том, что если ваше устройство уже подключено на момент включения ТК, то при включении ТК вам нужно запустить службу usbipd, а если вы будете подключать устройство уже во время работы ТК, то вам нет необходимоти этого делать. Поэтому здесь мы и воспользовались условным оператором if, а условие "-n $USB_IP" определяет запущен ли процесс usbipd.
Теперь нам остаётся собрать образ, загрузится с ТК, подключится в консоль и убедится, что наше устройство готово к использованию со стороны сервера. Переходим в терминал и командуем:
видим:
usbip_host 12943 0
usbip_core 5618 1 usbip_host
usbcore 124913 4 usbip_host,usbhid,uhci_hcd,ehci_hcd
ts_test_1:~# usbip list -l
Local USB devices
=================
- busid 2-1 (046d:c018)
2-1:1.0 -> usbhid
- busid 2-2 (04a9:2220)
2-2:1.0 -> usbip-host
Как видите строка "2-2:1.0 -> usbip-host" показывает, что наше устройство уже готово со стороны сервера, но подключится с винды получится если устройство было запущено или перезапущено после загрузки клиента.
Теперь остался последний штрих в нашем нелегком деле - настроить клиента. Клиентом в данном случае будет Windows 2008 R2, на других версиях Windows возможно не заведётся, но если такая уж необходимость, то надо пробовать.
Итак, идём вот сюда и скачиваем usbip_windows_v0.2.0.0_signed.zip. Распакуем это "добро" в каталог C:\ (желательно, чтобы название каталога было usbip, а не usbip_win..., это просто для дальнейшего удобства). Теперь добавим новое "старое устройство". Всё это описано в файле USAGE скачанного нами клиента. Итак, по шагам:
1. Открываем "Панель управления" - "Диспетчер устройств"
2. Правой кнопкой мыши на имени компьютера - "Установить старое устройство"
3. Откроется мастер, жмёте "Далее"
4. В следующем окне выбираете "Установка оборудования, выбранного из списка вручную" и жмёте "Далее"
5. Выбираете "Системные устройства" - "Далее"
6. "Установить с диска" указываете путь, куда распаковали клиента, и снова "Далее"
7. Выберите "USB/IP Enumerator", нажмите "ОК", "Далее" и "Готово"
Теперь необходимо подключить наше устройство, присоединенное к ТК. Открываем командную строку и пишем:
Командой "usbip -l 10.10.10.10" мы вывели список всех устройств с нашего ТК, "расшаренных" через usbip (10.10.10.10 - ip нашего ТК).
Командой "usbip -a 10.10.10.10 2-2" мы примапили это устройство к себе на наш терминальный сервер (2-2 это тот самый busid, необходимый для присоединения устройства).
Теперь в диспетчере устройств у вас есть новое неопознанное устройство. Ставите на него драйвера и оно должно заработать как ему и положено.
Коммандую строку закрывать нельзя, иначе связь обрывается. Есть проще решение - написать скрипт и выполнять в фоне. Самый простой вариант выглядит так:
Этот скрипт можно повесить в качестве logon-скрипта. Но есть один недостаток - если связь с терминалом потеряна и сессия остаётся незавершенной, то при входе вы снова попадаете в свою сессию, но скрипт уже не запустится, а связь с устройством прервана. Поэтому в таком случае есть два варианта - либо завершить сессию и войти снова, либо запустить скрипт вручную не перезапуская сессию. Конечно, можно написать скрипт как службу, которая будет постоянно мониторить доступные устройства по определенному адресу или диапазону адресов, но это уже нетривиальная задача для написания подобного решения. Простыми командами тут не обойдешься и скорее всего нужно использовать PowerShell. На данный момент у меня нет возможности написания такого скрипта, так что этот вопрос остаётся за вами. Буду рад увидеть от вас решения по автоматизации работы со стороны Windows.
Статья переработана 10.02.2017 года, в свете последних изменений в исходниках ядра.
Готовый пакет на ядре 4.6.3 можно забрать ЗДЕСЬ
Обсудить на форуме (комментариев 30).