miércoles, 6 de febrero de 2013

Instalación de Xen 4.1 en Ubuntu 12.04 + pci passthrough

Comenzamos con una instalación básica de Ubuntu Server 12.04 instalada previamente.

Primero configuraremos la red.

# aptitude install bridge-utils ifenslave-2.6 ethtool

Configuración de /etc/network/interfaces:
auto br0 iface br0 inet static
  address 192.168.1.10
  netmask 255.255.255.0
  network 192.168.1.0
  broadcast 192.168.1.255
  gateway 192.168.1.1

  # dns-* options are implemented by the resolvconf package, if installed
  dns-nameservers 192.168.1.254
  dns-search nuestrodominio.com

  bridge_ports eth0
  bridge_fd 9
  bridge_hello 2
  bridge_maxage 12
  bridge_stp on

Activamos la nueva configuración de red:

# /etc/init.d/networking restart

Instalamos el software del hipervisor de Xen:

# aptitude install xen-hypervisor-4.1-amd64 xen-tools xen-utils-4.1

Configuramos xen-tools modificando los siguientes parámetros, el resto los mantenemos como aparecen en el fichero de configuración original.
En /etc/xen-tools/xen-tools.conf
dir = /vserver
size   = 20Gb      # Disk image size.
memory = 2048Mb    # Memory size
swap   = 2048Mb    # Swap size

gateway    = 192.168.100.181
netmask    = 255.255.255.0
broadcast  = 192.168.100.255

nameserver = 192.168.100.182

bridge = br0
passwd = 1

arch = amd64
boot = 1
disk_device = xvda

Creamos el directorio donde se guardarán los discos de nuestras máquinas virtuales:
# mkdir /vserver

Configuramos xen cambiado las siguiente líneas de  /etc/xen/xend-config.sxp
(xend-unix-server yes)
(network-script network-bridge)
Completamos la configuración:

# ln -s /usr/share/qemu-linaro/ /usr/share/qemu

# sed -i 's/GRUB_DEFAULT=.*\+/GRUB_DEFAULT="Xen 4.1-amd64"/'
# /etc/default/grub
# update-grub

# reboot

Intentamos crear una máquina virtual nueva:

# xen-create-image --hostname=elantris --ip=192.168.1.200 --force --verbose

Y nos encontramos con el siguiente error:

Executing : xt-install-image --hostname=elantris --location=/tmp/0bz_TNjCaW --dist=precise --install-method=debootstrap --mirror=http://es.archive.ubuntu.com/ubuntu/ --cache=yes --cachedir=/var/cache/apt/archives/ --verbose --arch=amd64

  We are trying to configure an installation of precise in
 /tmp/0bz_TNjCaW - but there is no hook directory for us to use.

  This means we would not know how to configure this installation.

  We would expect the hook directory to be /usr/lib/xen-tools/precise.d.

  Aborting.
Finished : xt-install-image --hostname=elantris --location=/tmp/0bz_TNjCaW --dist=precise --install-method=debootstrap --mirror=http://es.archive.ubuntu.com/ubuntu/ --cache=yes --cachedir=/var/cache/apt/archives/ --verbose --arch=amd64 2>&1
Running command 'xt-install-image --hostname=elantris --location=/tmp/0bz_TNjCaW --dist=precise --install-method=debootstrap --mirror=http://es.archive.ubuntu.com/ubuntu/ --cache=yes --cachedir=/var/cache/apt/archives/ --verbose --arch=amd64 2>&1' failed with exit code 256.
Aborting
See /var/log/xen-tools/elantris.log for details
/tmp/0bz_TNjCaW/etc/ssh/ssh_host_rsa_key.pub: No such file or directory
Executing : umount /tmp/0bz_TNjCaW/proc
umount: /tmp/0bz_TNjCaW/proc: not found
Finished : umount /tmp/0bz_TNjCaW/proc 2>&1
Running command 'umount /tmp/0bz_TNjCaW/proc 2>&1' failed with exit code 256.
Aborting
See /var/log/xen-tools/elantris.log for details
cannot remove directory for /tmp/0bz_TNjCaW: Dispositivo o recurso ocupado at /usr/share/perl/5.14/File/Temp.pm line 902


Tenemos problemas con la versión de xen-tools instalada por lo que vamos a actualizarla:

# aptitude install add-apt-key
# apt-get install python-software-properties
# add-apt-repository ppa:xtaran/xen-tools

Además actualizamos el sistema completamente:
# aptitude update && aptitude safe-upgrade

Comprobamos las versiones disponibles e instaladas de xen-tools:
# apt-cache policy xen-tools
xen-tools:
  Instalados: 4.3.1~rc1-1
  Candidato:  4.3.1~rc1-1
  Tabla de versión:
 *** 4.3.1~rc1-1 0
        500 http://ppa.launchpad.net/xtaran/xen-tools/ubuntu/ precise/main amd64 Packages
        100 /var/lib/dpkg/status
     4.2.1-1 0
        500 http://es.archive.ubuntu.com/ubuntu/ precise/universe amd64 Packages

