LINUX.ORG.RU

Автоматизация подключения USB принтера в виртуальную машину libvirt

 , ,


0

1

Здравствуйте уважаемые! Ubuntu server + KVM Гостевая система windows 7

Подключение usb порта на лету работает так: #virsh attach-device PRINT-SERVER hostdev-04b8:002a.xml

Содержимое файла hostdev-03f0:0212.xml

<hostdev mode='subsystem' type='usb' managed='yes'>
        <source startupPolicy='optional'>
        <vendor id='0x04b8'/>
        <product id='0x002a'/>
        </source>
</hostdev>

Отключение соответственно делается командой …detauch…

Теперь сам вопрос. Как автоматизировать процесс, чтобы при включении принтера usb порт подключался в гостевой системе автоматически, и при выключении принтера отключался.

Я нагуглил, что это можно сделать через правило UDEV Таким образом:

ACTION=="add", \
    SUBSYSTEM=="usb", \
    ENV{ID_VENDOR_ID}=="03f0", \
    ENV{ID_MODEL_ID}=="0212", \
    RUN+="/usr/bin/virsh attach-device PRINT-SERVER /etc/libvirt/qemu/hostdev-04b8:002a.xml"
ACTION=="remove", \
    SUBSYSTEM=="usb", \
    ENV{ID_VENDOR_ID}=="03f0", \
    ENV{ID_MODEL_ID}=="0212", \
    RUN+="/usr/bin/virsh detach-device PRINT-SERVER /etc/libvirt/qemu/hostdev-04b8:002a.xml"

Таким образом, при первом включении и выключении принтера все также работает, но при последующем включении перестает работать.

Вот выхлоп syslog

May 10 22:52:41 HOME-SERVER kernel: [ 6342.128544] usb 2-4: new high-speed USB device number 8 using ehci-pci
May 10 22:52:41 HOME-SERVER kernel: [ 6342.290003] usb 2-4: New USB device found, idVendor=04b8, idProduct=002a
May 10 22:52:41 HOME-SERVER kernel: [ 6342.290010] usb 2-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
May 10 22:52:41 HOME-SERVER kernel: [ 6342.290015] usb 2-4: Product: USB2.0 Printer (Hi-speed)
May 10 22:52:41 HOME-SERVER kernel: [ 6342.290019] usb 2-4: Manufacturer: EPSON
May 10 22:52:41 HOME-SERVER kernel: [ 6342.290022] usb 2-4: SerialNumber: 504B4E4B3231363909
May 10 22:52:41 HOME-SERVER kernel: [ 6342.294383] usblp 2-4:1.0: usblp1: USB Bidirectional printer dev 8 if 0 alt 0 proto 2 vid 0x04B8 pid 0x002A
May 10 22:52:42 HOME-SERVER kernel: [ 6342.602030] audit: type=1400 audit(1557514362.181:45): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="libvirt-ed50980e-cb12-46a6-a7ed-a0199a862f06" pid=3652 comm="apparmor_parser"
May 10 22:52:42 HOME-SERVER libvirtd[1630]: 2019-05-10 18:52:42.190+0000: 1757: error : qemuMonitorJSONCheckError:392 : internal error: unable to execute QEMU command 'device_add': failed to find host usb device 2:8
May 10 22:52:42 HOME-SERVER kernel: [ 6342.892272] audit: type=1400 audit(1557514362.472:46): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="libvirt-ed50980e-cb12-46a6-a7ed-a0199a862f06" pid=3655 comm="apparmor_parser"
May 10 22:52:42 HOME-SERVER systemd-udevd[3645]: Process '/usr/bin/virsh attach-device PRINT-SERVER /etc/libvirt/qemu/hostdev-04b8:002a.xml' failed with exit code 1.

В конце появляется ошибка failed with exit code 1. Помогите выявить проблему. Я не такой уж спец. Разбираюсь по мере сил.

дык пишет же:

failed to find host usb device 2:8

т.е. нет такого девайса. может - не успел создаться, а может - напутали с vendorid/deviceid.

если первое - sleep перед вызовом virsh может помочь

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

напутали с vendorid/deviceid

