jueves, 29 de diciembre de 2011

Centos 5:Xen PCI Passthrough USB

   Hola, existen ocaciones donde necesitamos que nuestra maquina virtual pueda hacer uso de puertos como el USB, en mi caso de nuevo necesito que mi hvm pueda yo conectarle una memoria USB para que un software especifico funcione.

   El sistema que maneja recursos humanos que es muy usando en la empresas grandes llamado Tress hace uso de una memoria USB tipo HASP como candado de seguridad.

   Entonces si deseamos virtualizar el servidor donde se ejecuta el Tress necesitamos este opcion disponible en nuestra HVM.

   Pase varias semanas batallando esto, ya que uno se enfrenta a distintos obstaculos, entre ellas la mas critica y dificil que encontre:
  • Falta de documentacion por parte de los fabricantes tanto de placas madres como de procesadores.
   Por que comento esto de los fabricantes de placas madres?, he logrado esto con 2 placas distintas:
Una tipo desktop:
MoBo: SABERTOOTH+990FX
Procesador: AMD Athlon II 640
   Dicen los de soporte de la MoBo que si esta habilitada la opcion, pero nunca la encontre, me comunique con ellos y dicen que no pueden arreglar el BIOS.

  AMD esta en las mismas, la doc no dice nada de este dato.

   Para no perder el chip me fui por la que sigue:
MoBo:Asus M4A89TD PRO/USB3
Procesador: AMD Athlon II 640
   En esta si aparece la opcion en el BIOS para habilitar esta funcion, probe Xen 4.1.1 de gitco y gracias a el cielo que Xen me dio el mensaje esperado:

(XEN) I/O virtualisation enabled
(XEN) I/O virtualisation for PV guests disabled
   Ya con el simple hecho de que nos de este mensaje ya es ventaja, no me interesa que mi PV no pueda ya que no tengo nada en ellas que lo requiera, bien en la 1er placa actualice el BIOS hasta la ultima version y nada de nada asi que no quice perder mas mi tiempo, por ello mejor me fui por la segura.

  Esto me funciono en Centos 5.x, Xen 3.4.1,4.1 sin problemas, algo que note es que solo la v 1.1 del USB fue soportada, y las versiones de windows:
  • XP Pro xp3
  • Windows 7 Pro
   Otro detalle fue que windows 7, probe varias memorias USB y algunas si funcionaron otras no, pero lo que mas llamo la atencion que la memoria HASP que un programa llamado LabelView de www.teklynx.com no funciono.
   Pero mi plan era que el software llamado: Darwin de www.vanguardiatec.com funcionara y.... funciono, usa igual que el anterior una memoria HASP USB, entonces en este momento lo estan usando usando sin problemas.

   Ahora la siguiente tarea que encontre fue, puedo virtualizar windows 2003(sin problemas) y que tenga soporte de USB?

   En este caso ya no estamos hablando de un equipo tipo desktop, aqui ya es una placa servidor, siempre estas van a tener mejor electronica que una desktop por ello las separan.

Este es el equipo de SuperMicro:

SuperServer 5026T-TB
   Siempre hemos sido amantes de esta marca, no le pide nada a Dell, HP, IBM, es mas economica y se codea con ellos, la diferencia que aun en Mexico no existe una distribucion directa, todo viene de USA.

   Haste eso que el soporte es excelente y no tienes pasar por una PBX  que hace una infinidad de preguntas y siempre estan dispuestos a ayudarte.
   El procesador es una Intel Xeon E5649 con memoria ECC 1333Mhz.

   Dice la doc de Xen que tanto el MoBo como el CHIP deben tener soporte para que esta operacion funcione, por parte de la MoBo habia soporte, la doc de Intel como todas las demas, hasta AMD carece de informacion detallada.

   Me comunique via char con el soporte de Intel, y el hizo lo mismo que uno del ambito haria antes de preguntar, leer la documentacion del chip, ahi no venia nada al respecto, espere un poco y me dice "No tiene soporte", ok gracias.

   Entonces, ya era cuestion de probar por mi cuenta, por que en la lista de Xen, alguien comento que tenia algunos servidores con el chips de la familia 5600 y aparecia que si le aparecia el mensaje en su consola de:

