Consiglierei un approccio più sofisticato che includa un lavoro iniziale, uno script di avvio e arresto. Ad esempio, sto usando Windows XP, poiché la mia directory home consente di usare Tombert ... che dovresti cambiare di conseguenza. Ha il vantaggio di qualsiasi cosa tu faccia (riavvio, spegnimento, premendo il pulsante di accensione) gestisce bene la tua macchina virtuale .
Innanzitutto il processo di avvio, inserisci in /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
Il processo di avvio avvia la macchina virtuale nel runlevel 2 (che è in modalità grafica) e nel mio caso aumenta la priorità con nice
. Per arrestare correttamente la macchina virtuale, è necessario "disabilitare" la terminazione di avvio utilizzando l' kill signal SIGCONT
istruzione. Ciò lascia inizialmente la macchina virtuale in esecuzione (evitando l'impostazione predefinita SIGTERM
). Dopo 120 secondi SIGKILL
viene comunque inviato. Invece sto eseguendo la winxpvm-stop.sh
sceneggiatura.
Nota a margine 1: le stanze start on started runlevel [2]
e stop on starting runlevel [!2]
non funzionano. Bisogna menzionare specificamente il lavoro rc
.
Nota a margine 2: Ciò che confonde anche dal manuale di avvio: La kill signal
stanza specifica il segnale inviato dopo 5 secondi. In questo esempio l'ho impostato da SIGTERM
(impostazione predefinita) a SIGCONT, ma il timeout di 5 secondi non sono stato in grado di modificare. La kill timeout
stanza specifica il timeout dopo il quale SIGKILL
viene inviato - quale segnale non è possibile modificare. Un miglioramento sarebbe quindi quello di definire nuove stanze term signal
e term timeout
.
Ecco lo script iniziale 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
Dal momento che tutte le impostazioni ecc. Vengono eseguite in modalità utente (poiché il mio accesso è tombert ), anche quando eseguito come root, cambio l'account in tombert . L'utente ovviamente potrebbe essere modificato nella configurazione di avvio ma questa soluzione mi lascia la possibilità di avviare / arrestare la macchina virtuale "a mano" dalla console.
Il più interessante è lo script di arresto in 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
Per prima cosa faccio lo stesso dello script iniziale: sto cambiando l'utente da root a Tombert . Ora diamo un'occhiata alla funzione dostop
. Innanzitutto sto verificando se la macchina virtuale è persino in esecuzione. Quindi sto cercando di arrestare "dolcemente" l'invio di un arresto direttamente a WinXP utilizzando guestcontrol
. Qui devi fornire le credenziali per l'account WinXP, che nel mio caso è Tombert e una password. Windows shutdown
chiuderà con grazia tutte le applicazioni e spegnerà il sistema operativo (normalmente). Quindi consente di controllare continuamente lo stato della macchina virtuale showvminfo
. Farlo almeno 60 volte con 1 secondo di timeout (fare qualsiasi cosa tu pensi che sia giusto qui) dovrebbe lasciare alla macchina virtuale abbastanza tempo per spegnersi con grazia. Si noti che la chiamata ashowvminfo
richiede anche un po 'meno di un secondo (almeno sul mio computer) quindi questo mi dà ~ 120 secondi nel mio caso. Se tutto frena, possiamo forzare l'arresto usando l' poweroff
istruzione.
Dovresti anche vedere il acpipowerbutton
, ma non utilizzato. Questo perché non funziona in modo affidabile. Se hai effettuato l'accesso a Windows o, peggio ancora, più utenti, Windows mostrerà una finestra di dialogo di arresto di conferma che impedisce al sistema di arrestarsi. Questo è anche il motivo per cui acpibutton
in the /etc/default/virtualbox
non funzionerà al 100% affidabile. Inoltre poweroff
spegnerà forzatamente la macchina virtuale, come un pulsante di accensione a pressione prolungata. Pertanto è meglio impostare questo su vuoto:
Estratto da / 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=""
Per renderlo perfetto potresti voler cambiare il comportamento del pulsante di accensione:
Estratto da /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
...
...
C'è ancora un piccolo inconveniente. Quando la macchina virtuale è ancora in fase di avvio e il servizio di controllo guest non è attivo (nella macchina virtuale) non riceverà il comando di arresto. Un caso raro ... ma pensaci.
Questo è tutto, spero che sia d'aiuto.
reboot
in 12.10 dice "Quando viene chiamato con --force o quando nel runlevel 0 o 6, questo strumento richiama la stessa chiamata di sistema reboot (2) e riavvia direttamente il sistema. Altrimenti questo semplicemente invoca lo strumento shutdown (8) con gli argomenti appropriati. "; e la pagina man pershutdown
dice "Una volta che TIME è trascorso, shutdown invia una richiesta al demone init (8) per portare il sistema nel runlevel appropriato."