Virtualbox Arresto gradevole di Windows degli ospiti allo spegnimento dell'host


19

Sto cercando di trovare una soluzione per arrestare con grazia qualsiasi VM guest in esecuzione su Windows VirtualBox quando il computer host viene spento o riavviato.

Sembra che l'opzione più sicura sarebbe quella di attivare il comando "salva stato" quando l'host inizia a spegnersi, ma non è chiaro se l'host attenderà abbastanza a lungo affinché le macchine virtuali finiscano di salvare lo stato e spegnersi.

Qualcuno ha una soluzione solida per questo problema (apparentemente di base)?


Installare le aggiunte degli ospiti? Ciò non fornisce la funzionalità richiesta?
Canadian Luke REINSTATE MONICA

@CanadianLuke No. :)
Matt Jenkins,

Risposte:


6

Ho avuto un problema simile e l'ho risolto eseguendo VirtualBox come servizio:

http://vboxvmservice.sourceforge.net/

Con VBoxVMService è possibile scegliere come arrestare (salvare lo stato, spegnere) la macchina e avviarla. Poiché è in esecuzione come servizio, Windows attenderà automaticamente che si arresti, durante il processo di spegnimento del sistema.


Il processo di installazione non è così automatico su Windows 10. Devo fare riferimento alla risoluzione dei problemi per vedere cosa c'è che non va. Tuttavia, dopo aver configurato correttamente, questo software fa esattamente quello che mi serve. Grazie per l'ottimo lavoro.
Iuradz,

3

Sfortunatamente ciò non sembra possibile per le VM avviate tramite la GUI di VirtualBox. Anche se la GUI potrebbe rilevare l'evento di arresto dell'host e reagire, il servizio VirtualBox viene terminato: https://forums.virtualbox.org/viewtopic.php?p=278668#p278668

Se non hai bisogno di una console grafica, VBoxHeadlessTray o VBoxVMService potrebbe essere la strada da percorrere. Entrambi supportano il salvataggio e il ripristino automatici all'arresto e al riavvio dell'host Windows.

VirtualBox 5.0 introduce una modalità di avvio "UI rimovibile" . Questa modalità avvia una macchina virtuale senza testa con un processo UI separato. Le prestazioni grafiche ne risentono e l'accelerazione 3D non è ancora supportata. Ma forse questo può essere combinato con VBoxHeadlessTray in futuro (VBoxHeadlessTray non supporta ancora 5.0.) Collegamenti al repository GitHub VBoxHeadlessTray e alla corrispondente richiesta pull di GitHub per l'aggiunta del supporto VirtualBox 5 .

Modifica: VBoxVmService inoltre non supporta la nuova modalità staccabile dalla versione 5.0. Finora solo senza testa . Ho aggiunto una richiesta di funzionalità per questo.


Poiché non mi è consentito il porting di più di due collegamenti per post, ecco i collegamenti a VBoxHeadlessTray e alla corrispondente richiesta pull di GitHub per l'aggiunta del supporto di VirtualBox 5.
Leone B,

Non riscontro i problemi descritti nel thread. Vedi la mia risposta su questo argomento. Posso eseguire l'arresto dell'host di Windows e andare via. L'arresto si blocca fino a quando tutte le mie macchine virtuali sono chiuse e ho modificato l'azione predefinita per eseguire un arresto pulito o uno stato di salvataggio.
Kris Bahnsen,

2

Ho 3 script batch che uso al posto dei pulsanti di accensione del menu di avvio.

