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-guests
para CentOS, luego configureON_SHUTDOWN=shutdown
ySHUTDOWN_TIMEOUT=0
- Creo que también hay que activar el
libvirt-guests
servicio, por ejemplosystemctl enable libvirt-guests
ysystemctl start libvirt-guests