Virtualbox Windows изящное отключение гостей при отключении хоста


19

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

Кажется, что наиболее безопасным вариантом будет запуск команды «сохранить состояние», когда хост начинает отключаться, но неясно, будет ли хост ждать достаточно долго, чтобы виртуальные машины завершили сохранение состояния и отключили питание.

У кого-нибудь есть надежное решение этой (казалось бы, базовой) проблемы?


Установить гостевые дополнения? Разве это не обеспечивает требуемую функциональность?
Канадец Люк восстановит Монику

@CanadianLuke Это не так. :)
Мэтт Дженкинс

Ответы:


6

У меня была похожая проблема, и я решил ее, запустив VirtualBox как сервис:

http://vboxvmservice.sourceforge.net/

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


Процесс настройки не очень автоматический в Windows 10. Я должен обратиться к устранению неисправностей, чтобы увидеть, что не так. Однако после правильной настройки это программное обеспечение делает именно то, что мне нужно. Спасибо за отличную работу.
Иурадз

3

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

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

VirtualBox 5.0 вводит режим запуска «отсоединяемый пользовательский интерфейс» . Этот режим запускает безголовую виртуальную машину с отдельным процессом пользовательского интерфейса. Графическая производительность страдает, а 3D-ускорение пока не поддерживается. Но, возможно, это может быть объединено с VBoxHeadlessTray в будущем (VBoxHeadlessTray пока не поддерживает 5.0). Ссылки на репозиторий VBoxHeadlessTray GitHub и на соответствующий запрос GitHub для добавления поддержки VirtualBox 5 .

Изменить: VBoxVmService также не поддерживает новый режим отсоединения начиная с версии 5.0. Пока только без головы . Я добавил запрос функции для этого.


Поскольку мне не разрешено портировать более двух ссылок на пост, вот ссылки на VBoxHeadlessTray и на соответствующий запрос GitHub для добавления поддержки VirtualBox 5.
Лев B

Я не испытываю проблем, изложенных в теме. Смотрите мой ответ по этой теме. Я могу запустить выключение хоста Windows и уйти. Завершение работы блокируется до тех пор, пока все мои виртуальные машины не будут закрыты, и я изменил действие по умолчанию, чтобы выполнить чистое завершение работы или состояние сохранения.
Крис Бансен,

2

У меня есть 3 пакетных сценария, которые я использую вместо кнопок питания в стартовом меню.

do_shutdown.bat (выключение компьютера с 10- секундным периодом ожидания, чтобы не дать виртуальному виртуальному компьютеру 10-секундное время для сохранения, но чтобы я мог отменить выключение в течение 10 секунд. Обратный отсчет начинается после того, как виртуальный компьютер был выключен)

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

do_reboot.bat (перезагружается сразу после закрытия виртуальной машины )

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

do_cancel.bat (позволяет мне отменить выключение компьютера в течение 10 секунд ожидания. Затем он снова перезапускает виртуальные машины, так как они были закрыты с помощью 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/… Я использую его для очень короткой команды при завершении работы (один вызов curl), поэтому я не знаю, как она себя ведет на сценарии, которые требуют времени для завершения.
Даниэль Ф

2

Извините, я опоздал на вечеринку. Существует точный ответ на это, хотя для этого требуется некоторая командная строка-foo. См. Эту ветку сообщений для получения дополнительной информации: https://forums.virtualbox.org/viewtopic.php?f=6&t=53684#p285540

Команда, которую вы ищете:

"C: \ Program Files \ Oracle \ VirtualBox \ VBoxManage.exe" setextradata "ИМЯ Виртуальной машины" GUI / DefaultCloseAction Завершение работы

Это то, что я использую на нескольких виртуальных машинах, закройте окно, и оно автоматически начнет безопасное отключение. Завершите работу Windows и при попытке закрыть все будет ждать завершения этих процессов.


1

У меня был похожий вопрос и я нашел эту страницу. Я не хочу запускать VirtualBox как сервис, потому что у меня много виртуальных машин для тестирования, и я обычно выбираю разные для запуска в пользовательском интерфейсе VirtualBox. Когда я выключаю свой компьютер, раздражает ручное сохранение состояния каждой виртуальной машины. Использование сценариев для сохранения всех работающих виртуальных машин представляется в этом случае практическим решением. Чтобы сделать ответ Даниэля Ф. более общим, я написал эти сценарии, которые автоматически сохраняют состояние всех работающих виртуальных машин, не называя их явно.

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, который приостановил бы все работающие виртуальные машины VirtualBox, а затем настроил систему для запуска сценария при выходе из системы в качестве запланированной задачи.

Я не знаю, насколько надежен этот метод. Как уже отмечали другие, существуют ограничения на то, как долго система будет ждать завершения задачи Winlogon 7002. Но лично у меня не было никаких проблем с предоставлением пригодных для сохранения состояний даже с несколькими запущенными виртуальными машинами на 4+ ГБ общей виртуальной памяти.

Вот шаги, чтобы настроить это:

  1. Загрузите и установите Python 2.7.x с python.org
  2. Создайте файл скрипта Python где-нибудь в вашей системе, используя Блокнот или любой другой текстовый редактор (см. Ниже)
  3. Открыть планировщик задач
  4. Выберите «Действие» -> «Создать базовую задачу» и с помощью мастера создайте задачу со следующими настройками.
    • Имя по вашему выбору
    • Запустите задачу, когда определенное событие зарегистрировано
    • Журнал: Система
    • Источник: Winlogon
    • Код события: 7002
    • Начать программу
    • Рядом с Program / Script , введите полный путь к вашему python.exe, напримерc:\Python27\python.exe
    • Рядом с полем Добавить аргументы введите полный путь к файлу скрипта Python, например, я помещаю свой в подпапку папки с документами, так что это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, после того, как виртуальная машина, с которой я работал, была отключена через ночь при перезапуске Центра обновления Windows в течение последних двух дней подряд ...
rakslice
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.