Table of Contents

KVM

virtualizacion

Algunos conceptos:

Instalar

1. Entrar en la BIOS del sistema y asegurarse de que el soporte de virtualización está activado

2. Instalar un sistema GNU/Linux reciente (yo pruebo con Debian 6.x=

3. Comprobar que el sistema operativo soporta virtualizacion:

Una vez encontré un escenario en el que la prueba 3.1. era KO y la 3.2. OK, por lo que creo que la más exacta es la 3.1.

3.1. Ver si kvm está deshabilitado a nivel de BIOS

dmesg | grep bios

3.2 Ejecutar

sudo egrep '(vmx|svm)' --color=always /proc/cpuinfo

En caso de que SI soporte virtualizacion veremos lo siguiente:

flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm lahf_lm tpr_shadow vnmi flexpriority
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm lahf_lm tpr_shadow vnmi flexpriority

Con la palabra 'vmx' o 'svm' en rojo

4. Instalar los siguientes paquetes:

sudo aptitude install qemu-kvm libvirt-bin virtinst qemu-utils

Nota: qemu-utils es necesario para exportar de discos raw a qcow2

5. Anyadir el usuario X al grupo:

sudo adduser  USUARIO libvirt

6. Comprobar que el demonio libvirtd esta corriendo (necesario para poder administrar KVM desde un entorno grafico con virt-manager):

ps ax | grep libvirt
 4149 ?        Sl     0:00 /usr/sbin/libvirtd -d

Crear VM

Desde GUI

La principal diferencia es VNC. Configuracion:

<domain type='kvm'>
  <name>test-1.dev.jj.com</name>
  <uuid>12b440aa-fee3-b6cc-31d1-4d2bde56e0df</uuid>
  <memory>1048576</memory>
  <currentMemory>524288</currentMemory>
  <vcpu>2</vcpu>
  <os>
    <type arch='x86_64' machine='pc-0.12'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/bin/kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/test-1.dev.jj.com.img'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </disk>
    <disk type='block' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='1' unit='0'/>
    </disk>
    <controller type='ide' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <interface type='network'>
      <mac address='52:54:00:2a:b7:e1'/>
      <source network='default'/>
      <target dev='vnet0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <input type='tablet' bus='usb'/>
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' port='-1' autoport='yes'/>
    <video>
      <model type='cirrus' vram='9216' heads='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </memballoon>
  </devices>
</domain>

Desde linea de comandos

Lanzar los comandos desde el hipervisor.

Debian estable desde red configurada con NAT, 1024B de RAM, y disco duro con algunas configuraciones para mejor rendimiento:

sudo virt-install \
-n template-1.dev.local.legido.com \
-r 1024 \
--vcpus=2 \
--os-variant=debianwheezy \
--disk /var/lib/libvirt/images/template-1.dev.local.legido.com,size=5,bus=virtio,cache=none,format=qcow2 \
--nographics \
--network network=default \
-l http://ftp.debian.org/debian/dists/wheezy/main/installer-amd64/ \
-x console=ttyS0,115200

Debian estable desde red configurada con bridge, 512MB de RAM y 2 GB de disco duro:

virt-install \
-n vm1 \
-r 512 \
--vcpus=2 \
--os-variant=debiansqueeze \
--disk /var/lib/libvirt/images/vm1.img,size=2 \
--nographics \
--bridge br0 \
-l http://ftp.debian.org/debian/dists/squeeze/main/installer-amd64/ \
-x console=ttyS0,115200

Ubuntu server, NAT conectado a red “default”:

sudo virt-install \
-n template-2.dev.local.jamgo.org \
-r 512 \
--vcpus=2 \
--os-variant=ubuntuquantal \
--disk /var/lib/libvirt/images/template-2.dev.local.jamgo.org.qcow2,size=8,bus=virtio,cache=none \
--nographics \
--network network=default \
-l http://archive.ubuntu.com/ubuntu/dists/quantal/main/installer-amd64/ \
-x console=ttyS0,115200

Debian Jessie desde CD:

sudo virt-install \
-n template-1.dev.local.legido.com \
-r 512 \
--vcpus=2 \
--os-variant=debianwheezy \
--disk pool=template_1,sparse=false,size=8,cache=none,format=raw,bus=virtio \
--graphics vnc \
--bridge virbr0 \
--cdrom=/var/lib/libvirt/images/debian-jessie-amd64-netinst.iso

vmbuilder

http://www.howtoforge.com/virtualization-with-kvm-on-a-debian-squeeze-server

TODO Crear una VM desde linea de comandos con un VL como storage

Conectarse a KVM y VM

GUI

Escenario: NO quiero instalar las X en el hipervisor, y quiero administrar gráficamente el hipervisor y las máquinas virtuales desde otra máquina (cliente) con las X instaladas

1. (Hipervisor) Instalar los siguientes paquetes:

sudo aptitude update; sudo aptitude install netcat socat -R

2. (Hipervisor) Crear el siguiente archivo:

sudo vim /bin/netcatsocket

Con el siguiente contenido:

#!/bin/bash
socat - unix-client:$2

3. (Hipervisor) Darle permisos

sudo chmod +x /bin/netcatsocket

4. (Cliente) Instalar paquetes:

sudo aptitude update; sudo aptitude install virt-manager ssh-askpass -R

5. (Cliente) Conectarse al hipervisor:

virt-manager -c qemu+ssh://USUARIO@HIPERVISOR:PUERTO/system?netcat=netcatsocket

Conectarse a la consola de VM sin GUI

1. (VM) Editar

sudo vim /etc/inittab

Y anyadir:

T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100

2. (VM) Editar

sudo vim /etc/default/grub

Y dejar la linea tal que asi:

GRUB_CMDLINE_LINUX="console=tty0"

3. (VM) Recargar grub:

sudo update-grub

4. (Hipervisor) Conectarse a la consla de la VM:

sudo virsh console template

Connected to domain template
Escape character is ^]

Toca un tecla (por ejemplo enter) y aparecera el prompt:

Debian GNU/Linux 6.0 template ttyS0

template login:

5. Para finalizar la conexion CTRL + ]

Comandos varios

* Listar todas las Maquinas Virtuales (VM):

virsh list --all
 Id    Name                           State
----------------------------------------------------
 -     name                           shut off

* Forzar apagado VM:

sudo virsh destroy vm2

* Eliminar por completo una VM:

virsh undefine vm2
Domain vm2 has been undefined

* Cambiar la memoria maxima. IMPORTANTE: requiere apagar la VM, mejor apagarla primero a traves del Sistema Operativo:

sudo virsh shutdown vm2
sudo virsh setmaxmem vm2 524288
sudo virsh start vm2
sudo virsh setmem vm2 524288

En este ejemplo se establece el valor en 524288 KB

sudo virsh autostart myvmname

Salir de la consola

* virt-manager

CTRL + ALT + F7

o

CTRL + ALT

Errores

* Cannot recv data: Host key verification failed. : Connection reset by peer

Sucede al lanzar:

virt-manager -c qemu+ssh://usuario@hipervisor/system

Solucion: iniciar una sesion SSH para almacenar las claves del hipervisor en el cliente:

ssh usuario@hipervisor

* Error starting network 'default': internal error

Suce al intentar activar o crear una nueva red virtual desde virt-manager debido a un bug de libvirt.

Solucion: actualizar los paquetes relacionados con libvirt

1. Editar:

sudo vim /etc/apt/sources.list

Y anyadir la siguiente linea:

deb http://backports.debian.org/debian-backports squeeze-backports main

2. Actualizar la cache de paquetes:

sudo aptitude update

3. Instalar la version de backports de los siguientes paquetes:

sudo aptitude -t squeeze-backports install libvirt-bin libvirt0 python-libvirt dnsmasq-base -R

4. Reiniciar el demonio libvirtd:

sudo /etc/init.d/libvirt-bin restart

Renombrar VM

VM destino no existe

Queremos renombrar de “test-2.example.com” a “test-1.example.com”. Solo existe la primera, “test-2.example.com”

1. Volcar la configuración:

sudo su -
cd /etc/libvirt/qemu/
virsh dumpxml test-2.example.com.xml > test-1.example.com.xml

2. Apagar la VM si no lo está (a nivel de Sistema Operativo mejor).

Asegurarse de que NO tiene snapshot

3. Cepillarse la VM:

virsh undefine test-2.example.com

4. Editar el archivo de configuracion de la nueva VM:

sudo vim test-1.example.com.xml

Y asegurarse de que los siguientes valores son unicos y correctos:

<name>test-1.example.com</name>
<source dev='/dev/vg/lv_test_1'/>
  
<mac address='00:16:3e:0e:3e:53'/>

Script para generar MAC addresses:

#!/usr/bin/python
# macgen.py script to generate a MAC address for guests on Xen
#
import random
#
def randomMAC():
        mac = [ 0x00, 0x16, 0x3e,
                random.randint(0x00, 0x7f),
                random.randint(0x00, 0xff),
                random.randint(0x00, 0xff) ]
        return ':'.join(map(lambda x: "%02x" % x, mac))
#
print randomMAC()

Ahora obtenemos el listado de VMS:

virsh list --all

Y para cada una de ellas obtenemos la MAC address:

virsh dumpxml vm-1.example.com | grep "mac address" | awk '{print $2}' | cut -d "'" -f2

TODO: hacer un script en bash que lo haga

Finalmente nos aseguramos que la nueva MAC generada es unica.

5. Definir la nueva VM:

virsh define test-1.example.com.xml

VM destino existe

1. Para VM destino

2. Eliminarla:

sudo virsh undefine test-1.example.com

Seguir los pasos de vm_destino_no_existe

Dispositivos

CDROM

1. Dejar la imagen iso en el hipervisor:

/var/lib/libvirt/images/systemrescuecd-x86-3.4.2.iso

2. Editar la VM:

sudo virsh
edit vm_1

2.1. Anyadir el siguiente bloque dentro del bloque <devices>:

  <devices>
    ...
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/systemrescuecd-x86-3.4.2.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
    </disk>
    ...
  </devices>

Al grabar libvirt le asignara una entrada con la direccion PCI dentro del bloque <disk>

2.2. (Opcional) Si se quiere arrancar desde CD anyadir el siguiente bloque dentro del bloque <os>:

  <os>
    <boot dev='cdrom'/>
    <boot dev='hd'/>
  </os>

2.3. Grabar y salir

VNC

1. Editar la VM desde virsh:

sudo virsh
edit vm_1

1.1. Anyadir el siguiente bloque dentro del bloque <devices>:

  <devices>
    ...
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' port='-1' autoport='yes'/>
    <video>
      <model type='cirrus' vram='9216' heads='1'/>
    </video>
    ...
  </devices>

