USB (PCI) w domU

W wirtualnej maszynie uruchamiam Nagios. Jako, że powiadomienia o anomaliach za pomocą poczty elektronicznej nie są najlepszym rozwiązaniem, postanowiłem (blisko rok temu) wykorzystać bramkę GSM (EasyGate firmy 2N) do wysyłania wiadomości tekstowych. Sprawa dojrzała (znalazłem czas) i wziąłem się za konfigurację tego systemu.

Po pierwsze: bramka ma możliwość podłączenia do portu szeregowego (tylko), co oczywiście nie jest żadną jej wadą – łatwiej ją spiąć z oprogramowaniem firm trzecich (komunikacja za pomocą komend AT).  Producent nie dostarcza żadnego oprogramowania pod *NIX, więc trzeba użyć czegoś innego, chociażby gnokii. Oprogramowanie, które jest to samodzielny klient lub aplikacja w stylu klient / serwer, ale nie chciało mi się wgryzać w protokół komunikacji, żeby dopisać coś własnego, tym bardziej, że konfiguracja jest zawiła i odpuściłem temat.

USBW Xen mamy możliwość udostępnienia urządzeń z dom0 w domU, ale niestety nie portu szeregowego (bo to szyna ISA; chyba, że jest to karta rozszerzeń na PCI). Niemniej w serwerach,  gdzie jest port szeregowy, zazwyczaj jest on wykorzystany do przekierowania konsoli, więc i tak nie można go użyć.
Ja skorzystałem z przejściówki na USB (PL-2303 HX firmy Prolific Technology Inc. – USB_SERIAL_PL2303). Opinie o takim sprzęcie są różne (zwłaszcza wśród użytkowników systemów innych niż Windows) – w moim przypadku na 3 w ogóle używane  jedna nie działała pod Linuksem. Tak czy inaczej, obecna jest rozpoznawana.

Bus 005 Device 004: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port