Volvemos a lanzar la orden:

# xen-create-image --hostname=elantris --ip=192.168.1.200 --force --verbose

En esta ocasión todo ha funcionado correctamente, ya podemos acceder a nuestra nueva máquina virtual. Algunos comandos útiles:

# xm list
# xm create elantris.cfg
# xm destroy elantris
# xm console elantris o id

Para salir de la consola podemos utilizar la combinación: ctrl + Alt Gr + corchete cierre (la que tiene el símbolo +)

Una vez conectados a la máquina virtual comprobamos que dispone de una instalación básica, al menos configuramos el idioma y algunas utilidades:

# apt-get install aptitude bash-completion nano
# aptitude install locales manpages-es manpages-es-extra manpages
# locale-gen es_ES.UTF-8
# aptitude update && aptitude safe-upgrade

Vamos a instalar una utilidad para ver nuestras máquinas virtuales, su funcionalidad es límitada (sin más configuración no es recomendable realizar tareas de configuración) pero al menos nos permite visulizar las consolas de forma gráfica.

# aptitude install virt-manager

Pero la consola no funciona nos aparece el siguiente error:
"Error conectando a la consola de texto: No se puede abrir un dispositivo sin nombre de alias"

Es debido a este bug: https://bugs.launchpad.net/ubuntu/+source/virt-manager/+bug/1057319

He encontrado una solución en los foros de bugs de novell:

# cd /usr/share/virt-manager/virtManager
#cp serialcon.py serialcon.py.old
# cd ..
# wget http://bugzillafiles.novell.org/attachment.cgi?id=506198 -O virtman-reverse-serialcon.patch
#patch -p0 < virtman-reverse-serialcon.patch

Si volmemos a probar veremos que la consola ya funciona.

Podemos hacer que nuestras máquinas virtuales arranque automáticamente al encender el hipervisor:

# mkdir /etc/xen/auto# cd /etc/xen/auto
# ln -s . ../elantris.cfg

Este servidor es un blade de cisco UCS con tarjeta M81KR y nos interesa mapear directamente las tarjetas de red a las máquinas virtuales para ello utilizaremos Xen Pci Passthrough

Vamos a utilizar "Dynamic assignment with sysfs", creamos el script pciback_script.sh:
 #!/bin/bash

if [ $# -eq 0 ]; then
    echo "Require PCI devices in format:  ::."
    echo "Eg: $(basename $0) 0000:00:1b.0"
    exit 1
fi

modprobe xen-pciback

for pcidev in $@; do
    if [ -h /sys/bus/pci/devices/"$pcidev"/driver ]; then
        echo "Unbinding $pcidev from" $(basename $(readlink /sys/bus/pci/devices/"$pcidev"/driver))
        echo -n "$pcidev" > /sys/bus/pci/devices/"$pcidev"/driver/unbind
    fi
    echo "Binding $pcidev to pciback"
    echo -n "$pcidev" > /sys/bus/pci/drivers/pciback/new_slot
    echo -n "$pcidev" > /sys/bus/pci/drivers/pciback/bind
done
A este script le pasamos el identificador pci de nuestra tarjeta de red como parámetro, para averiguar que identificador utiliza nuestra tarjeta (eth0):

# cat /etc/udev/rules.d/70-persistent-net.rules
# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.

# PCI device 0x1137:/sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:00.0/0000:08:00.3 (enic)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:b5:00:00:19", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth3"

# PCI device 0x1137:/sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:00.0/0000:08:00.1 (enic)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:b5:00:00:18", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

# PCI device 0x1137:/sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:00.0/0000:08:00.0 (enic)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:b5:00:00:08", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

# PCI device 0x1137:/sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:00.0/0000:08:00.4 (enic)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:b5:00:00:16", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth4"

# PCI device 0x1137:/sys/devices/pci0000:00/0000:00:07.0/0000:04:00.0/0000:05:00.0/0000:06:00.0/0000:07:00.0/0000:08:00.2 (enic)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:25:b5:00:00:09", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth2"
Ejecutamos el script:
# sh pciback_script.sh 0000:08:00.0

Comprobamos su disponibilidad:
# xm pci-list-assignable-devices
0000:08:00.0

Modificamos el fichero de definición de VMS, /etc/xen/elantris.cfg y añadimos:

pci = ['0000:08:00.0']
En la línea del kernel del menu.lst del grub de la máquina virtual hay que añadir:
iommu=soft
Al arrancar nuestra máquina virtual tendremos otra interfaz de red, tan solo nos falta configurar su parámetros ip.

Con la colaboración de @alionka