Пренасочване на USB към виртуална машина през мрежата чрез UsbRedir и QEMU
Днес има доста начини за препращане на USB устройство към друг компютър или виртуална машина по мрежата. От най-популярните - хардуерни като AnywhereUSB и чисто софтуерни продукти, от тези, които пробвах сам: USB Redirector и USB / IP. Бих искал да ви разкажа за друг интересен метод, който работи директно с емулатора QEMU. Също така е част от проекта за подправки, официално поддържан от RedHat.
UsbRedir е отворен протокол за пренасочване на USB устройства през tcp към отдалечен виртуален сървър, разработен с подкрепата на RedHat като част от проекта spice. Но както се оказа, те могат да се използват доста успешно и без подправки. Ролята на сървъра е usbredirserver, който бърка usb устройството на определен порт, а клиентът е самият QEMU, който емулира връзката на експортираното usb устройство към конкретен usb контролер на вашата виртуална машина. Благодарение на този подход абсолютно всяка ОС може да се използва като система за гости, тъй като тя дори не знае, че устройството е отдалечено препратено и цялата логика пада върху QEMU.
Първо, няколко думи за горните решения
- AnywhereUSB е доста добро решение, но скъпо и има неприятни бъгове, например случва се ако падне споделена флашка, тогава можете да я свържете отново само като я извадите и поставите физически.
- USB/IP - OpenSource проект. Изглежда, че е изоставено. Всъщност е доста бъги. Когато връзката е прекъсната, машината често напълно замръзва и Windows показва BSOD
- USB Redirector - Страхотен софтуер. За споделяне на устройства от linux към linux е безплатно, във всички останали случаи вече струва пари, не толкова колкото AnywhereUSB, но небезплатно, както желаете :)
Настройка на виртуална машина
За да има къде да свържете експортираните устройства, трябва да създадете необходимите usb контролери на виртуалната машина:
- uhci - за USB1.0
- ehci - за USB2.0
- xhci - за USB3.0
За qemu (без libvirt)
Добавете опции към командата за стартиране на VM:
За libvirt
В първоначалния конфигурационен файл на виртуалната машина във възела<devices>изтрийте всички USB контролери и добавете следния блок:
Между другото, ако използвате spice, като добавите още 3 специални устройства към контролерите, ще бъде възможно да препратите usb устройства от spice клиента към сървъра.
Добавяме следните опции към командата за стартиране на виртуалната машина в допълнение към контролерите, които дефинирахме по-рано:
За libvirt
В първоначалния конфигурационен файл на виртуалната машина във възела <devices> добавете следните опции в допълнение към контролерите, които дефинирахме по-рано:
Сега всичко е готово за препращане.
Старт на сървъра
Пакетът usbredirserver може да бъде намерен в стандартните хранилища на почти всички популярни дистрибуции на Linux.
Поставяме USB флаш устройството в компютъра, гледаме изхода на USB устройствата:
Виждаме, че двойката vendorid:prodid е равна на 125f:c82a и ядрото е определило съответно флаш устройството 003-001 usbbus-usbaddr.
Сега нека го споделим на порт 4000:
Свързване на устройство към виртуална машина
Чрез опции при стартиране на VM
Устройството за свързване към VM може да бъде указано при стартиране чрез добавяне на следните опции към командата за стартиране
За libvirt
Този блок се поставя преди тага</devices>до контролерите, които дефинирахме по-рано:Може да се изпълни и с командатаvirsh attach-device
Или чрез qemu-monitor
Отиваме в хипервайзора и в qemu-монитора на нашата машина изпълняваме следните команди:
За да изключите флашката, е достатъчна следната команда:
Това е всичко, след тези стъпки вашата виртуална машина ще види вашето флаш устройство и ще може да работи с него първоначално.
Ако има много устройства и всички са еднакви
Тук се появи интересен проблем, как да пренасоча няколко идентични устройства към различни виртуални машини? В същото време си струва да се отбележи, че всички устройства имат една и съща двойка vendorid:prodid и двойката usbbus-usbaddr изобщо не е постоянна, веднага щом извадите и поставите устройството, то веднага ще промени своя usbaddr.
И така, нека да започнем
Първо, трябва да разберем серийния номер на нашето устройство, по който ще го идентифицираме в udev:
И вмъкваме нашето устройство, след което веднага ще видим списък с променливи за това устройство, което udev любезно инициализира за нас:
Информация за серийния номер и други атрибути може да се получи и по друг начин, но трябва да се има предвид, че за запис на правилата ще използваме променливите от командата по-горе, а не атрибутите от командата по-долу. В противен случай тригерът за премахване няма да се задейства, когато устройството е изключено.
Сега създайте файл /etc/udev/rules.d/99-usb-serial.rules и запишете следните правила в него:
Готово, сега, когато устройството ни е свързано, автоматично ще се рови до порта, който ни трябва и при разкачване usbredirserver ще спре да работи. По аналогия добавяме други устройства.
Това е всичко. Благодарим ви за проявения интерес:)