Samo udostępnienie urządzenia PCI odbywa się w Xen następująco:

  1. Przygotowanie jądra dla dom0 i domU, odpowiednio:
  2. CONFIG_XEN_PCIDEV_BACKEND=y

    i

    CONFIG_XEN_PCIDEV_FRONTEND=y

  3. Zablokowanie (ukrycie) urządzenia PCI w dom0 poprzez dodanie opcji do konfiguracji grub (plik grub.conf, linia z module)

    pciback.permissive pciback.hide=(<PCI ID>)

  4. Wskazanie w konfiguracji domU urządzenia do którego ma się odwoływać

    pci = ['<PCI ID>']

  5. Dodatkowo musiałem dodać swiotlb=force do konfiguracji jądra w domU (extra, bo paczka w Gentoo nie daje pvgrub’a – bug #236380), w przeciwnym razie ładowanie modułu kończyło się jak niżej:

    Oct 8 07:43:46 nagios usbcore: registered new driver usbfs
    Oct 8 07:43:46 nagios usbcore: registered new driver hub
    Oct 8 07:43:46 nagios USB Universal Host Controller Interface driver v3.0
    Oct 8 07:43:46 nagios PCI: Enabling device 0000:00:00.3 (0000 -> 0001)
    Oct 8 07:43:46 nagios PCI: Setting latency timer of device 0000:00:00.3 to 64
    Oct 8 07:43:46 nagios uhci_hcd 0000:00:00.3: UHCI Host Controller
    Oct 8 07:43:46 nagios uhci_hcd 0000:00:00.3: new USB bus registered, assigned bus number 1
    Oct 8 07:43:46 nagios uhci_hcd 0000:00:00.3: irq 22, io base 0x00004020
    Oct 8 07:43:46 nagios usb usb1: configuration #1 chosen from 1 choice
    Oct 8 07:43:46 nagios hub 1-0:1.0: USB hub found
    Oct 8 07:43:46 nagios hub 1-0:1.0: 2 ports detected
    Oct 8 07:43:46 nagios usb 1-1: new full speed USB device using uhci_hcd and address 2
    Oct 8 07:43:46 nagios Fatal DMA error! Please use 'swiotlb=force'
    Oct 8 07:43:46 nagios ----------- [cut here ] --------- [please bite here ] ---------
    Oct 8 07:43:46 nagios Kernel BUG at ...arch/x86_64/kernel/../../i386/kernel/pci-dma-xen.c:378

Nie wiem niczego o USB pod Linuksem (ani pod żadnym innym systemem operacyjnym), więc powiązanie konkretnego gniazdka z PCI ID było ciekawą podróżą :>
Przede wszystkim PCI passthrough odnosi się do konkretnego urządzenia PCI, a nie portu USB. Oczywiście może zdarzyć się tak, że każde gniazdko to osobny kontroler USB, ale może być tak, że wiele portów jest na jednym kontrolerze, co oznacza, że przekażemy je wszystkie. U mnie jest tak (lspci i lsusb):

00:1d.0 USB Controller: Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #1 (rev 09)
00:1d.1 USB Controller: Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #2 (rev 09)
00:1d.2 USB Controller: Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #3 (rev 09)
00:1d.3 USB Controller: Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #4 (rev 09)
00:1d.7 USB Controller: Intel Corporation 631xESB/632xESB/3100 Chipset EHCI USB2 Controller (rev 09)

Bus 001 Device 001: ID 1d6b:0002
Bus 005 Device 001: ID 1d6b:0001
Bus 004 Device 001: ID 1d6b:0001
Bus 002 Device 001: ID 1d6b:0001
Bus 003 Device 001: ID 1d6b:0001

Bardziej obfite informacje mamy w /proc/bus/usb/devices, a interpretację wyników wykonać możemy na podstawie Documentation/usb/proc_usb_info.txt.
W deskryptorze (S) znalazłem SerialNumber zbieżny z PCI ID i w przypadku kontrolerów należy się tego trzymać (For USB host controller drivers (virtual root hubs) this is some unique ID, normally a bus ID (address or slot name) that can’t be shared with any other device.).

W przypadku, gdy nie ukryjemy urządzenia w dom0 lub gdy już zostało przypisane do innego domU, napotkamy na błąd:

Error: failed to assign device: maybe the platform doesn't support VT-d, or VT-d isn't enabled properly?

W zależności od ustawienia CONFIG_XEN_PCIDEV_BACKEND_VPCI możemy ukryć prawdziwą topologię PCI (Virtual PCI oraz Slot) lub przekazać adres taki jak jest w dom0 (Passthrough). Wspomniany wyżej kontroler w moim domU ma zmieniony adres:

00:00.2 USB Controller: Intel Corporation 631xESB/632xESB/3100 Chipset UHCI USB Controller #3 (rev 09)

Bus 001 Device 002: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port

Dzięki przekazywaniu PCI możemy udostępnić również inne urządzenia do wirtualnych maszyn, np. karty sieciowe, kontrolery FC czy karty graficzne.

Wspomniany adapter daje nam dodatkowe urządzenie /dev/ttyUSB0:

usbcore: registered new driver usbserial
/usr/src/linux-2.6.18-xen-r12/drivers/usb/serial/usb-serial.c: USB Serial Driver core
/usr/src/linux-2.6.18-xen-r12/drivers/usb/serial/usb-serial.c: USB Serial support registered for pl2303
pl2303 1-1:1.0: pl2303 converter detected
usb 1-1: pl2303 converter now attached to ttyUSB0
usbcore: registered new driver pl2303
/usr/src/linux-2.6.18-xen-r12/drivers/usb/serial/pl2303.c: Prolific PL2303 USB to serial adaptor driver

Konfiguracja gnokii w moim przypadku wygląda mniej więcej tak (esencja bez domyślnych wartości):

[global]
port = /dev/ttyUSB0
model = AT
connection = serial

Samo wysyłanie wiadomości działa:

GNOKII Version 0.6.27
[...]
Message sent (reference: 7)
Send succeeded with reference 7!
Serial device: closing device

Połączenie z Nagios to już najprostsza sprawa – wyczerpujący opis znaleźć można np. na http://www.shinyconsole.pl/nagios-gnokii/ (z jednym wyjątkiem – w Gentoo użytkownik nagios musi być członkiem grupy uucp, aby miał dostęp do /dev/ttyUSB0 i /var/lock).

Tagi: , , ,

2 odpowiedzi do “USB (PCI) w domU”

  1. [...] co oznacza, że projekt jest dobry ;-) Zauważyłem, że oprócz przejrzenia wiadomości e-mail i SMS wysyłanych z Nagios (z tymi drugimi są jeszcze problemy, ale może to wynikać z zajętości [...]

Dodaj odpowiedź