в xml файле идет идентификация по vendorid и productid, а вот device id, если смотреть lsusb меняется в сторону увеличения на +1 при каждом новом подключении устройства. Может в этом причина? Учитывая, то что первый раз подключение и отключение срабатывает, а потом перестает, это похоже на правду. Как это отследить и пофиксить?

sleep перед вызовом virsh может помочь

А это как? Где почитать?

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

sleep перед вызовом virsh может помочь

А это как? Где почитать?

Вместо прямой команды в правилах udev прописать вызов скрипта

#!/bin/bash
# manage-ptr-script.sh или как удобно назвать
sleep 1 # хватит же?
/usr/bin/virsh ... # выполняете команду
и модифицировать правила udev
ACTION=="...
...
+RUN="manage-ptr-script.sh"

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

Попробовал создать 2 скрипта на подключение и отключение устройства. При запуске их вручную, все срабатывает на отлично. Но при работе через правила udev срабатывает только первое подключение. Далее при отключении устройства ничего не происходит. Хотя если вновь запустить скрипт на отключение порта в ручную, все отрабатывает, как положено. Следовательно грабли в правилах UDEV

ACTION=="add", \
    SUBSYSTEM=="usb", \
    ENV{ID_VENDOR_ID}=="04b8", \
    ENV{ID_MODEL_ID}=="002a", \
    RUN+="/opt/start-delay.sh"
ACTION=="remove", \
    SUBSYSTEM=="usb", \
    ENV{ID_VENDOR_ID}=="04b8", \
    ENV{ID_MODEL_ID}=="002a", \
    RUN+="/opt/stop-delay.sh"

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

If you want to match a specific USB port, you will probably want to use the DEVPATH attribute. To match a specific device instead, use the ID_VENDOR_ID and ID_MODEL_ID attributes. Note: It may be tempting to use ATTR{busnum} and ATTR{devpath} to match the USB bus and port number. However, those attributes are only available when the device is added, and not when the device is removed. This leads to the device not being properly removed from the VM

Как в UDEV задать другой параметр ENV для ACTION==«remove»? Например имя оборудования?

Вот что выдает UDEV - the event which udev sends out after rule processing при включении принтера.

UDEV  [63260.735912] add      /devices/pci0000:00/0000:00:13.2/usb2/2-4 (usb)
ACTION=add
BUSNUM=002
DEVNAME=/dev/bus/usb/002/009
DEVNUM=009
DEVPATH=/devices/pci0000:00/0000:00:13.2/usb2/2-4
DEVTYPE=usb_device
ID_BUS=usb
ID_MODEL=USB2.0_Printer__Hi-speed_
ID_MODEL_ENC=USB2.0\x20Printer\x20\x28Hi-speed\x29
ID_MODEL_ID=002a
ID_REVISION=0100
ID_SERIAL=EPSON_USB2.0_Printer__Hi-speed__504B4E4B3231363909
ID_SERIAL_SHORT=504B4E4B3231363909
ID_USB_INTERFACES=:070102:
ID_VENDOR=EPSON
ID_VENDOR_ENC=EPSON
ID_VENDOR_FROM_DATABASE=Seiko Epson Corp.
ID_VENDOR_ID=04b8
MAJOR=189
MINOR=136
PRODUCT=4b8/2a/100
SEQNUM=5149
SUBSYSTEM=usb
SYSTEMD_WANTS=printer.target
TAGS=:systemd:
TYPE=0/0/0
USEC_INITIALIZED=63255400473
Andrey_bk ()
Ответ на: комментарий от anymouze

Так если вручную запускать attach-device... и detach-device... то все работает замечательно. И если эти команды в скрипт записать и запускать вручную, то тоже работает. А через правило UDEV перестает работать на этапе отключения устройства.

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

Сейчас еще раз внимательно проследил события в syslog. Включение происходит удачно, а выключение завершается с ошибкой, хотя устройство и пропадает из виртуальной машины. Вот лог включения и выключения:

