Virtualbox Windows витончене відключення гостей при відключенні хоста


19

Я намагаюся знайти рішення для витонченого відключення будь-яких гостьових візків, що працюють під VirtualBox Windows, коли хост-комп'ютер вимикається або перезапускається.

Здається, що найбезпечнішим варіантом було б запустити команду «зберегти стан», коли хост почне вимикатися, але незрозуміло, чи буде хост чекати достатньо довго, щоб VM закінчили збереження стану та відключення живлення.

Хтось має надійне рішення цього (здавалося б базового) питання?


Встановити додатки для гостей? Це не забезпечує необхідну функціональність?
Канадський Люк ВІДНОВЛЕННЯ МОНИЦИ

@CanadianLuke Це не так. :)
Метт Дженкінс

Відповіді:


6

У мене була подібна проблема і вирішено її, запустивши VirtualBox як сервіс:

http://vboxvmservice.sourceforge.net/

За допомогою VBoxVMService ви можете вибрати, як ви хочете відключити машину (Зберегти стан, вимкнути живлення) та запустити. Оскільки вона працює як послуга, Windows автоматично чекатиме її вимкнення під час відключення системи.


Процес налаштування не є настільки автоматичним для Windows 10. Мені потрібно звернутися до виправлення неполадок, щоб побачити, що не так. Однак після коректної настройки це програмне забезпечення робить саме те, що мені потрібно. Дякую за велику роботу.
iuradz

3

На жаль, це, здається, неможливо для VM, запущених через VirtualBox GUI. Навіть незважаючи на те, що графічний інтерфейс може зафіксувати подію відключення хоста та реагувати, служба VirtualBox припиняється: https://forums.virtualbox.org/viewtopic.php?p=278668#p278668

Якщо вам не потрібна графічна консоль, VBoxHeadlessTray або VBoxVMService може стати дорогою. Обидва підтримують автоматичне збереження та відновлення при відключенні та перезапуску хоста Windows.

VirtualBox 5.0 вводить режим «знімного інтерфейсу користувача» . Цей режим запускає безголовий VM з окремим процесом інтерфейсу користувача. Графічна продуктивність страждає, але прискорення 3D ще не підтримується. Але , можливо , це може бути об'єднано з VBoxHeadlessTray в майбутньому (VBoxHeadlessTray не підтримує 5.0 ще.) Посилання на VBoxHeadlessTray GitHub сховище і до відповідних по запросу тягнути GitHub для додавання підтримки VirtualBox 5 .

Редагувати: VBoxVmService також не підтримує новий знімний режим, починаючи з версії 5.0. Тільки без голови поки що. Я додав запит на функцію для цього.


Оскільки мені не дозволяється переносити більше двох посилань на повідомлення, ось посилання на VBoxHeadlessTray та відповідний запит на додавання GitHub для додавання підтримки VirtualBox 5.
Лев Б

Я не відчуваю проблем, викладених у потоці. Дивіться мою відповідь на цю тему. Я можу запустити відключення хоста Windows і піти. Блокування відключення, поки всі мої віртуальні машини не закриті, і я змінив дію за замовчуванням, щоб зробити чисте відключення або стан збереження.
Кріс Бансен

2

У мене є 3 пакетні сценарії, які я використовую замість кнопок включення пускового меню.

do_shutdown.bat (відключення ПК із 10- секундним періодом очікування, щоб не дати 10-секундному режиму vm зберегти стан, а дозволити мені скасувати відключення протягом 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-секундного періоду очікування. Потім він знову перезапустить vm, оскільки вони закрилися за допомогою do_shutdown.bat)

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 або подіями відключення / відключення живлення акумулятора.
Метт Дженкінс

1
О, добре. Є також редактор групової політики з розділом "Сценарії (запуск / вимкнення)" lifehacker.com/… Я використовую цю команду для дуже короткої команди про вимкнення (один виклик згортання ), тож я не знаю, як вона веде себе на сценарії, які потребують певного часу.
Даніель Ф

2

Вибачте, що запізнився на вечірку. На це є точна відповідь, хоча це вимагає певного командного рядка. Дивіться цю тему для отримання додаткової інформації: https://forums.virtualbox.org/viewtopic.php?f=6&t=53684#p285540

Команда, яку ви шукаєте:

"C: \ Програмні файли \ Oracle \ VirtualBox \ VBoxManage.exe" setextradata "GUI IME" GUI / DefaultCloseAction Завершення роботи

Це те, що я використовую на декількох VM, закриваю вікно, і воно автоматично запускає безпечне відключення. Вимкніть Windows, і в його спробі закрити все, він чекатиме завершення цих процесів.


1

У мене було подібне питання і я знайшов цю сторінку. Я не хочу запускати VirtualBox як сервіс, тому що у мене дуже багато віртуальних машин для тестування, і зазвичай вибираю різні для запуску в інтерфейсі VirtualBox. Коли я вимикаю комп’ютер, прикро вручну зберігати стан кожної машини. Використання скриптів для збереження всіх запущених VM представляється практичним рішенням у цьому випадку. Щоб зробити відповідь Даніеля F більш загальною, я написав ці сценарії, які автоматично зберігають стан усіх запущених VM, не називаючи їх явно.

saveRunningVMs.bat для 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 для 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

Я створив сценарій python, який би призупинив усі запущені віртуальні віртуальні віртуальні віртуальні машини, а потім налаштував систему на запуск сценарію під час виходу як заплановане завдання.

Я не знаю, наскільки надійний цей метод. Як зазначають інші, існують обмеження в тому, як довго система чекатиме завершення завдання Winlogon 7002. Але в мене особисто не виникло жодних проблем з цим наданням зручних станів збереження навіть при декількох запущених VM на 4+ ГБ загальної ОЗУ.

Ось такі кроки для його налаштування:

  1. Завантажте та встановіть Python 2.7.x з python.org
  2. Створіть файл сценарію python десь у вашій системі за допомогою блокнота або будь-якого іншого редактора простого тексту (див. Нижче)
  3. Відкритий планувальник завдань
  4. Виберіть Дія -> Створити основне завдання ... та скористайтеся майстром, щоб створити завдання із наступними налаштуваннями
    • Ім'я на ваш вибір
    • Почніть завдання, коли реєструється конкретна подія
    • Журнал: Система
    • Джерело: Winlogon
    • Ідентифікатор події: 7002
    • Запустіть програму
    • Поруч програму / скрипт , введіть повний шлях до python.exe, наприклад ,c:\Python27\python.exe
    • Поруч із Додати аргументи , введіть повний шлях, куди ви поміщаєте файл сценарію python, наприклад, я помістив mine в підпапку моєї папки документів, так що цеC:\Users\rakslice\Documents\vboxsuspend\vboxsuspend.py
    • Виберіть «Готово».

Тепер віртуальну машину VirtualBox слід призупинити при виході / перезапуску / вимкненні.

Сценарій 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
Пропозиція інших використовувати пакетний скрипт, який ви можете запустити вручну, що робить збереження, а потім зробити вимкнення чудово, якщо це відповідає вашому випадку використання. Але те, що я дуже хочу цього, - це автоматичні перезавантаження Windows Update, після того, як VM, з яким я працював, протягом двох останніх днів поспіль було важко вимкнено, а перезавантаження Windows Update - протягом останніх двох днів поспіль ...
rakslice
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.