9.2.2.1.2.1.5. Script

Ya que usar directamente QEmu es incómodo y complicado, como se habrá podido comprobar sobradamente, proponemos un script que ayude a lanzarlo de manera más sencilla. Admite opciones propias y aquellas que no entiende las considera de qemu-system-x86_64 con lo que se las pasará sin alterar. Además, si algunas de las opciones es -- todas las que vengan detrás de ella las supondrá de qemu-system-x86_64 y las pasará también sin interpretar, tengan o no significado propio.

Antes de utilizarlo, no obstante, son necesarios cinco requisitos:

  1. Crear el grupo qemusers para que pertenezcan a él todos los usuarios que utilicen el script (puede editarse el código para cambiar el nombre).

  2. Crear un archivo /etc/sudoers.d/qemu con el siguiente contenido:

    Cmnd_Alias     QEMU=/ruta/absoluta/a/vm -up *, /ruta/absoluta/a/vm -down *
    %qemusers      ALL=NOPASSWD: QEMU
    

    que permitirá a los integrantes del grupo anterior crear las interfaces en los casos que sea necesario.

  3. Ajustar los permisos de /usr/lib/qemu/qemu-helper como se explica más atrás.

  4. Habilitar vhost-net según lo indicado al comienzo del apartado correspondiente.

  5. Si se quiere poder utilizar directamente los dispositivos USB en el anfitrión, alterar las reglas de udev como se propone en el apartado sobre USB.

El script tiene la siguiente sintaxis:

vm [opciones|opciones_de_qemu] [--] [opciones_de_qemu]

donde las opciones son de los siguientes tipos (de menor a mayor precedencia):

  1. Añadidas por defecto:

    • Acelaración por hardware

    • Memoria de 512MiB (manipulable a través de la variable de ambiente VM_MEM)

  2. Propias del script.

  3. Propias de qemu-system-x86_64 colocadas tras --.

  4. Propias de qemu-system-x86_64 colocadas antes de --.

Por tanto, para que la máquina virtual tuviera más memoria, bastaría con incluir con incluir -m en algún lugar de la orden:

$ vm -disk disco.qcw -m 1G

Y si, además, quisiéramos que tuviera dos procesadores:

$ vm -disk disco.qcw -m 1G -smp 2

También podríamos haber hecho:

$ vm -disk disco.qcw -- -m 1G -smp 2

pero no habría ninguna diferencia. El uso de -- sólo es estrictamente necesario cuando una misma opción es propia y de QEmu como es el caso de -display:

$ vm -disk disco.qcw -display none -- -device cirrus-vga -display sdl -monitor vc

En este caso, el primer -display será interpretado por el script y provocará que no defina ninguna salida de vídeo (por defecto, es vga), lo cual deja el camino expedito a las opciones tras --, que definen una no incluida entre las definidas por el script[1].

Las opciones propias empiezan todas con un único guión, no pueden fusionarse y facilitan, fundamentalmente, la introducción de cuatro aspectos:

Almacenamiento

Definido mediante las opciones -disk:

$ vm -disk disco.qcw

Pueden incluirse varias veces para indicar varias unidades y, si el firmware es BIOS, irán antes en la secuencia de arranque los referidos antes. Por ejemplo, esto arrancaría con un disco y un cedé, teniendo preferencia la unidad optica:

$ vm -disk gparted.iso -disk disco.qcw

Es posible referir dispositivos de bloques, en vez de archivos:

$ vm -disk /dev/sr0 -disk disco.qcw

Para cargar los discos se siguen las siguientes reglas:

  • Por defecto, se utiliza virtio-scsi para discos u unidades ópticas, pero con la variable de ambiente VM_HDDRIVER=virtio-blk, se utilizará virtio-blk para discos e ide-cd para unidades ópticas.

  • Se usa usb-storage para dispositivos USB de almacenamiento.

  • Sólo se soportan discos QCOW2, imágenes crudas, imágenes ISO y dispositivos de bloques.

  • A la expresión del disco pueden anteponerse dos prefijos:

    • cdrom:, que fuerza a que el disco sea interpretado como un dispositivo óptico. En principio, no debería ser necesario, puesto que script intenta adivinarlo atendiendo a la naturaleza del archivo regular o dispositivo de bloques.

    • usb:, que es necesario si se quiere que el disco se interprete como un dispositivo USB.

Por tanto, otras posibilidades son:

$ vm -disk cdrom:/dev/sr0 -disk disco.qcw

que no es necesaria, puesto que el script reconocerá el dispositivo de bloques como propio de un almacenamiento óptico, o:

$ vm -disk usb:slax.img -disk disco.qcw

Nota

Obviamente, pueden seguir usándose las opciones cortas de qemu-system-x86_64, aunque convendría no mezclarlas con -disk, porque no se ha comprobado el efecto de tal mezcla:

$ vm -hda disco.qcw -- -cdrom gparted.iso -boot order=d
Salida de vídeo

Mediante la opción -display. Admite varias:

-display none

No hay salida de vídeo. El único mode de acceder a la máquina será a través de la red (p.e. porque se haya instalado un servidor SSH):

$ vm -disk disco.qcw -display none
-display vga

El dispositivo de salida es virtio-vga/gtk:

$ vm -disk disco.qcw -display vga

