it-swarm.com.de

Virtualbox Windows ordnungsgemäßes Herunterfahren von Gästen beim Herunterfahren des Hosts

Ich versuche eine Lösung zu finden, um alle Gast-VMs, die unter VirtualBox Windows ausgeführt werden, ordnungsgemäß herunterzufahren, wenn der Host-Computer heruntergefahren oder neu gestartet wird.

Es scheint, dass die sicherste Option darin besteht, den Befehl "save state" auszulösen, wenn der Host heruntergefahren wird. Es ist jedoch nicht klar, ob der Host lange genug warten wird, bis die VMs den Speichervorgang abgeschlossen und ausgeschaltet haben.

Hat jemand eine robuste Lösung für dieses (scheinbar grundlegende) Problem?

18
Matt Jenkins

Ich hatte ein ähnliches Problem und löste es, indem ich VirtualBox als Dienst ausführte:

http://vboxvmservice.sourceforge.net/

Mit VBoxVMService können Sie festlegen, wie der Computer heruntergefahren (Status speichern, ausschalten) und gestartet werden soll. Da es als Dienst ausgeführt wird, wartet Windows während des Herunterfahrens des Systems automatisch darauf, dass es heruntergefahren wird.

6
Bill Westrup

Leider scheint dies für VMs, die über die VirtualBox-GUI gestartet wurden, nicht möglich zu sein. Auch wenn die GUI das Host-Shutdown-Ereignis abfängt und reagiert, wird der VirtualBox-Dienst beendet: https://forums.virtualbox.org/viewtopic.php?p=278668#p278668

Wenn Sie keine grafische Konsole benötigen, sind VBoxHeadlessTray oder VBoxVMService möglicherweise die richtige Wahl. Beide unterstützen das automatische Speichern und Fortsetzen beim Herunterfahren und Neustarten des Windows-Hosts.

VirtualBox 5.0 führt einen "abnehmbaren UI" Startmodus ein. Dieser Modus startet ein kopfloses VM mit einem separaten UI-Prozess. Die Grafikleistung leidet jedoch, und die 3D-Beschleunigung wird noch nicht unterstützt. Aber vielleicht kann dies in Zukunft mit VBoxHeadlessTray kombiniert werden (VBoxHeadlessTray unterstützt noch nicht 5.0.) Links zu VBoxHeadlessTray GitHub-Repository und zum entsprechenden GitHub-Pull-Anfrage zum Hinzufügen von VirtualBox 5-Unterstützung .

Edit: VBoxVmService unterstützt auch nicht den neuen abnehmbaren Modus ab Version 5.0. Bisher nur kopflos . Ich habe eine Feature-Anfrage hinzugefügt.

3
Leo B

Tut mir leid, dass ich zu spät zur Party komme. Es gibt eine genaue Antwort darauf, obwohl es einige Kommandozeilen-FOO erfordert. Weitere Informationen finden Sie in diesem Thread-Beitrag: https://forums.virtualbox.org/viewtopic.php?f=6&t=53684#p285540

Der gesuchte Befehl lautet:

"C:\Programme\Oracle\VirtualBox\VBoxManage.exe" setextradata "VM NAME" GUI/DefaultCloseAction Shutdown

Das verwende ich auf mehreren VMs, schließe das Fenster und es startet automatisch ein sicheres Herunterfahren. Fahren Sie Windows herunter, und warten Sie beim Versuch, alles zu schließen, bis diese Prozesse abgeschlossen sind.

2
Kris Bahnsen

Ich hatte eine ähnliche Frage und fand diese Seite. Ich möchte VirtualBox nicht als Dienst ausführen, da ich viele VMs zum Testen habe und normalerweise andere zur Ausführung in der VirtualBox-Benutzeroberfläche auswähle. Wenn ich meinen Computer herunterfahre, ist es ärgerlich, den Status jeder VM manuell zu speichern. Die Verwendung von Skripten zum Speichern aller laufenden VMs scheint in diesem Fall eine praktische Lösung zu sein. Um die Antwort von Daniel F zu verallgemeinern, habe ich diese Skripte geschrieben, die automatisch den Status aller laufenden VMs speichern, ohne sie explizit zu benennen.

saveRunningVMs.bat für Windows:

set VBoxManageEXE="%ProgramFiles%\Oracle\VirtualBox\VBoxManage.exe"
set ListRunningVMS=%VboxManageEXE% list runningvms
for /f tokens^=2^,4^ delims^=^" %%p in ('%ListRunningVMS%') do %VBoxManageEXE% controlvm %%p savestate

echo all vms saved, you can shutdown now.

rem shutdown /s /t 10

saveRunningVMs.sh für Linux:

#!/bin/bash
vboxmanage list runningvms | while read line; do
  #echo "VBoxManage controlvm $uuid savestate;"
  echo $line
  if [[ $line =~ \{(.*)\} ]]
  then
    vboxmanage controlvm ${BASH_REMATCH[1]} savestate
  fi
done
1
Karl Wolfram

Ich habe 3 Batch-Skripte, die ich anstelle der Power-Buttons des Startmenüs verwende.

do_shutdown.bat (Herunterfahren des PCs mit einer Wartezeit von 10 Sekunden, um dem VM nicht 10 Sekunden Zeit zum Speichern zu geben, sondern um das Herunterfahren abzubrechen innerhalb von 10 Sekunden. Der Countdown startet, nachdem die VMs heruntergefahren wurden.)

