ホストのシャットダウン時のゲストのVirtualbox Windowsの正常なシャットダウン


19

ホストコンピューターのシャットダウンまたは再起動時にVirtualBox Windowsで実行されているゲストVMを正常にシャットダウンするソリューションを見つけようとしています。

最も安全なオプションは、ホストがシャットダウンを開始したときに「状態保存」コマンドをトリガーすることですが、VMが状態の保存と電源オフを完了するまでホストが十分に待機するかどうかは不明です。

誰もがこの(一見基本的な)問題に対して堅牢なソリューションを持っていますか?


ゲストの追加をインストールしますか?それは必要な機能を提供しませんか?
カナダのルーク州立モニカ

@CanadianLukeそれはしません。:)
マットジェンキンス

回答:


6

同様の問題があり、VirtualBoxをサービスとして実行して解決しました。

http://vboxvmservice.sourceforge.net/

VBoxVMServiceを使用すると、マシンのシャットダウン(状態の保存、電源オフ)および起動の方法を選択できます。サービスとして実行されているため、Windowsはシステムのシャットダウンプロセス中に自動的にシャットダウンするまで待機します。


Windows 10では、設定プロセスはそれほど自動ではありません。何が問題なのかを確認するには、トラブルシューティングを参照する必要があります。ただし、正しく構成した後、このソフトウェアは必要なことを正確に実行します。お疲れ様でした。
iuradz

3

残念ながら、VirtualBox GUIを介して起動されたVMではこれは不可能のようです。GUIがホストのシャットダウンイベントをキャッチして反応する場合でも、VirtualBoxサービスは終了します:https : //forums.virtualbox.org/viewtopic.php? p=278668#p278668

グラフィカルコンソールが必要ない場合は、VBoxHeadlessTrayまたはVBoxVMServiceが最適です。どちらも、Windowsホストのシャットダウンと再起動での自動保存と再開をサポートしています。

VirtualBox 5.0では、「取り外し可能なUI」スタートモードが導入されています。このモードは、独立したUIプロセスでヘッドレスVMを起動します。ただし、グラフィックパフォーマンスは低下し、3Dアクセラレーションはまだサポートされていません。ただし、将来的にはこれをVBoxHeadlessTrayと組み合わせることができるかもしれません(VBoxHeadlessTrayはまだ5.0をサポートしていません。)VBoxHeadlessTray GitHubリポジトリおよびVirtualBox 5サポートを追加するための対応するGitHubプルリクエストへのリンク。

編集:VBoxVmService 、バージョン5.0の新しいデタッチャブルモードもサポートしいません。これまでのところ唯一のヘッドレス。そのための機能リクエストを追加しました。


投稿ごとに3つ以上のリンクを移植することは許可されていないため、VirtualBox 5サポートを追加するためのVBoxHeadlessTrayおよび対応するGitHubプルリクエストへのリンクを次に示します。
レオB

スレッドで概説されている問題は発生しません。このトピックに関する私の答えをご覧ください。Windowsホストのシャットダウンを実行して、立ち去ることができます。すべてのVMが閉じるまでシャットダウンはブロックされ、クリーンシャットダウンまたは保存状態を実行するようにデフォルトのアクションを変更しました。
クリスバーンセン

2

スタートメニューの電源ボタンの代わりに使用する3つのバッチスクリプトがあります。

do_shutdown.bat(10秒の待機時間でPCをシャットダウンします。VMの状態を保存するために10秒の時間を与えるのではなく、10秒以内にシャットダウンをキャンセルできるようにします。カウントダウンは、VMのシャットダウン後に開始します)

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

do_reboot.bat(vmがシャットダウンした直後にリブートします)

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

do_cancel.bat(10秒の待機時間内にpc-shutdownをキャンセルできます。do_shutdown.batでシャットダウンしたため、vmを再度再起動します)

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

