Schließen Sie virtualbox machine beim Host-Neustart

8

Ich betreibe Windows 7 in Virtualbox auf Ubuntu 11.10. Alles funktioniert gut. Ich starte es beim Start, aber ich habe ein Problem mit dem Neustart.

Wenn ich sudo reboot now eintippe, wird der Status des virtuellen Windows 7 nicht gespeichert. Nach dem Neustart startet die virtuelle Box, aber anstelle des laufenden Windows bekomme ich das Windows 7 Crash-Boot-Menü und das Windows bootet wieder.

Gibt es eine Option, dass Ubuntu ein Signal an die virtuelle Box senden kann, um die Instanz vor dem Host-Neustart sicher zu schließen?

    
takeshin 04.02.2012, 09:20

5 Antworten

6

Wenn Sie wirklich herunterfahren müssen, während eine virtuelle Maschine in Virtual Box läuft, können Sie ein eigenes Skript für ein manuelles Herunterfahren definieren, wo Sie einen Befehl zum Speichern des Maschinenzustands vor dem Herunterfahren des Prozesses ablegen:

VBoxManage controlvm <name> savestate # <name> is the name of your VM
gnome-session-quit --power-off # this example displays the power-off dialog for >11.10

Alternativ können Sie auch ein Skript erstellen, das immer beim Herunterfahren ausführt .

    
Takkat 04.02.2012, 10:08
4

Wenn Sie sudo reboot Programme verwenden, wird das Kill-Signal automatisch beendet, ohne dass Sie eine Anwendungszeit haben, um auf eine solche Situation zu reagieren. Dies ist kein Fehler, es hat immer auf die gleiche Weise funktioniert und das ist das erwartete Verhalten.

Es gibt eine ähnliche Frage, bei der Sie sehen können, welche Befehle gegeben werden, wenn Sie im Benutzermenü die Taste shutdown , reboot , suspend usw. drücken. Eine solche Lösung sollte Sie fragen, was Sie tun sollen Schließen Sie ein Fenster mit einer laufenden Anwendung und bevorzugen Sie (in Ihrem Fall) den sudo shutdown -Ansatz. Schau es dir an

Bruno Pereira 04.02.2012 09:40
4

Ich würde einen anspruchsvolleren Ansatz empfehlen, einschließlich eines Upstart-Jobs, eines Start- und Stopp-Skripts. Als Beispiel benutze ich Windows XP, da mein Home-Verzeichnis tombert verwenden kann ... was Sie entsprechend ändern sollten. Es hat den Vorteil von allem, was Sie tun (Neustart, Herunterfahren, Drücken der Einschalttaste), es handhabt Ihre virtuelle Maschine gut .

Zuerst den Upstart-Job, 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

Der Upstart-Job startet die virtuelle Maschine in Runlevel 2 (im grafischen Modus), und in meinem Fall erhöht sie die Priorität mit nice . Um die virtuelle Maschine ordnungsgemäß herunterzufahren, muss ich den Upstart-Abschluss mit der kill signal SIGCONT -Anweisung "deaktivieren". Dadurch wird die virtuelle Maschine zunächst ausgeführt (wobei der Standardwert SIGTERM vermieden wird). Nach 120 Sekunden wird die SIGKILL trotzdem gesendet. Stattdessen führe ich das Skript winxpvm-stop.sh aus.

Side-Note 1: Die Zeilengruppen start on started runlevel [2] und stop on starting runlevel [!2] funktionieren nicht. Man muss speziell den Job rc erwähnen.

Side-Note 2: Was auch im Upstart-Handbuch verwirrend ist: Die kill signal -Stanza gibt das Signal an, das nach 5 Sekunden gesendet wird. In diesem Beispiel habe ich es von SIGTERM (Standard) auf SIGCONT gesetzt - aber das Timeout von 5 Sekunden konnte ich nicht ändern. Die Zeilengruppe kill timeout gibt das Zeitlimit an, nach dem SIGKILL gesendet wird. Dieses Signal kann nicht geändert werden. Eine Verbesserung wäre daher, neue Zeilengruppen term signal und term timeout zu definieren.

Hier das Startscript 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

Da alle Einstellungen usw. im Benutzermodus vorgenommen werden (da meine Anmeldung tombert ist), ändere ich das Konto, selbst wenn es als root ausgeführt wird, in tombert . Der Benutzer könnte natürlich in der Upstart-Konfiguration geändert werden, aber diese Lösung lässt mir die Option, die virtuelle Maschine "von Hand" von der Konsole aus zu starten / stoppen.

Das interessantere ist das Shutdown-Skript 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