"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Server" savestate
"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Minimal" savestate
shutdown /s /t 10

do_reboot.bat (wird sofort nach dem Herunterfahren des virtuellen Computers neu gestartet)

"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Server" savestate
"C:\VirtualBox\VBoxManage.exe" controlvm "Ubuntu Minimal" savestate
shutdown /r /t 0

do_cancel.bat (Ermöglicht mir, das Herunterfahren des PCs innerhalb der Wartezeit von 10 Sekunden abzubrechen. Anschließend werden die VMs neu gestartet, da sie mit heruntergefahren wurden die do_shutdown.bat)

shutdown /a
C:\VirtualBox\VBoxManage.exe startvm "Ubuntu Minimal" --type headless
C:\VirtualBox\VBoxManage.exe startvm "Ubuntu Server" --type headless

Anstelle von savestate können Sie auch eine der folgenden Optionen verwenden

poweroff        - pulls the plug
                  (probably not a good idea...)

acpipowerbutton - presses the power off button for a clean shutdown
                  ("The system is going down for power off NOW!" to all consoles)

acpisleepbutton - tells the os to go to sleep
                  (probably just as bad as poweroff)
1
Daniel F

Ich habe ein Python-Skript erstellt, das alle ausgeführten VirtualBox-VMs anhält, und dann das System so eingerichtet, dass das Skript beim Abmelden als geplante Aufgabe ausgeführt wird.

Ich weiß nicht, wie zuverlässig diese Methode genau ist. Wie andere angemerkt haben , gibt es Einschränkungen, wie lange das System auf den Abschluss einer Winlogon 7002-Task warten soll. Aber ich persönlich hatte kein Problem damit, nutzbare Sicherungszustände zu liefern, selbst wenn mehrere VMs mit mehr als 4 GB Gesamt-VM RAM ausgeführt werden.

Hier sind die Schritte zum Einrichten:

  1. Laden Sie Python 2.7.x von python.org herunter und installieren Sie es.
  2. Erstellen Sie die Python-Skriptdatei irgendwo auf Ihrem System mit Notepad oder einem anderen Nur-Text-Editor (siehe unten).
  3. Öffnen Sie den Taskplaner
  4. Wählen Sie Aktion -> Grundlegende Aufgabe erstellen ... und erstellen Sie mit dem Assistenten eine Aufgabe mit den folgenden Einstellungen
    • Ein Name Ihrer Wahl
    • Starten Sie die Aufgabe, wenn ein bestimmtes Ereignis protokolliert wird
    • Protokoll: System
    • Quelle: Winlogon
    • Ereignisid: 7002
    • Starten Sie ein Programm
    • Geben Sie neben Program/Script den vollständigen Pfad zu Ihrem python.exe ein, zum Beispiel c:\Python27\python.exe
    • Geben Sie neben Argumente hinzufügen den vollständigen Pfad ein, in dem Sie die Python-Skriptdatei abgelegt haben. Beispielsweise habe ich meine in einem Unterordner meines Dokumentenordners abgelegt. Dies ist also C:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py.
    • Wählen Sie Finish.

Jetzt sollten VirtualBox-VMs beim Abmelden/Neustarten/Herunterfahren angehalten werden.

Das Python-Skript zum Herunterfahren ist unten:

# A script to suspend all running VirtualBox VMs

import os

import subprocess

import sys


class VM(object):
    def __init__(self, name, uuid):
        self.name = name
        self.uuid = uuid

    def __repr__(self):
        return "VM(%r,%r)" % (self.name, self.uuid)


class VBoxRunner(object):
    def __init__(self):
        program_files = os.environ["ProgramW6432"]
        vbox_dir = os.path.join(program_files, "Oracle", "VirtualBox")
        self.vboxmanage_filename = os.path.join(vbox_dir, "VBoxManage.exe")

    def vbox_run(self, *args):
        subprocess.check_call([self.vboxmanage_filename] + list(args))

    def vbox_run_output(self, *args):
        return subprocess.check_output([self.vboxmanage_filename] + list(args))

    def list(self, running=True):
        if running:
            list_cmd = "runningvms"
        else:
            list_cmd = "vms"

        return [self.parse_vm_list_entry(x) for x in self.vbox_run_output("list", list_cmd).strip().split("\n")]

    def suspend_all(self):
        success = True
        stopped_some_vms = False
        vms = self.list(running=True)
        for vm in vms:
            if vm is None:
                continue
            # noinspection PyBroadException
            try:
                self.suspend_vm(vm)
            except:
                success = False
            else:
                stopped_some_vms = True
        if not stopped_some_vms:
            self.message("No running vms")
        return success

    @staticmethod
    def parse_vm_list_entry(x):
        """:type x: str"""
        if not x.startswith('"'):
            return None
        end_pos = x.find('"', 1)
        if end_pos == -1:
            return None
        name = x[1:end_pos]
        assert x[end_pos + 1: end_pos + 3] == " {"
        assert x.endswith("}")
        uuid = x[end_pos + 2:]

        return VM(name, uuid)

    @staticmethod
    def message(msg):
        print >>sys.stderr, msg

    def suspend_vm(self, vm):
        assert isinstance(vm, VM)
        self.vbox_run("controlvm", vm.uuid, "savestate")


def main():
    vr = VBoxRunner()
    success = vr.suspend_all()
    if not success:
        sys.exit(1)


if __== "__main__":
    main()
0
rakslice