Сборка Xen 4.2 в Debian Wheezy и проброс устройств в гипервизор Xen
Прочитав однажды пост про успешный проброс видеокарты в виртуальную машину я подумал, что неплохо бы мне завести себе такую рабочую станцию.
При разработке кроссплатформенного программного обеспечения часто возникают проблемы с его тестированием. Всю свою работу я выполняю исключительно под Linux’ом, при этом конечный пользователь работает исключительно в операционной системе (ОС) Windows. Можно было бы использовать VirtualBox, например, но когда нужно проверить работу модулей использующих OpenGL или CUDA возникают серьёзные проблемы. Dual Boot как вариант даже не рассматриваю. Получается, что, так или иначе, мне приходиться использовать второй компьютер, который просто не куда поставить. При этом большую часть времени он простаивает без дела. Получается крайне не эффективная, с точки зрения использования ресурсов, схема.
Однажды моя мечта превратилась в крайнюю необходимость. Необходимо было собрать графическую станцию со следующими характеристиками:
- Операционная система Windows 7 (далее Windows);
- Набор программного обеспечения использующего DirectX, OpenGL и CUDA;
- Высокоскоростное, локальное, отказоустойчивое хранилище размером порядка 10 Тб;
- Механизм резервного копирования и восстановления всей системы;
- Периодическое автоматическое резервное копирование пользовательских данных.
Многие могут подумать: «Причём же тут виртуализация?». Проблема в том, что Windows, по моему личному мнению, не отличается высокой надёжностью. Зачастую конечными пользователями системы являются не особо квалифицированные люди, в следствии чего на компьютер попадает зловредное ПО, которое может уничтожить все данные на всех накопителях. При этом необходимо чтобы бэкап хранился локально, но уничтожить его было не возможно. Организация большого и быстрого хранилища данных так же не является тривиальной задачей. Так или иначе, было решено запускать Windows в среде виртуальной машины (ВМ).
Я прочитал множество статей и документации (в том числе на хабре [1] [2][3]) о пробросе видеокарт в среду ВМ. Вывод к которому я пришёл был не утешительным для меня. Большинство успешных пробросов осуществлялись с видеокартами ATI. Бробросить видеокарту NVIDIA возможно, но далеко не каждую. При этом требуется патчить гипервизор [4] [5].
Из-за необходимости использования технологии CUDA мне необходимо было пробросить именно видеокарту NVIDIA. Существует технология NVIDIA Multi-OS, которая позволяет пробрасывать видеокарты в ВМ. Поддерживают эту технологию только ускорители из серии Quadro.
Ещё одним недостатком большинства видеокарт является их ширина в два слота минимум. Зачастую это неприемлемо и именно поэтому была выбрана однослотовая видеокарта NVIDIA Quadro 4000. Она является самым мощном представителем семейства Quadro среди однослотовых вариантов.
Ключевые элементы системы:
- Материнская плата ASUS P9X79 WS;
- Процессор Core i7-3820;
- Оперативная память 32 ГиБ (4-е планки по 8 ГиБ);
- Видеокарта для dom0 (не важно какая);
- Видеокарта для domU NVIDIA Quadro 4000.
Изначально я хотел реализовать задуманное с использованием гипервизора Xen. В качестве ОС для dom0 я выбрал Debian GNU/Linux wheezy (далее Debian). В ядре Linux имеется отличная реализация программных RAID-массивов.
В ходе экспериментов я пробовал KVM. Он отлично справлялся с любыми устройствами кроме видеокарты. К сожалению с Xen 4.1, входящим в состав распространённых дистрибутивов, у меня тоже ни чего не вышло. В среде виртуальной машины видеокарта упорно отказывалась стартовать.
К счастью не за долго до того как я начал заниматься данной проблемой в свет вышел Xen 4.2.0. Доступен он, естественно, только в виде исходных кодов.
Чтобы не было проблем с отключением необходимых для пробрасывания устройств от dom0 необходимо чтобы драйвер xen-pciback был включён в состав ядра. В диструбутивах Debian он поставляется в виде модуля.
Таким образом, необходимо было собрать гипервизор и ядро.
Установка Debian
При установке Debian я не делал ничего необычного. Устанавливал только базовую систему. Графическое окружение устанавливать не стоит, поскольку вместе с ним ставится множество программного обеспечения часть которого будет конфликтовать с собранным Xen.
По окончании базовой установки произвел установку минимального набора необходимого программного обеспечения.
$ sudo apt-get install gnome-core gvncviewer mc
Сборка гипервизора и ядра
Чтобы не засорять боевую систему, сборку я выполнял в специально установленной под VirtualBox’ом чистой ОС.
Чтобы собрать Xen необходимо выполнить ряд незамысловатых команд.
$ sudo apt-get build-dep xen $ sudo apt-get install libglib2.0-dev libyajl-dev fakeroot bison flex libbz2-dev liblzo2-dev $ sudo apt-get install python-headers bin86 bcc iasl uuid-dev $ wget http://bits.xensource.com/oss-xen/release/4.2.0/xen-4.2.0.tar.gz $ tar xf xen-4.2.0.tar.gz $ cd xen-4.2.0 $ ./configure --enable-githttp $ echo "PYTHON_PREFIX_ARG=--install-layout=deb" > .config $ make deb
На выходе получил пакет xen-upstream-4.2.0.deb.
UPD: Для сборки XEN>=4.2.2 дополнительно необходимы следующие зависимости
# apt-get install build-essential # apt-get install bcc bin86 gawk bridge-utils iproute libcurl3 libcurl4-openssl-dev bzip2 module-init-tools transfig tgif # apt-get install texinfo texlive-latex-base texlive-latex-recommended texlive-fonts-extra texlive-fonts-recommended pciutils-dev mercurial # apt-get install make gcc libc6-dev zlib1g-dev python python-dev python-twisted libncurses5-dev patch libvncserver-dev libsdl-dev libjpeg62-dev # apt-get install iasl libbz2-dev e2fslibs-dev git-core uuid-dev ocaml ocaml-findlib libx11-dev bison flex xz-utils libyajl-dev # apt-get install gettext
Сборка ядра производилась из-за необходимости включения драйвера xen-pciback в состав ядра. Процесс сборки хорошо описан в официальной документации по Debian.
$ sudo apt-get install linux-source $ sudo apt-get build-dep linux-latest $ sudo apt-get install kernel-package fakeroot $ tar xf /usr/src/linux-source-3.2.tar.bz2 $ cd linux-source-3.2 $ cp /boot/config-`uname -r` .config $ sed -i 's/CONFIG_XEN_PCIDEV_BACKEND=.*$/CONFIG_XEN_PCIDEV_BACKEND=y/g' .config $ make-kpkg clean $ fakeroot make-kpkg --initrd --revision=1.0.0 kernel_image
На выходе получил linux-image-3.2.32_1.0.0_amd64.deb.
Установка ядра и гипервизора
Полученные пакеты я установил на целевую систему. При устанавке Xen в директории /boot создаются ненужные символьные ссылки, которые необходимо удалить. Поскольку в собранном пакете xen-upstream-4.2.0.deb не прописаны зависимости, пакеты необходимые для работы Xen требуется устанавливать в ручную.
$ sudo dpkg -i linux-image-3.2.32_1.0.0_amd64.deb $ sudo dpkg -i xen-upstream-4.2.0.deb $ sudo su -c "cd /boot; rm xen.gz xen-4.gz xen-4.2.gz xen-syms-4.2.0" $ sudo apt-get install libyajl2 liblzo2-2 libaio1
Делаем Xen загружаемым по умолчанию.
$ sudo dpkg-divert --divert /etc/grub.d/08_linux_xen --rename /etc/grub.d/20_linux_xen
Регистрируем службы Xen в системе.
$ sudo update-rc.d xend start 99 2 3 5 stop 99 0 1 6 $ sudo update-rc.d xencommons start 99 2 3 5 stop 99 0 1 6 $ sudo update-rc.d xendomains start 99 2 3 5 stop 99 0 1 6 $ sudo update-rc.d xen-watchdog start 99 2 3 5 stop 99 0 1 6
Чтобы скрыть необходимые для пробрасывания устройства от dom0 драйверу xen-pciback необходимо подать их список. Чтобы отключить Memory Ballooning необходимо заранее указать объём памяти требуемый для dom0. Для этого в /etc/default/grub необходимо добавить 2 строчки.
GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT="xen-pciback.hide=(02:00.0)(02:00.1) (00:1a.0)(00:1d.0)(09:00.0)(0a:00.0)(0b:00.0)(03:00.0)(00:1b.0)" GRUB_CMDLINE_XEN_DEFAULT="dom0_mem=15360M"
Помимо видеокарты было проброшено 4 USB-контроллера, сетевая и звуковая карты и ещё ряд периферии.
После этого необходимо обновить конфигурационный файл загрузчика GRUB.
$ sudo update-grub
Поскольку материнская плата ASUS P9X79 WS имеет два сетевых интерфейса было решено не делать ни каких сетевых мостов. dom0 и domU будут иметь независимые сетевые подключения.
Следующая последовательность команд устанавливает минимальный объём памяти для dom0 (тем самым окончательно отключается Memory Ballooning) и отключает ненужные сетевые скрипты. Так же я сделал VNC доступным по любому IP-адресу.
$ sudo sed -i 's/^XENDOMAINS_SAVE=.*$/XENDOMAINS_SAVE=""/g' /etc/default/xendomains $ cd /etc/xen $ sudo sed -i 's/^.*.(dom0-min-mem.*)$/(dom0-min-mem 15360)/g' xend-config.sxp $ sudo sed -i 's/^.*.(enable-dom0-ballooning.*)$/(enable-dom0-ballooning no)/g' xend-config.sxp $ sudo sed -i 's/^(network-script.*)$/#&/g' xend-config.sxp $ sudo sed -i 's/^(vif-script.*)$/#&/g' xend-config.sxp $ sudo sed -i "s/^.*.(vnc-listen.*)$/(vnc-listen '0.0.0.0')/g" xend-config.sxp
Установка Windows
Не буду подробно останавливаться на вопросе установки ОС Windows в среду ВМ. Скажу лишь, что установку необходимо производить удалённо с использованием VNC. NVIDIA Quadro начинает работать только после установки драйверов. Стартует она только при окончательной загрузке ОС. Так же были успешно установлены паравиртуальные драйвера (upd: репозитарий).
Среди сетевых устройств имеется VirtualBox Host-Only Ethernet Adapter. Дело в том, что я установил VirtualBox в среде ВМ (внутри domU). Внутрь была установлена ОС Windows XP. Даже при двойной вложенности внутрь ВМ ОС Windows XP работала с приемлемым быстродействием.
Конфигурационный файл домена
builder = "hvm" memory = 16384 vcpus = 8 name = "windows-7" uuid = "830460b8-3541-11e2-8560-5404a63ce590" disk = ['phy:/dev/storage/windows-7,hda,w'] boot = 'c' pci = ['02:00.0','02:00.1','00:1a.0','00:1d.0', '09:00.0','0a:00.0','0b:00.0','03:00.0','00:1b.0'] gfx_passthru = 0 pae = 1 nx = 1 videoram = 16 stdvga = 1 vnc = 1 usb = 1 usbdevice = "tablet" localtime = 1 xen_platform_pci = 1
Результаты тестирования
Сразу оговорюсь, что Windows на голое железо устанавливать даже не пытался, поэтому объективно мне сравнивать не с чем. Вся оценка свелась к просмотру Windows Experience Index (WEI) и установке 3DMark 2011. То есть, если быть честным, то тестирования быстродействия как такового не проводил.
WEI определяется результатом теста с наихудшим результатом. В моём случае узким местом был «жёсткий диск». Дело в том, что все эксперименты я проводил с использованием одно единственного старенького винчестера. В остальном же результаты весьма не плохие.
Видеокарту NVIDIA Quadro 4000 нельзя назвать игровой, но Crysis работал шустро.
Замечания по поводу Xen
Начиная с версии 4.1 в Xen пришёл инструментарий xl. Ему не требуется xend и в перспективе он должен заменить xm.
При работе в ручную xl никаких нареканий не вызвал. Однако скрипт xendomains явно не рассчитан на работу с ним. При запуске /etc/init.d/xendomains start домены domU запускались без проблем. Однако при вызове /etc/init.d/xendomains stop не происходило, ровным счётом, ничего. Работа domU автоматически не завершалась в следствии чего вся система зависала. В ходе небольшого расследования выяснилось, что часть функций внутри xendomains просто не адаптированы для работы с xl. С этими проблемами, в принципе, я готов был справится.
Самым страшным было то, что при запуске domU xl выдавал ошибку о том, что не может сбросить PCI устройство, а именно видеокарту, через sysfs. Для видеокарты файл reset в sysfs просто отсутствует. Я не уверен полностью, но мне кажется, что именно из-за этого после перезагрузки domU видекарта часто отказывалась стартовать. Помогала только перезагрузка всей системы.
libxl: error: libxl_pci.c:1001:libxl__device_pci_reset: The kernel doesn't support reset from sysfs for PCI device 0000:02:00.0 libxl: error: libxl_pci.c:1001:libxl__device_pci_reset: The kernel doesn't support reset from sysfs for PCI device 0000:02:00.1
В xm сброс PCI устройств, по всей видимости, реализован иначе. По крайней мере, при работе с ним проблем с видеокартой не было ни разу. Именно поэтому я остановился пока на xm.
Заключение
На осуществление всего описанного мне понадобилось 5 дней. В целом система работала очень стабильно. Никаких BSOD и зависаний не наблюдалось. Надеюсь, что в ближайшем будущем все без исключения видеокарты будут пригодны для пробрасывания в ВМ, поскольку NVIDIA Quadro нельзя назвать бюджетным вариантом.