Zuerst mache ich dasselbe wie im Startskript - ich ändere den Benutzer von root zu meinem Account Tombert . Nun schauen wir uns die Funktion dostop an. Zuerst überprüfe ich, ob die virtuelle Maschine überhaupt läuft. Dann versuche ich "sanft" herunterzufahren, indem ich einen Shutdown direkt an WinXP mit guestcontrol sende. Hier müssen Sie die Zugangsdaten für den WinXP-Account angeben, in meinem Fall Tombert und ein Passwort. Das Windows shutdown schließt alle Anwendungen ordnungsgemäß und schaltet das Betriebssystem (normalerweise) aus. Dann überprüfen wir den Status der virtuellen Maschine kontinuierlich mit showvminfo . Wenn Sie dies mindestens 60 Mal mit einer Zeitüberschreitung von 1 Sekunde tun (tun Sie alles, was Sie für richtig halten), sollte die virtuelle Maschine genug Zeit haben, um ordnungsgemäß herunterzufahren. Beachten Sie, dass der Aufruf von showvminfo auch ein wenig weniger als eine Sekunde dauert (zumindest auf meinem Computer), so dass es in meinem Fall ~ 120 Sekunden ergibt. Wenn alles bremst, können wir mit der poweroff -Anweisung zwangsweise herunterfahren.

Sie sollten auch acpipowerbutton sehen, aber nicht verwendet. Dies liegt daran, dass es nicht zuverlässig funktioniert. Wenn Sie bei Windows angemeldet sind oder sogar mehrere Benutzer haben, zeigt Windows einen Bestätigungsdialog an, der das Herunterfahren des Systems verhindert. Dies ist auch der Grund, warum das acpibutton in /etc/default/virtualbox nicht 100% zuverlässig funktioniert. Auch die poweroff wird die virtuelle Maschine zwangsweise herunterfahren - genau wie eine lange Einschalttaste. Daher ist es am besten, dies auf leer zu setzen:

Auszug aus / 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=""

Um es perfekt zu machen, möchten Sie vielleicht das Verhalten der Power-Taste ändern:

Auszug aus /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
...
...

Es gibt noch einen kleinen Nachteil. Wenn die virtuelle Maschine noch startet und der Gaststeuerungsdienst nicht aktiv ist (in der virtuellen Maschine), wird der Befehl shutdown nicht empfangen. Ein seltener Fall ... aber denke darüber nach.

Das ist es, hoffe es hilft.

    
tombert 07.04.2013 03:45
2

Folgen Sie dieser Antwort, um Ihre Systemrichtlinie für den Neustart zu ändern

Sie können das nicht in reboot rationalisieren. AFAIK init.d scripts funktionieren nicht, weil es zu lange dauert, aber Sie können den Befehl wie folgt ausführen:

VBoxManage controlvm <vm> savestate&&reboot

Dabei ist <vm> der Name der virtuellen Maschine

    
Amith KK 04.02.2012 10:13
1

Sie können eine Shutdown-Anforderung an die virtuelle Maschine senden mit:

VBoxManage controlvm <vm_name> acpipowerbutton

Wenn Sie dies jedoch in einem Init-Skript tun, sollte das Skript erst beendet werden, wenn das Herunterfahren abgeschlossen ist. Das können wir möglicherweise feststellen, indem wir die Laufwerksdatei (.vdi) der VM mit lsof oder fuser in einer Schleife abfragen. Oder als eine billige Problemumgehung kann sleep 20 ausreichen.

Hier ist, was ich gerade in dem geschlossenen Block meines Init-Skripts verwende:

# This always returns 0, even if an error is displayed!
su - "$DAEMONUSER" VBoxManage controlvm "$VMNAME" acpipowerbutton

# Wait until the disk file is no longer open...
for attempt in 'seq 1 20'
do
    fuser "$VMDISKIMAGE" >/dev/null 2>&1 || break
    sleep 2
done

return 0    # A better script would return success/fail

Nahe am Anfang der Datei habe ich definiert:

VMDISKIMAGE="/home/$DAEMONUSER/VirtualBox VMs/$VMNAME/$VMNAME.vdi"

Dies schließt möglicherweise nicht die VirtualBox App selbst, aber es wartet auf das Herunterfahren der VM. Es funktioniert auch nicht, wenn sich die virtuelle Maschine noch im Hochlauf befindet (viele Betriebssysteme ignorieren während dieser Phase die Ausschalttaste) oder wenn Sie ein altes System ohne ACPI-Unterstützung emulieren.

    
joeytwiddle 20.03.2013 09:25

Tags und Links