do_shutdown.bat (spegnimento del PC con un periodo di attesa di 10 secondi, non per dare il tempo 10 sec di vm al savestate, ma per consentirmi di annullare l'arresto entro 10 secondi. Il conto alla rovescia inizia dopo che i VM sono stati spenti)

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

do_reboot.bat (riavvia immediatamente dopo lo spegnimento del VM)

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

do_cancel.bat (mi consente di annullare lo spegnimento del PC entro il periodo di attesa di 10 secondi. Quindi riavvia nuovamente i vm, poiché sono stati chiusi con do_shutdown.bat)

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

Invece di savestatete puoi anche usare una delle seguenti

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
Grazie, è interessante Sfortunatamente, ci sono anche altri scenari di spegnimento / riavvio non manuali che devo gestire. Ad esempio, riavvia pianificato da Windows Update o eventi di spegnimento / spegnimento della batteria scarica.
Matt Jenkins,

1
Oh va bene. C'è anche il Group Policy Editor con le "Script (Avvio / Arresto)" sezione lifehacker.com/... sto usando quella per un tempo molto breve comando allo spegnimento (un ricciolo di chiamata), quindi non so come si comporta sugli script che richiedono del tempo per essere completati.
Daniel F,

2

Scusa, sono in ritardo alla festa. C'è una risposta esatta a questo, anche se richiede un po 'di riga di comando. Vedi questo post di discussione per ulteriori informazioni: https://forums.virtualbox.org/viewtopic.php?f=6&t=53684#p285540

Il comando che stai cercando è:

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

Questo è quello che uso su più macchine virtuali, chiudi la finestra e avvia automaticamente un arresto sicuro. Chiudi Windows e, nel suo tentativo di chiudere tutto, attenderà il completamento di questi processi.


1

Ho avuto una domanda simile e ho trovato questa pagina. Non voglio eseguire VirtualBox come servizio, perché ho molte macchine virtuali da testare e di solito ne scelgo diverse da eseguire nell'interfaccia utente di VirtualBox. Quando spengo il computer, è fastidioso salvare manualmente lo stato di ogni VM. L'uso degli script per salvare tutte le VM in esecuzione sembra essere una soluzione pratica in questo caso. Per rendere la risposta di Daniel F più generale, ho scritto questi script che salvano automaticamente lo stato di tutte le VM in esecuzione senza nominarle esplicitamente.

saveRunningVMs.bat per 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 per 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

0

Ho creato uno script Python che sospenderebbe tutte le VM VirtualBox in esecuzione, quindi imposterò il sistema per eseguire lo script al logout come attività pianificata.

Non so quanto sia affidabile questo metodo. Come altri hanno notato, esistono dei limiti per quanto tempo il sistema attenderà il completamento di un'attività Winlogon 7002. Ma personalmente non ho avuto alcun problema nel fornire stati di salvataggio utilizzabili anche con più macchine virtuali in esecuzione su 4+ GB di RAM complessiva della VM.

Ecco i passaggi per configurarlo:

  1. Scarica e installa Python 2.7.x da python.org
  2. Crea il file di script Python da qualche parte sul tuo sistema usando Blocco note o qualsiasi altro editor di testo semplice (vedi sotto)
  3. Apri l'Utilità di pianificazione
  4. Scegli Azione -> Crea un'attività di base ... e usa la procedura guidata per creare un'attività con le seguenti impostazioni
    • Un nome a tua scelta
    • Avvia l'attività quando viene registrato un evento specifico
    • Registro: sistema
    • Fonte: Winlogon
    • ID evento: 7002
    • Avvia un programma
    • Accanto a Programma / Script , inserisci il percorso completo del tuo python.exe, ad esempioc:\Python27\python.exe
    • Accanto a Aggiungi argomenti , inserisci il percorso completo in cui hai inserito il file di script Python, ad esempio ho inserito il mio in una sottocartella della cartella dei miei documenti, quindi questo èC:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
    • Scegli Fine.

Ora le VM VirtualBox dovrebbero essere sospese al logout / riavvio / spegnimento.

Lo script Python per eseguire l'arresto è di seguito:

# 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 __name__ == "__main__":
    main()

1
Altri suggerimenti di utilizzare uno script batch è possibile eseguire manualmente che esegue i savestates e quindi lo spegnimento è ottimo se si adatta al caso d'uso. Ma quello che voglio davvero per questo è il riavvio automatico di Windows Update, dopo che una macchina virtuale con cui ho lavorato è stata spenta durante la notte da Windows Update si riavvia da due giorni consecutivi ...
rakslice
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.