May 11 23:17:42 HOME-SERVER kernel: [94021.877608] usb 2-4: new high-speed USB device number 23 using ehci-pci
May 11 23:17:43 HOME-SERVER kernel: [94022.040304] usb 2-4: New USB device found, idVendor=04b8, idProduct=002a
May 11 23:17:43 HOME-SERVER kernel: [94022.040307] usb 2-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
May 11 23:17:43 HOME-SERVER kernel: [94022.040308] usb 2-4: Product: USB2.0 Printer (Hi-speed)
May 11 23:17:43 HOME-SERVER kernel: [94022.040309] usb 2-4: Manufacturer: EPSON
May 11 23:17:43 HOME-SERVER kernel: [94022.040310] usb 2-4: SerialNumber: 504B4E4B3231363909
May 11 23:17:43 HOME-SERVER kernel: [94022.044756] usblp 2-4:1.0: usblp1: USB Bidirectional printer dev 23 if 0 alt 0 proto 2 vid 0x04B8 pid 0x002A
May 11 23:17:49 HOME-SERVER kernel: [94028.598711] audit: type=1400 audit(1557602269.678:123): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="libvirt-ed50980e-cb12-46a6-a7ed-a0199a862f06" pid=11914 comm="apparmor_parser"
May 11 23:17:49 HOME-SERVER kernel: [94028.694542] usblp1: removed
May 11 23:17:50 HOME-SERVER kernel: [94029.050470] usb 2-4: reset high-speed USB device number 23 using ehci-pci
May 11 23:17:50 HOME-SERVER kernel: [94029.501876] usb 2-4: reset high-speed USB device number 23 using ehci-pci
May 11 23:18:32 HOME-SERVER kernel: [94071.482686] usb 2-4: USB disconnect, device number 23
May 11 23:18:34 HOME-SERVER kernel: [94072.793601] audit: type=1400 audit(1557602313.995:124): apparmor="STATUS" operation="profile_replace" profile="unconfined" name="libvirt-ed50980e-cb12-46a6-a7ed-a0199a862f06" pid=11928 comm="apparmor_parser"
May 11 23:18:34 HOME-SERVER libvirtd[1630]: 2019-05-11 19:18:34.006+0000: 1757: error : virSecurityDACSetOwnershipInternal:590 : unable to stat: /dev/bus/usb/002/023: Нет такого файла или каталога
May 11 23:18:34 HOME-SERVER libvirtd[1630]: 2019-05-11 19:18:34.006+0000: 1757: warning : qemuDomainRemoveHostDevice:4023 : Failed to restore host device labelling
Andrey_bk ()
Ответ на: комментарий от Andrey_bk

Я так понял что, только с автоматическим отключением остались ошибки. Тогда может попробовать в правиле извлечения использовать ID_VENDOR вместо ENV{ID_VENDOR_ID} и ENV{ID_MODEL_ID}

P.S. При «ручном» извлечении этих ошибок нет?

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

1. Задержку (sleep 1) убрать. Это может то работать, то не работать.

2. Добавить KERNEL==«usblp*».

Какого поведения вы ожидаете при отключении? Отвязать от гостя уже несуществующее на хосте устройство?

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

При «ручном» запуске скрипта на извлечение ошибок нет. Может это связано с тем что я запускаю скрипт от root, а у libvirtd не хватает прав на работу с usb?

KERNEL==«usblp*» добавил, изменений не заметил.

Правила сейчас выглядят так:

ACTION=="add", \
    SUBSYSTEM=="usb", \
    DEVPATH=="/devices/pci0000:00/0000:00:13.2/usb2/2-4", \
    RUN+="/opt/start-delay.sh"
ACTION=="remove", \
    SUBSYSTEM=="usb", \
    DEVPATH=="/devices/pci0000:00/0000:00:13.2/usb2/2-4", \
        KERNEL=="usblp*", \
    RUN+="/opt/stop-delay.sh"

Какого поведения вы ожидаете при отключении? Отвязать от гостя уже несуществующее на хосте устройство?

Если выключить принтер и не отвязать от гостя, то он со временем пропадает и при повторном включении не появляется.

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

При «ручном» запуске скрипта на извлечение ошибок нет. Может это связано с тем что я запускаю скрипт от root, а у libvirtd не хватает прав на работу с usb?

Выключите принтер, а потом запустите скрипт руками — ошибки будут те же.

KERNEL==«usblp*» и в ACTION==«add» надо.

и при повторном включении не появляется.

Покажите логи повторного включения.

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

Выключите принтер, а потом запустите скрипт руками — ошибки будут те же.

До меня наконец-то дошло. Ведь получается когда я выключаю принтер, устройство пропадает из системы и libvirtd вместо того чтобы просто убрать его из виртуалки по команде detauch-device, пытается найти это устройство - не находит и выпадает в ошибку.