Al grabar libvirt le asignara una entrada con la direccion PCI dentro del bloque <disk>

1.2. Grabar y salir

Almacenamiento

Archivo

Agrandar. Formato QCOW2 + LVM en VM

NOTA estas instrucciones sirven tambien cuando el almacenamiento de la VM se hace en un LV del host. Solo hay que cambiar el paso 2

La estrategia es extender el disco, crear una nueva particion en el nuevo espacio, crear un PV, anyadirlo al VG, extender el LV y redimensionar el sistema de archivos (EXT4…).

1. Para la VM, a ser posible desde el Sistema Operativo:

ssh test7
sudo shutdown -h now

2. Extender el disco:

sudo qemu-img resize /var/lib/libvirt/images/test7.qcow2 +8G
Image resized.

NOTA KVM todavia no muestra el nuevo tamano si hacemos 'ls -lath /var/lib/libvirt/images/test7.qcow2'

3. Arrancar la nueva VM:

sudo virsh start test7
Domain test7 started

4. Comprobar que el Sistema Operativa ve el nuevo espacio (10 GB):

ssh test7
sudo fdisk -l
Disk /dev/vda: 10.7 GB, 10737418240 bytes
16 heads, 63 sectors/track, 20805 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00031f27

   Device Boot      Start         End      Blocks   Id  System
/dev/vda1   *           3         496      248832   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/vda2             498        4159     1845249    5  Extended
Partition 2 does not end on cylinder boundary.
/dev/vda5             498        4159     1845248   8e  Linux LVM

Disk /dev/dm-0: 1753 MB, 1753219072 bytes
255 heads, 63 sectors/track, 213 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/dm-0 doesn't contain a valid partition table

Disk /dev/dm-1: 134 MB, 134217728 bytes
255 heads, 63 sectors/track, 16 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/dm-1 doesn't contain a valid partition table

NOTA Los mensajes “Partition 1 does not end on cylinder boundary.” son ajenos a esta receta, pero deben evitarse con un correcto particionamiento.

5. Crear una nueva particion

sudo fdisk /dev/vda
n
p
[enter] (en mi caso particion 3)

Aqui introducir el sector final de la partición anterior más 1, o el siguiente numero que sea divisible por 8 si el host tiene un tamanyo fisico de sector de 4096 bytes. Luego aceptar el valor propuesto (el último sector del disco menos 1)

w

6. Aqui hay que reiniciar para que la particion sea usable por el Sistema Operativo:

sudo shutdown -r now

7. Crear un PV con la nueva particion:

sudo pvcreate /dev/vda3
Physical volume "/dev/vda3" successfully created

8. Anyadir ese PV al VG. Primero obtener el nombre del VG y del PV:

sudo vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "template" using metadata type lvm2
sudo pvscan
  PV /dev/vda5   VG template        lvm2 [1.76 GiB / 0    free]
  PV /dev/vda3                      lvm2 [8.00 GiB]
  Total: 2 [9.76 GiB] / in use: 1 [1.76 GiB] / in no VG: 1 [8.00 GiB]

Anyadimos el PV '/dev/vda3' al VG 'template':

sudo vgextend template /dev/vda3
Volume group "template" successfully extended

9. Extendemos el VL. Primero los listamos:

sudo lvscan
ACTIVE            '/dev/template/root' [1.63 GiB] inherit
ACTIVE            '/dev/template/swap_1' [128.00 MiB] inherit

Vamos a extender el LV '/dev/template/root' todo lo que podamos:

sudo lvextend -l +100%FREE /dev/template/root
Extending logical volume root to 9.63 GiB
Logical volume root successfully resized

10. Extendemos el sistema de archivos. El proceso tarda 1 minuto para 8GB:

sudo resize2fs /dev/mapper/template-root
resize2fs 1.41.12 (17-May-2010)
Filesystem at /dev/mapper/template-root is mounted on /; on-line resizing required
old desc_blocks = 1, new_desc_blocks = 1
Performing an on-line resize of /dev/mapper/template-root to 2525184 (4k) blocks.
The filesystem on /dev/mapper/template-root is now 2525184 blocks long.

Comprobamos que todo ha ido bien:

df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/template-root
                      9.5G  565M  8.5G   7% /
tmpfs                 249M     0  249M   0% /lib/init/rw
udev                  244M  108K  244M   1% /dev
tmpfs                 249M     0  249M   0% /dev/shm
/dev/vda1             228M   16M  201M   8% /boot

Montar disco qcow2 con LVM y cambio de contraaseña

Todas las operaciones se realizan desde el hipervisor. Este procedimiento es útil si por ejemplo queremos cambiar una contraseña que se nos ha olvidado.

1. Cargar módulo del kernel

sudo modprobe nbd max_part=63

2. Montar disco qcow2:

sudo qemu-nbd -c /dev/nbd0 /ruta/disco/vm_1.qcow2
sudo mkdir /mnt/vm_1
sudo mount /dev/nbd0p1 /mnt/vm_1

3. Si la VM tiene LVM:

3.1 (Opcional) Instalar LVM

sudo aptitude install lvm2 -R

3.2 Buscar Volume Group:

vgscan

  Reading all physical volumes.  This may take a while...
  Found volume group "template-1" using metadata type lvm2

Encuentro el VG 'template-1'.

3.3 Activar Volume Group:

vgchange -ay

  2 logical volume(s) in volume group "template-1" now active

3.4 Listar Logical Volumes:

 lvdisplay 

  --- Logical volume ---
  LV Path                /dev/template-1/root
  LV Name                root
  VG Name                template-1
  LV UUID                Tvzd3L-24mZ-DJtf-3Rno-Inxv-r8et-fOAvpR
  LV Write Access        read/write
  LV Creation host, time template-1, 2013-04-05 10:21:48 +0200
  LV Status              available
  # open                 0
  LV Size                7.23 GiB
  Current LE             1851
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           252:0
   
  --- Logical volume ---
  LV Path                /dev/template-1/swap_1
  LV Name                swap_1
  VG Name                template-1
  LV UUID                4EY2TJ-Jcow-PFis-1VRJ-IWyE-NGwB-lSbNmd
  LV Write Access        read/write
  LV Creation host, time template-1, 2013-04-05 10:21:48 +0200
  LV Status              available
  # open                 0
  LV Size                508.00 MiB
  Current LE             127
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           252:1

En este caso me interesa el VL 'root', con el path '/dev/template-1/root'

3.5 Montar el LV deseado, en este caso “/”:

sudo mkdir /mnt/vm_1_root
sudo mount /dev/template-1/root /mnt/vm_1_root

3.6 Entrar en esa particion:

sudo chroot /mnt/vm_1_root

3.7 Cambiar la contrasenya o realizar la operacion que se quiera:

passwd root

3.8 Salir

exit

4. Desmontar todo:

umount /mnt/vm_1_root
vgchange -an VolGroupName
umount /mnt/vm_1
killall qemu-nbd

Comprobar con “ps ax” si el proceso “qemu-nbd” ha finalizado

LVM

Acronimos:

| LVM | Logical Volume Manager |
| PV | Physical Volume |
| VG | Volume Group |
| LV | Logical Volume |

Alinear particiones VM con LVM

                         Device Boot      Start         End      Blocks   Id  System
/dev/mapper/vg-lv_test_2p1   *        2048      499711      248832   83  Linux
/dev/mapper/vg-lv_test_2p2          501758    10483711     4990977    5  Extended
Partition 2 does not start on physical sector boundary.
/dev/mapper/vg-lv_test_2p5          501760    10483711     4990976   8e  Linux LVM

1. Determinar el tamanyo del LV de origen:

sudo lvs | grep test_2

2. Crear un LV de backup con el mismo tamanyo:

sudo lvcreate vg --name lv_test_2_clone --size=8G

3. Determinar el Path del nuevo LV:

sudo lvdisplay | grep Path | grep test_2_clone

4. Determinar el Path del LV origen:

sudo lvdisplay | grep Path | grep test_2

5. Apagar la VM (mejor desde dentro de la propia VM)

6. Copiar bit a bit el LV. El Path origen se toma del paso 4 y el destino del paso 3:

time sudo dd if=/dev/vg/lv_test_2 of=/dev/vg/lv_test_2_clone bs=4096

La velocidad ronda los 60 MB/s

7. Editar la VM y anyadirle:

sudo virsh edit test_2

Ejemplo de los bloques a anyadir en el XML de la VM (ajustar por ejemplo el nombre del disco 2, etc…):

  <os>
    <boot dev='cdrom'/>
    ...
  </os>

  <devices>
    ...
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/systemrescuecd-x86-3.4.2.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
    </disk>
    <disk type='block' device='disk'>
      <driver name='qemu' type='raw' cache='none'/>
      <source dev='/dev/vg/lv_test_2_clone'/>
      <target dev='vdb' bus='virtio'/>
    </disk>
    ...
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' port='-1' autoport='yes'/>
    <video>
      <model type='cirrus' vram='9216' heads='1'/>
    </video>
    ...
  </devices>

8. Arrancar la VM y conectarse a VNC con “virt-manager”:

sudo virsh start test_2

9. (VM arrancada con live CD) Con parted eliminar las particiones 2 y 5 y recrearlas. Recomiendo ejecutarlo asi:

parted -a optimal /dev/vda

Cambiamos a sectores como unidad:

u
s

Eliminamos particiones:

rm 5
rm 2

Creo la primera, extendida:

mkpart extended 501760 10483711
mkpart logical 503808 10483711

En la segunda he dejado 2048 sectores, que a 512 bytes cada uno hacen 1 MB, que parece ser que es buena practica, ya que de otra forma parted se queja de que las particiones no estan alineadas.

Le quito el flag lba a la particion extendida:

toggle 2 lba

Salgo:

quit

10. (VM arrancada con live CD) Copiar con dd de la particion destino a la origan, una vez recreada:

time dd if=/dev/vdb5 of=/dev/vda5 bs=512

Creo que el proceso de nuevo tiene una velocidad entorno a los 60 MB/s

11. (VM arrancada con live CD) Apagar

sudo shutdon -h now

12. Deshacer los cambios sobre la VM hechos en el paso 7. Si se quiere encerrarlo entre comentarios <!– –> por si hay que repetir algun paso

13. Arrancar la VM

14. Si todo funciona correctamente, borrar el LV de backup creado en el paso 2:

sudo lvremove /dev/vg/lv_test_2_clone

Usar LV como almacenamiento

http://blog.gadi.cc/better-lvm-for-kvm/

http://vitobotta.com/kvm-virtual-machines-lvm/#sthash.DSURrZdj.dpbs

Asumo que el PV y el VG ya existen. Vamos a crear un LV por cada VM. Seguimos pues los siguientes pasos:

