igor@4: \section{Распределение ресурсов между доменами Xen} igor@0: igor@4: \subsection{Процессор} igor@0: Виртуальные процессоры (VCPU) виртуальных машин автоматически распределяются igor@0: планировщиком между доступными физическими процессорами. igor@0: Назначать соответствие виртуального процесса реальному вручную не нужно. igor@0: Однако, при возникновении такой необходимости, igor@0: можно указать на каком процессоре будет выполняться виртуальный процессор. igor@0: Это делается с помощью команды \textbf{xm vcpu-pin}. igor@0: igor@4: Каждый домен характеризуется двумя числами — \textit{весом} (weight) и \textit{лимитом} (cap). igor@0: igor@0: Домен с весом 512 получает на том же хосте в два раза больше igor@0: процессорного времени чем домен с весом 256. igor@0: Вес может изменяться в диапазоне от 1 до 65535, igor@0: и он равен по умолчанию 256. igor@0: igor@0: Значение лимита (cap) может использоваться для того чтобы указать максимальную величину igor@0: процессорного времени, который может получить домен, даже в случае, если хост-система igor@4: простаивает. Значение выражается в процентах: 100 это 1 физический процессор, 50 это половина процессора, 400 — 4 процессора и т.д. igor@0: Значение по умолчанию равно 0, что означает, что верхнее ограничение отсутствует. igor@0: igor@0: Значения лимита и веса можно просматривать и модифицировать с помощью команд: igor@0: igor@0: \begin{itemize} igor@4: \item \textbf{xm sched-credit -d domain} — показать значение вес (weight) и верх (cap) для домена; igor@4: \item \textbf{xm sched-credit -d domain -w weight} — установить вес равным \textbf{weight}; igor@4: \item \textbf{xm sched-credit -d domain -c cap} — установить верх равным \textbf{cap}. igor@0: \end{itemize} igor@0: igor@4: Для того чтобы эти значения сохранялись и после перезапуска домена, igor@0: их нужно указать в конфигурационном файле igor@0: с помощью параметров: igor@0: \begin{itemize} igor@4: \item \texttt{cpu\_cap} — верх (по умолчанию 0) igor@4: \item \texttt{cpu\_weight} — вес (по умолчанию 256) igor@0: \end{itemize} igor@0: igor@4: \subsection{Оперативная память} igor@4: Объём памяти, выделяемой домену 0, задаётся как параметр \textbf{dom0\_mem} гипервизора Xen. igor@4: В этом случае подразумевается, что объём памяти igor@4: указан в килобайтах. igor@0: igor@4: Пример секции конфигурационного файла \texttt{menu.lst} загрузчика GRUB: igor@4: igor@4: \begin{verbatim} igor@4: title Xen 3.2-1-i386 / Debian GNU/Linux, kernel 2.6.18-4-xen igor@4: root (hd0,0) igor@4: kernel /boot/xen-3.2-1-i386.gz dom0_mem=1200000 igor@4: module /boot/vmlinuz-2.6.18-4-xen-686 root=/dev/sda1 ro console=tty0 igor@4: module /boot/initrd.img-2.6.18-4-xen-686 igor@4: savedefault igor@4: \end{verbatim} igor@4: igor@4: В этом примере домен 0 при старте будет в объёме оперативной igor@4: памяти до 1.2G. igor@4: igor@4: По умолчанию (то есть, если параметр \texttt{dom0\_mem} не указан), igor@4: домен 0 сначала получает весь доступный объём оперативной памяти, igor@4: а потом, по мере необходимости, при старте других доменов, его начинают снижать. igor@4: Это делает специально предназначенный для такой работы balloon-драйвер. igor@4: igor@4: Снижение будет производиться до величины \texttt{dom0-min-mem}, igor@4: заданной в конфигурационном файле \texttt{/etc/xen/xend-config.sxp}. igor@4: Здесь величина памяти указывается в мегабайтах. igor@4: Если в качестве значения указан 0, igor@4: уменьшение памяти домена 0 выполняться не будет. igor@4: igor@4: Пример настройки: igor@4: \begin{verbatim} igor@4: (dom0-min-mem 0) igor@4: \end{verbatim} igor@4: igor@4: Объём памяти, выделяемой остальным доменам (то есть, виртуальным машинам), igor@4: задаётся в их конфигурационных файлах с помощью параметра \texttt{memory}. igor@0: Параметр может быть указан с суффиксом B, K, M или G, что означает байты, килобайты, мегабайты или гигабайты соответственно. igor@4: По умолчанию подразумевается, что в конфигурационном файле домена объём памяти указан в мегабайтах. igor@0: igor@4: Впоследствии этот размер можно изменить прямо для работающего igor@4: домена при помощи команды: igor@0: igor@4: \begin{verbatim} igor@4: xm mem-set igor@4: \end{verbatim} igor@4: igor@4: Подняться выше заданного в конфигурационном файле значения без дополнительных igor@4: хитростей не получится. igor@4: Самая простая хитрость — задавать при старте домена большое значение памяти, igor@4: потом его сразу же снижать, а потом повышать по мере необходимости. igor@4: igor@4: Более правильный способ — использовать параметр конфигурационного файла домена \texttt{maxmem}, igor@4: и передавать ядру гостевой системы (при условии что это Linux) параметр \texttt{mem}: igor@4: igor@4: \begin{verbatim} igor@4: $ grep mem /etc/xen/dhcp igor@4: memory = 128 igor@4: maxmem = 512 igor@4: extra = "mem=512M" igor@4: \end{verbatim} igor@4: igor@4: Система при старте получает 128 MB ОЗУ, igor@4: но она сможет корректно отработать увеличение igor@4: памяти до 512 MB. igor@4: igor@4: \begin{verbatim} igor@4: $ sudo xm create dhcp igor@4: Using config file "/etc/xen/dhcp". igor@4: Started domain dhcp igor@4: $ sudo xm list igor@6: Name ID Mem VCPUs State Time(s) igor@6: Domain-0 0 1171 1 r----- 5274.5 igor@6: dhcp 8 128 1 -b---- 2.8 igor@4: \end{verbatim} igor@4: igor@4: Гостевая операционная система видит 128MB: igor@4: igor@4: \begin{verbatim} igor@4: $ sudo xm console dhcp igor@4: Debian GNU/Linux lenny/sid dhcp tty1 igor@4: dhcp login: root igor@4: Password: igor@4: dhcp:~# free igor@6: total used free shared buffers cached igor@6: Mem: 131220 33132 98088 0 1524 12204 igor@6: -/+ buffers/cache: 19404 111816 igor@6: Swap: 0 0 0 igor@4: \end{verbatim} igor@4: igor@4: Увеличиваем объём доступной домену оперативной памяти: igor@4: igor@4: \begin{verbatim} igor@4: %$ sudo xm mem-set dhcp 256 igor@4: %$ sudo xm list igor@6: Name ID Mem VCPUs State Time(s) igor@6: Domain-0 0 1171 1 r----- 5329.8 igor@6: dhcp 8 256 1 -b---- 2.9 igor@4: \end{verbatim} igor@4: igor@4: Гостевая операционная система теперь видит 256MB: igor@4: igor@4: \begin{verbatim} igor@4: $ sudo xm console dhcp igor@4: dhcp:~# free igor@6: total used free shared buffers cached igor@6: Mem: 262144 33336 228808 0 1620 12228 igor@6: -/+ buffers/cache: 19488 242656 igor@6: Swap: 0 0 0 igor@4: \end{verbatim} igor@4: igor@4: В настоящий момент изменение памяти на лету \textit{НЕ} поддерживает igor@4: ядро Linux, работающее через \textit{pv-ops}. igor@4: Это означает, в частности, что паравиртуальные ядра 2.6.24 и 2.6.25 igor@4: не смогут увидеть изменение памяти в домене. igor@4: igor@4: \subsection{Распределение устройств} igor@4: В режиме нормальной работы Xen-инсталляции все устройства (дисковая подсистема, сетевые адаптеры и проч.) igor@4: видны напрямую только домену 0. igor@4: Гостевые домены могут пользоваться этими устройствами, igor@4: но не напрямую, а только опосредованно, igor@4: при помощи механизмов, предоставляемых доменом 0. igor@4: igor@4: В некоторых случаях, однако, бывает необходимо чтобы гостевой igor@4: домен увидел устройство сам, без посредников. igor@4: Такое, в частности, возможно, когда гостевая система igor@4: должна использовать специфический драйвер для доступа igor@4: к специальным функциям устройства, недоступным через паравиртуальный igor@4: интерфейс. igor@4: igor@4: Для проброса PCI-устройств необходимо чтобы: igor@0: \begin{itemize} igor@4: \item в ядре привилегированного домена (домена 0) присутствовала поддержка PCI backend; igor@4: \item в ядрах, которые будут запускаться в пользовательских доменах и которые собираются использовать PCI-устройства, присутствовала поддержка PCI frontend. igor@4: \end{itemize} igor@4: В XenLinux PCI backend включается в конфигурационной секции Xen, igor@4: а PCI frontend включается в зависимой от архитектуры секции \dq{}Bus Options\dq{}. igor@4: Можно вкомпилировать вместе в одно ядро поддержку backend\rq{}а и поддержку frontend\rq{}а. Они друг другу не мешают. igor@4: Обычно в ядрах, которые входят в состав распространённых дистрибутивов, igor@4: поддержка есть по умолчанию. igor@4: igor@4: PCI-устройство, которое передаётся непривилегированному домену, igor@4: должно быть скрыто от backend-домена (обычно домена 0) — igor@4: не должно так получиться, что домен 0 загрузит случайно драйвер устройства, igor@4: и тот начнём работать с этим устройством. igor@4: igor@4: Для этого нужно указать PCI backend, какое устройство он должен скрыть. igor@4: Он привязывает себя как драйвер к устройству igor@4: и тем самым гарантирует, что никакие другие драйверы устройств к нему не привяжутся. igor@4: То есть, в действительности, устройства не скрываются от домена 0, просто они никак им не используются. igor@4: igor@4: Информация о том, какое устройство должно скрываться, igor@4: передаётся как параметр ядра \texttt{pciback.hide} igor@4: в его командной строке, задающейся через загрузчик. igor@4: PCI-устройства идентифицируются шестнадцатеричными числами слот/функция (slot/function), igor@4: в Linux эти номера можно определить с помощью программы \textbf{lspci}. igor@4: Их можно указывать с информацией о номере домена или без неё: igor@4: igor@4: \begin{verbatim} igor@4: (bus:slot.func) например (02:1d.3) igor@4: (domain:bus:slot.func) например (0000:02:1d.3) igor@4: \end{verbatim} igor@4: igor@4: Пример параметров ядра Linux, скрывающих два PCI-устройства: igor@4: igor@4: \begin{verbatim} igor@4: root=/dev/sda4 ro console=tty0 pciback.hide=(02:01.f)(0000:04:1d.0) igor@4: \end{verbatim} igor@4: igor@4: Устройство можно отобрать у драйвера и скрыть его igor@4: и без перезагрузки: igor@4: igor@4: \begin{verbatim} igor@4: # echo -n 0000:05:02.0 > /sys/bus/pci/drivers/3c905/unbind igor@4: # echo -n 0000:05:02.0 > /sys/bus/pci/drivers/pciback/new_slot igor@4: # echo -n 0000:05:02.0 > /sys/bus/pci/drivers/pciback/bind igor@4: \end{verbatim} igor@4: igor@4: Сначала устройство отвязывается от драйвера, igor@4: который его держит. igor@4: Затем оно привязывается к PCI backend. igor@4: igor@4: Просмотреть к какому устройству привязан какой драйвер igor@4: можно командой: igor@4: igor@4: \begin{verbatim} igor@4: %# ls -l /sys/bus/pci/devices/*/driver igor@4: \end{verbatim} igor@4: igor@4: После того как устройство освобождено от домена 0, igor@4: его можно передавать внутрь гостевого домена. igor@4: Для того чтобы передать устройство внутрь домена, igor@4: в его конфигурационном файле нужно указать строку: igor@4: igor@4: \begin{verbatim} igor@4: pci=['05:02.0'] igor@4: \end{verbatim} igor@4: igor@4: Когда гостевой домен будет запущен, igor@4: проверить видит ли он проброшенное внутрь устройство, igor@4: можно командой: igor@4: igor@4: \begin{verbatim} igor@4: %# lspci igor@4: \end{verbatim} igor@4: igor@4: \subsection{Дополнительная информация} igor@4: \begin{itemize} igor@4: \item \htmladdnormallinkfoot{Распределение ресурсов между доменами Xen}{http://xgu.ru/wiki/xen/resources} (рус.) igor@0: \end{itemize} igor@0: