¿Cómo apago correctamente mis máquinas virtuales kvm cuando apago el host?

¿Cómo apago correctamente mis máquinas virtuales kvm cuando apago el host?

Aclarando esta preguntade aquí.

Estoy ejecutando archlinux y tengo una máquina virtual ejecutándose con frecuencia junto con el sistema. De hecho, la mayoría de las veces.

Mi objetivo es producir el siguiente comportamiento:

  • Se envía una señal de apagado/apagado/reinicio/detención al sistema.
  • No hay otra acción que intentar apagar las máquinas virtuales correctamente.
  • Si las máquinas virtuales se apagan correctamente después de X segundos, se procede a apagar también el sistema host.
  • Si no, ejecute un comando diferente

Sólo dame una buena idea sobre en qué trabajar, porque ni siquiera sé por dónde empezar. Supongo que hay una llamada al kernel que se puede examinar.

Hágamelo saber.


mi codigo actual

En este momento estoy usando estos scripts para apagar correctamente mis máquinas virtuales kvm, ¡y funciona! Pero sólo mientras mi usuario inicie uncerraro unreiniciarusando su caparazón. Cualquier otro caso no funcionaría.

Estos alias:

alias sudocheck="/bin/bash /home/damiano/.script/sudocheck"
alias sudo="sudocheck "

Están activando esta función:

#!/bin/bash

# This script checks for what is being passed to sudo.
# If the command passed is poweroff or reboot, it
# launches a custom script instead, that also looks
# fur currently running virtual machines and shuts them.

sudocheck() {
    if [ $1 == "poweroff" ] || [ $1 == "reboot" ]; then
        eval "sudo /home/damiano/.script/graceful $@"
    else
        eval "sudo $@"
    fi
}
sudocheck $@

Eso lanza este script si es necesario:

#!/bin/bash
i=0
e=0
## if virsh finds VMs running
virsh -c qemu:///system list | awk '{ print $3}' | \
if grep running > /dev/null ; then
    virsh -c qemu:///system list --all | grep running | awk '{print "-c qemu:///system shutdown "$2}' | \
## shuts them dow gracefully
    xargs -L1 virsh
## wait 30 seconds for them to go down
    until (( i >= 30 || e == 1 )) ; do
## check every second for their status
        virsh -c qemu:///system list --all | awk '{ print $3}' | \
        if grep -E '(running|shutdown)' > /dev/null ; then
## keep waiting if still running
            if (( i <= 30 )) ; then
                sleep 1 && let i++ && echo $i
            else
                e=1 && notify-send 'Shutdown has been canceled' 'Please check the status of your virtual machines: seems like even though a stop signal has been sent, some are still running.' --urgency=critical
            fi
        else
## if no machine is running anymore, original power command can be executed
            e=1 && eval $@
        fi
    done
fi

Unidad del sistema

También hice el siguiente borrador para gestionar la ejecución de mi VM:

[correo electrónico protegido]

[Unit]
Description=This service manages the execution of the %i virtual machine
Documentation=https://libvirt.org/manpages/virsh.html

[Service]
ExecStartPre=virsh -c qemu:///system
ExecStart=virsh start %i
ExecStop=virsh -c qemu:///system
ExecStop=virsh shutdown %i 
TimeoutStopSec=30
KillMode=none

[Install]
WantedBy=multi-user.target

Pero, ¿cómo puedo decirle al sistema que no apague el entorno de escritorio y que permanezca como está?HASTA¿La VM se ha apagado correctamente? Porque si el sistema no puede apagar la máquina virtual, quiero hacerlo mientras aún estoy en mi DE. No quiero que la computadora comience a detener todos los servicios y permanezca colgada hasta que fuerce el apagado.

Respuesta1

Forma extraña de controlar VM. Buen camino: utilice systemd para iniciar y detener automáticamente la máquina virtual. Por ejemplo:

/etc/systemd/sistema/[correo electrónico protegido]

[Unit]
Description=QEMU virtual machine

[Service]
Environment="type=system-x86_64" "haltcmd=kill -INT $MAINPID"
EnvironmentFile=/etc/conf.d/qemu.d/%i
ExecStart=/usr/bin/qemu-${type} -name %i -nographic $args
ExecStop=/bin/sh -c ${haltcmd}
TimeoutStopSec=30
KillMode=none

[Install]
WantedBy=multi-user.target

... Y, por supuesto, configuraciones para ejecutar máquinas virtuales:

/etc/conf.d/qemu.d/one

type="system-x86_64"

args="-enable-kvm -m 512 -hda /dev/vg0/vm1 -net nic,macaddr=DE:AD:BE:EF:E0:00 \
 -net tap,ifname=tap0 -serial telnet:localhost:7000,server,nowait,nodelay \
 -monitor telnet:localhost:7100,server,nowait,nodelay -vnc :0"

haltcmd="echo 'system_powerdown' | nc localhost 7100" # or netcat/ncat

# You can use other ways to shut down your VM correctly
#haltcmd="ssh powermanager@vm1 sudo poweroff"

...y otra configuración de VM:

/etc/conf.d/qemu.d/two

args="-enable-kvm -m 512 -hda /srv/kvm/vm2.img -net nic,macaddr=DE:AD:BE:EF:E0:01 \
 -net tap,ifname=tap1 -serial telnet:localhost:7001,server,nowait,nodelay \
 -monitor telnet:localhost:7101,server,nowait,nodelay -vnc :1"

haltcmd="echo 'system_powerdown' | nc localhost 7101"

Etcétera. Gracias a los contribuyentes de ArchWiki.para este artículo.

Respuesta2

El borrador de la publicación original y la respuesta de @Oxyd son útiles cuando necesitas controlar cada máquina virtual individualmente.

Sin embargo, si se desea apagar/iniciartodas las máquinas virtualesuno podría usar los invitados libvirt como se menciona enDocumentos de Libvirt.

  • Edite el archivo /etc/conf.d/libvirt-guests, o /etc/sysconfig/libvirt-guestspara CentOS, luego configure ON_SHUTDOWN=shutdownySHUTDOWN_TIMEOUT=0
  • Creo que también hay que activar el libvirt-guestsservicio, por ejemplo systemctl enable libvirt-guestsysystemctl start libvirt-guests

información relacionada