Запуск VirtualBox 3.1.2 в отдельной X-сессии в Ubuntu 9.04

Как-то набрёл на хабре на статью "VirtualBox. Удобное переключение между Host и Guest" - там описывался вариант запуска виртуальной машины VirtualBox в Headless-mode и rdesktop-vrdp для неё в отдельной виртуальной консоли с голыми иксами (без DE) для Debian. Работает как "безголовый режим"+rdesktop-vrdp, так и перенаправление "обычной" виртуальной машины на отдельные X-ы. Преимущество метода в независимости от основной (нулевой) X-сессии и использование полноэкранного режима виртуальной машины с достаточно быстрым переключением между Host и Guest, а из недостатков - отсутствие Shared Clipboard и необходимость следить за виртуальной машиной при выключении компьютера (именно выключении, а не рестарте нулевой X-сессии) . На хабре предлагают вариант с запуском виртуальной машины в headless-mode, X-сессии и rdesktop-vrdp посредством дописывания в /etc/rc.local строк

su rigid -c "VBoxHeadless -a 127.0.0.1 -s WinXP" &
X :1 vt08 &
DISPLAY=":1" rdesktop-vrdp -f localhost &

где rigid - имя пользователя, от которого запускается виртуальная машина.

С Ubuntu (Infra-Linux) 9.04 пришлось немного поразвлечься, чтобы получить аналогичный удобоваримый результат - часть мытарств описывал на форуме lafox.net.

В Ubuntu для запуска отдельной X-сессии 8-я виртуальная консоль, как выяснилось по факту, не подходит - занята служебным выводом - использовал 9-ю - переключение по Ctrl+Alt+F9/Ctrl+Alt+F7.

Кроме того, я держу образы дисков виртуальных машин на USB-HDD и использую сетевой мост с виртуальным сетевым адаптером, поднимаемым с помощью того же /etc/rc.local (описывал тут). Так как /etc/rc.local вызывается на всех уровнях инициализации системы, я, соответственно, не могу уверенно использовать рекомендации с хабра для запуска самой виртуальной машины из /etc/rc.local, потому как либо USB-drive не примонтируется, либо сетевой адаптер стартанёт позже виртуальной машины, тем более ещё и этот порядок может смениться с новой версией ядра с новой версией порядка инициализации. Итак, запускать собственно виртуальную машину и rdesktop-vrdp при загрузке я не стал - решил, что это буду делать из нулевой X-сессии или 1-й виртуальной консоли (ежели чего).

Но если просто прописать в /etc/rc.localX :1 vt09 & то получаем, что при загрузке системы попадаем именно в первую, а не нулевую, X-сессию в 9-ю виртуальную консоль - т.е. черный экран и поди пойми, что нужно нажать Ctrl+F7 для попадания в логин-экран (или как там его) - просто 1-я X-сессия запускается позже 0-й. Пришлось разбираться хоть немного с run-level и порядком загрузки Ubuntu.

Для того, чтобы стартануть 1-ю X-сессию раньше 0-й пришлось создать в /etc/init.d скрипт (от root) с именем secondXsession следующего содержания

#!/bin/sh -e
#
# secondXsession
 
X :1 vt09 &
 
exit 0

дать ему права на выполнение (я ставлю птичку в свойствах файла в Nautilus-е, запущенном через sudo) и положить в /etc/rc2.d симлинк на него c именем S29secondXsession (/etc/rc2.dS29secondXsession выполняется ранее /etc/rc2.d/S30gdm, в котором стартует 0-я X-сессия), опять же за root-ом. (Симлинк делаю опять же правым кликом по файлу в Nautilus-е, запущенном через sudo, - создать ссылку; хотя, конечно, никто ln в консоли не отменял).

Для запуска из терминала собственно виртуальной машины в headless-mode и rdesktop-vrdp ранее пришлось установить nohup:

sudo apt-get install nohup

чтобы можно было закрывать терминал, а машина оставалась запущенной.

Позже для запуска кликом по ярлыку написал скрипт с теми же строками запуска

#!/bin/sh -e
#
# FLPC_Headless
 
nohup VBoxHeadless -a 127.0.0.1 -s FLPC 2>&1 > /dev/null &
DISPLAY=":1" nohup rdesktop-vrdp -f localhost 2>&1 > /dev/null &
 
exit 0

где FLPC имя виртуальной машины. Скрипт вызываю кнопкой запуска на Рабочем столе или из консоли.

Далее готовим почву для автоматизации выключения виртуальной машины при выключении Host-а.

Выключить виртуальную машину из 0-й X-сессии можно дав команду

VBoxManage controlvm <vm> poweroff

Однако это долгая процедура, к тому же выбрасывающая нас в конце в 9-ю виртуальную консоль, где нужно ждать порядком 10 секунд до появления голых иксов дабы переключиться обратно в 7-ю. Быстрее - дать команду выключиться с сохранением состояния

VBoxManage controlvm <vm> savestate

- она срабатывает, но, к сожалению, так же выбрасывает в 9-ю виртуальную консоль и приходится опять же ждать, пока проявятся голые первые иксы из которых можно переключиться в 7-ю.

Проблемой оказалось то, что в VirtualBox 3.1.2 виртуальная машина не стартует в headless-mode, если была выключена с сохранением состояния.

И тут при попытке повторного запуска виртуальной машины проявился баг VirtualBox 3.1.2 (якобы искоренённый в версии 3.08): не работает

VBoxManage startvm <vm>

В принципе работает другое:

VirtualBox --startvm <vm>

но так запускается не только виртуальная машина, но и оболочка(окно) запуска, которая не гасится манипуляциями из командной строки с виртуальной машиной. Оказалось, что в экспериментальном порядке разработчиками VirtualBox предлагается ещё один способ запуска виртуальной машины, который всё-таки работает как нам надо

VBoxSDL --startvm <vm>

оформляем это дело скриптом

#!/bin/sh -e
#
# FLPC_Headless
 
DISPLAY=":1" nohup VBoxSDL --startvm FLPC 2>&1 > /dev/null &
 
exit 0

- в его пользу отказываюсь (надеюсь пока) от запуска виртуальной машины в headless-mode. Ну и, соответственно, завёл кнопку запуска.

Для выключения с сохранением намалевал скриптик /etc/init.d/vmsavestate :

#!/bin/sh -e
#
# vmsavestate 
 
su vitaly -c "VBoxManage controlvm FLPC savestate" &
sleep 10
 
exit 0

дал ему права на исполнение и сделал симлинки на него в /etc/rc0.d для shutdown и в /etc/rc6.d для reboot:

sudo ln -s /etc/init.d/vmsavestate /etc/rc0.d/K01vmsavestate
sudo ln -s /etc/init.d/vmsavestate /etc/rc6.d/K01vmsavestate

- идею подсмотрел там. Думаю, что можно как-то анализировать код возврата и тем самым ускорить выключение при отсутствии запущенной виртуальной машины или если машина была запущена и свернулась быстрее 10-и секунд, но пока я этого, к сожалению, не умею.