1. Crear el LV con la extension deseada:

sudo lvcreate vg --name lv_machine_1 --size=8G

NOTA: NO tenemos que formatear el LV, de eso se encarga el guest

2. Ya podemos usar la ruta (Path) al LV como almacenamiento. Ejemplo de clonar una VM:

sudo virt-clone  --connect=qemu:///system -o original.example.com -n machine-1.example.com -f /dev/vg/lv_machine_1

Montar LV dentro de una VM en el host

1. Apagar la VM

2. Instalar paquete:

sudo aptitude install kpartx

3. Listar todos los LVs del host:

sudo lvdisplay | grep Path

En este caso nos interesa este:

/dev/vg/lv_test_2

4. (Host) Crear el mapeo de dispositivos desde la tabla de particiones:

sudo kpartx -av /dev/mapper/vg-lv_test_2

Salida:

add map vg-lv_test_2p1 (253:9): 0 497664 linear /dev/mapper/vg-lv_test_2 2048
add map vg-lv_test_2p2 (253:11): 0 2 linear /dev/mapper/vg-lv_test_2 501758
add map vg-lv_test_2p5 : 0 9981952 linear /dev/mapper/vg-lv_test_2 501760

5. Listar nuevos LVs y VG:

sudo lvscan 

Aparecen estos dos nuevos:

  inactive          '/dev/template-1/root' [4.51 GiB] inherit
  inactive          '/dev/template-1/swap_1' [252.00 MiB] inherit

Aparece tambien un nuevo VG, al que pertenecen esos dos nuevos LVs:

sudo vgscan 
  Reading all physical volumes.  This may take a while...
  Found volume group "template-1" using metadata type lvm2

6. Activar el nuevo VG, para que los LVs se puedan montar:

sudo vgchange -ay template-1

Salida:

2 logical volume(s) in volume group "template-1" now active

Comprobar que ahora los LVs estan activos:

sudo lvscan 

Aparecen estos dos nuevos:

  ACTIVE            '/dev/template-1/root' [4.51 GiB] inherit
  ACTIVE            '/dev/template-1/swap_1' [252.00 MiB] inherit

7. Usar los LVs. Por ejemplo lo monto:

touch /tmp/root
sudo mount /dev/template-1/root /tmp/root

8. Deshacer los cambios:

8.1. Desmontar:

sudo umount /tmp/root

8.2. Deshabilitar el VG:

sudo vgchange -an template-1

Salida:

0 logical volume(s) in volume group "template-1" now active

8.3. Eliminar el mapeo de dispositivos desde la tabla de particiones:

sudo kpartx -rv /dev/mapper/vg-lv_test_2

Salida:

del devmap : vg-lv_test_2p5
del devmap : vg-lv_test_2p2
del devmap : vg-lv_test_2p1

Crear storage pool

En este ejemplo le vamos a asignar un LV a una VM.

1. Crear un .xml con la definicion, no importa la ruta:

vim ~/vm_1.xml
<pool type="fs">
        <name>template_1</name>
        <source>
                <device path="/dev/vg/vm_1"/>
        </source>
        <target>
                <path>/var/lib/libvirt/images/template_1</path>
        </target>
</pool>

2. Crear el directorio “target”

sudo mkdir /var/lib/libvirt/images/template_1

3. Definir el pool storage:

sudo virsh pool-define ~/vm_1.xml

4. Marcarlo para que se inicie al arrancar la maquina:

sudo virsh pool-autostart vm_1

5. Arrancar el pool. Esta accion monta “source” en “target”. Si “target” no existe devuelve un error:

sudo virsh pool-start vm_1

6. Comprobar:

cat /etc/mtab | grep vm_1
/dev/mapper/vg-vm_1 /var/lib/libvirt/images/vm_1 ext4 rw,relatime,data=ordered 0 0

Cambiar formato del disco

1. Paramos la VM:

sudo shutdown www-1.dev.local.example.com

2. Exportamos el disco de formato 'raw' a 'qcow2':

sudo qemu-img convert -p -O qcow2 /var/lib/libvirt/images/www-1.dev.local.example.com.raw /var/lib/libvirt/images/www-1.dev.local.example.com.qcow2

Se ha creado el nuevo archivo.

3. Editamos la VM:

sudo virsh edit www-1.dev.local.example.com

Y editamos los parametros 'type' y 'source file':

    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='none'/>
      <source file='/var/lib/libvirt/images/www-1.dev.local.example.com.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </disk>

Grabamos y salimos

4. Arrancamos la VM:

sudo virsh start www-1.dev.local.example.com

Si arranca correctamente nos cepillamos el disco en formato “raw” que ya no usaremos:

sudo rm -fr www-1.dev.local.example.com.raw

Anyadir un disco en caliente

http://serverfault.com/questions/457250/kvm-and-libvirt-how-do-i-hotplug-a-new-virtio-disk

First of all, you should avoid using virsh attach-disk with its limited amount of options. Instead, I suggest to specify the exact disk format you prefer in a separate, temporary XML file, like this:

<disk type='file' device='disk'>
  <driver name='qemu' type='qcow2' cache='writeback'/>
  <source file='/home/gert/kvm/testdomain-vdb.img'/>
  <target dev='vdb' bus='virtio'/>
</disk>

Before adding it, make sure the hotplug kernel modules are loaded in the guest:

modprobe acpiphp
modprobe pci_hotplug

Some distributions, including recent CentOS/RHEL/Fedora have this built-in in the kernel. In this case, check for CONFIG_HOTPLUG_PCI_ACPI. If it's y, then you're all set.

Finally, add it to the running VM using

virsh # attach-device [domain] /path/to/disk.xml

(optionally, add the –persistent option to let Libvirt update the domain XML definition 'persistent'.)

In the guest, the kernel should now be triggered, as can be checked with dmesg:

[  321.946440] virtio-pci 0000:00:06.0: using default PCI settings
[...]
[  321.952782]  vdb: vdb1 vdb2

This also works perfectly using the GUI-enabled virt-manager application.

See also:

http://www.linux-kvm.org/page/Hotadd_pci_devices http://serverfault.com/questions/453456/adding-virtio-block-devices-at-runtime-in-libvirt-kvm

Snapshots

http://redes-privadas-virtuales.blogspot.com.es/2011/03/taking-snapshots-on-kvm-with-libvirt.html

http://www.thegoldfish.org/2011/09/reverting-to-a-previous-snapshot-using-linux-lvm/

Caracteristicas/limitaciones:

raw + LVM

Consideraciones y estrategia propuesta:

Tomar snapshot

1. Se puede ejecutar con la VM corriendo. Desde el host ejecutar:

sudo lvcreate -s /dev/vg/lv_vm_1 -L 1G -n lv_vm_1_snapshot_1

Backup del snapshot

1. Crear un nuevo LV para el backup. Tiene que tener el mismo tamanyo que el del LV del cual se tomo el snapshot:

sudo lvcreate vg --name lv_vm_1_snapshot_1_backup --size=8G

2. Copiar con dd el snapshot al backup. Ajustar el block size (bs):

time sudo dd if=/dev/vg/lv_vm_1_snapshot_1 of=/dev/vg/lv_vm_1_snapshot_1_backup bs=512

Velocidad: 50.9 MB/s

3. Eliminar el snapshot:

sudo lvremove /dev/vg/lv_vm_1_snapshot_1

Restaurar el snapshot

1. Parar la VM

2. Copiar con dd desde el backup al LV original. Ajustar el block size (bs):

time sudo dd if=/dev/vg/lv_vm_1_snapshot_1_backup of=/dev/vg/lv_vm_1 bs=512

Velocidad: 53.8 MB/s

3. Encender la VM

qcow2

Tomar snapshot / migrar formato de disco raw a qcow2

1. Conectarse al hipervisor. Yo por simplicidad lo hago a traves de SSH, pero a lo mejor es posible conectarse desde el cliente con un virsh -c URL

ssh usuario@hipervisor

2. Crear un archivo .xml con informacion sobre el snapshot:

sudo vim /var/lib/libvirt/qemu/snapshot/test2_snapshot_01.xml

Con el siguiente contenido:

<domainsnapshot>
   <name>test2_snapshot_01_160520121140</name>
   <description>Fresh install of Debian Squeeze 64 bits</description>
</domainsnapshot>

Grabar y salir

3. IMPORTANTE: solo el formato qcow2 soporta snapshots. Vamos a comprobar que formato tiene el disco duro de la VM, que en este ejemplo se llama “test2”

sudo virsh edit test2

De la informacion que muestra nos fijamos en el disco:

...
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/test2.img'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </disk>
...

Si intentamos tomar el snapshot veremos que NO lo soporta (:q! para salir de la ventana de edicion):

sudo virsh snapshot-create test2 /var/lib/libvirt/qemu/snapshot/test2_snapshot_01.xml 
error: Requested operation is not valid: Disk '/var/lib/libvirt/images/test2.img' does not support snapshotting

Por lo que volvemos a editar:

sudo virsh edit test2

Y dejamos la seccion de disco tal que asi (solo cambiar qcow2):

...
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/test2.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </disk>
...

Grabar y salir

Domain test2 XML configuration edited.

TODO: quiza hay un comando para cambiar el formato del disco

4. Convertir el disco de formato raw a qcow2. La VM debe estar apagada

sudo qemu-img convert -f raw -O qcow2 -o preallocation=metadata /var/lib/libvirt/images/test2.img /var/lib/libvirt/images/test2.qcow2
sudo chown libvirt-qemu:kvm /var/lib/libvirt/images/test2.qcow2

5. Volver a tomar el snapshot:

sudo virsh snapshot-create test2 /var/lib/libvirt/qemu/snapshot/test2_snapshot_01.xml 
Domain snapshot test2_snapshot_01_160520121140 created from '/var/lib/libvirt/qemu/snapshot/test2_snapshot_01.xml'

Para verlo:

sudo virsh snapshot-list test2
 Name                 Creation Time             State
------------------------------------------------------------
 test2_snapshot_01_160520121140 2012-05-16 12:46:48 +0200 shutoff

RENDIMIENTO si tomamos el snapshot de una VM corriendo (2GB de disco duro) me tomo 03'14“

6. Arrancar la VM y verificar que funciona correctamente

sudo virsh start test2
Domain test2 started

7. Si ha arrancado correctamente, eliminar el viejo disco:

sudo rm -fr /var/lib/libvirt/images/test2.img

Script para tomar snapshot

#!/usr/bin/python

import sys, commands, time, os, datetime

# Variables

path_snapshots = '/var/lib/libvirt/qemu/snapshot/'
header = ['Id', 'Name', 'State']
snapshot_template = """\
<domainsnapshot>
   <name>NAME</name>
   <description>DESCRIPTION</description>
</domainsnapshot>
"""

