В данном вопросе всё было бы исключительно позитивно, если бы не вполне обычная для свободного ПО проблема: разработка данной ветки GRUB уже как несколько лет полностью остановлена в пользу GRUB2, а сообщество разработчиков Xen, судя по всему, в ближайшие годы основанной на актуальной версии GRUB замены PV загрузчику предоставить не готово. Сам PV-GRUB, несмотря на то, что является, в общем-то, частью официального дистрибутива Xen, в настоящее время уже исключён как минимум из соответствующих пакетов в репозиториях Debian и Ubuntu, а пользователи, привыкшие к удобствам, между тем требуют (Debian bug #588839: Include pv-grub to securely boot guest kernels) и требуют (Ubuntu bug #798583: xen-utils-4.1 does not have pvgrub)… Хотя лично для меня не очень понятна мотивация мейнтейнеров Xen пакетов, ссылающихся на некие невнятные проблемы с зависимостями, в то время как пакеты с GRUB 0.97 всё ещё доступны и работоспособны, да и к существующему функционалу претензий нет.
Здесь я постараюсь описать, пожалуй, наиболее приемлемое в настоящий момент решение насущной проблемы — самостоятельную сборку PV-GRUB и необходимую настройку DomU для его использования, благо никаких сверхъестественных усилий для этого не требуется.
Для заинтересованных в понимании подноготной реализации для паравиртуальной среды Xen почти традиционного загрузчика будет уместно сразу подбросить некоторых материалов про появившийся ещё в Xen 3.3 функционал stub domains. Краткое введение есть в блоге Xen.org (Xen 3.3 Feature: Stub Domains, Xen 3.3 Feature: HVM Device Model Domain). В остальном стоит полистать презентацию (PDF) и послушать доклад «Stub domains: A step towards Dom0 disaggregation», представленный на Xen Summit North America.
Для сборки загрузчика понадобится исходный код Xen. Лучше всего взять ту версию, которая уже применяется на вашей хост-системе. Поскольку я использую Debian GNU/Linux «Wheezy», для меня это будет Xen 4.1.4. Собирать можно на любой системе с минимальным девелоперским набором (gcc+binutils+make). С официального сайта Xen (Xen 4.1 series, Xen 4.2 series) скачиваем и распаковываем tarball с исходниками:
$ wget http://bits.xensource.com/oss-xen/release/4.1.4/xen-4.1.4.tar.gz $ tar xzf xen-4.1.4.tar.gz
Переходим в директорию stubdom
. Запускаем сборку загрузчика:
$ make grub
Если необходимо собрать загрузчик под архитектуру, отличную от системной, то её можно задать через переменную XEN_TARGET_ARCH:
$ XEN_TARGET_ARCH=x86_32 make grub
В процессе не обходится и без некоторых подводных камней. Сборка данного компонента останавливается на банальных ошибках включения некоторых заголовочных файлов по несуществующим путям.
In file included from xc_core.c:69:0: xc_core.h:26:35: fatal error: xen/libelf/elfstructs.h: Нет такого файла или каталога compilation terminated.
Ищем виновника:
$ find .. -type f -name xc_core.h ../tools/libxc/xc_core.h
Заменяем в нём строку
#include "xen/libelf/elfstructs.h"
на
#include "xen/elfstructs.h"
При повторном выполнении make grub
следует ещё несколько подобных:
xc_dom.h:17:31: fatal error: xen/libelf/libelf.h: Нет такого файла или каталога xc_hvm_build.c:34:31: fatal error: xen/libelf/libelf.h: Нет такого файла или каталога ../../xen/common/libelf/libelf-private.h:70:31: fatal error: xen/libelf/libelf.h: Нет такого файла или каталога
Все решаются заменой
#include <xen/libelf/libelf.h>
на
#include <xen/libelf.h>
Теперь сборка должна завершиться успешно. Последние строки вывода, которые вы скорее всего увидите, будут:
gzip -f -9 -c /home/user/xen-4.1.4/stubdom/mini-os-x86_64-grub/mini-os >/home/user/xen-4.1.4/stubdom/mini-os-x86_64-grub/mini-os.gz make[1]: Leaving directory `/home/user/xen-4.1.4/extras/mini-os'
Полученный уже сжатый файл mini-os-x86_64-grub/mini-os.gz
пожно переименовать в более понятное pv-grub-x86_64.gz
(или pv-grub-x86_32.gz
если собирали под x86_32), а затем положить в директорию /usr/lib/xen-4.1/boot
вашего Dom0, где ему самое место (справедливо для Debian при установленном пакете xen-utils-4.1, там же находится hvmloader
).
Перед непосредственным переключением на использование загрузчика стоит проделать некоторые подготовительные процедуры для вашей гостевой системы.
Стоит отметить, что старый GRUB непосредственным образом не дружит с современными файловыми системами вроде Ext4, не говоря уже о менее распространённых. Поэтому предварительно стоит убедиться, что раздел, где у вас будет размещаться образ ядра, initrd и конфигурационные файлы GRUB (по умолчанию всё хранится в директории /boot
), будет доступен загрузчику для чтения. Я в процессе прохождения описываемого здесь квеста уже наступил на грабли: несмотря на теоретически существующую обратную совместимость Ext4 с Ext2, существует немало различных расширений (features), которые эту совместимость полностью исключают, особенно если при создании вашего Ext4 раздела вы специально об этом не задумывались. Прежде создавать отдельный раздел под /boot
у меня не возникало особой необходимости. Сейчас же решением может быть как раз вынос вышеотмеченной стартовой троицы на микро-раздел (думаю, двойного объёма от текущего содержимого /boot
будет вполне достаточно), отформатированный в Ext2. Не забудьте также отредактировать /etc/fstab
вашего DomU, добавив туда /boot
раздел и изменив наименования блочных устройств остальных разделов, если это необходимо. Это же касается и конфигурации дисков самой виртуальной машины.
Проверить насколько существующий раздел годится для монтирования в режиме обратной совместимости с Ext2 можно элементарно через mount -t ext2
.
На самой виртуальной машине необходимо установить старую версию GRUB (пакет grub-legacy в Debian или максимально кастрированный grub-legacy-ec2 в Ubuntu). На запросы об установке GRUB в загрузочный сектор какого-либо раздела стоит отвечать отрицательно — это не имеет смысла.
После установки убедимся, что директория для хранения конфигурации GRUB существует и доступна для записи. Запуск update-grub
создаст файл меню загрузчика, добавив в список загрузки установленные в системе ядра.
$ mkdir /boot/grub $ update-grub Searching for GRUB installation directory ... found: /boot/grub Probing devices to guess BIOS drives. This may take a long time. Searching for default file ... Generating /boot/grub/default file and setting the default boot entry to 0 Searching for GRUB installation directory ... found: /boot/grub Testing for an existing GRUB menu.lst file ... Generating /boot/grub/menu.lst Searching for splash image ... none found, skipping ... Found kernel: /vmlinuz-3.2.0-4-amd64 Updating /boot/grub/menu.lst ... done
Заглянем в созданный /boot/grub/menu.lst
:
title Debian GNU/Linux, kernel 3.2.0-4-amd64 root (/dev/xvda1) kernel /vmlinuz-3.2.0-4-amd64 root=UUID=f5731cf7-420a-4094-acf7-bec5976a0b62 ro initrd /initrd.img-3.2.0-4-amd64 title Debian GNU/Linux, kernel 3.2.0-4-amd64 (single-user mode) root (/dev/xvda1) kernel /vmlinuz-3.2.0-4-amd64 root=UUID=f5731cf7-420a-4094-acf7-bec5976a0b62 ro single initrd /initrd.img-3.2.0-4-amd64
Здесь бросается в глаза, что конфигуратор неверно заполнил опцию root
, подставив вместо понятного GRUB обозначения диска и раздела имя файла блочного устройства. При выборе данных пунктов меню GRUB попросту будет ругаться на неверное значение опции.
Чтобы исправить ситуацию, немного модифицируем сгенерированный /boot/grub/menu.lst
добавив опцию groot
с явным указанием порядкового номера загрузочного «диска», который впоследствие монтируется как /boot
(поскольку полноценных дисков с таблицей разделов в паравиртуальной среде не существует):
groot=(hd0)
Тут же можно уменьшить таймаут перед началом загрузки, чтобы не тратить время понапрасну:
## timeout sec # Set a timeout, in SEC seconds, before automatically booting the default entry # (normally the first entry defined). timeout 1
Чтобы значение groot
корректно воспринималось генератором конфигурации update-grub
, дополнительно создадим файл /boot/grub/device.map
, куда впишем единственную строку, касающуюся упомянутого загрузочного раздела:
(hd0) /dev/xvda1
Теперь update-grub
должен сгенерировать корректный файл меню, работоспособность которого к тому же не будет нарушена, если вы захотите обновить версию основного ядра или добавить дополнительные.
title Debian GNU/Linux, kernel 3.2.0-4-amd64 root (hd0) kernel /vmlinuz-3.2.0-4-amd64 root=UUID=f5731cf7-420a-4094-acf7-bec5976a0b62 ro initrd /initrd.img-3.2.0-4-amd64 title Debian GNU/Linux, kernel 3.2.0-4-amd64 (single-user mode) root (hd0) kernel /vmlinuz-3.2.0-4-amd64 root=UUID=f5731cf7-420a-4094-acf7-bec5976a0b62 ro single initrd /initrd.img-3.2.0-4-amd64
Если необходимо передавать ядру какие-либо дополнительные параметры, которые прежде задавались непосредственно в конфигурации виртуальной машины через опцию extra
, то это можно сделать путём модификации kopt
в том же /boot/grub/menu.lst
.
В качестве финального аккорда остаётся переконфигурировать процесс запуска DomU: имя файла загрузчика необходимо указать в опции kernel
. Если образ загрузчика лежит в директории по умолчанию (там же, где и hvmloader
), то полный путь указывать не обязательно. В опции extra
указывается раздел и путь к файлу меню GRUB.
kernel = 'pv-grub-x86_64.gz' extra = '(hd0)/grub/menu.lst'
От прежних опций ramdisk
и root
необходимо избавиться.
Чтобы убедиться в полной работоспособности новой конфигурации, первый запуск DomU стоит производить в режиме автоподключения к консоли (xm start -c
). Если всё проделано верно, то вы увидите меню GRUB и последующий процесс загрузки ядра с монтированием корневого раздела.
ссылка на оригинал статьи http://habrahabr.ru/post/178581/
Добавить комментарий