(XEN) I/O virtualisation enabled
Pero no mostraba que chips, por ello no quedo otra que mancharme las manos.

Entonces ya fue mucho rollo, vamos a ver como habilitar esto en Xen:

NOTA1: Este procedimiento es igual para todos los chips o MoBo.
NOTA2: Xen 4.x no necesita el paso 1, ya viene por default.

1; Si usan Xen anterior a 4.x deben habilitar la opcion en su kernel asi:

kernel /xen.gz-3.4.3 dom0_max_vcpus=2 dom0_vcpus_pin dom0_mem=1024MB iommu=1

Xen 4.x ya lo tiene.

Reiniciar el server.

2; Asegurarse antes de nada que aparezca el mensaje esperado cuando ejecuten el comando: xen dmesg.
(XEN) I/O virtualisation enabled
Si no aparece esto, ni le sigan.

2; Detectar la direccion de nuestro puerto USB.

   Aqui estoy hablando de un puerto USB, pero aplica a los puertos que desean enviar, video, paralelo, etc, etc.

   Ahora como puedo yo saber cual es la direccion de una puerto USB especifico?

Existe un comando poco usado llamado:

udevmonitor

   Este comando lo que hace es monitorear los puertos para ver en consola que estamos conectando, cuando conectamos una memoria USB aparece esto en pantalla:

UEVENT[1325036667.645024] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2
UEVENT[1325036667.645051] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2/usbdev1.3_ep00
UEVENT[1325036667.645235] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2/1-2:1.0
UEVENT[1325036667.645245] add@/class/scsi_host/host5
UEVENT[1325036667.645251] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2/1-2:1.0/usbdev1.3_ep01
UEVENT[1325036667.645257] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2/1-2:1.0/usbdev1.3_ep82
UEVENT[1325036667.645264] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2/1-2:1.0/usbdev1.3_ep83
UEVENT[1325036667.645270] add@/class/usb_device/usbdev1.3
UDEV  [1325036667.656886] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2
UDEV  [1325036667.764765] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2/usbdev1.3_ep00
UDEV  [1325036668.179955] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2/1-2:1.0
UDEV  [1325036668.389248] add@/class/scsi_host/host5
UDEV  [1325036668.400871] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2/1-2:1.0/usbdev1.3_ep82
UDEV  [1325036668.400884] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2/1-2:1.0/usbdev1.3_ep83
UDEV  [1325036668.400891] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2/1-2:1.0/usbdev1.3_ep01
UDEV  [1325036668.546698] add@/class/usb_device/usbdev1.3
UEVENT[1325036672.644024] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2/1-2:1.0/host5/target5:0:0/5:0:0:0
UEVENT[1325036672.644042] add@/class/scsi_disk/5:0:0:0
UEVENT[1325036672.770313] add@/block/sdg
UEVENT[1325036672.770326] add@/class/scsi_device/5:0:0:0
UEVENT[1325036672.770333] add@/class/scsi_generic/sg7
UDEV  [1325036672.894515] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2/1-2:1.0/host5/target5:0:0/5:0:0:0
UDEV  [1325036673.105483] add@/class/scsi_disk/5:0:0:0
UDEV  [1325036673.108784] add@/class/scsi_generic/sg7
UDEV  [1325036673.314546] add@/class/scsi_device/5:0:0:0
UDEV  [1325036673.399994] add@/block/sdg


Vamos buscar nuestro puerto:

UEVENT[1325036667.645024] add@/devices/pci0000:00/0000:00:1a.7/usb1/1-2

Ahora vamos a compararlo con el listado de Centos:

lspci


