Я использую Windows 7 в Virtualbox на Ubuntu 11.10. Все отлично работает Я запускаю его при запуске, но у меня проблема с перезагрузкой.
Когда я набираю sudo reboot now
, состояние виртуальной Windows 7 не сохраняется. После перезагрузки запускается виртуальная коробка, но вместо работающей Windows я получаю меню аварийной загрузки Windows 7, и окна снова загружаются.
Есть ли возможность, что Ubuntu может послать некоторый сигнал в виртуальный ящик, чтобы безопасно закрыть экземпляр перед перезагрузкой хоста?
В случае, если действительно необходимо завершить работу, в то время как виртуальная машина в Виртуальном Поле работает, Вы могли определить свой собственный сценарий для ручного завершения работы, куда Вы помещаете команду для сохранения состояния машины, прежде чем процесс завершения работы запустится:
VBoxManage controlvm <name> savestate # <name> is the name of your VM
gnome-session-quit --power-off # this example displays the power-off dialog for >11.10
Кроме того, Вы могли также генерировать сценарий, который всегда работает на завершении работы.
Следуйте этому ответу, чтобы изменить системную политику для перезагрузки
Вы не можете упростить это в reboot
. Сценарии AFAIK init.d
не будут работать, потому что это занимает слишком много времени, но вы можете выполнить команду следующим образом:
VBoxManage controlvm <vm> savestate&&reboot
где <vm>
- имя виртуальной машины
Если вы используете sudo reboot
, программы получают сигнал уничтожения, завершающий их автоматически, не давая приложению времени действовать в такой ситуации. Это не ошибка, она всегда работала одинаково, и это ожидаемое поведение.
Существует аналогичный вопрос, где вы можете увидеть, какие команды выдаются при нажатии кнопки shutdown
, reboot
, suspend
и т. Д. В пользовательском меню, такое решение должно спрашивать вас, что делать при попытке закройте окно с запущенным приложением и его предпочтительным (в вашем случае) подходом sudo shutdown
. Посмотрите
Я рекомендовал бы более сложный подход включая новомодное задание, запуск и сценарий остановки. Как пример я использую Windows XP, поскольку мой корневой каталог позволяет использованию tombert..., который необходимо изменить соответственно. Это имеет преимущество того, что Вы делаете (перезагрузка, завершение работы, нажимая кнопку питания), это обрабатывает Вашу виртуальную машину приятно.
Сначала новомодное задание, помещенное в/etc/init/winxpvm.conf:
description "WinXP VirtualBox job"
author "Thomas Perschak"
## 0: system halt
## 1: single-user mode
## 2: graphical multi-user plus networking
## 6: system reboot
start on started rc RUNLEVEL=[2]
stop on starting rc RUNLEVEL=[!2]
## upstart config
kill timeout 120
kill signal SIGCONT
nice -10
## start WinXP VirtualBox
exec /home/tombert/scripts/winxpvm-start.sh
## stop WinXP VirtualBox
pre-stop exec /home/tombert/scripts/winxpvm-stop.sh
Новомодное задание запускает виртуальную машину в runlevel 2 (который находится в графическом режиме), и в моем случае это увеличивает приоритет с nice
. Для хорошего завершения работу виртуальной машины, я должен "отключить" новомодное завершение с помощью kill signal SIGCONT
оператор. Это оставляет виртуальную машину, работающую сначала (избегающий значения по умолчанию SIGTERM
). После 120 секунд SIGKILL
отправляют во всяком случае. Вместо этого я работаю winxpvm-stop.sh
сценарий.
Заметка на полях 1: строки файла конфигурации start on started runlevel [2]
и stop on starting runlevel [!2]
не работать. Нужно конкретно упомянуть задание rc
.
Заметка на полях 2: Что сбивает с толку также из новомодного руководства: kill signal
строка файла конфигурации указывает сигнал, отправленный после 5 секунд. В этом примере я установил его от SIGTERM
(значение по умолчанию) к SIGCONT - но тайм-аут этих 5 секунд я не мог измениться. kill timeout
строка файла конфигурации указывает тайм-аут после который SIGKILL
отправляется - которые сигнализируют, что нельзя измениться. Улучшение поэтому должно было бы определить новые строки файла конфигурации term signal
и term timeout
.
Здесь сценарий запуска winxpvm-start.sh:
#! /bin/bash -e
function dostart()
{
echo -n "Running WinXP ... "
vboxheadless --startvm WinXP
echo "now closed"
}
export -f dostart
if [ $(whoami) != "tombert" ]; then
su -c dostart tombert
else
dostart
fi
Так как все настройки и т.д. сделаны в непривилегированном режиме (поскольку мой вход в систему является tombert), даже когда выполнено как корень, я изменяю учетную запись на tombert. Пользователь, конечно, мог быть изменен в новомодной конфигурации, но это решение оставляет меня опцией запустить/остановить виртуальную машину "вручную" с консоли.
Более интересным является сценарий завершения работы в winxpvm-stop.sh:
#! /bin/bash
function dostop()
{
## check if WinXP is running
vboxmanage showvminfo WinXP --machinereadable | grep -q 'VMState="running"' &> /dev/null
if [ $? -ne 0 ]; then
echo "WinXP not running"
exit
fi
## try gracefully shutdown
echo -n "Shutting down WinXP ... "
#vboxmanage controlvm WinXP acpipowerbutton
vboxmanage guestcontrol WinXP execute --image "%SystemRoot%\system32\shutdown.exe" --username tombert --password <mypassword> --wait-exit -- "-s" "-f" "-t" "0" &> /dev/null
## check vm status
INDEX=60
while [ $INDEX -gt 0 ]; do
echo -n "$INDEX "
vboxmanage showvminfo WinXP --machinereadable | grep -q 'VMState="running"' &> /dev/null
if [ $? -ne 0 ]; then
echo "gracefully done"
break
fi
sleep 1
let INDEX+=-1
done
## close forcefully
if [ $INDEX -eq 0 ]; then
vboxmanage controlvm WinXP poweroff &> /dev/null
echo "forcefully done"
fi
}
export -f dostop
if [ $(whoami) != "tombert" ]; then
su -c dostop tombert
else
dostop
fi
Сначала я делаю то же как в сценарии запуска - я изменяю пользователя от корня до моей учетной записи tombert. Теперь позволяет взгляду на функцию dostop
. Сначала я проверяю, работает ли виртуальная машина даже. Затем я пытаюсь "мягко" завершить работу путем отправки завершения работы непосредственно в использование WinXP guestcontrol
. Здесь необходимо обеспечить учетные данные для учетной записи WinXP, которая в моем случае является tombert и паролем. Windows shutdown
корректно закроет все приложения и выключать операционную систему (обычно). Затем позволяет, проверяют состояние виртуальной машины непрерывно использование showvminfo
. Выполнение этого по крайней мере 60 раз с 1 вторым тайм-аутом (делают то, что Вы думаете appropiate, здесь), должен оставить виртуальную машину достаточным количеством времени для завершения работу корректно. Обратите внимание что вызов к showvminfo
также берет немного меньше, чем секунда (по крайней мере, на моем компьютере), таким образом, это дает ему ~120 секунд в моем случае. Если все тормозит, мы можем сильно завершить работу использования poweroff
оператор.
Также необходимо видеть acpipowerbutton
, но неиспользованный. Это вызвано тем, что это не работает надежное. Если Вы будете зарегистрированы на Windows или еще худших многочисленных пользователях, то Windows покажет, что подтверждение завершает работу диалогового окна, препятствующего системе завершение работы. Это - также причина почему acpibutton
в /etc/default/virtualbox
не будет работать надежных 100%. Также poweroff
сильно завершит работу виртуальной машины - то же как кнопка питания длинного нажатия. Поэтому лучше устанавливать это для освобождения:
Выборка от/etc/default/virtualbox:
# SHUTDOWN_USERS="foo bar"
# check for running VMs of user 'foo' and user 'bar'
# 'all' checks for all active users
# SHUTDOWN=poweroff
# SHUTDOWN=acpibutton
# SHUTDOWN=savestate
# select one of these shutdown methods for running VMs
# acpibutton and savestate causes the init script to wait
# 30 seconds for the VMs to shutdown
SHUTDOWN_USERS=""
SHUTDOWN=""
Для создания этого прекрасным, Вы могли бы хотеть изменить поведение кнопки питания:
Выборка от/etc/acpi/powerbtn.sh:
#!/bin/sh
# /etc/acpi/powerbtn.sh
# Initiates a shutdown when the power putton has been
# pressed.
# @backup
# plain shutdown
/sbin/shutdown -h now "Power button pressed"
# fini
exit 0
...
...
Существует тот мало оставленного недостатка. Когда виртуальная машина все еще загружается, и гостевая контрольная служба не (в виртуальной машине), она не получит команду завершения работы. Редкий случай..., но думает об этом.
Вот именно надежда это помогает.
Вы можете отправить запрос на завершение работы виртуальной машине с помощью:
VBoxManage controlvm <vm_name> acpipowerbutton
Но если вы сделаете это в сценарии инициализации, сценарий не должен завершиться до завершения выключения. Мы можем обнаружить это путем опроса файла диска виртуальной машины (.vdi) с lsof
или fuser
в цикле. Или в качестве дешевого обходного пути, sleep 20
может быть достаточно.
Вот что я сейчас использую в блоке закрытия моего скрипта инициализации:
# This always returns 0, even if an error is displayed!
su - "$DAEMONUSER" VBoxManage controlvm "$VMNAME" acpipowerbutton
# Wait until the disk file is no longer open...
for attempt in `seq 1 20`
do
fuser "$VMDISKIMAGE" >/dev/null 2>&1 || break
sleep 2
done
return 0 # A better script would return success/fail
В верхней части файла, который я определил:
VMDISKIMAGE="/home/$DAEMONUSER/VirtualBox VMs/$VMNAME/$VMNAME.vdi"
На самом деле это может и не быть. закройте само приложение VirtualBox, но оно ожидает завершения работы виртуальной машины. Также это не работает, если виртуальная машина все еще находится в процессе загрузки (многие операционные системы игнорируют кнопку выключения питания на этом этапе), или если вы эмулируете старую систему без поддержки ACPI.