# Code

if not os.geteuid() == 0:
    print "You aren't root.  Goodbye."
    sys.exit()

output = commands.getoutput('virsh list --all')
print output
list_vm = [line for line in output.split('\n') if '---' not in line and not all(e in line for e in header)]
row_number_list_vm = int(raw_input('Select which VM to take snapshot.\nUse line number (1 for " %s" etc...): '\
 %(list_vm[0])))

line = list_vm[row_number_list_vm-1]
print 'You selected "%s"' %(line)

description = raw_input('Please type a description for this snapshot: ')

aux = line.split('   ')[0].split(' ')
vm_name = aux[len(aux)-1]
snapshot_name =  vm_name + '_' + str(time.time()).split('.')[0]

snapshot_xml_path = path_snapshots + snapshot_name + '.xml'
snapshot_xml = snapshot_template.replace('NAME',snapshot_name).replace('DESCRIPTION',description)

file = open(snapshot_xml_path, 'w+')
file.write(snapshot_xml)
file.close()

print "WARNING, the process takes a while. For a running machine with 2 GB disk can take 3 minutes"
print datetime.datetime.today()

output = commands.getstatusoutput('virsh snapshot-create %s %s' %(vm_name,snapshot_xml_path))
if output[0] != 0:
    print 'Error %s' %(str(output))

print datetime.datetime.today()

Restaurar snapshot

1. Conectarse al hipervisor. Yo por simplicidad lo hago a traves de SSH, pero a lo mejor es posible conectarse desde el cliente con un virsh -c URL

ssh usuario@hipervisor

2. Listar las snapshots que tenemos (nuestra VM se llama 'test2'):

sudo virsh snapshot-list test2
 Name                 Creation Time             State
------------------------------------------------------------
 test2_snapshot_01_160520121140 2012-05-16 12:46:48 +0200 shutoff
 test2_snapshot_02    2012-05-16 12:58:29 +0200 running
 test2_snapshot_03    2012-05-16 13:03:33 +0200 running

3. Restaurar por ejemplo segunda (test2_snapshot_02):

sudo virsh snapshot-revert test2 test2_snapshot_02

Tarda un par de segundos

Borrar snapshot

Los snapshots soportan como parametros –children, pero si no se le ha pasado en el momento de tomarlo, son considerados totalmente independientes, es decir, se pueden borar 1 a 1:

sudo virsh snapshot-delete test2 test2_snapshot_02
Domain snapshot test2_snapshot_02 deleted

Clonar

1. Conectar al hipervisor

ssh USUARIO@HIPERVISOR

2. Pausar la VM a clonar. Durante este tiempo consume recursos pero NO es accesible

sudo virsh suspend template
Domain template suspended

3. Clonar la VM:

sudo virt-clone  --connect=qemu:///system -o template -n template_clone -f /var/lib/libvirt/images/template_clone.qcow2
Asignando 'template_clone.qcow2'                                                                                                                                                                                        | 2.0 GB     00:02     

Clon 'template_clone' creado correctamente.

NOTA: para mayor rendimiento el almacenamiento tiene que ser un LV de LVM previamente creado y NO montado:

sudo virt-clone  --connect=qemu:///system -o template -n template_clone -f /dev/lvm_vg/lvm_lv_template_clone

4. Reanudar la VM:

sudo virsh resume template
Domain template resumed

Tabla resumen de tiempos

CPU host Memoria host Discos host Formato origen Formato destino MB/s
2xIntel(R) Core(TM)2 Duo E6750 2.66GHz 8GB DDR2 800MHz RAID 1 2xST1000DM003-1CH162 qcow2 file qcow2 LV 105.03

Exportar

El proceso comprende dos pasos: exportar la configuracion del guest y copiar el disco o discos.

El primero es comun para cualquier tipo de disco, y se hace asi:

virsh dumpxml foo > /tmp/foo.xml

El segundo depende del tipo de almacenamiento que se haya escogido.

Copiar el disco o discos. En mi caso lo he hecho con un disco .qcow2, pero hay que documentar como exportar VMs con discos en volumenes LVM

scp /path/disco_1.qcow2 /destino/disco_1.qcow2
time sudo dd if=/dev/vg/lv_test_3 bs=512 | gzip -9 > /srv/no_data/test_3_backup

o

time sudo qemu-img convert -c /dev/vg/lv_test_3 -O qcow2 test.img -p

o

time sudo qemu-img convert /dev/vg/lv_test_3 test_3.img -p

o

time sudo qemu-img convert /dev/vg/lv_test_3 /dev/vg/lv_test_3_clone -p
Metdo Almacenamiento origen Formato origen Almacenamiento destino Formato destino AlMB/s
dd ? ? ? ? 20.2 MB/s
qemu-img (cambio formato) ? ? ? ? 40.3 MB/s
qemu-img (mantengo formato) ? ? ? ? 124.12 MB/s
qemu-img (mantengo formato, destino LV) ? ? ? ? 91.02 MB/s
qemu-img LV raw LV raw 54.61 MB/s
dd bs=4096 LV raw LV raw 57.1 MB/s

Importar

Metodo 1 (seguir este)

1. Copiar el .xml donde se define la VM y que previamente hemos exportado a una ruta accesible por livbirt-bin:

sudo cp /tmp/vm-1.example.com.xml /etc/libvirt/qemu

2. Editar el archivo para verificar que los siguientes elementos existen o son soportados. en el nuevo hipervisor al que se quiere importar:

  <cpu mode='custom' match='exact'>
    <model fallback='allow'>core2duo</model>
    <vendor>Intel</vendor>
    <feature policy='require' name='pbe'/>
    <feature policy='require' name='tm2'/>
    <feature policy='require' name='est'/>
    <feature policy='require' name='smx'/>
    <feature policy='require' name='ss'/>
    <feature policy='require' name='dtes64'/>
    <feature policy='require' name='ht'/>
    <feature policy='require' name='ds'/>
    <feature policy='require' name='lahf_lm'/>
    <feature policy='require' name='tm'/>
    <feature policy='require' name='cx16'/>
    <feature policy='require' name='vmx'/>
    <feature policy='require' name='ds_cpl'/>
    <feature policy='require' name='pdcm'/>
    <feature policy='require' name='xtpr'/>
    <feature policy='require' name='acpi'/>
  </cpu>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw' cache='none'/>
      <source file='/var/lib/libvirt/images/vm-1.example.com.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </disk>
    <interface type='network'>
      <mac address='52:54:00:bb:9f:e9'/>
      <source network='default'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>

3. Mover/montar el disco a la ruta/punto de montaje especificado por el archivo .xml

4. Definir la VM:

sudo virsh define /etc/libvirt/qemu/vm-1.example.com.xml

5. Si todo ha ido bien ya podemos arrancar la maquina:

sudo virsh start vm-1.example.com

Metodo 2 (revisar)

1. Arrancar la red 'default':

sudo  virsh net-start default

Salida:

Network default started

2. Restaurar/importar una VM a partir de un archivo:

sudo virt-install --name dns-1.dev.jj.com --ram 512 --disk /var/lib/libvirt/images/dns-1.dev.jj.com.qcow2 --import

Red

Configuraciones de red

Hipervisor

Probar con el procedimiento documentado en:

http://libvirt.org/sources/virshcmdref/html/sect-net-start.html

1. Crear directorio:

sudo mkdir /var/lib/libvirt/network

2. Crear archivo de configuracion:

sudo vim /var/lib/libvirt/network/default.xml

Con el siguiente contenido:

<network>
  <name>default</name>
  <uuid>066c4de2-ec3f-aebe-742e-dfa7f4de3f28</uuid>
  <forward mode='nat'/>
  <bridge name='virbr0' stp='on' delay='0' />
  <ip address='10.0.0.1' netmask='255.255.255.0'>
  </ip>
</network>

3. Intentar editar el archivo:

sudo virsh
net-create /var/lib/libvirt/network/default.xml

Si da un error, intentar arrancar la red:

sudo virsh net-autostart default

4. Ajustar IP y nombre del bridge de la maquina KVM en las reglas de cortafuegos

1. Editar la red, en este caso “default”:

sudo virsh net-edit default

2. Realizar los cambios y guardarlos

3. AVISO en este punto se pierde conectividad. Reiniciar la red:

sudo virsh net-destroy default;  sudo virsh net-start default

VM

Ejemplo de archivo de configuracion de VM:

<domain type='kvm'>
  <name>template-1.dev.jj.com</name>
  <uuid>f75dcbdc-8fc9-b50c-6612-c34dfebea16f</uuid>
  <memory unit='KiB'>1048576</memory>
  <currentMemory unit='KiB'>524288</currentMemory>
  <vcpu placement='static'>2</vcpu>
  <os>
    <type arch='x86_64' machine='pc-1.1'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/bin/kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2' cache='none'/>
      <source file='/var/lib/libvirt/images/template-1.dev.jj.com.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </disk>
    <controller type='usb' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
    </controller>
    <interface type='network'>
      <mac address='52:54:00:c0:c6:24'/>
      <source network='default'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </memballoon>
  </devices>
</domain>

Compartir directorios del hipervisor a las VM

http://wiki.qemu.org/Documentation/9psetup

http://libvirt.org/formatdomain.html#elementsFilesystems

http://v9fs.sourceforge.net/

http://sourceforge.net/p/v9fs/mailman/v9fs-users/?viewmonth=201310

http://troglobit.com/blog/2013/07/05/file-system-pass-through-in-kvm-slash-qemu-slash-libvirt/

https://www.kernel.org/doc/ols/2010/ols2010-pages-109-120.pdf

Virtfs (9p) mapped

NO hace falta cargar los modulos en el host. En los guests ya se cargan por defecto, por tanto no hay que hacer nada a nivel de modolos del kernel.

1. (Hipervisor) Editar la vm en cuestion, mejor si esta apagada:

sudo virsh edit vm_1

Y anyadirle el siguiente bloque, dentro de la seccion <devices>:

...
  <devices>
...
    <filesystem type='mount' accessmode='mapped'>
      <source dir='/srv/data'/>
      <target dir='tag_srv_data'/>
    </filesystem>
...
  </devices>
...

NOTA: tras grabar KVM le anyadira la siguiente linea:

<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>

2. (Hipervisor) Arrancar la VM:

sudo virsh start vm_1

3. (VM) Montar manualmente la particion:

sudo mkdir /mnt/kvm_9p
sudo mount -t 9p -o trans=virtio tag_srv_data /mnt/kvm_9p -oversion=9p2000.L

Con fstab:

/mnt/kvm_9p	/mnt/kvm_9p	9p	trans=virtio,version=9p2000.L,rw,users,auto	0	0