Было бы здорово научить udev не удалять файлы устройства из системы, пока не выполнится скрипт на отключение устройства из виртуалки. Умеет ли так udev?

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

Это задача не для udev, а для libvirt.

И еще раз: вы используете attach-device не по назначению. Для проброса usb устройств есть, как минимум, два готовых механизма, работающих из коробки. За поисковые запросы гугл (пока) денег не берет.

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

Так я еще до того как эту тему создать, нашел в гугле скрипт как раз для этих целей: https://github.com/olavmrk/usb-libvirt-hotplug

Но он у меня выдает такую же ошибку в syslog при отключении устройства.

А других готовых решений не нашел. Я три дня гугл штурмовал на эту тему. Может не так ищу. Ткните носом пожлста на готовое решение. Задача то тривиальная действительно. Есть Ubuntu server который работает 24\7. Так получается, что рядом с ним удобно расположить несколько принтеров. И чтобы полноценно использовать функционал принтеров, решил поставить виртуалку windows 7, чтобы установить нормальные (родные) драйвера. И все ведь работает, пока не выключишь принтер.

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

Готовое решение — virt-manager, например. 100% кошерное, ынтерпрайзное, редхатовское. Проброс делается тремя кликами мыши, никаких скриптов.

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

Попробуй отредактировать настройки виртуалки с помощью virsh edit vmname и добавить элемент hostdev из твоего стартового поста внутрь элемента devices настроек виртуалки. По идее libvirt должен будет передать всё это в командной строке запуска qemu, а qemu уже сам будет ждать подключения к хосту указанного устройства и сразу пробросит его в гостя.

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

При всем уважении, virt-manager мне не подходит, т.к. на сервере нет GUI. А по этой ссылке >https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html... Предлагается два варианта подключения. Один для проброса usb от клиента в ВМ (это мне не надо). А второй вариант как раз описывает, то что я делаю.

Я уже не раз наткнулся в сети на заметку о том, что это все-таки баг.

Вот например: https://www.redhat.com/archives/libvir-list/2010-March/msg00177.html

Или вот: https://bugs.launchpad.net/ubuntu/ source/libvirt/ bug/1219435

И там еще какой-то код прилагается, типа buf-fix. Но что с ним делать, моих знаний не достаточно.

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

qemu запустит ВМ, если прописать опцию

Да.

это все-таки баг.

Баг по ссылке исправлен давно.

Ваши «трудности» — ожидаемое поведение системы. Все из-за нежелания читать документацию. Вы даже на задаваемые вам вопросы не отвечаете.

В этой теме представлена исчерпывающая информация о том, как пробросить usb тремя способами. Если все же не получается и требуется пошаговая инструкция на русском языке, то создавайте тему в Job.

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

Проверил на rhel 7.6, здесь это работает именно так как я написал. Вносишь hostdev в конфигурацию виртуалки (с помощью virsh edit, так как virt-manager не добавляет атрибут startupPolicy=«optional» и виртуалка перестаёт стартовать, если устройство не подключено к хосту на момент старта виртуалки), перезапускаешь виртуалку. Если устройство есть на хосте при запуске виртуалки, оно пробрасывается при запуске виртуалки. Если устройство подключается к хосту в процессе работы виртуалки, оно пробрасывается. Если устройство отключается от хоста в процессе работы виртуалки, оно исчезает с виртуалки, а в конфигурации виртуалки остается. Если устройство повторно подключается к хосту в процессе работы виртуалки, оно снова пробрасывается. Без каких-либо udev-правил. libvirt-daemon-4.5.0-10.el7_6.4.

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

Все так. Итого, вот все 3 варианта: 1. С правилом udev (это работает, на самом деле, просто ТС допускает ошибки)

2. Так, как вы написали.

3. redirdev. Либо spice, либо tcp. 4 варианта даже.

Думаю, что ТС — тролль. Есть предложение забанить.

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

просто ТС допускает ошибки

Возможно где-то ошибаюсь. Я новичок в linux.

Думаю, что ТС — тролль.

ТС - не тролль. Предлагаю ветку почистить, и оставить последние 2 поста не считая этого.

Andrey_bk ()