La ventana queda bloqueada para que no pueda cerrarse accidentalmente pulsando el botón de cierre (el aspa) que gestiona el gestor de ventanas. Es el valor predeterminado, si no se especifica opción -display o se define la variable VM_VIDEO con otro valor:

$ VM_VIDEO=spice vm -disk disco.qcw
-display spice

Prepara la salida para el uso de spice. Internamente usa la salida spice-app, por lo que necesita que haya un cliente instalado y asociado al tipo x-scheme-handler/spice+unix. También permite el cortapega, si el cliente tiene instalado spice-vdagent:

$ vm -disk disco.qcw -display spice

El monitor estará disponible a través de telnet por un puerto igual o superior a 2345.

-display vnc

El anfitrión se encuentra disposible a través de VNC por un puerto igual o superior a 10000.

-display stdio

La salida es la propia terminal de texto para lo cual es necesario que se haya preparado el cliente para que ofrezca salida y entrada a través del puerto serie. Es la única salida que no libera la terminal por razones obvias:

$ vm -disk disco.qcw -display stdio

El monitor es accesible pulsando Control-A+h.

-display telnet

Semejante a la anterior, pero la salida se hace disponible a través de telnet por un puerto igual o superior a 10000:

$ vm -disk disco.qcw -display telnet

Si se quiere elegir expresamente el puerto de escucha:

$ vm -disk disco.qcw -display telnet:2020

El comportamiento (salvo para stdio) es dejar libre la terminal pasando a segundo plano la ejecución de la máquina. Si se quiere evitar este comportamiento puede añadirse la opción -f:

$ vm -f -disk disco.qcw

En este caso, el huésped aparecerá en una ventana gráfica gtk, pero la terminal quedará ocupada por la orden hasta que no la apaguemos.

Red

Mediante la opción -net. El argumento puede ser una combinación de «u» (red de usuario), «p» (interfaz puente) y digitos hexadecimales 0-9a-f (redes internas). También puede escribirse none para que la máquina no disponga de interfaz de red. Por ejemplo:

  • Una sola interfaz en red de usuario: -net u

  • Dos interfaces, una en red de usuario y otra en la red interna 0: -net  u0.

  • Tres interfaces, una en adaptador puente, otra en la red interna 0 y la última en la red interna a: -net p0a.

Se siguen las siguientes reglas:

  • En ausencia de la opción se supone una interfaz en red de usuario.

  • La red de usuario siempre redirige el primer puerto libre del anfitrión a partir del 10022 al puerto 22 del huésped.

  • Para la interfaz puente se escoge automáticamente la solución apropiada (puente o macvtap) según esté definida la interfaz en el anfitrión.

  • Las redes internas se construyen con socket, pero se basan en puentes si se añade el prefijo tap: al argumento (p.e. -net  tap:p0a).

Por ejemplo:

  1. Máquina con una interfaz en red de usuario:

    $ vm -disk caca.qcw
    
  2. Máquina sin red:

    $ vm -net none -disk caca.qcw
    
  3. Máquina con una interfaz en adaptador puente y otra en la red interna «2»:

    $ vm -net p2 -disk caca.qcw
    
  4. Ídem pero la red interna se crea mediante un puente:

    $ vm -net tap:p2 -disk caca.qcw
    
USB

Mediante la opción -usb se pueden pasar al huésped los dispositivos USB que queremos que estén disponibles para él:

$ vm -disk disco.qcw -usb 1234:abcd

donde 1234 es el identificador del vendedor y abcd el identificador del producto tal y cómo los vemos en la salida de lsusb. Para pasar varios dispositivos basta con repetir la opción.

Nota

-disk usb:1234:abcd se traduce a -usb 1234:abcd, sin entrar a valorar la naturaleza del dispositivo (que puede no serlo de almacenamiento).

Aún hay algunas opciones más que alteran el comportamiento de la máquina:

-U

que provoca que la máquina tenga firmware EFI. La ubicación del archivo de firmware en el anfitrión es /usr/share/qemu/OVMF.fd, esto es, la propia de Debian. Si es otra, puede definirse a través de la variable VM_UEFIFIRM:

$ VM_UEFIFIRM="/otra/ruta/a/OVMF.fd" vm -U -disk disco.qcw
-s

muestra las órdenes por pantalla, pero no llega a ejecutar ninguna:

$ vm -s -hda disco.qcw2
qemu-system-x86_64 -nodefaults -m 512 -machine accel=kvm \
   -device virtio-net,netdev=nic0,mac=de:ad:be:ef:d0:5f -netdev user,id=nic0,hostfwd=tcp:127.0.0.1:10022-:22 \
   -device virtio-vga -display gtk,window-close=off -monitor vc -hda caca.qcw

Si la línea supone órdenes adicionales, también se mostrarán:

$ vm -s -hda disco.qcw2 -net tap:0
ip link add name vmnet0 type bridge
ip link set vmnet0 up
qemu-system-x86_64 -nodefaults -m 512 -machine accel=kvm \
   -device virtio-net,netdev=nic0,mac=de:ad:be:ef:21:b0 -netdev bridge,id=nic0,br=vmnet0 \
   -device virtio-vga -display gtk,window-close=off -monitor vc -hda disco.qcw2
ip link del vmnet0
-v

que muestra las órdenes como -s, pero a diferencia de ella sí las ejecuta.

Notas al pie