4. Pruebas:

4.1. Lectura:

sudo ls -la /mnt/kvm_9p

Si hay algun error, consultar los logs del hipervisor y ver si es apparmor el que se queja:

Apr 18 14:03:10 kvm-1 kernel: [446419.384647] type=1400 audit(1366286590.878:72): apparmor="DENIED" operation="open" parent=1 profile="libvirt-c9fcbe04-e995-48eb-0bae-6a00427cb0cf" name="/tmp/test/" pid=6786 comm="pool" requested_mask="r" denied_mask="r" fsuid=106 ouid=0

Si es asi hay que mirar apparmor (TODO)

4.2. Escritura:

touch /mnt/kvm_9p/file

Si obtenemos un error de permiso:

4.2.1. (Hipervisor) Ver con que usuario correo el proceso “qemu-system-x86_64”:

ps aux | grep qemu-system-x86_64

En mi caso:

libvirt+

TODO: ver por que no aparece el nombre completo, que es 'libvirt-qemu'

4.2.2. (Hipervisor) Ajustar los permisos:

sudo chown libvirt-qemu:libvirt-qemu /srv/data

TODO

Virtfs (9p) passthrough

El proceso es identico a virtfs_9p_mapped con la excepcion que se usa “passthrough” en lugar de “mapped” en el paso 1.

Ademas no se podra escribir (si leer) a no ser que el proceso “qemu-system-x86_64” se ejecute como root.

Performance tunning

http://pic.dhe.ibm.com/infocenter/lnxinfo/v3r0m0/index.jsp?topic=%2Fliaat%2Fliaattunkickoff.htm

http://virt-tools.org/learning/install-with-command-line/

Disco

TODO

CPU

https://www.berrange.com/posts/2010/02/15/guest-cpu-model-configuration-in-libvirt-with-qemukvm/

Primero algunos conceptos:

En este ejemplo vamos a ver el antes y el despues en las capacidades CPU de una VM antes y despues de exponerle las capacidades de la CPU del host en el que esta.

1. (Host) Vemos capacidades de la CPU a nivel de sistema operativo:

cat /proc/cpuinfo | grep flags | uniq

O para importar en una tabla:

cat /proc/cpuinfo | grep flags | uniq | cut -d ":" -f2 | sed 's/\ /\n/g' | sort

2. (Host) Repetimos el mismo procedimiento en una VM. Iniciamos sesion en la VM y lanzamos el mismo comando:

cat /proc/cpuinfo | grep flags | uniq

Pongo juntos en una misma tabla los resultados:

Capacidades CPU host Capacidades CPU guest (antes) Capacidades CPU guest (despues)
acpi
aperfmperf
apic apic
arat
arch_perfmon
bts
clflush clflush
cmov cmov
constant_tsc
cx16 cx16
cx8 cx8
de de
ds_cpl
dtes64
dtherm
dts
epb
ept
est
flexpriority
fpu fpu
fxsr fxsr
ht hypervisor
lahf_lm lahf_lm
lm lm
mca mca
mce mce
mmx mmx
monitor
msr msr
mtrr mtrr
nonstop_tsc
nopl nopl
nx nx
pae pae
pat
pbe
pcid
pclmulqdq
pdcm
pebs
pge pge
pln
pni pni
popcnt popcnt
pse pse
pse36 pse36
pts
rdtscp
rep_good rep_good
sep sep
ss
sse sse
sse2 sse2
sse4_1
sse4_2
ssse3
syscall syscall
tm
tm2
tpr_shadow
tsc tsc
tsc_deadline_timer
vme
vmx vmx
vnmi
vpid
xsave
xsaveopt
xtopology
xtpr

3. (Host) vemos las capacidades que libvirt nos dice que tiene el host:

sudo virsh capabilities | more

Nos quedamos con el siguiente bloque:

    <cpu>
      <arch>x86_64</arch>
      <model>Nehalem</model>
      <vendor>Intel</vendor>
      <topology sockets='1' cores='2' threads='1'/>
      <feature name='rdtscp'/>
      <feature name='osxsave'/>
      <feature name='xsave'/>
      <feature name='tsc-deadline'/>
      <feature name='pdcm'/>
      <feature name='xtpr'/>
      <feature name='tm2'/>
      <feature name='est'/>
      <feature name='vmx'/>
      <feature name='ds_cpl'/>
      <feature name='monitor'/>
      <feature name='dtes64'/>
      <feature name='pclmuldq'/>
      <feature name='pbe'/>
      <feature name='tm'/>
      <feature name='ht'/>
      <feature name='ss'/>
      <feature name='acpi'/>
      <feature name='ds'/>
      <feature name='vme'/>
    </cpu>

4. (Host) vemos las capacidades que libvirt nos dice que tiene la VM:

sudo virsh dumpxml vm-1.example.com | more

Nos quedamos con el siguiente bloque:

...
  <vcpu placement='static'>2</vcpu>
...

Como puede observarse no tienen acceso a ninguna de las capacidades de la CPU del host donde corre.

5. Expongo las capacidades de la CPU del host a la VM:

5.1. Apago la VM a nivel de sistema operativo:

ssh vm-1.example.com
sudo shutdown -h now

5.2. Edito la VM:

sudo virsh edit vm-1.example.com

En el editor busco el bloque del paso 4:

  <vcpu placement='static'>2</vcpu>
  

Y lo sustituyo por el siguiente bloque, adaptacion del bloque del paso 3:

  <cpu mode='custom' match='exact'>
    <model fallback='allow'>Nehalem</model>
    <vendor>Intel</vendor>
    <feature policy='require' name='rdtscp'/>
    <feature policy='require' name='osxsave'/>
    <feature policy='require' name='xsave'/>
    <feature policy='require' name='tsc-deadline'/>
    <feature policy='require' name='pdcm'/>
    <feature policy='require' name='xtpr'/>
    <feature policy='require' name='tm2'/>
    <feature policy='require' name='est'/>
    <feature policy='require' name='vmx'/>
    <feature policy='require' name='ds_cpl'/>
    <feature policy='require' name='monitor'/>
    <feature policy='require' name='dtes64'/>
    <feature policy='require' name='pclmuldq'/>
    <feature policy='require' name='pbe'/>
    <feature policy='require' name='tm'/>
    <feature policy='require' name='ht'/>
    <feature policy='require' name='ss'/>
    <feature policy='require' name='acpi'/>
    <feature policy='require' name='ds'/>
    <feature policy='require' name='vme'/>
  </cpu>

Grabo y salgo.

5.3. Compruebo que los cambios se han grabado repitiendo el paso 4.

5.4. Arranco la VM:

sudo virsh start vm-1.example.com

5.5. Repito el paso 2. La salida ahora es diferente. Resumen:

Capacidades CPU host Capacidades CPU guest (antes) Capacidades CPU guest (despues)

| acpi | | |

aperfmperf
apic apic apic
arat
arch_perfmon
bts
clflush clflush clflush
cmov cmov cmov
constant_tsc
cx16 cx16 cx16
cx8 cx8 cx8
de de de
ds_cpl
dtes64
dtherm
dts
epb
ept
est
flexpriority
fpu fpu fpu
fxsr fxsr fxsr
ht hypervisor hypervisor
lahf_lm lahf_lm lahf_lm
lm lm lm
mca mca mca
mce mce mce
mmx mmx mmx
monitor
msr msr msr
mtrr mtrr mtrr
nonstop_tsc
nopl nopl nopl
nx nx nx
pae pae pae
pat
pbe
pcid
pclmulqdq pclmulqdq
pdcm
pebs
pge pge pge
pln
pni pni pni
popcnt popcnt popcnt
pse pse pse
pse36 pse36 pse36
pts
rdtscp rdtscp
rep_good rep_good rep_good
sep sep sep
ss ss
sse sse sse
sse2 sse2 sse2
sse4_1 sse4_1
sse4_2 sse4_2
ssse3 ssse3
syscall syscall syscall
tm
tm2
tpr_shadow
tsc tsc tsc
tsc_deadline_timer tsc_deadline_timer
up
vme vme
vmx vmx vmx
vnmi
vpid
xsave
xsaveopt
xtopology
xtpr

Conclusiones:

Apagado y encendido controlado

Siempre es bueno ir VM a VM parando servicios de forma controlada, como por ejemplo mysql, pero si tenemos prisa:

1. Parar todas las VMs:

sudo service libvirt-guests stop

Por pantalla va indicando el progreso. Para comprobar siempre haremos un:

sudo virsh list --all

2. Arrancar todas las VMs que esten definidas como autostart:

sudo service libvirt-bin restart

Otras herramientas

http://libguestfs.org/virt-resize.1.html

http://libguestfs.org/guestfish.1.html

libvirt

TODO quiza habria que mover esta seccion a un articulo propio

ACL

http://libvirt.org/acl.html

http://libvirt.org/aclpolkit.html

https://wiki.archlinux.org/index.php/libvirt#Using_Python

Ejemplo sencillo de uso sin contrasenya si se dan las siguientes condiciones:

virsh -c qemu:///system list

La url sirve para la API tambien

API

http://libvirt.org/html/libvirt-libvirt.html

virConnect