00:00.0 Host bridge: Intel Corporation 5520/5500/X58 I/O Hub to ESI Port (rev 22)
00:01.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 1 (rev 22)
00:03.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 3 (rev 22)
00:05.0 PCI bridge: Intel Corporation 5520/X58 I/O Hub PCI Express Root Port 5 (rev 22)
00:07.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 7 (rev 22)
00:09.0 PCI bridge: Intel Corporation 5520/5500/X58 I/O Hub PCI Express Root Port 9 (rev 22)
00:14.0 PIC: Intel Corporation 5520/5500/X58 I/O Hub System Management Registers (rev 22)
00:14.1 PIC: Intel Corporation 5520/5500/X58 I/O Hub GPIO and Scratch Pad Registers (rev 22)
00:14.2 PIC: Intel Corporation 5520/5500/X58 I/O Hub Control Status and RAS Registers (rev 22)
00:14.3 PIC: Intel Corporation 5520/5500/X58 I/O Hub Throttle Registers (rev 22)
00:16.0 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.1 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.2 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.3 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.4 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.5 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.6 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:16.7 System peripheral: Intel Corporation 5520/5500/X58 Chipset QuickData Technology Device (rev 22)
00:1a.0 USB Controller: Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #4
00:1a.1 USB Controller: Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #5
00:1a.2 USB Controller: Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #6
00:1a.7 USB Controller: Intel Corporation 82801JI (ICH10 Family) USB2 EHCI Controller #2
00:1c.0 PCI bridge: Intel Corporation 82801JI (ICH10 Family) PCI Express Root Port 1
00:1c.1 PCI bridge: Intel Corporation 82801JI (ICH10 Family) PCI Express Port 2
00:1d.0 USB Controller: Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #1
00:1d.1 USB Controller: Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #2
00:1d.2 USB Controller: Intel Corporation 82801JI (ICH10 Family) USB UHCI Controller #3
00:1d.7 USB Controller: Intel Corporation 82801JI (ICH10 Family) USB2 EHCI Controller #1
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev 90)
00:1f.0 ISA bridge: Intel Corporation 82801JIR (ICH10R) LPC Interface Controller
00:1f.2 IDE interface: Intel Corporation 82801JI (ICH10 Family) 4 port SATA IDE Controller #1
00:1f.3 SMBus: Intel Corporation 82801JI (ICH10 Family) SMBus Controller
00:1f.5 IDE interface: Intel Corporation 82801JI (ICH10 Family) 2 port SATA IDE Controller #2
06:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection
07:00.0 Ethernet controller: Intel Corporation 82574L Gigabit Network Connection
08:01.0 SCSI storage controller: LSI Logic / Symbios Logic 53c1010 66MHz  Ultra3 SCSI Adapter (rev 01)
08:04.0 VGA compatible controller: Matrox Graphics, Inc. MGA G200eW WPCM450 (rev 0a)


   Ya dimos y confirmamos que es la direccion que necesitamos.

3; Habilitar el modulo pciback en el kernel.

   Este modulo ni RedHat ni Centos lo tienen compilado en el kernel,xen para ello tenemos 2 opciones:

A) Agregarlo
B) Compilar el kernel xen y habilitarlo.

   Yo me voy por la mas rapida la A, para esto tenemos que hacer lo siguente.

1.1 Esconder del Host el puerto requerido, ya tenemos la direccion que necesitamos, para esto modificamos el archivo modprobe.conf que esta en  /etc y agregamos esta linea a el final:

options pciback hide=(00:1a.7)

Salvamos y salimos, como podran ver es la direccion que obtuvimos anteriormente cuando ejecutamos udevmonitor.

1.2 Agregamos el modulo a nuestro modulo initrd para que cada que reinicie lo cargue antes de darnos la consola del poder.

Nos vamos a el folder boot:

cd /boot

NOTA 3: Por seguridad hacer una copia del initrd actual por si algo sale mal:

cp initrd-$(uname -r).img initrd-$(uname -r).img-default

Ahora si a agregar el modulo:

