Recomendaría un enfoque más sofisticado que incluye un trabajo inicial, un script de inicio y detención. Como ejemplo, estoy usando Windows XP, ya que mi directorio de inicio permite usar tombert ... que debes cambiar en consecuencia. Tiene la ventaja de lo que sea que haga (reiniciar, apagar, presionar el botón de encendido), maneja su máquina virtual muy bien .
Primero el trabajo inicial, poner en /etc/init/winxpvm.conf:
description "WinXP VirtualBox job"
author "Thomas Perschak"
## 0: system halt
## 1: single-user mode
## 2: graphical multi-user plus networking
## 6: system reboot
start on started rc RUNLEVEL=[2]
stop on starting rc RUNLEVEL=[!2]
## upstart config
kill timeout 120
kill signal SIGCONT
nice -10
## start WinXP VirtualBox
exec /home/tombert/scripts/winxpvm-start.sh
## stop WinXP VirtualBox
pre-stop exec /home/tombert/scripts/winxpvm-stop.sh
El trabajo inicial inicia la máquina virtual en el nivel de ejecución 2 (que está en modo gráfico), y en mi caso aumenta la prioridad con nice
. Para poder apagar la máquina virtual, necesito "deshabilitar" la terminación de inicio utilizando la kill signal SIGCONT
instrucción. Esto deja la máquina virtual ejecutándose al principio (evitando el valor predeterminado SIGTERM
). Después de 120 segundos, SIGKILL
se envía de todos modos. En cambio, estoy ejecutando el winxpvm-stop.sh
script.
Nota al margen 1: Las estrofas start on started runlevel [2]
y stop on starting runlevel [!2]
no funcionan. Hay que mencionar específicamente el trabajo rc
.
Nota al margen 2: Lo que es confuso también en el manual inicial: la kill signal
estrofa especifica la señal enviada después de 5 segundos. En este ejemplo, lo configuré de SIGTERM
(predeterminado) a SIGCONT, pero no pude cambiar el tiempo de espera de 5 segundos. La kill timeout
estrofa especifica el tiempo de espera después del cual SIGKILL
se envía, qué señal no se puede cambiar. Por lo tanto, una mejora sería definir nuevas estrofas term signal
y term timeout
.
Aquí el script de inicio winxpvm-start.sh:
#! /bin/bash -e
function dostart()
{
echo -n "Running WinXP ... "
vboxheadless --startvm WinXP
echo "now closed"
}
export -f dostart
if [ $(whoami) != "tombert" ]; then
su -c dostart tombert
else
dostart
fi
Dado que todas las configuraciones, etc., se realizan en modo de usuario (ya que mi inicio de sesión es tombert ), incluso cuando se ejecuta como root, cambio la cuenta a tombert . El usuario, por supuesto, podría cambiar en la configuración inicial, pero esta solución me deja la opción de iniciar / detener la máquina virtual "a mano" desde la consola.
Lo más interesante es el script de apagado en winxpvm-stop.sh:
#! /bin/bash
function dostop()
{
## check if WinXP is running
vboxmanage showvminfo WinXP --machinereadable | grep -q 'VMState="running"' &> /dev/null
if [ $? -ne 0 ]; then
echo "WinXP not running"
exit
fi
## try gracefully shutdown
echo -n "Shutting down WinXP ... "
#vboxmanage controlvm WinXP acpipowerbutton
vboxmanage guestcontrol WinXP execute --image "%SystemRoot%\system32\shutdown.exe" --username tombert --password <mypassword> --wait-exit -- "-s" "-f" "-t" "0" &> /dev/null
## check vm status
INDEX=60
while [ $INDEX -gt 0 ]; do
echo -n "$INDEX "
vboxmanage showvminfo WinXP --machinereadable | grep -q 'VMState="running"' &> /dev/null
if [ $? -ne 0 ]; then
echo "gracefully done"
break
fi
sleep 1
let INDEX+=-1
done
## close forcefully
if [ $INDEX -eq 0 ]; then
vboxmanage controlvm WinXP poweroff &> /dev/null
echo "forcefully done"
fi
}
export -f dostop
if [ $(whoami) != "tombert" ]; then
su -c dostop tombert
else
dostop
fi
Primero hago lo mismo que en el script de inicio: estoy cambiando el usuario de root a mi cuenta tombert . Ahora veamos la función dostop
. Primero estoy verificando si la máquina virtual está funcionando. Entonces estoy tratando de apagar "suavemente" enviando un apagado directamente a WinXP usando guestcontrol
. Aquí debe proporcionar las credenciales para la cuenta WinXP, que en mi caso es tombert y una contraseña. Windows shutdown
cerrará con gracia todas las aplicaciones y apagará el sistema operativo (normalmente). Luego, verifiquemos el estado de la máquina virtual continuamente usando showvminfo
. Hacer esto al menos 60 veces con 1 segundo de tiempo de espera (haga lo que considere apropiado aquí) debería dejar a la máquina virtual el tiempo suficiente para apagarse correctamente. Tenga en cuenta que la llamada ashowvminfo
También toma un poco menos de un segundo (al menos en mi computadora), por lo que esto me da ~ 120 segundos en mi caso. Si todo se frena, podemos apagarlo forzosamente usando la poweroff
declaración.
También debería ver el acpipowerbutton
, pero sin usar. Esto se debe a que no funciona de manera confiable. Si ha iniciado sesión en Windows o, lo que es peor, en varios usuarios, Windows mostrará un diálogo de confirmación de apagado que evitará que el sistema se apague. Esta es también la razón por acpibutton
la /etc/default/virtualbox
cual no funcionará 100% confiable. Además poweroff
, la máquina virtual se apagará por la fuerza, igual que un botón de encendido de larga duración. Por lo tanto, es mejor configurar esto para vaciar:
Extracto de / etc / default / virtualbox:
# SHUTDOWN_USERS="foo bar"
# check for running VMs of user 'foo' and user 'bar'
# 'all' checks for all active users
# SHUTDOWN=poweroff
# SHUTDOWN=acpibutton
# SHUTDOWN=savestate
# select one of these shutdown methods for running VMs
# acpibutton and savestate causes the init script to wait
# 30 seconds for the VMs to shutdown
SHUTDOWN_USERS=""
SHUTDOWN=""
Para que sea perfecto, es posible que desee cambiar el comportamiento del botón de encendido:
Extracto de /etc/acpi/powerbtn.sh:
#!/bin/sh
# /etc/acpi/powerbtn.sh
# Initiates a shutdown when the power putton has been
# pressed.
# @backup
# plain shutdown
/sbin/shutdown -h now "Power button pressed"
# fini
exit 0
...
...
Queda un pequeño inconveniente. Cuando la máquina virtual todavía se está iniciando y el servicio de control de invitados no está activo (en la máquina virtual), no recibirá el comando de apagado. Un caso raro ... pero piénsalo.
Eso es, espero que ayude.
reboot
12.10 dice "Cuando se llama con --force o cuando está en el nivel de ejecución 0 o 6, esta herramienta invoca el sistema reiniciar (2), se llama a sí mismo y reinicia directamente el sistema. De lo contrario, esto simplemente invoca la herramienta de apagado (8) con los argumentos apropiados "; y la página del manualshutdown
dice "Una vez que ha transcurrido el TIEMPO, el apagado envía una solicitud al demonio init (8) para que el sistema baje al nivel de ejecución apropiado".