[('__class__', <class 'libvirt.virConnect'>)
('__del__', <bound method virConnect.__del__ of <libvirt.virConnect object at 0x7f653a08df10>>)
('__delattr__', <method-wrapper '__delattr__' of virConnect object at 0x7f653a08df10>)
('__dict__', {'_o': <capsule object "virConnectPtr" at 0x7f6538716c00>})
('__doc__', None)
('__format__', <built-in method __format__ of virConnect object at 0x7f653a08df10>)
('__getattribute__', <method-wrapper '__getattribute__' of virConnect object at 0x7f653a08df10>)
('__hash__', <method-wrapper '__hash__' of virConnect object at 0x7f653a08df10>)
('__init__', <bound method virConnect.__init__ of <libvirt.virConnect object at 0x7f653a08df10>>)
('__module__', 'libvirt')
('__new__', <built-in method __new__ of type object at 0x8fbce0>)
('__reduce__', <built-in method __reduce__ of virConnect object at 0x7f653a08df10>)
('__reduce_ex__', <built-in method __reduce_ex__ of virConnect object at 0x7f653a08df10>)
('__repr__', <method-wrapper '__repr__' of virConnect object at 0x7f653a08df10>)
('__setattr__', <method-wrapper '__setattr__' of virConnect object at 0x7f653a08df10>)
('__sizeof__', <built-in method __sizeof__ of virConnect object at 0x7f653a08df10>)
('__str__', <method-wrapper '__str__' of virConnect object at 0x7f653a08df10>)
('__subclasshook__', <built-in method __subclasshook__ of type object at 0x29d7020>)
('__weakref__', None)
('_dispatchCloseCallback', <bound method virConnect._dispatchCloseCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventBalloonChangeCallback', <bound method virConnect._dispatchDomainEventBalloonChangeCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventBlockPullCallback', <bound method virConnect._dispatchDomainEventBlockPullCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventCallbacks', <bound method virConnect._dispatchDomainEventCallbacks of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventDeviceRemovedCallback', <bound method virConnect._dispatchDomainEventDeviceRemovedCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventDiskChangeCallback', <bound method virConnect._dispatchDomainEventDiskChangeCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventGenericCallback', <bound method virConnect._dispatchDomainEventGenericCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventGraphicsCallback', <bound method virConnect._dispatchDomainEventGraphicsCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventIOErrorCallback', <bound method virConnect._dispatchDomainEventIOErrorCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventIOErrorReasonCallback', <bound method virConnect._dispatchDomainEventIOErrorReasonCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventLifecycleCallback', <bound method virConnect._dispatchDomainEventLifecycleCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventPMSuspendCallback', <bound method virConnect._dispatchDomainEventPMSuspendCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventPMSuspendDiskCallback', <bound method virConnect._dispatchDomainEventPMSuspendDiskCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventPMWakeupCallback', <bound method virConnect._dispatchDomainEventPMWakeupCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventRTCChangeCallback', <bound method virConnect._dispatchDomainEventRTCChangeCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventTrayChangeCallback', <bound method virConnect._dispatchDomainEventTrayChangeCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_dispatchDomainEventWatchdogCallback', <bound method virConnect._dispatchDomainEventWatchdogCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('_o', <capsule object "virConnectPtr" at 0x7f6538716c00>)
('baselineCPU', <bound method virConnect.baselineCPU of <libvirt.virConnect object at 0x7f653a08df10>>)
('changeBegin', <bound method virConnect.changeBegin of <libvirt.virConnect object at 0x7f653a08df10>>)
('changeCommit', <bound method virConnect.changeCommit of <libvirt.virConnect object at 0x7f653a08df10>>)
('changeRollback', <bound method virConnect.changeRollback of <libvirt.virConnect object at 0x7f653a08df10>>)
('close', <bound method virConnect.close of <libvirt.virConnect object at 0x7f653a08df10>>)
('compareCPU', <bound method virConnect.compareCPU of <libvirt.virConnect object at 0x7f653a08df10>>)
('createLinux', <bound method virConnect.createLinux of <libvirt.virConnect object at 0x7f653a08df10>>)
('createXML', <bound method virConnect.createXML of <libvirt.virConnect object at 0x7f653a08df10>>)
('createXMLWithFiles', <bound method virConnect.createXMLWithFiles of <libvirt.virConnect object at 0x7f653a08df10>>)
('defineXML', <bound method virConnect.defineXML of <libvirt.virConnect object at 0x7f653a08df10>>)
('domainEventDeregister', <bound method virConnect.domainEventDeregister of <libvirt.virConnect object at 0x7f653a08df10>>)
('domainEventDeregisterAny', <bound method virConnect.domainEventDeregisterAny of <libvirt.virConnect object at 0x7f653a08df10>>)
('domainEventRegister', <bound method virConnect.domainEventRegister of <libvirt.virConnect object at 0x7f653a08df10>>)
('domainEventRegisterAny', <bound method virConnect.domainEventRegisterAny of <libvirt.virConnect object at 0x7f653a08df10>>)
('domainXMLFromNative', <bound method virConnect.domainXMLFromNative of <libvirt.virConnect object at 0x7f653a08df10>>)
('domainXMLToNative', <bound method virConnect.domainXMLToNative of <libvirt.virConnect object at 0x7f653a08df10>>)
('findStoragePoolSources', <bound method virConnect.findStoragePoolSources of <libvirt.virConnect object at 0x7f653a08df10>>)
('getCPUMap', <bound method virConnect.getCPUMap of <libvirt.virConnect object at 0x7f653a08df10>>)
('getCPUModelNames', <bound method virConnect.getCPUModelNames of <libvirt.virConnect object at 0x7f653a08df10>>)
('getCPUStats', <bound method virConnect.getCPUStats of <libvirt.virConnect object at 0x7f653a08df10>>)
('getCapabilities', <bound method virConnect.getCapabilities of <libvirt.virConnect object at 0x7f653a08df10>>)
('getCellsFreeMemory', <bound method virConnect.getCellsFreeMemory of <libvirt.virConnect object at 0x7f653a08df10>>)
('getFreeMemory', <bound method virConnect.getFreeMemory of <libvirt.virConnect object at 0x7f653a08df10>>)
('getHostname', <bound method virConnect.getHostname of <libvirt.virConnect object at 0x7f653a08df10>>)
('getInfo', <bound method virConnect.getInfo of <libvirt.virConnect object at 0x7f653a08df10>>)
('getLibVersion', <bound method virConnect.getLibVersion of <libvirt.virConnect object at 0x7f653a08df10>>)
('getMaxVcpus', <bound method virConnect.getMaxVcpus of <libvirt.virConnect object at 0x7f653a08df10>>)
('getMemoryParameters', <bound method virConnect.getMemoryParameters of <libvirt.virConnect object at 0x7f653a08df10>>)
('getMemoryStats', <bound method virConnect.getMemoryStats of <libvirt.virConnect object at 0x7f653a08df10>>)
('getSecurityModel', <bound method virConnect.getSecurityModel of <libvirt.virConnect object at 0x7f653a08df10>>)
('getSysinfo', <bound method virConnect.getSysinfo of <libvirt.virConnect object at 0x7f653a08df10>>)
('getType', <bound method virConnect.getType of <libvirt.virConnect object at 0x7f653a08df10>>)
('getURI', <bound method virConnect.getURI of <libvirt.virConnect object at 0x7f653a08df10>>)
('getVersion', <bound method virConnect.getVersion of <libvirt.virConnect object at 0x7f653a08df10>>)
('interfaceDefineXML', <bound method virConnect.interfaceDefineXML of <libvirt.virConnect object at 0x7f653a08df10>>)
('interfaceLookupByMACString', <bound method virConnect.interfaceLookupByMACString of <libvirt.virConnect object at 0x7f653a08df10>>)
('interfaceLookupByName', <bound method virConnect.interfaceLookupByName of <libvirt.virConnect object at 0x7f653a08df10>>)
('isAlive', <bound method virConnect.isAlive of <libvirt.virConnect object at 0x7f653a08df10>>)
('isEncrypted', <bound method virConnect.isEncrypted of <libvirt.virConnect object at 0x7f653a08df10>>)
('isSecure', <bound method virConnect.isSecure of <libvirt.virConnect object at 0x7f653a08df10>>)
('listAllDevices', <bound method virConnect.listAllDevices of <libvirt.virConnect object at 0x7f653a08df10>>)
('listAllDomains', <bound method virConnect.listAllDomains of <libvirt.virConnect object at 0x7f653a08df10>>)
('listAllInterfaces', <bound method virConnect.listAllInterfaces of <libvirt.virConnect object at 0x7f653a08df10>>)
('listAllNWFilters', <bound method virConnect.listAllNWFilters of <libvirt.virConnect object at 0x7f653a08df10>>)
('listAllNetworks', <bound method virConnect.listAllNetworks of <libvirt.virConnect object at 0x7f653a08df10>>)
('listAllSecrets', <bound method virConnect.listAllSecrets of <libvirt.virConnect object at 0x7f653a08df10>>)
('listAllStoragePools', <bound method virConnect.listAllStoragePools of <libvirt.virConnect object at 0x7f653a08df10>>)
('listDefinedDomains', <bound method virConnect.listDefinedDomains of <libvirt.virConnect object at 0x7f653a08df10>>)
('listDefinedInterfaces', <bound method virConnect.listDefinedInterfaces of <libvirt.virConnect object at 0x7f653a08df10>>)
('listDefinedNetworks', <bound method virConnect.listDefinedNetworks of <libvirt.virConnect object at 0x7f653a08df10>>)
('listDefinedStoragePools', <bound method virConnect.listDefinedStoragePools of <libvirt.virConnect object at 0x7f653a08df10>>)
('listDevices', <bound method virConnect.listDevices of <libvirt.virConnect object at 0x7f653a08df10>>)
('listDomainsID', <bound method virConnect.listDomainsID of <libvirt.virConnect object at 0x7f653a08df10>>)
('listInterfaces', <bound method virConnect.listInterfaces of <libvirt.virConnect object at 0x7f653a08df10>>)
('listNWFilters', <bound method virConnect.listNWFilters of <libvirt.virConnect object at 0x7f653a08df10>>)
('listNetworks', <bound method virConnect.listNetworks of <libvirt.virConnect object at 0x7f653a08df10>>)
('listSecrets', <bound method virConnect.listSecrets of <libvirt.virConnect object at 0x7f653a08df10>>)
('listStoragePools', <bound method virConnect.listStoragePools of <libvirt.virConnect object at 0x7f653a08df10>>)
('lookupByID', <bound method virConnect.lookupByID of <libvirt.virConnect object at 0x7f653a08df10>>)
('lookupByName', <bound method virConnect.lookupByName of <libvirt.virConnect object at 0x7f653a08df10>>)
('lookupByUUID', <bound method virConnect.lookupByUUID of <libvirt.virConnect object at 0x7f653a08df10>>)
('lookupByUUIDString', <bound method virConnect.lookupByUUIDString of <libvirt.virConnect object at 0x7f653a08df10>>)
('networkCreateXML', <bound method virConnect.networkCreateXML of <libvirt.virConnect object at 0x7f653a08df10>>)
('networkDefineXML', <bound method virConnect.networkDefineXML of <libvirt.virConnect object at 0x7f653a08df10>>)
('networkLookupByName', <bound method virConnect.networkLookupByName of <libvirt.virConnect object at 0x7f653a08df10>>)
('networkLookupByUUID', <bound method virConnect.networkLookupByUUID of <libvirt.virConnect object at 0x7f653a08df10>>)
('networkLookupByUUIDString', <bound method virConnect.networkLookupByUUIDString of <libvirt.virConnect object at 0x7f653a08df10>>)
('newStream', <bound method virConnect.newStream of <libvirt.virConnect object at 0x7f653a08df10>>)
('nodeDeviceCreateXML', <bound method virConnect.nodeDeviceCreateXML of <libvirt.virConnect object at 0x7f653a08df10>>)
('nodeDeviceLookupByName', <bound method virConnect.nodeDeviceLookupByName of <libvirt.virConnect object at 0x7f653a08df10>>)
('nodeDeviceLookupSCSIHostByWWN', <bound method virConnect.nodeDeviceLookupSCSIHostByWWN of <libvirt.virConnect object at 0x7f653a08df10>>)
('numOfDefinedDomains', <bound method virConnect.numOfDefinedDomains of <libvirt.virConnect object at 0x7f653a08df10>>)
('numOfDefinedInterfaces', <bound method virConnect.numOfDefinedInterfaces of <libvirt.virConnect object at 0x7f653a08df10>>)
('numOfDefinedNetworks', <bound method virConnect.numOfDefinedNetworks of <libvirt.virConnect object at 0x7f653a08df10>>)
('numOfDefinedStoragePools', <bound method virConnect.numOfDefinedStoragePools of <libvirt.virConnect object at 0x7f653a08df10>>)
('numOfDevices', <bound method virConnect.numOfDevices of <libvirt.virConnect object at 0x7f653a08df10>>)
('numOfDomains', <bound method virConnect.numOfDomains of <libvirt.virConnect object at 0x7f653a08df10>>)
('numOfInterfaces', <bound method virConnect.numOfInterfaces of <libvirt.virConnect object at 0x7f653a08df10>>)
('numOfNWFilters', <bound method virConnect.numOfNWFilters of <libvirt.virConnect object at 0x7f653a08df10>>)
('numOfNetworks', <bound method virConnect.numOfNetworks of <libvirt.virConnect object at 0x7f653a08df10>>)
('numOfSecrets', <bound method virConnect.numOfSecrets of <libvirt.virConnect object at 0x7f653a08df10>>)
('numOfStoragePools', <bound method virConnect.numOfStoragePools of <libvirt.virConnect object at 0x7f653a08df10>>)
('nwfilterDefineXML', <bound method virConnect.nwfilterDefineXML of <libvirt.virConnect object at 0x7f653a08df10>>)
('nwfilterLookupByName', <bound method virConnect.nwfilterLookupByName of <libvirt.virConnect object at 0x7f653a08df10>>)
('nwfilterLookupByUUID', <bound method virConnect.nwfilterLookupByUUID of <libvirt.virConnect object at 0x7f653a08df10>>)
('nwfilterLookupByUUIDString', <bound method virConnect.nwfilterLookupByUUIDString of <libvirt.virConnect object at 0x7f653a08df10>>)
('registerCloseCallback', <bound method virConnect.registerCloseCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('restore', <bound method virConnect.restore of <libvirt.virConnect object at 0x7f653a08df10>>)
('restoreFlags', <bound method virConnect.restoreFlags of <libvirt.virConnect object at 0x7f653a08df10>>)
('saveImageDefineXML', <bound method virConnect.saveImageDefineXML of <libvirt.virConnect object at 0x7f653a08df10>>)
('saveImageGetXMLDesc', <bound method virConnect.saveImageGetXMLDesc of <libvirt.virConnect object at 0x7f653a08df10>>)
('secretDefineXML', <bound method virConnect.secretDefineXML of <libvirt.virConnect object at 0x7f653a08df10>>)
('secretLookupByUUID', <bound method virConnect.secretLookupByUUID of <libvirt.virConnect object at 0x7f653a08df10>>)
('secretLookupByUUIDString', <bound method virConnect.secretLookupByUUIDString of <libvirt.virConnect object at 0x7f653a08df10>>)
('secretLookupByUsage', <bound method virConnect.secretLookupByUsage of <libvirt.virConnect object at 0x7f653a08df10>>)
('setKeepAlive', <bound method virConnect.setKeepAlive of <libvirt.virConnect object at 0x7f653a08df10>>)
('setMemoryParameters', <bound method virConnect.setMemoryParameters of <libvirt.virConnect object at 0x7f653a08df10>>)
('storagePoolCreateXML', <bound method virConnect.storagePoolCreateXML of <libvirt.virConnect object at 0x7f653a08df10>>)
('storagePoolDefineXML', <bound method virConnect.storagePoolDefineXML of <libvirt.virConnect object at 0x7f653a08df10>>)
('storagePoolLookupByName', <bound method virConnect.storagePoolLookupByName of <libvirt.virConnect object at 0x7f653a08df10>>)
('storagePoolLookupByUUID', <bound method virConnect.storagePoolLookupByUUID of <libvirt.virConnect object at 0x7f653a08df10>>)
('storagePoolLookupByUUIDString', <bound method virConnect.storagePoolLookupByUUIDString of <libvirt.virConnect object at 0x7f653a08df10>>)
('storageVolLookupByKey', <bound method virConnect.storageVolLookupByKey of <libvirt.virConnect object at 0x7f653a08df10>>)
('storageVolLookupByPath', <bound method virConnect.storageVolLookupByPath of <libvirt.virConnect object at 0x7f653a08df10>>)
('suspendForDuration', <bound method virConnect.suspendForDuration of <libvirt.virConnect object at 0x7f653a08df10>>)
('unregisterCloseCallback', <bound method virConnect.unregisterCloseCallback of <libvirt.virConnect object at 0x7f653a08df10>>)
('virConnGetLastError', <bound method virConnect.virConnGetLastError of <libvirt.virConnect object at 0x7f653a08df10>>)
('virConnResetLastError', <bound method virConnect.virConnResetLastError of <libvirt.virConnect object at 0x7f653a08df10>>)]

virDomain

[('ID', <bound method virDomain.ID of <libvirt.virDomain object at 0x7f39740e6750>>)
('OSType', <bound method virDomain.OSType of <libvirt.virDomain object at 0x7f39740e6750>>)
('UUID', <bound method virDomain.UUID of <libvirt.virDomain object at 0x7f39740e6750>>)
('UUIDString', <bound method virDomain.UUIDString of <libvirt.virDomain object at 0x7f39740e6750>>)
('XMLDesc', <bound method virDomain.XMLDesc of <libvirt.virDomain object at 0x7f39740e6750>>)
('__class__', <class 'libvirt.virDomain'>)
('__del__', <bound method virDomain.__del__ of <libvirt.virDomain object at 0x7f39740e6750>>)
('__delattr__', <method-wrapper '__delattr__' of virDomain object at 0x7f39740e6750>)
('__dict__', {'_conn': <libvirt.virConnect object at 0x7f3975a5ff50>, '_o': <capsule object "virDomainPtr" at 0x7f39740e7c90>})
('__doc__', None)
('__format__', <built-in method __format__ of virDomain object at 0x7f39740e6750>)
('__getattribute__', <method-wrapper '__getattribute__' of virDomain object at 0x7f39740e6750>)
('__hash__', <method-wrapper '__hash__' of virDomain object at 0x7f39740e6750>)
('__init__', <bound method virDomain.__init__ of <libvirt.virDomain object at 0x7f39740e6750>>)
('__module__', 'libvirt')
('__new__', <built-in method __new__ of type object at 0x8fbce0>)
('__reduce__', <built-in method __reduce__ of virDomain object at 0x7f39740e6750>)
('__reduce_ex__', <built-in method __reduce_ex__ of virDomain object at 0x7f39740e6750>)
('__repr__', <method-wrapper '__repr__' of virDomain object at 0x7f39740e6750>)
('__setattr__', <method-wrapper '__setattr__' of virDomain object at 0x7f39740e6750>)
('__sizeof__', <built-in method __sizeof__ of virDomain object at 0x7f39740e6750>)
('__str__', <method-wrapper '__str__' of virDomain object at 0x7f39740e6750>)
('__subclasshook__', <built-in method __subclasshook__ of type object at 0x1d606f0>)
('__weakref__', None)
('_conn', <libvirt.virConnect object at 0x7f3975a5ff50>)
('_o', <capsule object "virDomainPtr" at 0x7f39740e7c90>)
('abortJob', <bound method virDomain.abortJob of <libvirt.virDomain object at 0x7f39740e6750>>)
('attachDevice', <bound method virDomain.attachDevice of <libvirt.virDomain object at 0x7f39740e6750>>)
('attachDeviceFlags', <bound method virDomain.attachDeviceFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('autostart', <bound method virDomain.autostart of <libvirt.virDomain object at 0x7f39740e6750>>)
('blkioParameters', <bound method virDomain.blkioParameters of <libvirt.virDomain object at 0x7f39740e6750>>)
('blockCommit', <bound method virDomain.blockCommit of <libvirt.virDomain object at 0x7f39740e6750>>)
('blockInfo', <bound method virDomain.blockInfo of <libvirt.virDomain object at 0x7f39740e6750>>)
('blockIoTune', <bound method virDomain.blockIoTune of <libvirt.virDomain object at 0x7f39740e6750>>)
('blockJobAbort', <bound method virDomain.blockJobAbort of <libvirt.virDomain object at 0x7f39740e6750>>)
('blockJobInfo', <bound method virDomain.blockJobInfo of <libvirt.virDomain object at 0x7f39740e6750>>)
('blockJobSetSpeed', <bound method virDomain.blockJobSetSpeed of <libvirt.virDomain object at 0x7f39740e6750>>)
('blockPeek', <bound method virDomain.blockPeek of <libvirt.virDomain object at 0x7f39740e6750>>)
('blockPull', <bound method virDomain.blockPull of <libvirt.virDomain object at 0x7f39740e6750>>)
('blockRebase', <bound method virDomain.blockRebase of <libvirt.virDomain object at 0x7f39740e6750>>)
('blockResize', <bound method virDomain.blockResize of <libvirt.virDomain object at 0x7f39740e6750>>)
('blockStats', <bound method virDomain.blockStats of <libvirt.virDomain object at 0x7f39740e6750>>)
('blockStatsFlags', <bound method virDomain.blockStatsFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('connect', <bound method virDomain.connect of <libvirt.virDomain object at 0x7f39740e6750>>)
('controlInfo', <bound method virDomain.controlInfo of <libvirt.virDomain object at 0x7f39740e6750>>)
('coreDump', <bound method virDomain.coreDump of <libvirt.virDomain object at 0x7f39740e6750>>)
('create', <bound method virDomain.create of <libvirt.virDomain object at 0x7f39740e6750>>)
('createWithFiles', <bound method virDomain.createWithFiles of <libvirt.virDomain object at 0x7f39740e6750>>)
('createWithFlags', <bound method virDomain.createWithFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('destroy', <bound method virDomain.destroy of <libvirt.virDomain object at 0x7f39740e6750>>)
('destroyFlags', <bound method virDomain.destroyFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('detachDevice', <bound method virDomain.detachDevice of <libvirt.virDomain object at 0x7f39740e6750>>)
('detachDeviceFlags', <bound method virDomain.detachDeviceFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('diskErrors', <bound method virDomain.diskErrors of <libvirt.virDomain object at 0x7f39740e6750>>)
('emulatorPinInfo', <bound method virDomain.emulatorPinInfo of <libvirt.virDomain object at 0x7f39740e6750>>)
('fSTrim', <bound method virDomain.fSTrim of <libvirt.virDomain object at 0x7f39740e6750>>)
('getCPUStats', <bound method virDomain.getCPUStats of <libvirt.virDomain object at 0x7f39740e6750>>)
('hasCurrentSnapshot', <bound method virDomain.hasCurrentSnapshot of <libvirt.virDomain object at 0x7f39740e6750>>)
('hasManagedSaveImage', <bound method virDomain.hasManagedSaveImage of <libvirt.virDomain object at 0x7f39740e6750>>)
('hostname', <bound method virDomain.hostname of <libvirt.virDomain object at 0x7f39740e6750>>)
('info', <bound method virDomain.info of <libvirt.virDomain object at 0x7f39740e6750>>)
('injectNMI', <bound method virDomain.injectNMI of <libvirt.virDomain object at 0x7f39740e6750>>)
('interfaceParameters', <bound method virDomain.interfaceParameters of <libvirt.virDomain object at 0x7f39740e6750>>)
('interfaceStats', <bound method virDomain.interfaceStats of <libvirt.virDomain object at 0x7f39740e6750>>)
('isActive', <bound method virDomain.isActive of <libvirt.virDomain object at 0x7f39740e6750>>)
('isPersistent', <bound method virDomain.isPersistent of <libvirt.virDomain object at 0x7f39740e6750>>)
('isUpdated', <bound method virDomain.isUpdated of <libvirt.virDomain object at 0x7f39740e6750>>)
('jobInfo', <bound method virDomain.jobInfo of <libvirt.virDomain object at 0x7f39740e6750>>)
('jobStats', <bound method virDomain.jobStats of <libvirt.virDomain object at 0x7f39740e6750>>)
('listAllSnapshots', <bound method virDomain.listAllSnapshots of <libvirt.virDomain object at 0x7f39740e6750>>)
('managedSave', <bound method virDomain.managedSave of <libvirt.virDomain object at 0x7f39740e6750>>)
('managedSaveRemove', <bound method virDomain.managedSaveRemove of <libvirt.virDomain object at 0x7f39740e6750>>)
('maxMemory', <bound method virDomain.maxMemory of <libvirt.virDomain object at 0x7f39740e6750>>)
('maxVcpus', <bound method virDomain.maxVcpus of <libvirt.virDomain object at 0x7f39740e6750>>)
('memoryParameters', <bound method virDomain.memoryParameters of <libvirt.virDomain object at 0x7f39740e6750>>)
('memoryPeek', <bound method virDomain.memoryPeek of <libvirt.virDomain object at 0x7f39740e6750>>)
('memoryStats', <bound method virDomain.memoryStats of <libvirt.virDomain object at 0x7f39740e6750>>)
('metadata', <bound method virDomain.metadata of <libvirt.virDomain object at 0x7f39740e6750>>)
('migrate', <bound method virDomain.migrate of <libvirt.virDomain object at 0x7f39740e6750>>)
('migrate2', <bound method virDomain.migrate2 of <libvirt.virDomain object at 0x7f39740e6750>>)
('migrate3', <bound method virDomain.migrate3 of <libvirt.virDomain object at 0x7f39740e6750>>)
('migrateGetCompressionCache', <bound method virDomain.migrateGetCompressionCache of <libvirt.virDomain object at 0x7f39740e6750>>)
('migrateGetMaxSpeed', <bound method virDomain.migrateGetMaxSpeed of <libvirt.virDomain object at 0x7f39740e6750>>)
('migrateSetCompressionCache', <bound method virDomain.migrateSetCompressionCache of <libvirt.virDomain object at 0x7f39740e6750>>)
('migrateSetMaxDowntime', <bound method virDomain.migrateSetMaxDowntime of <libvirt.virDomain object at 0x7f39740e6750>>)
('migrateSetMaxSpeed', <bound method virDomain.migrateSetMaxSpeed of <libvirt.virDomain object at 0x7f39740e6750>>)
('migrateToURI', <bound method virDomain.migrateToURI of <libvirt.virDomain object at 0x7f39740e6750>>)
('migrateToURI2', <bound method virDomain.migrateToURI2 of <libvirt.virDomain object at 0x7f39740e6750>>)
('migrateToURI3', <bound method virDomain.migrateToURI3 of <libvirt.virDomain object at 0x7f39740e6750>>)
('name', <bound method virDomain.name of <libvirt.virDomain object at 0x7f39740e6750>>)
('numaParameters', <bound method virDomain.numaParameters of <libvirt.virDomain object at 0x7f39740e6750>>)
('openChannel', <bound method virDomain.openChannel of <libvirt.virDomain object at 0x7f39740e6750>>)
('openConsole', <bound method virDomain.openConsole of <libvirt.virDomain object at 0x7f39740e6750>>)
('openGraphics', <bound method virDomain.openGraphics of <libvirt.virDomain object at 0x7f39740e6750>>)
('pMSuspendForDuration', <bound method virDomain.pMSuspendForDuration of <libvirt.virDomain object at 0x7f39740e6750>>)
('pMWakeup', <bound method virDomain.pMWakeup of <libvirt.virDomain object at 0x7f39740e6750>>)
('pinEmulator', <bound method virDomain.pinEmulator of <libvirt.virDomain object at 0x7f39740e6750>>)
('pinVcpu', <bound method virDomain.pinVcpu of <libvirt.virDomain object at 0x7f39740e6750>>)
('pinVcpuFlags', <bound method virDomain.pinVcpuFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('reboot', <bound method virDomain.reboot of <libvirt.virDomain object at 0x7f39740e6750>>)
('reset', <bound method virDomain.reset of <libvirt.virDomain object at 0x7f39740e6750>>)
('resume', <bound method virDomain.resume of <libvirt.virDomain object at 0x7f39740e6750>>)
('revertToSnapshot', <bound method virDomain.revertToSnapshot of <libvirt.virDomain object at 0x7f39740e6750>>)
('save', <bound method virDomain.save of <libvirt.virDomain object at 0x7f39740e6750>>)
('saveFlags', <bound method virDomain.saveFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('schedulerParameters', <bound method virDomain.schedulerParameters of <libvirt.virDomain object at 0x7f39740e6750>>)
('schedulerParametersFlags', <bound method virDomain.schedulerParametersFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('schedulerType', <bound method virDomain.schedulerType of <libvirt.virDomain object at 0x7f39740e6750>>)
('screenshot', <bound method virDomain.screenshot of <libvirt.virDomain object at 0x7f39740e6750>>)
('securityLabel', <bound method virDomain.securityLabel of <libvirt.virDomain object at 0x7f39740e6750>>)
('securityLabelList', <bound method virDomain.securityLabelList of <libvirt.virDomain object at 0x7f39740e6750>>)
('sendKey', <bound method virDomain.sendKey of <libvirt.virDomain object at 0x7f39740e6750>>)
('sendProcessSignal', <bound method virDomain.sendProcessSignal of <libvirt.virDomain object at 0x7f39740e6750>>)
('setAutostart', <bound method virDomain.setAutostart of <libvirt.virDomain object at 0x7f39740e6750>>)
('setBlkioParameters', <bound method virDomain.setBlkioParameters of <libvirt.virDomain object at 0x7f39740e6750>>)
('setBlockIoTune', <bound method virDomain.setBlockIoTune of <libvirt.virDomain object at 0x7f39740e6750>>)
('setInterfaceParameters', <bound method virDomain.setInterfaceParameters of <libvirt.virDomain object at 0x7f39740e6750>>)
('setMaxMemory', <bound method virDomain.setMaxMemory of <libvirt.virDomain object at 0x7f39740e6750>>)
('setMemory', <bound method virDomain.setMemory of <libvirt.virDomain object at 0x7f39740e6750>>)
('setMemoryFlags', <bound method virDomain.setMemoryFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('setMemoryParameters', <bound method virDomain.setMemoryParameters of <libvirt.virDomain object at 0x7f39740e6750>>)
('setMemoryStatsPeriod', <bound method virDomain.setMemoryStatsPeriod of <libvirt.virDomain object at 0x7f39740e6750>>)
('setMetadata', <bound method virDomain.setMetadata of <libvirt.virDomain object at 0x7f39740e6750>>)
('setNumaParameters', <bound method virDomain.setNumaParameters of <libvirt.virDomain object at 0x7f39740e6750>>)
('setSchedulerParameters', <bound method virDomain.setSchedulerParameters of <libvirt.virDomain object at 0x7f39740e6750>>)
('setSchedulerParametersFlags', <bound method virDomain.setSchedulerParametersFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('setVcpus', <bound method virDomain.setVcpus of <libvirt.virDomain object at 0x7f39740e6750>>)
('setVcpusFlags', <bound method virDomain.setVcpusFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('shutdown', <bound method virDomain.shutdown of <libvirt.virDomain object at 0x7f39740e6750>>)
('shutdownFlags', <bound method virDomain.shutdownFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('snapshotCreateXML', <bound method virDomain.snapshotCreateXML of <libvirt.virDomain object at 0x7f39740e6750>>)
('snapshotCurrent', <bound method virDomain.snapshotCurrent of <libvirt.virDomain object at 0x7f39740e6750>>)
('snapshotListNames', <bound method virDomain.snapshotListNames of <libvirt.virDomain object at 0x7f39740e6750>>)
('snapshotLookupByName', <bound method virDomain.snapshotLookupByName of <libvirt.virDomain object at 0x7f39740e6750>>)
('snapshotNum', <bound method virDomain.snapshotNum of <libvirt.virDomain object at 0x7f39740e6750>>)
('state', <bound method virDomain.state of <libvirt.virDomain object at 0x7f39740e6750>>)
('suspend', <bound method virDomain.suspend of <libvirt.virDomain object at 0x7f39740e6750>>)
('undefine', <bound method virDomain.undefine of <libvirt.virDomain object at 0x7f39740e6750>>)
('undefineFlags', <bound method virDomain.undefineFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('updateDeviceFlags', <bound method virDomain.updateDeviceFlags of <libvirt.virDomain object at 0x7f39740e6750>>)
('vcpuPinInfo', <bound method virDomain.vcpuPinInfo of <libvirt.virDomain object at 0x7f39740e6750>>)
('vcpus', <bound method virDomain.vcpus of <libvirt.virDomain object at 0x7f39740e6750>>)
('vcpusFlags', <bound method virDomain.vcpusFlags of <libvirt.virDomain object at 0x7f39740e6750>>)]

Varios

conn = libvirt.open("qemu+ssh://localhost/system")
domains = conn.listDefinedDomains()
conn = libvirt.open("qemu+ssh://localhost/system")
domains = conn.listDomainsID()