Poleciłbym bardziej wyrafinowane podejście, w tym pracę upstart, skrypt start i stop. Jako przykład używam systemu Windows XP, ponieważ mój katalog domowy pozwala na użycie tomberta ... który należy odpowiednio zmienić. Ma tę zaletę, że wszystko, co robisz (restart, zamknięcie, naciśnięcie przycisku zasilania), dobrze radzi sobie z maszyną wirtualną .
Najpierw zadanie upstart, umieść w /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
Zadanie upstart uruchamia maszynę wirtualną na poziomie 2 (który jest w trybie graficznym), aw moim przypadku zwiększa priorytet o nice
. Aby ładnie zamknąć maszynę wirtualną, muszę „wyłączyć” zakończenie upstart za pomocą kill signal SIGCONT
instrukcji. To powoduje, że maszyna wirtualna najpierw działa (unikając domyślnej SIGTERM
). Po 120 sekundach i tak SIGKILL
zostanie wysłany. Zamiast tego uruchamiam winxpvm-stop.sh
skrypt.
Uwaga dodatkowa 1: Sekcje start on started runlevel [2]
i stop on starting runlevel [!2]
nie działają. Należy szczególnie wspomnieć o pracy rc
.
Uwaga dodatkowa 2: Co jest mylące również z podręcznika dla początkujących: Sekcja kill signal
określa sygnał wysłany po 5 sekundach. W tym przykładzie ustawiłem go z SIGTERM
(domyślnie) na SIGCONT - ale nie mogłem zmienić limitu 5 sekund. Sekcja kill timeout
określa limit czasu, po którym SIGKILL
jest wysyłany - którego sygnału nie można zmienić. Ulepszeniem byłoby zatem zdefiniowanie nowych zwrotek term signal
i term timeout
.
Oto skrypt startowy 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
Ponieważ wszystkie ustawienia itp. Są wykonywane w trybie użytkownika (ponieważ mój login to tombert ), nawet po uruchomieniu jako root zmieniam konto na tombert . Użytkownik może oczywiście zostać zmieniony w konfiguracji upstart, ale to rozwiązanie pozostawia mi opcję uruchamiania / zatrzymywania maszyny wirtualnej „ręcznie” z konsoli.
Bardziej interesujący jest skrypt zamykający w 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
Najpierw robię to samo, co w skrypcie startowym - zmieniam użytkownika z root na moje konto tombert . Teraz spójrzmy na funkcję dostop
. Najpierw sprawdzam, czy maszyna wirtualna w ogóle działa. Następnie próbuję „miękko” zamknąć system, wysyłając go bezpośrednio do WinXP przy użyciu guestcontrol
. Tutaj musisz podać poświadczenia konta WinXP, które w moim przypadku to tombert i hasło. Windows shutdown
z wdziękiem zamknie wszystkie aplikacje i wyłączy system operacyjny (normalnie). Następnie pozwala stale sprawdzać stan maszyny wirtualnej za pomocą showvminfo
. Wykonanie tego co najmniej 60 razy z 1-sekundowym limitem czasu (rób wszystko, co uważasz, że jest to właściwe) powinno pozostawić maszynie wirtualnej wystarczająco dużo czasu, aby mogła się bezpiecznie zamknąć. Pamiętaj, że połączenie zshowvminfo
zajmuje również trochę mniej niż sekundę (przynajmniej na moim komputerze), więc w moim przypadku daje to ~ 120 sekund. Jeśli wszystko zahamuje, możemy wymusić wyłączenie przy użyciu poweroff
oświadczenia.
Powinieneś także zobaczyć acpipowerbutton
, ale nieużywany. Jest tak, ponieważ nie działa niezawodnie. Jeśli jesteś zalogowany do systemu Windows lub nawet gorzej wielu użytkowników, system Windows wyświetli okno dialogowe potwierdzenia zamknięcia, uniemożliwiające zamknięcie systemu. Jest to również powód, dla którego acpibutton
w /etc/default/virtualbox
nie będzie działać w 100% niezawodny. Również poweroff
silnie wyłączy maszynę wirtualną - tak samo jak długo naciśnij przycisk zasilania. Dlatego najlepiej ustawić to na puste:
Fragment z / 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=""
Aby było idealnie, możesz zmienić zachowanie przycisku zasilania:
Fragment /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
...
...
Pozostaje jedna mała wada. Gdy maszyna wirtualna nadal się uruchamia, a usługa kontroli gościa nie jest uruchomiona (na maszynie wirtualnej), nie otrzyma polecenia zamknięcia. Rzadki przypadek ... ale pomyśl o tym.
To wszystko, mam nadzieję, że to pomoże.
reboot
podręcznika dla 12.10 mówi: „Gdy zostanie wywołana z --force lub w trybie 0 lub 6, to narzędzie wywołuje samo wywołanie systemowe reboot (2) i bezpośrednio ponownie uruchamia system. W przeciwnym razie po prostu wywołuje narzędzie shutdown (8) z odpowiednie argumenty. ”; a strona podręcznika manshutdown
mówi: „Po upływie CZASU zamknięcie wysyła żądanie do demona init (8), aby doprowadzić system do odpowiedniego poziomu uruchamiania”.