mkinitrd -f --preload=pciback /boot/initrd-$(uname -r).img $(uname -r)

   Como podran ver hemos agregado el modulo pciback para que cuando arranque el kernel lo tenga listo, asi cuando ejecute el modprobe.conf ya pueda el esconder nuestro puerto y quede libre para nuestra hvm, de lo contrario el host se negara  a soltar el puerto.

1.3 Decirle a Xen que puerto el va a tomar control para entregar a la HVM que lo necesite.

   Para esto vamos a buscar otro dato que necesitamos de nuestro hw, ya tenemos la direccion del puerto, pero Xen requiere otro mas de ese puerto, y este lo obtenemos ejectando el comando lspci -n, buscamos nuestro hw id y buscamos este dato:

lspci -n

00:00.0 0600: 8086:3405 (rev 22)
00:01.0 0604: 8086:3408 (rev 22)
00:03.0 0604: 8086:340a (rev 22)
00:05.0 0604: 8086:340c (rev 22)
00:07.0 0604: 8086:340e (rev 22)
00:09.0 0604: 8086:3410 (rev 22)
00:14.0 0800: 8086:342e (rev 22)
00:14.1 0800: 8086:3422 (rev 22)
00:14.2 0800: 8086:3423 (rev 22)
00:14.3 0800: 8086:3438 (rev 22)
00:16.0 0880: 8086:3430 (rev 22)
00:16.1 0880: 8086:3431 (rev 22)
00:16.2 0880: 8086:3432 (rev 22)
00:16.3 0880: 8086:3433 (rev 22)
00:16.4 0880: 8086:3429 (rev 22)
00:16.5 0880: 8086:342a (rev 22)
00:16.6 0880: 8086:342b (rev 22)
00:16.7 0880: 8086:342c (rev 22)
00:1a.0 0c03: 8086:3a37
00:1a.1 0c03: 8086:3a38
00:1a.2 0c03: 8086:3a39
00:1a.7 0c03: 8086:3a3c
00:1c.0 0604: 8086:3a40
00:1c.1 0604: 8086:3a42
00:1d.0 0c03: 8086:3a34
00:1d.1 0c03: 8086:3a35
00:1d.2 0c03: 8086:3a36
00:1d.7 0c03: 8086:3a3a
00:1e.0 0604: 8086:244e (rev 90)
00:1f.0 0601: 8086:3a16
00:1f.2 0101: 8086:3a20
00:1f.3 0c05: 8086:3a30
00:1f.5 0101: 8086:3a26
06:00.0 0200: 8086:10d3
07:00.0 0200: 8086:10d3
08:01.0 0100: 1000:0021 (rev 01)
08:04.0 0300: 102b:0532 (rev 0a)


   Ahi lo tenemos, el dato que requiere Xen es: 8086:3a3c.

   Abrimos el archivo de Xen llamado /etx/xen/xend-pci-permissive.sxp

   Y nos queda asi:

###############################################################################
(unconstrained_dev_ids
     #('0123:4567:89AB:CDEF')
('8086:3a3c')
)


   Viendo su archivo van a notar la diferencia, dice el doc que no es necesario, pero a mi me ha funcionado asi y no he tenido problema con mi HVM ni host.

1.4 Agregar el puerto a la configuracion de nuestra HVM, en este caso Windows XP:
pci = ["00:1a.7"]
   Esto lo agregamos a el final del archivo.

4; Reiniciar servidor y a probar.

5; Arracamos nuestra maquina virtual, ya que este lista, le conectamos el USB y tenemos esto:

Imagen 1: Mostrando contenido del USB.

 Imagen 2: Controlador de USB en Windows.

Imagen 3: Device Manager de Windows.

   No he tenido exito con USB 2.0, pero para lo que lo he necesitado que son las HASP USB Keys me ha funcionado sin problemas.

OS probados y funcionando:
Windows XP Profesional
Windows 2003 Standard Edition
Windows 7 Profesional
Saludos.