代わりにsavestate、次のいずれかを使用することもできます

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
ありがとう、これは面白い。残念ながら、他の非手動のシャットダウン/再起動シナリオもあります。たとえば、Windows Updateでスケジュールされた再起動、または低バッテリー電源オフ/シャットダウンイベント。
マットジェンキンス

1
ああ、わかった。あります、グループポリシーエディタをして、「スクリプト(スタートアップ/シャットダウン)」セクションlifehacker.com/...私はどのように振る舞うかわからないので、私はシャットダウン時に非常に短いコマンドの1つを使用しています(1つのカールコール)完了するまでに時間がかかるスクリプトの場合。
ダニエルF

2

パーティーに遅れてすみません。これには正確な答えがありますが、コマンドラインfooが必要です。詳細については、次のスレッドの投稿を参照してください:https : //forums.virtualbox.org/viewtopic.php?f=6&t=53684#p285540

探しているコマンドは次のとおりです。

「C:\ Program Files \ Oracle \ VirtualBox \ VBoxManage.exe」setextradata「VM NAME」GUI / DefaultCloseActionシャットダウン

これは複数のVMで使用しているもので、ウィンドウを閉じると自動的に安全なシャットダウンが開始されます。Windowsをシャットダウンし、すべてを閉じようとすると、これらのプロセスが完了するまで待機します。


1

同様の質問があり、このページを見つけました。テスト用のVMがたくさんあるため、VirtualBoxをサービスとして実行したくありません。通常、VirtualBox UIで実行する別のVMを選択します。コンピューターをシャットダウンすると、各VMの状態を手動で保存するのが面倒です。この場合、スクリプトを使用して実行中のすべてのVMを保存することが実用的なソリューションのようです。Daniel Fの答えをより一般的にするために、実行中のすべてのVMの状態を明示的に名前を付けずに自動的に保存するこれらのスクリプトを書きました。

Windows用のsaveRunningVMs.bat

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

Linux用のsaveRunningVMs.sh

#!/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

実行中のすべてのVirtualBox VMを一時停止するPythonスクリプトを作成してから、スケジュールされたタスクとしてログアウト時にスクリプトを実行するようにシステムを設定しました。

この方法が正確にどれだけ信頼できるかわかりません。他の人が指摘したように、Winlogon 7002タスクが完了するまでシステムが待機する時間には制限があります。しかし、個人的には、4 GBを超えるVM RAM全体で複数の実行中のVMを使用する場合でも、使用可能な保存状態を提供することに何の問題もありません。

設定手順は次のとおりです。

  1. python.orgからPython 2.7.xをダウンロードしてインストールします
  2. メモ帳またはその他のプレーンテキストエディタを使用して、システムのどこかにpythonスクリプトファイルを作成します(以下を参照)
  3. タスクスケジューラを開く
  4. [アクション]-> [基本タスクの作成...]を選択し、ウィザードを使用して次の設定でタスクを作成します。
    • お好みの名前
    • 特定のイベントが記録されたときにタスクを開始する
    • ログ:システム
    • ソース:Winlogon
    • イベントID:7002
    • プログラムを開始する
    • Program / Scriptの横にpython.exe、たとえばへのフルパスを入力しますc:\Python27\python.exe
    • [ 引数追加]の横に、Pythonスクリプトファイルを配置するフルパスを入力します。たとえば、ドキュメントフォルダーのサブフォルダーに配置します。C:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
    • 終了を選択します。

これで、ログアウト/再起動/シャットダウン時にVirtualBox VMを一時停止する必要があります。

シャットダウンを行うPythonスクリプトは次のとおりです。

# 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
手動で実行でき、savestatesを実行してからシャットダウンするバッチスクリプトを使用するという他の人の提案は、それがユースケースに適合する場合は素晴らしいです。しかし、私は本当に... VM私は行で、過去2日間のハードWindows Updateの再起動で一晩電源をオフにされてきたと取り組んできた後、このためには、Windows Updateの自動再起動しますたい
rakslice
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.