---
description: 'Программное обеспечение виртуализации позволяет нескольким операционным системам работать одновременно на одном компьютере'
next: books/handbook/l10n
params:
  path: /books/handbook/virtualization/
part: 'Часть III. Администрирование системы'
prev: books/handbook/filesystems
showBookMenu: 'true'
tags: ["virtualization", "Parallels", "VMware", "VirtualBox", "QEMU", "bhyve", "XEN"]
title: 'Глава 24. Виртуализация'
weight: 28
---

[[virtualization]]
= Виртуализация
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 24
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/handbook/virtualization/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[[virtualization-synopsis]]
== Обзор

Программное обеспечение виртуализации позволяет нескольким операционным системам работать одновременно на одном компьютере. Такие программные системы для ПК часто включают основную операционную систему, которая запускает ПО виртуализации и поддерживает произвольное количество гостевых операционных систем.

Прочитайте эту главу, чтобы узнать:

* Разница между основной операционной системой и гостевой операционной системой.
* Как установить FreeBSD на следующие платформы виртуализации:
** Parallels Desktop(Apple(R) macOS(R))
** VMware Fusion(Apple(R) macOS(R))
** VirtualBox(TM)(Microsoft(R) Windows(R), Apple(R) macOS(R) на базе Intel(R), Linux)
** QEMU(FreeBSD)
** bhyve(FreeBSD)
* Как настроить систему FreeBSD для достижения наилучшей производительности при виртуализации.

Прежде чем читать эту главу, необходимо:

* Понимать crossref:basics[basics,основы UNIX(R) и FreeBSD].
* Знать, как crossref:bsdinstall[bsdinstall,установить FreeBSD].
* Уметь настраивать сетевое соединение, как описано в crossref:advanced-networking[advanced-networking,разделе по расширенной настройке сети].
* Знать, как crossref:ports[ports,установить дополнительное стороннее программное обеспечение].

[[virtualization-guest-parallelsdesktop]]
== FreeBSD в качестве гостевой системы в Parallels Desktop для macOS(R)

Parallels Desktop for Mac(R) - это коммерческий программный продукт, доступный для компьютеров Apple(R) Mac(R) под управлением macOS(R) 10.14.6 или новее. FreeBSD является полностью поддерживаемой гостевой операционной системой. После установки Parallels на macOS(R) пользователь должен настроить виртуальную машину и затем установить желаемую гостевую операционную систему.

[[virtualization-guest-parallelsdesktop-install]]
=== Установка FreeBSD на Parallels Desktop на Mac(R)

Первым шагом при установке FreeBSD на Parallels является создание новой виртуальной машины для установки FreeBSD.

Выберите menu:Установка Windows или другой ОС с DVD или файла образа[] и продолжите.

image::parallels-freebsd1.png["Мастер настройки Parallels с выбранным пунктом \"Установить Windows или другую ОС с DVD или из файла образа\""]

Выберите файл образа FreeBSD.

image::parallels-freebsd2.png["Мастер настройки Parallels с выбранным образом FreeBSD"]

Выберите menu:Другое в качестве операционной системы[].

[WARNING]
====
Выбор FreeBSD приведет к ошибке загрузки при запуске.
====

image::parallels-freebsd3.png["Мастер настройки Parallels, показывающий \"Другое как операционной система\""]

Назовите виртуальную машину и отметьте пункт menu:Настроить параметры перед установкой (Customize settings before installation)[]

image::parallels-freebsd4.png["Мастер настройки Parallels с отмеченным флажком для настройки параметров перед установкой"]

Когда появится окно конфигурации, перейдите на вкладку menu:Hardware[], выберите menu:Boot order[] и нажмите menu:Advanced[]. Затем выберите *EFI 64-bit* в качестве menu:BIOS[].

image::parallels-freebsd5.png["Мастер настройки Parallels с выбранным EFI 64-bit в качестве BIOS"]

Нажмите menu:OK[], закройте окно конфигурации и нажмите menu:Continue[].

image::parallels-freebsd6.png["Мастер настройки Parallels, отображающий сводную информацию о новой виртуальной машине"]

Виртуальная машина автоматически загрузится. Установите FreeBSD, следуя общим шагам.

image::parallels-freebsd7.png["FreeBSD загружена в Parallels"]

[[virtualization-guest-parallels-configure]]
=== Настройка FreeBSD на Parallels

После успешной установки FreeBSD на macOS(R) X с использованием Parallels, можно выполнить ряд шагов по настройке для оптимизации системы в виртуальной среде.

[.procedure]
. Установка переменных загрузчика
+
Самый важный шаг — уменьшить параметр `kern.hz`, чтобы снизить использование CPU FreeBSD в среде Parallels. Это достигается добавлением следующей строки в [.filename]#/boot/loader.conf#:
+
[.programlisting]
....
kern.hz=100
....
+
Без этой настройки бездействующая гостевая система FreeBSD в Parallels будет использовать около 15% процессора однопроцессорного iMac(R). После внесения изменений использование снизится до примерно 5%.
+
Если установлена FreeBSD 14.0 или более поздняя версия, а использование ЦП по-прежнему высокое, добавьте следующую строку в [.filename]#/boot/loader.conf#:
+
[.programlisting]
....
debug.acpi.disabled="ged"
....
. Создание нового файла конфигурации ядра
+
Все драйверы SCSI, FireWire и USB могут быть удалены из конфигурационного файла собственного ядра. Parallels предоставляет виртуальный сетевой адаптер, используемый драйвером man:ed[4], поэтому все сетевые устройства, кроме man:ed[4] и man:miibus[4], могут быть удалены из ядра.
. Настройка сети
+
Самая базовая настройка сети использует DHCP для подключения виртуальной машины к той же локальной сети, что и хост-компьютер Mac(R). Это можно сделать, добавив `ifconfig_ed0="DHCP"` в [.filename]#/etc/rc.conf#. Более сложные настройки сети описаны в crossref:advanced-networking[advanced-networking,Расширенная настройка сети].

[[virtualization-guest-vmware]]
== FreeBSD в качестве гостевой системы на VMware Fusion для macOS(R)

VMware Fusion для Mac(R) — это коммерческий программный продукт, доступный для компьютеров Apple(R) Mac(R) под управлением macOS(R) 12 или новее. FreeBSD является полностью поддерживаемой гостевой операционной системой. После установки VMware Fusion на macOS(R) пользователь может настроить виртуальную машину и установить желаемую гостевую операционную систему.

[[virtualization-guest-vmware-install]]
=== Установка FreeBSD на VMware Fusion

Первым шагом является запуск VMware Fusion, который загрузит библиотеку виртуальных машин. Нажмите [.guimenuitem]#+->Создать#, чтобы создать виртуальную машину:

image::vmware-freebsd01.png[]

Это запустит Мастер создания новой виртуальной машины. Выберите [.guimenuitem]#Создать пользовательскую виртуальную машину# и нажмите [.guimenuitem]#Продолжить#, чтобы продолжить:

image::vmware-freebsd02.png[]

Выберите [.guimenuitem]#Другое# в качестве [.guimenuitem]#Операционной системы# и либо [.guimenuitem]#FreeBSD X#, либо [.guimenuitem]#FreeBSD X 64-bit# в качестве menu:Версия[] при запросе:

image::vmware-freebsd03.png[]

Выберите прошивку (рекомендуется UEFI):

image::vmware-freebsd04.png[]

Выберите [.guimenuitem]#Создать новый виртуальный диск# и нажмите [.guimenuitem]#Продолжить#:

image::vmware-freebsd05.png[]

Проверьте конфигурацию и нажмите [.guimenuitem]#Завершить#:

image::vmware-freebsd06.png[]

Выберите имя виртуальной машины и каталог, в котором она будет сохранена:

image::vmware-freebsd07.png[]

Нажмите command+E, чтобы открыть настройки виртуальной машины, и выберите [.guimenuitem]#CD/DVD#:

image::vmware-freebsd08.png[]

Выберите образ FreeBSD в формате ISO или с CD/DVD:

image::vmware-freebsd09.png[]

Запустите виртуальную машину:

image::vmware-freebsd10.png[]

Установите FreeBSD как обычно:

image::vmware-freebsd11.png[]

После завершения установки можно изменить параметры виртуальной машины, такие как использование памяти и количество процессоров, доступных виртуальной машине:

[NOTE]
====
Настройки аппаратного обеспечения системы виртуальной машины нельзя изменить во время её работы.
====

image::vmware-freebsd12.png[]

Состояние устройства CD-ROM. Обычно CD/DVD/ISO отключается от виртуальной машины, когда в нём больше нет необходимости.

image::vmware-freebsd09.png[]

Последнее, что нужно изменить, — это способ подключения виртуальной машины к сети. Чтобы разрешить подключения к виртуальной машине с других машин, кроме хоста, выберите [.guimenuitem]#Подключиться напрямую к физической сети (Bridged)#. В противном случае предпочтительнее выбрать [.guimenuitem]#Использовать интернет-подключение хоста (NAT)#, чтобы виртуальная машина имела доступ в Интернет, но сеть не могла получить доступ к виртуальной машине.

image::vmware-freebsd13.png[]

После изменения настроек загрузите новую виртуальную машину с установленной FreeBSD.

[[virtualization-guest-vmware-configure]]
=== Настройка FreeBSD на VMware Fusion

После успешной установки FreeBSD на macOS(R) X с использованием VMware Fusion можно выполнить ряд шагов по настройке для оптимизации системы в виртуальной среде.

[.procedure]
. Установка переменных загрузчика
+
Самый важный шаг — уменьшить параметр `kern.hz`, чтобы снизить использование CPU FreeBSD в среде VMware Fusion. Это достигается добавлением следующей строки в [.filename]#/boot/loader.conf#:
+
[.programlisting]
....
kern.hz=100
....
+
Без этой настройки бездействующая гостевая система FreeBSD в VMware Fusion будет использовать около 15% процессора однопроцессорного iMac(R). После внесения изменений использование снизится до примерно 5%.
. Создание нового файла конфигурации ядра
+
Все драйверы устройств FireWire и USB могут быть удалены из файла конфигурации собственного ядра. VMware Fusion предоставляет виртуальный сетевой адаптер, используемый драйвером man:em[4], поэтому все сетевые устройства, кроме man:em[4], могут быть удалены из ядра.
. Настройка сети
+
Самая базовая настройка сети использует DHCP для подключения виртуальной машины к той же локальной сети, что и хост-компьютер Mac(R). Это можно сделать, добавив `ifconfig_em0="DHCP"` в [.filename]#/etc/rc.conf#. Более сложные настройки сети описаны в crossref:advanced-networking[advanced-networking,Сложные вопросы работы в сети].
+
. Установите драйверы и open-vm-tools
+
Для бесперебойной работы FreeBSD на VMWare необходимо установить драйверы:
+
[source, shell]
....
# pkg install xf86-video-vmware xf86-input-vmmouse open-vm-tools
....

[NOTE]
====
Пакеты xf86 доступны только для гостевых систем FreeBSD на архитектуре x86.
====

[.procedure]
====
.Включение мыши
+
Некоторые пользователи сообщали о проблемах с использованием мыши в виртуальной машине. Мышь можно включить, добавив следующее в [.filename]#/boot/loader.conf#:
+
[.programlisting]
....
# ums_load=“YES”
....
====

[[virtualization-guest-virtualbox]]
== FreeBSD в качестве гостевой системы в VirtualBox(TM)

FreeBSD хорошо работает в качестве гостевой системы в VirtualBox(TM). Это программное обеспечение виртуализации доступно для большинства распространённых операционных систем, включая саму FreeBSD.

Дополнения гостевой ОС VirtualBox(TM) обеспечивают поддержку:

* Общий буфер обмена.
* Интеграция указателя мыши.
* Синхронизация времени хоста.
* Масштабирование окна.
* Бесшовный режим.

[NOTE]
====
Эти команды выполняются в гостевой системе FreeBSD.
====

Сначала установите пакет или порт package:emulators/virtualbox-ose-additions[]` в гостевой системе FreeBSD. Это установит порт:

[source, shell]
....
# cd /usr/ports/emulators/virtualbox-ose-additions && make install clean
....

Добавьте следующие строки в файл [.filename]#/etc/rc.conf#:

[.programlisting]
....
vboxguest_enable="YES"
vboxservice_enable="YES"
....

Если используется man:ntpd[8] или man:ntpdate[8], отключите синхронизацию времени хоста:

[.programlisting]
....
vboxservice_flags="--disable-timesync"
....

Xorg автоматически распознает драйвер `vboxvideo`. Его также можно вручную добавить в [.filename]#/etc/X11/xorg.conf#:

[.programlisting]
....
Section "Device"
	Identifier "Card0"
	Driver "vboxvideo"
	VendorName "InnoTek Systemberatung GmbH"
	BoardName "VirtualBox Graphics Adapter"
EndSection
....

Чтобы использовать драйвер `vboxmouse`, измените раздел мыши в [.filename]#/etc/X11/xorg.conf#:

[.programlisting]
....
Section "InputDevice"
	Identifier "Mouse0"
	Driver "vboxmouse"
EndSection
....

Общие папки для передачи файлов между хостом и виртуальной машиной доступны путем их монтирования с помощью `mount_vboxvfs`. Общую папку можно создать на хосте через графический интерфейс VirtualBox или с помощью `vboxmanage`. Например, чтобы создать общую папку с именем _myshare_ в [.filename]#/mnt/bsdboxshare# для виртуальной машины с именем _BSDBox_, выполните:

[source, shell]
....
# vboxmanage sharedfolder add 'BSDBox' --name myshare --hostpath /mnt/bsdboxshare
....

Обратите внимание, что имя общей папки не должно содержать пробелов. Подключите общую папку из гостевой системы следующим образом:

[source, shell]
....
# mount_vboxvfs -w myshare /mnt
....

[[virtualization-host-virtualbox]]
== FreeBSD в качестве хоста с VirtualBox(TM)

VirtualBox(TM) — это активно развивающийся комплексный пакет виртуализации, доступный для большинства операционных систем, включая Windows(R), macOS(R), Linux(R) и FreeBSD. Он одинаково хорошо подходит для запуска гостевых систем Windows(R) или UNIX(R)-подобных ОС. Программа распространяется как открытое программное обеспечение, но с проприетарными компонентами, доступными в отдельном пакете расширений. Эти компоненты включают поддержку устройств USB 2.0. Дополнительную информацию можно найти на http://www.virtualbox.org/wiki/Downloads[странице загрузок вики VirtualBox(TM)]. В настоящее время эти расширения недоступны для FreeBSD.

[[virtualization-virtualbox-install]]
=== Установка VirtualBox(TM)

VirtualBox(TM) доступен в FreeBSD как пакет или порт в package:emulators/virtualbox-ose[]. Порт можно установить с помощью следующих команд:

[source, shell]
....
# cd /usr/ports/emulators/virtualbox-ose
# make install clean
....

Одна полезная опция в меню настройки порта — набор программ `GuestAdditions`. Они предоставляют ряд полезных функций в гостевых операционных системах, таких как интеграция указателя мыши (позволяя использовать мышь совместно между хостом и гостем без необходимости нажатия специальной комбинации клавиш для переключения) и ускоренный рендеринг видео, особенно в гостевых системах Windows(R). Гостевые дополнения доступны в меню menu:Devices[] после завершения установки гостевой системы.

Для начала работы с VirtualBox(TM) необходимо внести несколько изменений в конфигурацию. Порт устанавливает модуль ядра в [.filename]#/boot/modules#, который должен быть загружен в работающее ядро:

[source, shell]
....
# kldload vboxdrv
....

Чтобы модуль всегда загружался после перезагрузки, добавьте эту строку в [.filename]#/boot/loader.conf#:

[.programlisting]
....
vboxdrv_load="YES"
....

Для использования модулей ядра, которые позволяют организовать мостовую или гостевую сеть, добавьте следующую строку в [.filename]#/etc/rc.conf# и перезагрузите компьютер:

[.programlisting]
....
vboxnet_enable="YES"
....

Группа `vboxusers` создается во время установки VirtualBox(TM). Все пользователи, которым необходим доступ к VirtualBox(TM), должны быть добавлены в эту группу. Для добавления новых участников можно использовать `pw`:

[source, shell]
....
# pw groupmod vboxusers -m username
....

Настройки прав доступа по умолчанию для [.filename]#/dev/vboxnetctl# являются ограничительными и требуют изменения для работы мостового соединения:

[source, shell]
....
# chown root:vboxusers /dev/vboxnetctl
# chmod 0660 /dev/vboxnetctl
....

Чтобы сделать это изменение прав постоянным, добавьте следующие строки в [.filename]#/etc/devfs.conf#:

[.programlisting]
....
own     vboxnetctl root:vboxusers
perm    vboxnetctl 0660
....

Для запуска VirtualBox(TM) введите в сеансе Xorg:

[source, shell]
....
% VirtualBox
....

Для получения дополнительной информации о настройке и использовании VirtualBox(TM) обратитесь к http://www.virtualbox.org[официальному сайту]. Информация, относящаяся к FreeBSD, и инструкции по устранению проблем доступны на http://wiki.FreeBSD.org/VirtualBox[соответствующей странице wiki FreeBSD].

[[virtualization-virtualbox-usb-support]]
=== Поддержка USB в VirtualBox(TM)

В VirtualBox(TM) можно настроить передачу USB-устройств в гостевую операционную систему. Хост-контроллер версии OSE ограничен эмуляцией USB 1.1 устройств до тех пор, пока расширение, поддерживающее USB 2.0 и 3.0 устройства, не станет доступным в FreeBSD.

Чтобы VirtualBox(TM) мог обнаруживать USB-устройства, подключённые к машине, пользователь должен быть членом группы `operator`.

[source, shell]
....
# pw groupmod operator -m username
....

Затем добавьте следующее в [.filename]#/etc/devfs.rules# или создайте этот файл, если он ещё не существует:

[.programlisting]
....
[system=10]
add path 'usb/*' mode 0660 group operator
....

Чтобы загрузить эти новые правила, добавьте следующее в [.filename]#/etc/rc.conf#:

[.programlisting]
....
devfs_system_ruleset="system"
....

Затем перезапустите devfs:

[source, shell]
....
# service devfs restart
....

Перезапустите сеанс входа и VirtualBox(TM), чтобы изменения вступили в силу, и при необходимости создайте фильтры USB.

[[virtualization-virtualbox-host-dvd-cd-access]]
=== Виртуальный DVD/CD-доступ хоста VirtualBox(TM)

Доступ к DVD/CD-приводам хоста из гостевых систем обеспечивается путем совместного использования физических приводов. В VirtualBox(TM) это настраивается в окне `Хранилище` (Storage) в настройках (Settings) виртуальной машины. При необходимости сначала создайте пустое устройство IDECD/DVD. Затем выберите `Привод хоста` (Host drive) из всплывающего меню для выбора виртуального привода CD/DVD. Появится флажок с меткой `Сквозной доступ` (Passthrough). Это позволяет виртуальной машине использовать оборудование напрямую. Например, аудио-CD или записывающее устройство будут работать только при выборе этой опции.

Для того чтобы пользователи могли использовать функции VirtualBox(TM) для работы с DVD/CD, им необходим доступ к [.filename]#/dev/xpt0#, [.filename]#/dev/cdN# и [.filename]#/dev/passN#. Обычно это достигается путем добавления пользователя в группу `operator`. Права доступа к этим устройствам можно настроить, добавив следующие строки в [.filename]#/etc/devfs.conf#:

[.programlisting]
....
perm cd* 0660
perm xpt0 0660
perm pass* 0660
....

[source, shell]
....
# service devfs restart
....

[[qemu-virtualization-host-guest]]
== Виртуализация с QEMU на FreeBSD

link:https://www.qemu.org[QEMU] — это универсальный эмулятор и виртуализатор машин, представляющий собой полностью открытое программное обеспечение. Он разрабатывается большим активным сообществом и поддерживает FreeBSD, OpenBSD, NetBSD, а также другие операционные системы.

link:https://www.qemu.org/docs/master/[Документация QEMU]:

* QEMU можно использовать несколькими способами. Наиболее распространённый — это эмуляция системы, при которой предоставляется виртуальная модель всей машины (процессор, память и эмулируемые устройства) для запуска гостевой ОС. В этом режиме процессор может быть полностью эмулирован или работать с гипервизором, таким как `KVM`, `Xen` или `Hypervisor.Framework`, что позволяет гостевой системе выполняться непосредственно на процессоре хоста.

* Второй поддерживаемый способ использования QEMU — это эмуляция пользовательского режима, при которой QEMU может запускать процессы, скомпилированные для одного ЦП, на другом ЦП. В этом режиме ЦП всегда эмулируется.

* QEMU также предоставляет ряд автономных утилит командной строки, таких как утилита для работы с образами дисков man:qemu-img[1], которая позволяет создавать, преобразовывать и изменять образы дисков.

QEMU может эмулировать широкий спектр архитектур, включая `Arm(TM)`, `i386`, `x86_64`, `MIPS(TM)`, `s390X`, `SPARC(TM)` (Sparc(TM) и Sparc64(TM)), и другие. Список link:https://www.qemu.org/docs/master/system/targets.html#system-targets-ref[целевых систем QEMU System Emulator] регулярно обновляется.

Этот раздел описывает, как использовать QEMU для системной эмуляции и эмуляции пользовательского режима в FreeBSD, а также содержит примеры использования команд QEMU и утилит командной строки.

[[qemu-installing-qemu-software]]
=== Установка программы QEMU
QEMU доступен в виде пакета FreeBSD или порта в package:emulators/qemu[]. Сборка пакета включает разумные опции и настройки по умолчанию для большинства пользователей и является рекомендуемым способом установки.

[source, shell]
....
# pkg install qemu
....

Установка пакета включает несколько зависимостей. После завершения установки создайте ссылку на основную версию QEMU для хоста, которая будет использоваться чаще всего. Если хост — 64-битная система Intel(TM) или AMD(TM), это будет:

[source, shell]
....
# ln -s /usr/local/bin/qemu-system-x86_64 /usr/local/bin/qemu
....

Протестируйте установку, выполнив следующую команду от имени непривилегированного пользователя:

[source, shell]
....
% qemu
....
Открывается окно, в котором QEMU активно пытается загрузиться с жёсткого диска, дискеты, DVD/CD и PXE. Пока ничего не настроено, поэтому команда выдаст несколько ошибок и завершится сообщением «No bootable device» (Нет загрузочного устройства), как показано на crossref:virtualization[qemu-nullboot,рисунке {counter:figure}]. Тем не менее, это подтверждает, что ПО QEMU установлено корректно.

[[qemu-nullboot]]
.QEMU без загрузочного образа
image::qemu-freebsd01.png["QEMU без загрузочного образа"]

[[qemu-virtual-machine-install]]
=== Установка виртуальной машины

[NOTE]
====
QEMU находится в стадии активной разработки. Возможности и параметры команд могут меняться от одной версии к другой. В этом разделе приведены примеры, разработанные с использованием QEMU версии 9.0.1 (лето 2024 года). В случае сомнений всегда обращайтесь к link:https://www.qemu.org/docs/master/[документации QEMU], особенно к странице link:https://www.qemu.org/docs/master/about/index.html[О QEMU], где содержатся ссылки на поддерживаемые платформы сборки, эмуляцию, устаревшие и удалённые возможности.
====

Выполните следующие шаги, чтобы создать две виртуальные машины с именами `*left*` и `*right*`. Большинство команд можно выполнять без привилегий root.

. Создайте тестовую среду для работы с QEMU:
+
[source, shell]
....
% mkdir -p ~/QEMU  ~/QEMU/SCRIPTS  ~/QEMU/ISO  ~/QEMU/VM
....
+
Каталог [.filename]#SCRIPTS# предназначен для стартовых скриптов и утилит. Каталог [.filename]#ISO# содержит загрузочные ISO-образы для гостевых систем. В каталоге [.filename]#VM# хранятся образы виртуальных машин (`ВМ`).

. Скачайте свежую копию FreeBSD в [.filename]#~/QEMU/ISO#:
+
[source, shell]
....
% cd ~/QEMU/ISO
% fetch https://download.freebsd.org/releases/ISO-IMAGES/14.1/FreeBSD-14.1-RELEASE-amd64-bootonly.iso
....
+
После завершения загрузки создайте сокращенную ссылку. Эта сокращенная ссылка используется в скриптах запуска ниже.
+
[source, shell]
....
% ln -s FreeBSD-14.1-RELEASE-amd64-bootonly.iso  fbsd.iso
....
. Перейдите в каталог для виртуальных машин ([.filename]#~/QEMU/VM#). Запустите man:qemu-img[1] для создания образов дисков виртуальной машины "left":
+
[source, shell]
....
% cd ~/QEMU/VM
% qemu-img create -f raw  left.img   15G
....
+
Формат `raw` в QEMU предназначен для обеспечения высокой производительности. Этот формат прост и не имеет накладных расходов, что делает его быстрее, особенно в сценариях с высокой производительностью или высокой пропускной способностью. Он используется в случаях, когда требуется максимальная производительность, а дополнительные функции, такие как снимки состояния, не нужны. Этот формат используется в скрипте для виртуальной машины "left", приведённой ниже.
+
Отдельным форматом является `qcow2`, который использует технологию QEMU "копирования при записи" для управления дисковым пространством. Эта технология не требует полного диска размером 15G, а лишь заготовку, которой напрямую управляет виртуальная машина. Диск растёт динамически по мере записи данных виртуальной машиной. Этот формат поддерживает снимки состояния, сжатие и шифрование. Его применение целесообразно в разработке, тестировании и сценариях, требующих этих расширенных возможностей. Данный формат используется в скрипте для виртуальной машины "right" ниже.
+
Снова выполните man:qemu-img[1], чтобы создать образ диска для ВМ "right", используя `qcow2`:
+
[source, shell]
....
% qemu-img create -f qcow2 -o preallocation=full,cluster_size=512K,lazy_refcounts=on right.qcow2 20G
....
+
Чтобы увидеть фактический размер файла, используйте:
+
[source, shell]
....
% du -Ah right.qcow2
....
+
. Настройте сеть для обеих виртуальных машин с помощью следующих команд. В этом примере сетевой интерфейс хоста — `em0`. При необходимости измените его в соответствии с интерфейсом вашей системы. Это необходимо выполнять после каждой перезагрузки хоста, чтобы обеспечить возможность обмена данными для гостевых QEMU ВМ.
+
[source, shell]
....
# ifconfig tap0 create
# ifconfig tap1 create
# sysctl net.link.tap.up_on_open=1
net.link.tap.up_on_open: 0 -> 1
# sysctl net.link.tap.user_open=1
net.link.tap.user_open: 0 -> 1
# ifconfig bridge0 create
# ifconfig bridge0 addm tap0 addm tap1 addm em0
# ifconfig bridge0 up
....
+
Приведенные выше команды создают два устройства man:tap[4] (`tap0`, `tap1`) и одно устройство man:if_bridge[4] (`bridge0`). Затем они добавляют устройства `tap` и интерфейс локального хоста (`em0`) в `bridge`, а также устанавливают две записи man:sysctl[8], чтобы разрешить обычным пользователям открывать устройство tap. Эти команды позволят виртуальным машинам взаимодействовать с сетевым стеком на хосте.
+
. Перейдите в [.filename]#~/QEMU/SCRIPTS# и используйте следующий скрипт для запуска первой виртуальной машины — "left". Этот скрипт использует диск QEMU в формате raw.
+
[.programlisting]
....
/usr/local/bin/qemu-system-x86_64  -monitor none \
  -cpu qemu64 \
  -vga std \
  -m 4096 \
  -smp 4   \
  -cdrom ../ISO/fbsd.iso \
  -boot order=cd,menu=on \
  -blockdev driver=file,aio=threads,node-name=imgleft,filename=../VM/left.img \
  -blockdev driver=raw,node-name=drive0,file=imgleft \
  -device virtio-blk-pci,drive=drive0,bootindex=1  \
  -netdev tap,id=nd0,ifname=tap0,script=no,downscript=no,br=bridge0 \
  -device e1000,netdev=nd0,mac=02:20:6c:65:66:74 \
  -name \"left\"
....

[TIP]
====
Сохраните приведённый выше код в файл (например, `left.sh`) и просто выполните: `/bin/sh left.sh`
====

QEMU запустит виртуальную машину в отдельном окне и загрузит FreeBSD iso, как показано на crossref:virtualization[qemu-newboot-loader-menu,рисунке {counter:figure}]. Все параметры команд, такие как `-cpu` и `-boot`, полностью описаны в man-странице QEMU man:qemu[1].

[[qemu-newboot-loader-menu]]
.Меню загрузчика FreeBSD
image::qemu-freebsd02.png["Меню загрузчика FreeBSD."]

[TIP]
====
Если в окне консоли QEMU кликнуть мышкой , QEMU «захватит» мышь, как показано в crossref:virtualization[qemu-grab,Рисунок {counter:figure}]. Нажмите kbd:[Ctrl]+kbd:[Alt]+kbd:[G], чтобы освободить мышь.
====

[[qemu-grab]]
.Когда QEMU захватил мышь
image::qemu-freebsd03.png["Когда QEMU захватит мышь"]

[NOTE]
====
На FreeBSD первоначальная установка QEMU может быть несколько медленной. Это происходит потому, что эмулятор записывает форматирование файловой системы и метаданные при первом использовании диска. Последующие операции, как правило, выполняются значительно быстрее.
====

Во время установки следует обратить внимание на несколько моментов:

* Выберите использование UFS в качестве файловой системы. ZFS работает неэффективно при небольшом объеме памяти.
* Для использования сети настройте DHCP. При необходимости настройте IPv6, если он поддерживается локальной сетью.
* При добавлении пользователя по умолчанию убедитесь, что он является членом группы *wheel*.

После завершения установки виртуальная машина перезагружается в только что установленный образ FreeBSD.

Войдите как `root` и обновите систему следующим образом:

[source, shell]
....
# freebsd-update fetch install
# reboot
....

[NOTE]
====
После успешной установки QEMU загрузит операционную систему, установленную на диске, а не программу установки.
====

[NOTE]
====
QEMU поддерживает параметр ```-runas```. Для повышения безопасности добавьте параметр "-runas user_name" в приведённый выше скрипт. Подробности см. в man:qemu[1].
====

Войдите снова как `root` и добавьте любые необходимые пакеты. Чтобы использовать систему X Window в гостевой системе, см. раздел «Использование системы X Window» ниже.

Завершена настройка виртуальной машины "left".

Для установки виртуальной машины "right" выполните следующий скрипт. Этот скрипт содержит необходимые изменения для tap1, format=qcow2, имени файла образа, MAC-адреса и названия окна терминала. При желании можно добавить параметр "-runas", как описано в примечании выше.

[.programlisting]
....

/usr/local/bin/qemu-system-x86_64  -monitor none \
  -cpu qemu64 \
  -vga cirrus \
  -m 4096  -smp 4   \
  -cdrom ../ISO/fbsd.iso \
  -boot order=cd,menu=on \
  -drive if=none,id=drive0,cache=writeback,aio=threads,format=qcow2,discard=unmap,file=../VM/right.qcow2 \
  -device virtio-blk-pci,drive=drive0,bootindex=1  \
  -netdev tap,id=nd0,ifname=tap1,script=no,downscript=no,br=bridge0 \
  -device e1000,netdev=nd0,mac=02:72:69:67:68:74 \
  -name \"right\"
....

После завершения установки обе машины "left" и "right" могут взаимодействовать друг с другом и с хостом. Если на хосте действуют строгие правила брендмауэра, рассмотрите возможность добавления или изменения правил для разрешения взаимодействия между мостом (bridge) и устройствами tap.

[[qemu-usage-tips]]
=== Советы по использованию
[[qemu-setting-up-x-windows]]
==== Использование системы X Window

crossref:x11[x-install,Установка Xorg] описывает, как настроить систему `X Window`. Обратитесь к этому руководству для первоначальной настройки `X Window`, затем ознакомьтесь с crossref:desktop[desktop,Среды рабочего стола], чтобы настроить полноценную рабочую среду.

Этот раздел демонстрирует использование рабочего стола XFCE.

После завершения установки войдите в систему как обычный пользователь, затем введите:

[source, shell]
....
% startx
....

Менеджер окон XFCE4 должен запуститься и предоставить рабочий графический рабочий стол, как на crossref:virtualization[qemu-two-qemu,рисунке {counter:figure}]. При первом запуске отображение рабочего стола может занять до минуты. Подробности использования см. в документации на link:https://www.xfce.org[сайте XFCE].
[[qemu-two-qemu]]
.Обе виртуальные машины QEMU
image::qemu-freebsd04.png["Обе виртуальные машины QEMU"]

[TIP]
====
Добавление дополнительной памяти в гостевую систему может ускорить работу графического интерфейса пользователя.
====

Здесь на виртуальной машине "left" установлена система `X Window`, а виртуальная машина "right" всё ещё находится в текстовом режиме.

[[qemu-using-qemu-window]]
==== Использование окна QEMU

Окно QEMU функционирует как полноценная консоль FreeBSD и способно работать с несколькими виртуальными терминалами, как и система на реальном оборудовании.

Для переключения на другую виртуальную консоль кликните в окно QEMU и нажмите kbd:[Alt+F2] или kbd:[Alt+F3]. FreeBSD должна переключиться на другую виртуальную консоль. crossref:virtualization[qemu-console-ttyv3,Рисунок {counter:figure}] показывает ВМ "left" с виртуальной консолью на `ttyv3`.
[[qemu-console-ttyv3]]
.Переключение на другую виртуальную консоль в окне QEMU
image::qemu-freebsd05.png["Переключение на другую виртуальную консоль в окне QEMU"]

[TIP]
====
Текущий менеджер рабочего стола или оконный менеджер на хосте может быть уже настроен на другое действие для комбинаций клавиш kbd:[Alt+F1], kbd:[Alt+F2]. В таком случае попробуйте нажать kbd:[Ctrl+Alt+F1], kbd:[Ctrl+Alt+F2] или другую подобную комбинацию. Подробности смотрите в документации вашего оконного менеджера или менеджера рабочего стола.
====

[[qemu-using-qemu-window-menus]]
==== Использование меню окна QEMU

Еще одна особенность окна QEMU — это меню `View` и элементы управления масштабом. Наиболее полезным является пункт `Zoom to Fit`. При выборе этого пункта меню появляется возможность изменить размер окна QEMU, перетаскивая его углы. На crossref:virtualization[qemu-zoom-to-fit,рисунке {counter:figure}] показан эффект изменения размера окна "left" в графическом режиме.

[[qemu-zoom-to-fit]]
.Использование опции `Zoom to Fit` в меню View
image::qemu-freebsd06.png["Использование опции `Zoom to Fit` в меню View"]

[[qemu-other-qemu-window-menu-options]]
==== Другие пункты меню окна QEMU

Также в меню `View` отображаются

* Опции `cirrus-vga`, `serial0` и `parallel0`. Они позволяют переключать ввод/вывод на выбранное устройство.

Окно QEMU в меню `Machine` предоставляет четыре типа управления гостевой виртуальной машиной:

* `Pause` позволяет приостановить виртуальную машину QEMU. Это может быть полезно для остановки быстро прокручивающегося окна.
* `Reset` немедленно возвращает виртуальную машину в исходное состояние, как "при включении питания". Как и с реальной машиной, это не рекомендуется, если в этом нет крайней необходимости.
* `Power Down` имитирует сигнал отключения ACPI, и операционная система выполняет аккуратное завершение работы.
* `Quit` немедленно выключает виртуальную машину — также не рекомендуется, если в этом нет необходимости.

[[qemu-adding-serial-port-to-guest-vm]]
=== Добавление интерфейса последовательного порта к гостевой ВМ

Для использования последовательной консоли гостевая ВМ под управлением FreeBSD должна добавить
[.programlisting]
....
console="comconsole"
....
в [.filename]#/boot/loader.conf# для разрешения использования последовательной консоли FreeBSD.

Обновлённая конфигурация ниже показывает, как реализовать последовательную консоль на гостевой ВМ. Запустите скрипт для старта ВМ.
[.programlisting]
....
# left+serial.sh
echo
echo "NOTE: telnet startup server running on guest VM!"
echo "To start QEMU, start another session and telnet to localhost port 4410"
echo

/usr/local/bin/qemu-system-x86_64  -monitor none \
  -serial telnet:localhost:4410,server=on,wait=on\
  -cpu qemu64 \
  -vga std \
  -m 4096 \
  -smp 4   \
  -cdrom ../ISO/fbsd.iso \
  -boot order=cd,menu=on \
  -blockdev driver=file,aio=threads,node-name=imgleft,filename=../VM/left.img \
  -blockdev driver=raw,node-name=drive0,file=imgleft \
  -device virtio-blk-pci,drive=drive0,bootindex=1  \
  -netdev tap,id=nd0,ifname=tap0,script=no,downscript=no,br=bridge0 \
  -device e1000,netdev=nd0,mac=02:20:6c:65:66:74 \
  -name \"left\"
....
[[qemu-left-serial-port]]
.Включение последовательного порта через TCP
image::qemu-freebsd07.png[]

На crossref:virtualization[qemu-notes-on-serial-console,рисунке {counter:figure}] последовательный порт перенаправляется на TCP-порт хост-системы при запуске ВМ, а монитор QEMU ожидает (`wait=on`), активируя гостевую ВМ только после установления соединения man:telnet[1] с указанным портом localhost. После получения соединения из отдельного сеанса система FreeBSD начинает загрузку и ищет директиву консоли в [.filename]#/boot/loader.conf#. С директивой "console=comconsole" FreeBSD запускает консольный сеанс на последовательном порту. Монитор QEMU обнаруживает это и направляет необходимый символьный ввод-вывод с этого последовательного порта в telnet-сеанс на хосте. Система загружается, и после завершения загрузки приглашения для входа в систему становятся доступными на последовательном порту (`ttyu0`) и на консоли (`ttyv0`).

Важно отметить, что этот последовательный перенаправление через TCP происходит вне виртуальной машины. Нет взаимодействия с какой-либо сетью внутри виртуальной машины, и поэтому оно не подчиняется никаким правилам брандмауэра. Представьте это как простой терминал, подключенный к RS-232 или USB-порту на реальном компьютере.

[[qemu-notes-on-serial-console]]
==== Заметки об использовании последовательной консоли

На последовательной консоли, если размер окна изменен, выполните man:resizewin[1], чтобы обновить размер терминала.

Может быть желательно (или даже необходимо) остановить отправку сообщений syslog на консоль (как консоль QEMU, так и последовательный порт). Подробности о перенаправлении сообщений консоли можно найти в man:syslog.conf[5].

[NOTE]
====
После обновления файла [.filename]#/boot/loader.conf# для разрешения использования последовательной консоли гостевая ВМ будет пытаться загружаться с последовательного порта при каждом запуске. Убедитесь, что последовательный порт включен, как показано в приведённом выше листинге, или измените файл [.filename]#/boot/loader.conf#, чтобы не требовать использования последовательной консоли.
====

[[qemu-user-mode-emulation]]
=== Эмуляция пользовательского режима QEMU

QEMU также поддерживает выполнение приложений, скомпилированных для архитектуры, отличной от архитектуры основного процессора. Например, можно запустить операционную систему архитектуры Sparc64 на хосте с архитектурой x86_64. Это демонстрируется в следующем разделе.

[[qemu-sparc64-user-mode-emulation]]
==== Настройка гостевой ВМ SPARC64 на хосте x86_64

Настройка новой виртуальной машины с архитектурой, отличной от архитектуры хоста, включает несколько шагов:

* Получение программного обеспечения, которое будет работать на гостевой ВМ
* Создание нового образа диска для гостевой ВМ
* Настройка нового скрипта QEMU с новой архитектурой
* Выполнение установки

В следующей процедуре используется копия программного обеспечения OpenBSD 6.8 SPARC64 для этого упражнения по эмуляции пользовательского режима QEMU.

[NOTE]
====
Не все версии OpenBSD Sparc64 работают в QEMU. Известно, что OpenBSD версии 6.8 работает, и она была выбрана в качестве примера для этого раздела.
====

. Скачать OpenBSD 6.8 Sparc64 из архива OpenBSD.
+
На сайтах загрузки OpenBSD поддерживаются только самые последние версии. Для получения предыдущих выпусков необходимо искать в архиве.
+
[source, shell]
....
% cd ~/QEMU/ISO
% fetch https://mirror.planetunix.net/pub/OpenBSD-archive/6.8/sparc64/install68.iso
....

. Создание нового образа диска для виртуальной машины Sparc64 аналогично описанному выше для "правильной" виртуальной машины. В данном случае используется формат диска QEMU qcow2:
+
[source, shell]
....
% cd ~/QEMU/VM
qemu-img create -f qcow2 -o preallocation=full,lazy_refcounts=on sparc64.qcow2 16G
....

. Используйте приведенный ниже скрипт для новой архитектуры Sparc64. Как и в предыдущем примере, запустите скрипт, затем начните новую сессию и подключитесь через `telnet` к localhost на указанном порту:
+
[.programlisting]
....
echo
echo "NOTE: telnet startup server running on guest VM!"
echo "To start QEMU, start another session and telnet to localhost port 4410"
echo

/usr/local/bin/qemu-system-sparc64 \
  -serial telnet:localhost:4410,server=on,wait=on \
  -machine sun4u,usb=off \
  -smp 1,sockets=1,cores=1,threads=1 \
  -rtc base=utc \
  -m 1024 \
  -boot d \
  -drive file=../VM/sparc64.qcow2,if=none,id=drive-ide0-0-1,format=qcow2,cache=none \
  -cdrom ../ISO/install68.iso \
  -device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-1,id=ide0-0-1 \
  -msg timestamp=on \
  -net nic,model=sunhme -net user \
  -nographic \
  -name \"sparc64\"
....

Обратите внимание на следующее:

* Опция `-boot d` загружает систему с устройства CDROM QEMU, которое указано как `-cdrom ../ISO/install68.iso`.
* Как и ранее, параметр сервера `telnet` настроен на ожидание отдельного подключения на порту 4410. Запустите еще один сеанс и используйте man:telnet[1] для подключения к localhost на порту 4410.
* Скрипт устанавливает опцию `-nographic`, что означает использование только ввода/вывода через последовательный порт. Графический интерфейс отсутствует.
* Сетевое взаимодействие не настраивается через комбинацию man:tap[4] / man:if_bridge[4]. В этом примере используется отдельный метод сетевого взаимодействия QEMU, известный как "Serial Line Internet Protocol" (SLIRP), иногда называемый "User Mode Networking". Документация по этому и другим методам сетевого взаимодействия QEMU находится здесь: link:https://wiki.qemu.org/Documentation/Networking[Документация по сетевому взаимодействию QEMU]

Если все настроено правильно, система загрузится, как показано на crossref:virtualization[qemu-sparc64-boot-cdrom-installation,рисунке {counter:figure}].
[[qemu-sparc64-boot-cdrom-installation]]
.QEMU Загрузка OpenBSD 6.8 Sparc64 с CDROM с эмуляцией пользовательского режима
image::qemu-freebsd08.png[]

После установки системы измените скрипт и замените параметр загрузки на `-boot c`. Это укажет QEMU загружаться с предоставленного жесткого диска, а не с CDROM.

Установленная система может использоваться как любая другая гостевая виртуальная машина. Однако, базовая архитектура гостевой системы — Sparc64, а не x86_64.

[TIP]
====
Если система остановлена на приглашении консоли OpenBios `0 >`, введите `power-off`, чтобы завершить работу системы.
====
На crossref:virtualization[qemu-sparc64-login-to-installed-system,рисунке {counter:figure}] показан вход в систему от имени root в установленной системе и выполнение man:uname[1].

[[qemu-sparc64-login-to-installed-system]]
.QEMU Загрузка с CDROM с эмуляцией пользовательского режима
image::qemu-freebsd09.png[]

[[qemu-using-qemu-monitor]]
=== Использование монитора QEMU

link:https://www.qemu.org/docs/master/system/monitor.html[Монитор QEMU] управляет работающим эмулятором QEMU (гостевой виртуальной машиной).

Используя монитор, можно:

* Динамически удалять или добавлять устройства, включая диски, сетевые интерфейсы, CD-ROM или дисководы гибких дисков
* Заморозить/разморозить гостевую ВМ и сохранить или восстановить её состояние из файла на диске
* Собрать информацию о состоянии ВМ и устройств
* Изменить настройки устройств на лету

А также сделать множество других операций.

Наиболее распространённые способы использования монитора — это проверка состояния виртуальной машины, а также добавление, удаление или изменение устройств. Некоторые операции, такие как миграция, доступны только при использовании гипервизоров с ускорением, например KVM, Xen и т.д., и не поддерживаются на хостах FreeBSD.

При использовании графической среды рабочего стола самый простой способ доступа к монитору QEMU — это опция `-monitor stdio` при запуске QEMU из терминала.

[.programlisting]
....
# /usr/local/bin/qemu-system-x86_64  -monitor stdio \
  -cpu qemu64 \
  -vga cirrus \
  -m 4096  -smp 4   \
  ...
....

Это приводит к появлению новой строки приглашения `(qemu)` в окне терминала, как показано на crossref:virtualization[qemu-monitor-operation,рисунке {counter:figure}].

[[qemu-monitor-operation]]
.Приглашение монитора QEMU и команда "stop"
image::qemu-freebsd13.png[]

На изображении также показано, что команда `stop` замораживает систему во время последовательности загрузки FreeBSD. Система останется замороженной до тех пор, пока в мониторе не будет введена команда `cont`.

[[qemu-adding-new-disk]]
==== Добавление нового диска в виртуальную машину

Чтобы добавить новый диск к работающей виртуальной машине, его необходимо подготовить, как описано выше:

[source, shell]
....
% cd ~/QEMU/VM
% qemu-img create -f raw  new10G.img  10G
....

crossref:virtualization[qemu-add-new-disk-figure,Рисунок {counter:figure}] показывает последовательность команд в мониторе, необходимую для добавления нового диска в виртуальную машину. После добавления устройства с помощью команды `device_add` в мониторе оно появляется на консоли системы FreeBSD, как показано в нижней части рисунка. Диск можно настроить по необходимости.

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

[[qemu-add-new-disk-figure]]
.Команды монитора QEMU для добавления нового диска
image::qemu-freebsd14.png[]

[[qemu-using-monitor-manage-snapshots]]
==== Использование монитора QEMU для управления снимками

Документация QEMU описывает несколько схожих концепций, используя термин *снимок (snapshot)*. Существует опция `-snapshot` в командной строке, которая означает использование диска или его части для хранения копии устройства. Также есть команды монитора `snapshot_blkdev` и `snapshot_blkdev_internal`, описывающие сам процесс копирования блочного устройства. Наконец, команды монитора `savevm`, `loadvm` и `delvm` относятся к созданию, сохранению, загрузке или удалению копии всей виртуальной машины. Вместе с последними, команда монитора `info snapshots` выводит детали недавних снимков состояния.

Этот раздел посвящён созданию, сохранению и загрузке полного образа ВМ и использует термин *снимок* для этой цели.

Для начала заново создайте виртуальную машину "left", на этот раз используя формат `qcow2`.

[source, shell]
....
% cd ~/QEMU/VM
% rm left.img
% qemu-img create -f qcow2 left.qcow2 16G  # Clean file for a new FreeBSD installation.
% cd ../SCRIPTS
# /bin/sh left.sh                     # See the below program listing.
....

После завершения установки перезагрузите систему, на этот раз с использованием опции `-monitor stdio`, чтобы обеспечить доступ к монитору.

[.programlisting]
....
# left VM script.
/usr/local/bin/qemu-system-x86_64  -monitor stdio \
  -cpu qemu64 \
  -vga std \
  -m 4096 \
  -smp 4   \
  -cdrom ../ISO/fbsd.iso \
  -boot order=cd,menu=on \
  -blockdev driver=file,aio=threads,node-name=imgleft,filename=../VM/left.qcow2 \
  -blockdev driver=qcow2,node-name=drive0,file=imgleft \
  -device virtio-blk-pci,drive=drive0,bootindex=1  \
  -netdev tap,id=nd0,ifname=tap0,script=no,downscript=no,br=bridge0 \
  -device e1000,netdev=nd0,mac=02:20:6c:65:66:74 \
  -name \"left\"
....

Для демонстрации работы снимков можно использовать следующую процедуру:

. Установите FreeBSD с нуля
. Подготовьте окружение и создайте снимок состояния с помощью команды монитора `savevm`
. Установите несколько пакетов
. Выключите систему
. Перезапустите экземпляр QEMU без оболочки и используйте команду монитора `loadvm` для восстановления ВМ
. Обратите внимание, что восстановленная ВМ не имеет установленных пакетов

На этапе «Подготовка окружения» в отдельной виртуальной консоли (ttyv1) запускается сеанс редактирования в man:vi[1], имитирующий активность пользователя. При желании можно запустить дополнительные программы. Снимок должен учитывать состояние всех приложений, работающих на момент его создания.

crossref:virtualization[qemu-using-monitor-snapshots,Рисунок {counter:figure}] показывает новую установленную систему FreeBSD без пакетов, а также отдельно сеанс редактирования на ttyv1. Редактор man:vi[1] в данный момент находится в режиме `insert`, и пользователь набирает слово "broadcast".

[[qemu-using-monitor-snapshots]]
.Виртуальная машина QEMU перед первым снимком состояния
image::qemu-freebsd15.png[]

Чтобы создать снимок состояния, введите `savevm` в мониторе. Убедитесь, что указали метку (например, `original_install`).

[source, shell]
....
QEMU 9.0.1 monitor - type 'help' for more information
(qemu)
(qemu) savevm original_install
....

Далее, в главном окне консоли, установите пакет, например man:zip[1], который не имеет зависимостей. После завершения установки вернитесь в монитор и создайте ещё один снимок состояния (`snap1_pkg+zip`).

crossref:virtualization[qemu-after-monitor-snapshots,Рисунок {counter:figure}] показывает результаты выполненных выше команд и вывод команды `info shapshots`.

[[qemu-after-monitor-snapshots]]
.QEMU — Использование команд монитора для создания снимков состояния
image::qemu-freebsd16.png[]

Перезагрузите систему, и до запуска FreeBSD переключитесь на монитор и введите `stop`. Виртуальная машина остановится.

Введите `loadvm` с тегом, который вы использовали ранее (здесь `original_install`).

[source, shell]
....
QEMU 9.0.1 monitor - type 'help' for more information
(qemu) stop
(qemu) loadvm original_install
(qemu) cont
....

Сразу же экран виртуальной машины переключится на тот момент, когда была введена команда `savevm`, как указано выше. Обратите внимание, что виртуальная машина всё ещё остановлена.

Введите `cont`, чтобы запустить ВМ, переключитесь на сеанс редактирования на `ttyv1` и наберите одну букву на клавиатуре. Редактор, всё ещё находящийся в режиме вставки, должен отреагировать соответствующим образом. Любые другие программы, работавшие в момент создания снимка, не должны быть затронуты.

Приведенные выше шаги показывают, как можно создать снимок состояния, изменить систему, а затем «откатить» изменения, восстановив предыдущий снимок.

По умолчанию QEMU хранит данные снимков в том же файле, что и образ. Просмотреть список снимков можно с помощью man:qemu-img[1], как показано ниже в crossref:virtualization[qemu-examine-monitor-snapshots,Рисунок {counter:figure}].

[[qemu-examine-monitor-snapshots]]
.QEMU Использование man:qemu-img[1] для проверки снимков
image::qemu-freebsd17.png[]

[[qemu-using-qemu-usb-devices]]
=== Использование USB-устройств в QEMU

QEMU поддерживает создание виртуальных USB-устройств, которые используют файл образа. Это виртуальные USB-устройства, которые можно разбивать на разделы, форматировать, монтировать и использовать, как реальное USB-устройство.

[.programlisting]
....
/usr/local/bin/qemu-system-x86_64  -monitor stdio \
  -cpu qemu64 \
  -vga cirrus \
  -m 4096  -smp 4   \
  -cdrom ../ISO/fbsd.iso \
  -boot order=cd,menu=on \
  -drive if=none,id=usbstick,format=raw,file=../VM/foo.img \
  -usb \
  -device usb-ehci,id=ehci \
  -device usb-storage,bus=ehci.0,drive=usbstick \
  -device usb-mouse \
  -blockdev driver=file,node-name=img1,filename=../VM/right.qcow2 \
  -blockdev driver=qcow2,node-name=drive0,file=img1 \
  -device virtio-blk-pci,drive=drive0,bootindex=1  \
  -netdev tap,id=nd0,ifname=tap1,script=no,downscript=no,br=bridge0 \
  -device e1000,netdev=nd0,mac=02:72:69:67:68:74 \
  -name \"right\"
....

Эта конфигурация включает спецификацию `-drive` с `id=usbstick`, формат raw и файл образ (который должен быть создан с помощью man:qemu-img[1]). Следующая строка содержит спецификацию `-device usb-ehci` для контроллера USB EHCI с `id=ehci`. Наконец, спецификация `-device usb-storage` связывает указанный накопитель с шиной USB EHCI.

При загрузке системы FreeBSD распознает USB-концентратор, добавит подключенное USB-устройство и назначит его на `da0`, как показано на crossref:virtualization[qemu-usb-internal-storage,рисунке {counter:figure}].

[[qemu-usb-internal-storage]]
.QEMU Созданные USB-концентратор и устройство хранения данных
image::qemu-freebsd12.png[]

Устройство готово к разделению с помощью man:gpart[8] и форматированию с помощью man:newfs[8]. Поскольку USB-устройство использует файл, созданный man:qemu-img[1], записанные на него данные сохранятся после перезагрузки.

[[qemu-using-host-usb-devices]]
=== Использование USB-устройств хоста через проброс (passthrough)

Поддержка проброса USB в QEMU указана как экспериментальная в версии 9.0.1 (лето 2024 года). Тем не менее, следующие шаги показывают, как USB-накопитель, подключённый к хосту, может быть использован в гостевой ВМ.

Для получения дополнительной информации и примеров см.:

* link:https://www.qemu.org/docs/master/system/devices/usb.html[]

Верхняя часть crossref:virtualization[qemu-usb-passthrough,рисунка {counter:figure}] показывает команды монитора QEMU:

* `info usbhost` отображает информацию обо всех USB-устройствах в хост-системе. Найдите нужное USB-устройство в хост-системе и запишите два шестнадцатеричных значения в соответствующей строке. (В примере ниже хост-устройство — это Memorex Mini с vendorid 0718 и productid 0619.) Используйте эти два значения, показанные командой `info usbhost`, на этапе `device_add` ниже.
* `device_add` добавляет USB-устройство в гостевую ВМ.

[[qemu-usb-passthrough]]
.Команды монитора QEMU для доступа к USB-устройству на хосте
image::qemu-freebsd18.png[]

Как и ранее, после завершения `device_add` ядро FreeBSD распознает новое USB-устройство, как показано в нижней части экрана.

Использование нового устройства показано на crossref:virtualization[qemu-usb-passthrough2,рисунке {counter:figure}].

[[qemu-usb-passthrough2]]
.Использование USB-устройства хоста через проброс (passthrough)
image::qemu-freebsd19.png[]

Если USB-устройство отформатировано как файловая система FAT16 или FAT32, его можно подключить как файловую систему MS-DOS(TM) с помощью man:mount_msdosfs[8], как показано в примере. Файл `/etc/hosts` копируется на только что подключённый диск, и для проверки целостности файла на USB-устройстве вычисляются контрольные суммы. Затем устройство отключается с помощью man:umount[8].

Если USB-устройство отформатировано в NTFS, необходимо установить пакет `fusefs-ntfs` и использовать man:ntfs-3g[8] для доступа к устройству:

[source, shell]
....
# pkg install fusefs-ntfs
# kldload fusefs
# gpart show da1
# ntfs-3g /dev/da1s1 /mnt

Access the drive as needed.  When finished:

# umount /mnt
....

Замените приведенные выше идентификаторы устройств в соответствии с установленным оборудованием. Дополнительную информацию о работе с файловыми системами NTFS см. в man:ntfs-3g[8].

[[qemu-summary]]
=== QEMU на FreeBSD Краткое описание

Как упоминалось выше, QEMU работает с несколькими различными гипервизорными ускорителями.

Список поддерживаемых QEMU link:https://www.qemu.org/docs/master/system/introduction.html#virtualisation-accelerators[ускорителей виртуализации] включает:

* `KVM` в Linux с поддержкой 64-битных архитектур Arm, MIPS, PPC, RISC-V, s390x и x86
* `Xen` на Linux в качестве dom0 с поддержкой Arm и x86
* `Hypervisor Framework (hvf)` в macOS с поддержкой x86 и Arm (только 64-битные)
* `Windows Hypervisor Platform (whpx)` в Windows с поддержкой x86
* `Диспетчер виртуальных машин NetBSD (nvmm)` на NetBSD с поддержкой x86
* `Tiny Code Generator (tcg)` на Linux и других POSIX-совместимых системах, Windows, macOS с поддержкой Arm, x86, Loongarch64, MIPS, PPC, s390x и Sparc64.

Все примеры в этом разделе использовали ускоритель `Tiny Code Generator (tcg)`, так как это единственный поддерживаемый ускоритель в FreeBSD на данный момент.

[[virtualization-host-bhyve]]
== FreeBSD в качестве хоста с bhyve

Гипервизор bhyve с лицензией BSD стал частью базовой системы начиная с FreeBSD 10.0-RELEASE. Этот гипервизор поддерживает несколько гостевых систем, включая FreeBSD, OpenBSD, многие дистрибутивы Linux(R) и Microsoft Windows(R). По умолчанию bhyve предоставляет доступ к последовательной консоли и не эмулирует графическую консоль. Функции оффлоадинга виртуализации современных процессоров используются для избежания устаревших методов трансляции инструкций и ручного управления отображением памяти.

Дизайн bhyve требует

* процессор Intel(R), поддерживающий Intel Extended Page Tables (EPT),
* или процессор AMD(R), поддерживающий AMD Rapid Virtualization Indexing (RVI) или Nested Page Tables (NPT),
* или процессор ARM(R) aarch64.

На ARM поддерживается только чистая виртуализация ARMv8.0, расширения Virtualization Host Extensions в настоящее время не используются. Для запуска гостевых систем Linux(R) или FreeBSD с более чем одним vCPU требуется поддержка неограниченного режима VMX (UG).

Самый простой способ проверить, поддерживает ли процессор Intel или AMD технологию bhyve, — выполнить команду `dmesg` или посмотреть в файле [.filename]#/var/run/dmesg.boot# флаг `POPCNT` в строке `Features2` для процессоров AMD(R) или флаги `EPT` и `UG` в строке `VT-x` для процессоров Intel(R).

[[virtualization-bhyve-prep]]
=== Подготовка хоста

Первым шагом к созданию виртуальной машины в bhyve является настройка хостовой системы. Сначала загрузите модуль ядра bhyve:

[source, shell]
....
# kldload vmm
....

Существует несколько способов подключения гостевой виртуальной машины к сети хоста; один из простых способов — создать интерфейс [.filename]#tap#, к которому подключится сетевое устройство виртуальной машины. Чтобы сетевое устройство могло участвовать в сети, также необходимо создать мостовой интерфейс, включающий интерфейс [.filename]#tap# и физический интерфейс в качестве членов. В данном примере физический интерфейс — это _igb0_:

[source, shell]
....
# ifconfig tap0 create
# sysctl net.link.tap.up_on_open=1
net.link.tap.up_on_open: 0 -> 1
# ifconfig bridge0 create
# ifconfig bridge0 addm igb0 addm tap0
# ifconfig bridge0 up
....

[[virtualization-bhyve-freebsd]]
=== Создание гостевой системы FreeBSD

Создайте файл, который будет использоваться как виртуальный диск для гостевой машины. Укажите размер и имя виртуального диска:

[source, shell]
....
# truncate -s 16G guest.img
....

Скачать образ установки FreeBSD для установки:

[source, shell]
....
# fetch https://download.freebsd.org/releases/ISO-IMAGES/14.0/FreeBSD-14.0-RELEASE-amd64-bootonly.iso
FreeBSD-14.0-RELEASE-amd64-bootonly.iso                426 MB   16 MBps    22s
....

FreeBSD включает пример скрипта `vmrun.sh` для запуска виртуальной машины в bhyve. Он запускает виртуальную машину и выполняет её в цикле, поэтому она автоматически перезапустится в случае сбоя. `vmrun.sh` принимает несколько опций для управления конфигурацией машины, включая:

* `-c` управляет количеством виртуальных процессоров,
* `-m` ограничивает объем памяти, доступной гостевой системе,
* `-t` указывает, какой [.filename]#tap#-устройство использовать,
* `-d` указывает, какой образ диска использовать,
* `-i` указывает bhyve загружаться с образа CD вместо диска, и
* `-I` определяет, какой образ CD использовать.

Последний параметр — это имя виртуальной машины, которое используется для отслеживания работающих машин. Следующая команда выводит список всех доступных аргументов программы:

[source, shell]
....
# sh /usr/share/examples/bhyve/vmrun.sh -h
....

Этот пример запускает виртуальную машину в режиме установки:

[source, shell]
....
# sh /usr/share/examples/bhyve/vmrun.sh -c 1 -m 1024M -t tap0 -d guest.img \
     -i -I FreeBSD-14.0-RELEASE-amd64-bootonly.iso guestname
....

Виртуальная машина загрузится и запустит установщик. После установки системы в виртуальной машине, когда система предложит перейти в оболочку в конце установки, выберите btn:[Да].

Перезагрузите виртуальную машину. Хотя перезагрузка виртуальной машины приводит к выходу из bhyve, скрипт [.filename]#vmrun.sh# запускает `bhyve` в цикле и автоматически перезапустит его. Когда это произойдет, выберите опцию перезагрузки в меню загрузчика, чтобы выйти из цикла. Теперь гостевую систему можно запустить с виртуального диска:

[source, shell]
....
# sh /usr/share/examples/bhyve/vmrun.sh -c 4 -m 1024M -t tap0 -d guest.img guestname
....

[[virtualization-bhyve-linux]]
=== Создание гостевой системы Linux(R)

Гостевые системы Linux можно загружать как любую другую обычную виртуальную машину на основе crossref:virtualization[virtualization-bhyve-uefi,"UEFI"], либо, в качестве альтернативы, можно использовать порт package:sysutils/grub2-bhyve[].

Для этого сначала убедитесь, что порт установлен, затем создайте файл, который будет использоваться как виртуальный диск для гостевой машины:

[source, shell]
....
# truncate -s 16G linux.img
....

Запуск виртуальной машины Linux с `grub2-bhyve` — это двухэтапный процесс.

. Сначала необходимо загрузить ядро, затем можно запустить гостевую систему.
. Ядро Linux(R) загружается с помощью пакета package:sysutils/grub2-bhyve[].

Создайте файл [.filename]#device.map#, который grub будет использовать для сопоставления виртуальных устройств с файлами в хостовой системе:

[.programlisting]
....
(hd0) ./linux.img
(cd0) ./somelinux.iso
....

Используйте package:sysutils/grub2-bhyve[] для загрузки ядра Linux(R) из образа ISO:

[source, shell]
....
# grub-bhyve -m device.map -r cd0 -M 1024M linuxguest
....

Это запустит grub. Если на установочном CD содержится файл [.filename]#grub.cfg#, будет отображено меню. Если нет, файлы `vmlinuz` и `initrd` необходимо найти и загрузить вручную:

[source, shell]
....
grub> ls
(hd0) (cd0) (cd0,msdos1) (host)
grub> ls (cd0)/isolinux
boot.cat boot.msg grub.conf initrd.img isolinux.bin isolinux.cfg memtest
splash.jpg TRANS.TBL vesamenu.c32 vmlinuz
grub> linux (cd0)/isolinux/vmlinuz
grub> initrd (cd0)/isolinux/initrd.img
grub> boot
....

Теперь, когда ядро Linux(R) загружено, можно запустить гостевую систему:

[source, shell]
....
# bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 \
    -s 3:0,virtio-blk,./linux.img -s 4:0,ahci-cd,./somelinux.iso \
    -l com1,stdio -c 4 -m 1024M linuxguest
....

Система загрузится и запустит установщик. После установки системы в виртуальной машине перезагрузите виртуальную машину. Это приведёт к завершению работы bhyve. Экземпляр виртуальной машины необходимо уничтожить перед тем, как его можно будет запустить снова:

[source, shell]
....
# bhyvectl --destroy --vm=linuxguest
....

Теперь гостевую систему можно запустить напрямую с виртуального диска. Загрузите ядро:

[source, shell]
....
# grub-bhyve -m device.map -r hd0,msdos1 -M 1024M linuxguest
grub> ls
(hd0) (hd0,msdos2) (hd0,msdos1) (cd0) (cd0,msdos1) (host)
(lvm/VolGroup-lv_swap) (lvm/VolGroup-lv_root)
grub> ls (hd0,msdos1)/
lost+found/ grub/ efi/ System.map-2.6.32-431.el6.x86_64 config-2.6.32-431.el6.x
86_64 symvers-2.6.32-431.el6.x86_64.gz vmlinuz-2.6.32-431.el6.x86_64
initramfs-2.6.32-431.el6.x86_64.img
grub> linux (hd0,msdos1)/vmlinuz-2.6.32-431.el6.x86_64 root=/dev/mapper/VolGroup-lv_root
grub> initrd (hd0,msdos1)/initramfs-2.6.32-431.el6.x86_64.img
grub> boot
....

Запустите виртуальную машину:

[source, shell]
....
# bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 \
    -s 3:0,virtio-blk,./linux.img -l com1,stdio -c 4 -m 1024M linuxguest
....

Linux(R) теперь загрузится в виртуальной машине и в конечном итоге покажет приглашение для входа. Войдите в систему и используйте виртуальную машину. Когда вы закончите, перезагрузите виртуальную машину для выхода из bhyve. Уничтожьте экземпляр виртуальной машины:

[source, shell]
....
# bhyvectl --destroy --vm=linuxguest
....

[[virtualization-bhyve-uefi]]
=== Загрузка виртуальных машин bhyve с прошивкой UEFI

В дополнение к `bhyveload` и `grub-bhyve`, гипервизор bhyve также может загружать виртуальные машины с использованием прошивки UEFI. Этот вариант может поддерживать гостевые операционные системы, которые не поддерживаются другими загрузчиками.

Чтобы использовать поддержку UEFI в bhyve, сначала получите образы прошивки UEFI. Это можно сделать, установив порт package:sysutils/bhyve-firmware[] или пакет.

Имея микропрограмму, добавьте флаги `-l bootrom,_/путь/к/микропрограмме_` в командную строку bhyve. Фактическая команда bhyve может выглядеть так:

[source, shell]
....
# bhyve -AHP -s 0:0,hostbridge -s 1:0,lpc \
  	-s 2:0,virtio-net,tap1 -s 3:0,virtio-blk,./disk.img \
	-s 4:0,ahci-cd,./install.iso -c 4 -m 1024M \
	-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
	guest
....

Чтобы разрешить гостевой системе сохранять переменные UEFI, вы можете использовать файл переменных, указанный с флагом `-l`. Обратите внимание, что bhyve будет записывать изменения, внесённые гостевой системой, в указанный файл переменных. Поэтому убедитесь, что вы предварительно создали отдельную копию шаблонного файла переменных для каждой гостевой системы:

[source, shell]
....
# cp /usr/local/share/uefi-firmware/BHYVE_UEFI_VARS.fd /path/to/vm-image/BHYVE_UEFI_VARS.fd
....

Затем добавьте этот файл переменных в аргументы bhyve:

[source, shell]
....
# bhyve -AHP -s 0:0,hostbridge -s 1:0,lpc \
  	-s 2:0,virtio-net,tap1 -s 3:0,virtio-blk,./disk.img \
	-s 4:0,ahci-cd,./install.iso -c 4 -m 1024M \
	-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd,/path/to/vm-image/BHYVE_UEFI_VARS.fd \
	guest
....

[NOTE]
====
Некоторые дистрибутивы Linux требуют использования переменных UEFI для хранения пути к их загрузочному файлу UEFI (например, используют `linux64.efi` или `grubx64.efi` вместо `bootx64.efi`). Поэтому рекомендуется использовать файл переменных для виртуальных машин Linux, чтобы избежать необходимости вручную изменять файлы загрузочного раздела.
====

Для просмотра или изменения содержимого файла переменных используйте man:efivar[8] с хоста.

package:sysutils/bhyve-firmware[] также содержит прошивку с поддержкой CSM для загрузки гостевых систем без поддержки UEFI в режиме устаревшего BIOS:

[source, shell]
....
# bhyve -AHP -s 0:0,hostbridge -s 1:0,lpc \
  	-s 2:0,virtio-net,tap1 -s 3:0,virtio-blk,./disk.img \
	-s 4:0,ahci-cd,./install.iso -c 4 -m 1024M \
	-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI_CSM.fd \
	guest
....

[[virtualization-bhyve-framebuffer]]
=== Графический UEFI фреймбуфер для гостевых систем bhyve

Поддержка микропрограммы UEFI особенно полезна для преимущественно графических гостевых операционных систем, таких как Microsoft Windows(R).

Поддержка фреймбуфера UEFI-GOP также может быть включена с помощью флагов `-s 29,fbuf,tcp=_0.0.0.0:5900_`. Разрешение фреймбуфера можно настроить с помощью параметров `w=_800_` и `h=_600_`, а также можно указать bhyve ожидать подключения VNC перед загрузкой гостевой системы, добавив `wait`. Доступ к фреймбуферу возможен с хоста или по сети через протокол VNC. Дополнительно можно добавить `-s 30,xhci,tablet` для точной синхронизации курсора мыши с хостом.

Результирующая команда bhyve будет выглядеть так:

[source, shell]
....
# bhyve -AHP -s 0:0,hostbridge -s 31:0,lpc \
  	-s 2:0,virtio-net,tap1 -s 3:0,virtio-blk,./disk.img \
	-s 4:0,ahci-cd,./install.iso -c 4 -m 1024M \
	-s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600,wait \
	-s 30,xhci,tablet \
	-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
	guest
....

Заметим, что в режиме эмуляции BIOS обновление кадрового буфера прекращается после передачи управления от микропрограммы гостевой операционной системе.

[[virtualization-bhyve-windows]]
=== Создание гостевой системы Microsoft Windows(R) ===

Настройка гостевой системы для Windows версий 10 или более ранних может быть выполнена непосредственно с оригинального установочного носителя и является относительно простым процессом. Помимо минимальных требований к ресурсам, для работы Windows в качестве гостевой системы требуется

* привязка памяти виртуальной машины (флаг `-w`) и
* загрузка с загрузочной памяти (bootrom) UEFI.

Пример загрузки гостевой виртуальной машины с установочным ISO-образом Windows:

[source, shell]
....
bhyve \
      -c 2 \
      -s 0,hostbridge \
      -s 3,nvme,windows2016.img \
      -s 4,ahci-cd,install.iso \
      -s 10,virtio-net,tap0 \
      -s 31,lpc \
      -s 30,xhci,tablet \
      -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
      -m 8G -H -w \
      windows2016
....

Только один или два виртуальных процессора (VCPU) следует использовать во время установки, но их количество можно увеличить после установки Windows.

Для использования определенного сетевого интерфейса `virtio-net` необходимо установить link:https://github.com/virtio-win/virtio-win-pkg-scripts/blob/master/README.md[драйверы VirtIO]. Альтернативой является переключение на эмуляцию E1000 (Intel E82545) путем замены `virtio-net` на `e1000` в приведенной выше командной строке. Однако это повлияет на производительность.

[[virtualization-bhyve-windows-win11]]
==== Создание гостевой системы Windows 11 ====

Начиная с Windows 11, Microsoft ввела требование к оборудованию в виде модуля TPM 2. bhyve поддерживает передачу аппаратного TPM гостевой системе. Установочный носитель можно модифицировать для отключения соответствующих проверок оборудования. Подробное описание этого процесса доступно по ссылке link:https://wiki.freebsd.org/bhyve/Windows#iso-remaster[FreeBSD Wiki].

[WARNING]
====
Изменение установочных носителей Windows и запуск гостевых систем Windows без модуля TPM не поддерживаются производителем. Учитывайте свои задачи и сценарии использования перед применением подобных методов.
====

[[virtualization-bhyve-zfs]]
=== Использование ZFS с гостевыми ВМ в bhyve

Если на хост-машине доступен ZFS, использование томов ZFS вместо файлов образов дисков может обеспечить значительное повышение производительности для гостевых ВМ. Том ZFS можно создать следующим образом:

[source, shell]
....
# zfs create -V16G -o volmode=dev zroot/linuxdisk0
....

При запуске ВМ укажите том ZFS в качестве диска:

[source, shell]
....
# bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 \
  	-s3:0,virtio-blk,/dev/zvol/zroot/linuxdisk0 \
	-l com1,stdio -c 4 -m 1024M linuxguest
....

Если вы используете ZFS как на хосте, так и внутри гостевой системы, учитывайте конкуренцию за память из-за кэширования содержимого виртуальной машины обеими системами. Чтобы уменьшить эту нагрузку, рассмотрите возможность настройки файловых систем ZFS на хосте для использования кэширования только метаданных. Для этого примените следующие параметры к файловым системам ZFS на хосте, заменив `<name>` на имя конкретного zvol-набора данных виртуальной машины.

[source, shell]
....
# zfs set primarycache=metadata <name>
....

[[virtualiziation-bhyve-snapshot]]
=== Создание снимка виртуальной машины ===

Современные гипервизоры позволяют своим пользователям создавать "снимки" состояния; такой снимок включает в себя диск гостевой системы, содержимое процессора и памяти. Снимок обычно можно сделать независимо от того, работает гостевая система или выключена. Затем можно сбросить и вернуть виртуальную машину в точное состояние на момент создания снимка.

[[virtualization-bhyve-snapshot-zfs]]
==== ZFS Снимки ====

Использование томов ZFS в качестве основного хранилища для виртуальной машины позволяет создавать снимки диска гостевой системы. Например:

[source, shell]
....
zfs snapshot zroot/path/to/zvol@snapshot_name
....

Хотя можно создать снимок ZFS тома таким образом, пока гостевая система работает, следует учитывать, что содержимое виртуального диска может находиться в несогласованном состоянии, пока гость активен. Поэтому рекомендуется сначала завершить работу или приостановить гостевую систему перед выполнением этой команды. Функция приостановки гостевой системы не поддерживается по умолчанию и должна быть сначала включена (см. crossref:virtualization[virtualization-bhyve-snapshot-builtin,Снимки памяти и процессора])

[WARNING]
====
Откат ZFS zvol к снимку во время использования виртуальной машиной может повредить содержимое файловой системы и вызвать сбой гостевой ОС. Все несохранённые данные в гостевой системе будут потеряны, а изменения, сделанные после последнего снимка, могут быть уничтожены.

Повторный откат может потребоваться после выключения виртуальной машины, чтобы вернуть файловую систему в работоспособное состояние. Это, в свою очередь, окончательно уничтожит все изменения, сделанные после создания снимка.
====

[[virtualization-bhyve-snapshot-builtin]]
==== Снимки памяти и процессора (экспериментальная функция) ====

Начиная с FreeBSD 13, bhyve имеет экспериментальную функцию "snapshot" для сохранения состояния памяти и процессора гостевой системы в файл с последующей остановкой виртуальной машины. Гостевая система может быть возобновлена из содержимого файла снимка позже.

Однако эта функция не включена по умолчанию и требует пересборки системы из исходного кода. Подробное описание процесса компиляции ядра с пользовательскими настройками приведено в crossref:cutting-edge[updating-src-building, Сборка из исходного кода].

[WARNING]
====
Функциональность не готова для промышленного использования и ограничена работой с определёнными конфигурациями виртуальных машин. Существует несколько ограничений:

* `nvme` и `virtio-blk` бэкенды хранения пока не работают
* Снимки поддерживаются только в случае, если гостевая система использует один тип каждого устройства. То есть, если подключено более одного диска `ahci-hd`, создание снимка завершится ошибкой
* дополнительно, функция может быть достаточно стабильной на процессорах Intel, но, скорее всего, не будет работать на процессорах AMD.
====

[NOTE]
====
Убедитесь, что каталог [.filename]#/usr/src# актуален, прежде чем выполнять следующие шаги. Подробная процедура обновления описана в разделе crossref:cutting-edge[updating-src-obtaining-src, Updating the Source].
====

Добавьте следующее в [.filename]#/etc/src.conf#:

[.programlisting]
....
WITH_BHYVE_SNAPHOT=yes
BHYVE_SNAPSHOT=1
MK_BHYVE_SNAPSHOT=yes
....

[NOTE]
====
Если система была частично или полностью пересобрана, рекомендуется выполнить

[source, shell]
....
# cd /usr/src
# make cleanworld
....

прежде чем продолжить.
====

Затем выполните шаги, описанные в разделе crossref:cutting-edge[updating-src-quick-start,"Быстрый старт обновления FreeBSD из исходного кода"], чтобы собрать и установить систему и ядро.

Чтобы проверить успешную активацию функции снимков, введите

[source, shell]
....
# bhyvectl --usage
....

и проверить, есть ли в выводе флаг `--suspend`. Если флаг отсутствует, значит функция не активировалась корректно.

Затем вы можете создать снимок состояния и приостановить работающую виртуальную машину по вашему выбору:

[source, shell]
....
# bhyvectl --vm=vmname --suspend=/path/to/snapshot/filename
....

[NOTE]
====
Укажите абсолютный путь и имя файла для `--suspend`. В противном случае bhyve запишет данные снимка в тот каталог, из которого был запущен bhyve.

Убедитесь, что записываете данные снимка в защищённый каталог. Сформированный вывод содержит полный дамп памяти гостевой системы и, следовательно, может включать конфиденциальные данные (например, пароли)!
====

Это создает три файла:

* моментальный снимок памяти - назван аналогично параметру `--suspend`
* файл ядра - имя, аналогичное входному параметру `--suspend`, с суффиксом [.filename]#.kern#
* metadata - содержит метаданные о состоянии системы, с именем, оканчивающимся на суффикс [.filename]#.meta#

Для восстановления гостевой системы из снимка используйте флаг `-r` с `bhyve`:

[source, shell]
....
# bhyve -r /path/to/snapshot/filename
....

Восстановление снимка гостевой системы на архитектуре процессора, отличной от исходной, невозможно. Как правило, попытка восстановления на системе, не идентичной той, на которой был создан снимок, скорее всего, завершится неудачей.

[[virtualization-bhyve-jailed]]
=== bhyve в клетке ===

Для повышения безопасности и изоляции виртуальных машин от основной операционной системы можно запускать bhyve в клетке. См. crossref:jails[,Клетки] для подробного описания клеток и их преимуществ в плане безопасности.

[[virtualization-bhyve-jailed-creation]]
==== Создание клетки для bhyve ====

Сначала создайте окружение клетки. Если используется файловая система UFS, просто выполните:

[source, shell]
....
# mkdir -p /jails/bhyve
....

Если используется crossref:zfs[,файловая система ZFS], выполните следующие команды:

[source, shell]
....
# zfs create zroot/jails
# zfs create zroot/jails/bhyve
....

Затем создайте ZFS zvol для виртуальной машины `bhyvevm0`:

[source, shell]
....
# zfs create zroot/vms
# zfs create -V 20G zroot/vms/bhyvevm0
....

Если ZFS не используется, для создания файла образа диска непосредственно в структуре каталогов клетки применяйте следующие команды:

[source, shell]
....
# mkdir /jails/bhyve/vms
# truncate -s 20G /jails/bhyve/vms/bhyvevm0
....

Загрузите образ FreeBSD, предпочтительно версии, равной или более старой, чем на хосте, и извлеките его в каталог клетки:

[source, shell]
....
# cd /jails
# fetch -o base.txz http://ftp.freebsd.org/pub/FreeBSD/releases/amd64/13.2-RELEASE/base.txz
# tar -C /jails/bhyve -xvf base.txz
....

[NOTE]
====
Запуск более высокой версии FreeBSD в клетке, чем на хосте, не поддерживается (например, запуск 14.0-RELEASE в jail на хосте с 13.2-RELEASE).
====

Далее добавьте набор правил devfs в [.filename]#/etc/devfs.rules#:

[.programlisting]
....
[devfsrules_jail_bhyve=100]
add include $devfsrules_hide_all
add include $devfsrules_unhide_login
add path 'urandom' unhide
add path 'random' unhide
add path 'crypto' unhide
add path 'shm' unhide
add path 'zero' unhide
add path 'null' unhide
add path 'mem' unhide
add path 'vmm' unhide
add path 'vmm/*' unhide
add path 'vmm.io' unhide
add path 'vmm.io/*' unhide
add path 'nmdmbhyve*' unhide
add path 'zvol' unhide
add path 'zvol/zroot' unhide
add path 'zvol/zroot/vms' unhide
add path 'zvol/zroot/vms/bhyvevm0' unhide
add path 'zvol/zroot/vms/bhyvevm1' unhide
add path 'tap10*' unhide
....

[NOTE]
====
Если в вашем файле [.filename]#/etc/devfs.rules# уже есть другое правило devfs с числовым идентификатором 100, замените указанный в примере идентификатор на другой, еще не использованный.
====

[NOTE]
====
Если не используется файловая система ZFS, пропустите связанные с zvol правила в [.filename]#/etc/devfs.rules#:

[.programlisting]
....
add path 'zvol' unhide
add path 'zvol/zroot' unhide
add path 'zvol/zroot/vms' unhide
add path 'zvol/zroot/vms/bhyvevm0' unhide
add path 'zvol/zroot/vms/bhyvevm1' unhide
....
====

Эти правила приведут к тому, что bhyve

* создаст виртуальную машину с дисковыми томами `bhyvevm0` и `bhyvevm1`,
* будет использовать сетевые интерфейсы [.filename]#tap# с префиксом имени `tap10`. Это означает, что допустимыми именами интерфейсов будут `tap10`, `tap100`, `tap101`, ... `tap109`, `tap1000` и так далее.
+
Ограничение доступа к подмножеству возможных имён интерфейсов [.filename]#tap# предотвратит доступ клетки (и, следовательно, bhyve) к интерфейсам [.filename]#tap# хоста и других клеток.
* используйте устройства [.filename]#nmdm# с префиксом "bhyve", например [.filename]#/dev/nmdmbhyve0#.

Эти правила можно расширять и изменять, используя различные имена гостевых систем и интерфейсов по необходимости.

[NOTE]
====
Если вы планируете использовать bhyve как на хосте, так и в одной или нескольких клеток, помните, что имена интерфейсов [.filename]#tap# и [.filename]#nmdm# будут работать в общей среде. Например, [.filename]#/dev/nmdmbhyve0# можно использовать либо для bhyve на хосте, либо в клетке.
====

Перезапустите devfs для применения изменений:

[source, shell]
....
# service devfs restart
....

Затем добавьте определение для вашей новой клетке в [.filename]#/etc/jail.conf# или [.filename]#/etc/jail.conf.d#. Замените номер интерфейса [.filename]#$if# и IP-адрес на свои значения.

.Использование NAT или маршрутизируемого трафика с межсетевым экраном
[example]
====
[.programlisting]
....
bhyve {
        $if = 0;
        exec.prestart = "/sbin/ifconfig epair${if} create up";
        exec.prestart += "/sbin/ifconfig epair${if}a up";
        exec.prestart += "/sbin/ifconfig epair${if}a name ${name}0";
        exec.prestart += "/sbin/ifconfig epair${if}b name jail${if}";
        exec.prestart += "/sbin/ifconfig ${name}0 inet 192.168.168.1/27";
        exec.prestart += "/sbin/sysctl net.inet.ip.forwarding=1";

        exec.clean;

        host.hostname = "the-hostname-here";
        vnet;
        vnet.interface = "jail${if}";
        path = "/jails/${name}";
        persist;
        securelevel = 3;
        devfs_ruleset = 100;
        mount.devfs;

        allow.vmm;

        exec.start += "/bin/sh /etc/rc";
        exec.stop = "/bin/sh /etc/rc.shutdown";

        exec.poststop += "/sbin/ifconfig ${name}0 destroy";
}
....

Этот пример предполагает использование межсетевого экрана, такого как `pf` или `ipfw`, для трансляции сетевых адресов (NAT) трафика вашей jail. Подробнее о доступных вариантах реализации этого смотрите в главе crossref:firewalls[,Межсетевые экраны].
====
.Использование мостового сетевого подключения
[example]
====
[.programlisting]
....
bhyve {
        $if = 0;
        exec.prestart = "/sbin/ifconfig epair${if} create up";
        exec.prestart += "/sbin/ifconfig epair${if}a up";
        exec.prestart += "/sbin/ifconfig epair${if}a name ${name}0";
        exec.prestart += "/sbin/ifconfig epair${if}b name jail${if}";
        exec.prestart += "/sbin/ifconfig bridge0 addm ${name}0";
        exec.prestart += "/sbin/sysctl net.inet.ip.forwarding=1";

        exec.clean;

        host.hostname = "the-hostname-here";
        vnet;
        vnet.interface = "jail${if}";
        path = "/jails/${name}";
        persist;
        securelevel = 3;
        devfs_ruleset = 100;
        mount.devfs;

        allow.vmm;

        exec.start += "/bin/sh /etc/rc";
        exec.stop = "/bin/sh /etc/rc.shutdown";

        exec.poststop += "/sbin/ifconfig ${name}0 destroy";
}
....
====

[NOTE]
====
Если вы ранее заменили идентификатор набора правил devfs 100 в [.filename]#/etc/devfs.rules# на свой уникальный номер, не забудьте также заменить числовой идентификатор в вашем [.filename]#jails.conf#.
====

[[virtualization-bhyve-jailed-config]]
==== Настройка клетки ====

Для первого запуска клетки и выполнения дополнительных настроек введите:

[source, shell]
....
# cp /etc/resolv.conf /jails/bhyve/etc
# service jail onestart bhyve
# jexec bhyve
# sysrc ifconfig_jail0="inet 192.168.168.2/27"
# sysrc defaultrouter="192.168.168.1"
# sysrc sendmail_enable=NONE
# sysrc cloned_interfaces="tap100"
# exit
....

Перезапустите и включите клетку:

[source, shell]
....
# sysrc jail_enable=YES
# service jail restart bhyve
....

После этого вы можете создать виртуальную машину внутри клетки. Для гостевой системы FreeBSD сначала загрузите установочный ISO-образ:

[source, shell]
....
# jexec bhyve
# cd /vms
# fetch -o freebsd.iso https://download.freebsd.org/releases/ISO-IMAGES/14.0/FreeBSD-14.0-RELEASE-amd64-bootonly.iso
....

[[virtualization-bhyve-jailed-createvm]]
==== Создание виртуальной машины внутри клетки ====

Чтобы создать виртуальную машину, сначала инициализируйте её с помощью `bhyvectl`:

[source, shell]
....
# jexec bhyve
# bhyvectl --create --vm=bhyvevm0
....

[NOTE]
====
Создание гостевой системы с помощью `bhyvectl` может потребоваться при запуске виртуальной машины из клетки. Пропуск этого шага может привести к следующему сообщению об ошибке при запуске `bhyve`:

`vm_open: vm-name could not be opened. No such file or directory`
====

Наконец, используйте предпочитаемый способ запуска гостевой системы.

.Запуск с `vmrun.sh` и ZFS
[example]
====
Используя `vmrun.sh` на файловых системах ZFS:

[source, shell]
....
# jexec bhyve
# sh /usr/share/examples/bhyve/vmrun.sh -c 1 -m 1024M \
     -t tap100 -d /dev/zvol/zroot/vms/bhyvevm0 -i -I /vms/FreeBSD-14.0-RELEASE-amd64-bootonly.iso bhyvevm0
....
====

.Запуск с `vmrun.sh` и UFS
[example]
====
Используя `vmrun.sh` на файловой системе UFS:

[source, shell]
....
# jexec bhyve
# sh /usr/share/examples/bhyve/vmrun.sh -c 1 -m 1024M \
     -t tap100 -d /vms/bhyvevm0 -i -I /vms/FreeBSD-14.0-RELEASE-amd64-bootonly.iso bhyvevm0
....
====

.Запуск bhyve для гостевой системы UEFI с ZFS
[example]
====
Если же вы хотите использовать гостевую систему с UEFI, не забудьте сначала установить необходимый пакет с микропрограммой package:sysutils/bhyve-firmware[] в клетку:

[source, shell]
....
# pkg -j bhyve install bhyve-firmware
....

Затем используйте `bhyve` напрямую:

[source, shell]
....
# bhyve -A -c 4 -D -H -m 2G \
        -s 0,hostbridge \
        -s 1,lpc \
        -s 2,virtio-net,tap100 \
        -s 3,virtio-blk,/dev/zvol/zroot/vms/bhyvevm0 \
	-s 4,ahci-cd,/vms/FreeBSD-14.0-RELEASE-amd64-bootonly.iso \
        -s 31,fbuf,tcp=127.0.0.1:5900,w=1024,h=800,tablet \
        -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \
        -l com1,/dev/nmdbbhyve0A \
        bhyvevm0
....

Это позволит вам подключиться к вашей виртуальной машине `bhyvevm0` через VNC, а также через последовательную консоль по адресу [.filename]#/dev/nmdbbhyve0B#.
====

[[virtualization-bhyve-nmdm]]
=== Консоли виртуальной машины

Преимуществом является обёртывание консоли bhyve в инструмент управления сеансами, например package:sysutils/tmux[] или package:sysutils/screen[], чтобы иметь возможность отключаться и подключаться к консоли. Также можно сделать консоль bhyve нуль-модемным устройством, доступным через `cu`. Для этого загрузите модуль ядра [.filename]#nmdm# и замените `-l com1,stdio` на `-l com1,/dev/nmdm0A`. Устройства [.filename]#/dev/nmdm# создаются автоматически по мере необходимости, где каждое представляет собой пару, соответствующую двум концам нуль-модемного кабеля ([.filename]#/dev/nmdm0A# и [.filename]#/dev/nmdm0B#). Подробнее см. в man:nmdm[4].

[source, shell]
....
# kldload nmdm
# bhyve -A -H -P -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,tap0 -s 3:0,virtio-blk,./linux.img \
    -l com1,/dev/nmdm0A -c 4 -m 1024M linuxguest
# cu -l /dev/nmdm0B
Connected

Ubuntu 13.10 handbook ttyS0

handbook login:
....

Чтобы отключиться от консоли, введите перевод строки (т.е. нажмите `RETURN`), затем тильду (`~`) и точку (`.`). Учтите, что разрывается только соединение, а сеанс входа в систему остаётся активным. Таким образом, другой пользователь, подключившись к той же консоли, может воспользоваться активными сеансами без необходимости аутентификации. По соображениям безопасности рекомендуется выйти из системы перед отключением.

Число в пути устройства [.filename]#nmdm# должно быть уникальным для каждой виртуальной машины и не должно использоваться другими процессами до запуска bhyve. Это число можно выбирать произвольно, оно не обязательно должно быть взято из последовательного ряда чисел. Пара узлов устройств (например, [.filename]#/dev/nmdm0a# и [.filename]#/dev/nmdm0b#) создаётся динамически при подключении консоли bhyve и уничтожается при её завершении. Учитывайте это при создании скриптов для запуска виртуальных машин: необходимо убедиться, что всем виртуальным машинам назначены уникальные устройства [.filename]#nmdm#.

[[virtualization-bhyve-managing]]
=== Управление виртуальными машинами

Для каждой виртуальной машины создается узел устройства в [.filename]#/dev/vmm#. Это позволяет администратору легко просматривать список работающих виртуальных машин:

[source, shell]
....
# ls -al /dev/vmm
total 1
dr-xr-xr-x   2 root  wheel    512 Mar 17 12:19 ./
dr-xr-xr-x  14 root  wheel    512 Mar 17 06:38 ../
crw-------   1 root  wheel  0x1a2 Mar 17 12:20 guestname
crw-------   1 root  wheel  0x19f Mar 17 12:19 linuxguest
crw-------   1 root  wheel  0x1a1 Mar 17 12:19 otherguest
....

Указанную виртуальную машину можно уничтожить с помощью `bhyvectl`:

[source, shell]
....
# bhyvectl --destroy --vm=guestname
....

Уничтожение виртуальной машины таким способом означает её немедленное завершение. Все несохранённые данные будут потеряны, открытые файлы и файловые системы могут быть повреждены. Для корректного завершения работы виртуальной машины отправьте сигнал `TERM` её процессу bhyve. Это инициирует событие ACPI завершения работы для гостевой системы:

[source, shell]
....
# ps ax | grep bhyve
17424  -  SC      56:48.27 bhyve: guestvm (bhyve)
# kill 17424
....

[[virtualization-tools-utilities]]
=== Инструменты и утилиты

В портах доступно множество утилит и приложений, которые помогают упростить настройку и управление виртуальными машинами bhyve:

.Менеджеры bhyve
[options="header", cols="1,1,1,1"]
|===
| Имя | Лицензия | Пакет | Documentation

| vm-bhyve
| BSD-2
| package:sysutils/vm-bhyve[]
| link:https://github.com/churchers/vm-bhyve[Документация]

| CBSD
| BSD-2
| package:sysutils/cbsd[]
| link:https://github.com/cbsd/cbsd/tree/develop/share/docs[Документация]

| Virt-Manager
| LGPL-3
| package:deskutils/virt-manager[]
| link:https://virt-manager.org/[Документация]

| Bhyve RC Script
| Неизвестно
| package:sysutils/bhyve-rc[]
| link:https://www.freshports.org/sysutils/bhyve-rc/[Документация]

| bmd
| BSD-2
| package:sysutils/bmd[]
| link:https://github.com/yuichiro-naito/bmd[Документация]

| vmstated
| BSD-2
| package:sysutils/vmstated[]
| link:https://github.com/christian-moerz/vmstated[Документация]

|===

[[virtualization-bhyve-onboot]]
=== Постоянная конфигурация

Для настройки системы на автоматический запуск гостевых систем bhyve при загрузке необходимо внести изменения в некоторые конфигурационные файлы.

[.procedure]
. [.filename]#/etc/sysctl.conf#
+
При использовании интерфейсов [.filename]#tap# в качестве сетевого бэкенда необходимо либо вручную переводить каждый используемый интерфейс [.filename]#tap# в состояние UP, либо просто установить следующий параметр sysctl:
+
[.programlisting]
....
net.link.tap.up_on_open=1
....

. [.filename]#/etc/rc.conf#
+
Чтобы подключить устройство [.filename]#tap# вашей виртуальной машины к сети через [.filename]#bridge#, необходимо сохранить настройки устройства в [.filename]#/etc/rc.conf#. Дополнительно можно загрузить необходимые модули ядра `vmm` для bhyve и `nmdm` для устройств [.filename]#nmdm# через переменную конфигурации `kld_list`. При настройке `ifconfig_bridge0` убедитесь, что заменили `<ipaddr>/<netmask>` на реальный IP-адрес вашего физического интерфейса ([.filename]#igb0# в данном примере) и удалите IP-настройки с вашего физического устройства.
+
[source, shell]
....
# sysrc cloned_interfaces+="bridge0 tap0"
# sysrc ifconfig_bridge0="inet <ipaddr>/<netmask> addm igb0 addm tap0"
# sysrc kld_list+="nmdm vmm"
# sysrc ifconfig_igb0="up"
....

[[virtualization-bhyve-onboot-bridgenet]]
.Установка IP для устройства bridge
[example]
====
Для хоста с интерфейсом _igb0_, подключенным к сети с IP `10.10.10.1` и маской подсети `255.255.255.0`, используйте следующие команды:

[source, shell]
....
# sysrc ifconfig_igb0="up"
# sysrc ifconfig_bridge0="inet 10.10.10.1/24 addm igb0 addm tap0"
# sysrc kld_list+="nmdm vmm"
# sysrc cloned_interfaces+="bridge0 tap0"
....
====

[WARNING]
====
Изменение конфигурации IP-адреса системы может заблокировать ваш доступ, если вы выполняете эти команды, подключившись удаленно (например, через SSH)! Примите меры предосторожности, чтобы сохранить доступ к системе, или вносите эти изменения, работая в локальной терминальной сессии.
====

[[virtualization-host-xen]]
== FreeBSD в качестве хоста Xen(TM)

Xen — это гипервизор класса 1 с лицензией GPLv2 для архитектур Intel(R) и ARM(R). Начиная с FreeBSD 8.0, система включает поддержку непривилегированных доменов (виртуальных машин) https://wiki.xenproject.org/wiki/DomU[DomU] и https://en.wikipedia.org/wiki/Amazon_Elastic_Compute_Cloud[Amazon EC2] для i386(TM) и AMD(R) 64-битных процессоров, а также поддержку управляющего домена (хоста) Dom0 в FreeBSD 11.0. Поддержка паравиртуализованных (PV) доменов была удалена в FreeBSD 11 в пользу аппаратно-виртуализованных (HVM) доменов, которые обеспечивают лучшую производительность.

Xen(TM) — это гипервизор первого типа (bare-metal), что означает, что он загружается первым после BIOS. Затем запускается специальная привилегированная гостевая система, называемая Domain-0 (сокращенно `Dom0`). Dom0 использует свои особые привилегии для прямого доступа к физическому оборудованию, что делает его высокопроизводительным решением. Она может напрямую обращаться к контроллерам дисков и сетевым адаптерам. Инструменты управления Xen(TM) для управления гипервизором Xen(TM) также используются Dom0 для создания, перечисления и удаления виртуальных машин. Dom0 предоставляет виртуальные диски и сетевые ресурсы для непривилегированных доменов, часто называемых `DomU`. Xen(TM) Dom0 можно сравнить с сервисной консолью других гипервизоров, в то время как DomU — это среда, в которой запускаются отдельные гостевые виртуальные машины.

Xen(TM) может переносить виртуальные машины между разными серверами Xen(TM). Если два хоста Xen используют общее хранилище данных, миграцию можно выполнить без предварительного выключения виртуальной машины. Вместо этого миграция выполняется в реальном времени, пока DomU работает, и нет необходимости перезапускать его или планировать простой. Это полезно в сценариях обслуживания или обновления, чтобы гарантировать непрерывность предоставления услуг DomU. Множество других возможностей Xen(TM) перечислены на https://wiki.xenproject.org/wiki/Category:Overview[странице обзора Xen Wiki]. Обратите внимание, что не все функции пока поддерживаются в FreeBSD.

[[virtualization-host-xen-requirements]]
=== Требования к оборудованию для Xen(TM) Dom0

Для запуска гипервизора Xen(TM) на хосте требуется определенная аппаратная функциональность. Для работы FreeBSD в качестве хоста Xen (Dom0) необходимы поддержка Intel Extended Page Tables (https://en.wikipedia.org/wiki/Extended_Page_Table[EPT]) или AMD Nested Page Tables (https://en.wikipedia.org/wiki/Rapid_Virtualization_Indexing[NPT]), а также поддержка Input/Output Memory Management Unit (https://en.wikipedia.org/wiki/List_of_IOMMU-supporting_hardware[IOMMU]) в процессоре хоста.

[NOTE]
====
Для запуска FreeBSD 13 в качестве Xen(TM) Dom0 система должна быть загружена в режиме legacy boot (BIOS). FreeBSD 14 и новее поддерживают загрузку в качестве Xen(TM) Dom0 как в режиме BIOS, так и в режиме UEFI.
====

[[virtualization-host-xen-dom0-setup]]
=== Настройка управляющего домена Xen(TM) Dom0

Пользователям следует установить пакеты package:emulators/xen-kernel[] и package:sysutils/xen-tools[], основанные на Xen(TM) 4.18.

После установки пакетов Xen необходимо отредактировать конфигурационные файлы, чтобы подготовить хост для интеграции с Dom0. В файл [.filename]#/etc/sysctl.conf# следует добавить запись, отключающую ограничение на количество страниц памяти, которые могут быть закреплены. В противном случае виртуальные машины DomU с повышенными требованиями к памяти не смогут запуститься.

[source, shell]
....
# echo 'vm.max_wired=-1' >> /etc/sysctl.conf
....

Ещё одна настройка, связанная с памятью, включает изменение файла [.filename]#/etc/login.conf#, где необходимо установить параметр `memorylocked` в значение `unlimited`. В противном случае создание доменов DomU может завершиться ошибкой `Cannot allocate memory`. После внесения изменений в [.filename]#/etc/login.conf# выполните команду `cap_mkdb` для обновления базы данных capability. Подробности см. в разделе crossref:security[security-resourcelimits,"Ограничения ресурсов"].

[source, shell]
....
# sed -i '' -e 's/memorylocked=64K/memorylocked=unlimited/' /etc/login.conf
# cap_mkdb /etc/login.conf
....

Добавьте запись для консоли Xen(TM) в [.filename]#/etc/ttys#:

[source, shell]
....
# echo 'xc0     "/usr/libexec/getty Pc"         xterm   onifconsole  secure' >> /etc/ttys
....

Выбор ядра Xen(TM) в [.filename]#/boot/loader.conf# активирует Dom0. Xen(TM) также требует ресурсы, такие как процессор и память, от основной машины для себя и других доменов DomU. Количество процессоров и памяти зависит от индивидуальных требований и возможностей оборудования. В этом примере для Dom0 доступно 8 ГБ памяти и 4 виртуальных процессора. Также активирована последовательная консоль и определены параметры журналирования.

Следующая команда используется для пакетов Xen 4.7:

[source, shell]
....
# echo 'hw.pci.mcfg=0' >> /boot/loader.conf
# echo 'if_tap_load="YES"' >> /boot/loader.conf
# echo 'xen_kernel="/boot/xen"' >> /boot/loader.conf
# echo 'xen_cmdline="dom0_mem=8192M dom0_max_vcpus=4 dom0pvh=1 console=com1,vga com1=115200,8n1 guest_loglvl=all loglvl=all"' >> /boot/loader.conf
....

Для версий Xen 4.11 и выше вместо этого следует использовать следующую команду:

[source, shell]
....
# echo 'if_tap_load="YES"' >> /boot/loader.conf
# echo 'xen_kernel="/boot/xen"' >> /boot/loader.conf
# echo 'xen_cmdline="dom0_mem=8192M dom0_max_vcpus=4 dom0=pvh console=com1,vga com1=115200,8n1 guest_loglvl=all loglvl=all"' >> /boot/loader.conf
....

[TIP]
====

Файлы журналов, создаваемые Xen(TM) для DomU ВМ, хранятся в [.filename]#/var/log/xen#. В случае возникновения проблем обязательно проверьте содержимое этого каталога.
====

Активируйте сервис xencommons при загрузке системы:

[source, shell]
....
# sysrc xencommons_enable=yes
....

Этих настроек достаточно для запуска системы с поддержкой Dom0. Однако в ней отсутствует сетевая функциональность для машин DomU. Чтобы это исправить, определите мостовой интерфейс с основной сетевой картой системы, который DomU-виртуальные машины смогут использовать для подключения к сети. Замените _em0_ на имя сетевого интерфейса хоста.

[source, shell]
....
# sysrc cloned_interfaces="bridge0"
# sysrc ifconfig_bridge0="addm em0 SYNCDHCP"
# sysrc ifconfig_em0="up"
....

Перезагрузите хост для загрузки ядра Xen(TM) и запуска Dom0.

[source, shell]
....
# reboot
....

После успешной загрузки ядра Xen(TM) и повторного входа в систему, инструмент управления Xen(TM) `xl` используется для отображения информации о доменах.

[source, shell]
....
# xl list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0  8192     4     r-----     962.0
....

Вывод подтверждает, что Dom0 (называемый `Domain-0`) имеет идентификатор `0` и работает. Также у него есть память и виртуальные CPU, которые были определены ранее в [.filename]#/boot/loader.conf#. Дополнительную информацию можно найти в https://www.xenproject.org/help/documentation.html[документации Xen(TM)]. Теперь можно создавать гостевые ВМ DomU.

[[virtualization-host-xen-domu-setup]]
=== Конфигурация гостевой виртуальной машины Xen(TM) DomU

Непривилегированные домены состоят из конфигурационного файла и виртуальных или физических жестких дисков. Виртуальное дисковое хранилище для DomU может быть файлами, созданными с помощью man:truncate[1], или томами ZFS, как описано в crossref:zfs[zfs-zfs-volume,“Создание и уничтожение томов”]. В этом примере используется том объемом 20 ГБ. Виртуальная машина создается с томом ZFS, образом ISO FreeBSD, 1 ГБ оперативной памяти и двумя виртуальными процессорами. Файл установки ISO извлекается с помощью man:fetch[1] и сохраняется локально в файле с именем [.filename]#freebsd.iso#.

[source, shell]
....
# fetch https://download.freebsd.org/releases/ISO-IMAGES/14.0/FreeBSD-14.0-RELEASE-amd64-bootonly.iso -o freebsd.iso
....

Создается том ZFS объемом 20 ГБ с именем [.filename]#xendisk0#, который будет использоваться в качестве дискового пространства для виртуальной машины.

[source, shell]
....
# zfs create -V20G -o volmode=dev zroot/xendisk0
....

Новый гостевая ВМ DomU определяется в файле. Некоторые конкретные определения, такие как имя, раскладка клавиатуры и детали подключения VNC, также задаются. Следующий файл [.filename]#freebsd.cfg# содержит минимальную конфигурацию DomU для этого примера:

[source, shell]
....
# cat freebsd.cfg
builder = "hvm" <.>
name = "freebsd" <.>
memory = 1024 <.>
vcpus = 2 <.>
vif = [ 'mac=00:16:3E:74:34:32,bridge=bridge0' ] <.>
disk = [
'/dev/zvol/tank/xendisk0,raw,hda,rw', <.>
'/root/freebsd.iso,raw,hdc:cdrom,r' <.>
  ]
vnc = 1 <.>
vnclisten = "0.0.0.0"
serial = "pty"
usbdevice = "tablet"
....

Эти строки объясняются более подробно:

<.> Это определяет, какой тип виртуализации использовать. `hvm` означает аппаратную виртуализацию или аппаратную виртуальную машину. Гостевые операционные системы могут работать без изменений на процессорах с расширениями виртуализации, обеспечивая производительность, почти такую же, как и на физическом оборудовании. `generic` — значение по умолчанию, которое создает PV-домен.
<.> Имя этой виртуальной машины для отличия от других, работающих на том же Dom0. Обязательно.
<.> Количество оперативной памяти в мегабайтах, которое будет доступно виртуальной машине. Этот объем вычитается из общего объема доступной памяти гипервизора, а не из памяти Dom0.
<.> Количество виртуальных CPU, доступных гостевой ВМ. Для наилучшей производительности не следует создавать гостевые системы с количеством виртуальных CPU, превышающим число физических CPU на хосте.
<.> Виртуальный сетевой адаптер. Это мост, подключенный к сетевому интерфейсу хоста. Параметр `mac` — это MAC-адрес, установленный на виртуальном сетевом интерфейсе. Этот параметр необязателен: если MAC-адрес не указан, Xen(TM) сгенерирует случайный.
<.> Полный путь к диску, файлу или тому ZFS для дискового хранилища этой ВМ. Параметры и определения нескольких дисков разделяются запятыми.
<.> Определяет загрузочный носитель, с которого устанавливается исходная операционная система. В данном примере это загруженный ранее образ ISO. О других типах устройств и настраиваемых параметрах см. документацию Xen(TM).
<.> Параметры, управляющие подключением VNC к последовательной консоли DomU. В порядке перечисления: поддержка VNC, определение IP-адреса для прослушивания, файл устройства последовательной консоли и метод ввода для точного позиционирования мыши и других методов ввода. `keymap` определяет, какую раскладку клавиатуры использовать, по умолчанию установлено значение `english`.

После создания файла со всеми необходимыми параметрами DomU создаётся путём передачи его в `xl create` в качестве аргумента.

[source, shell]
....
# xl create freebsd.cfg
....

[NOTE]
====
Каждый раз при перезапуске Dom0 конфигурационный файл необходимо снова передавать в `xl create`, чтобы воссоздать DomU. По умолчанию после перезагрузки создается только Dom0, но не отдельные виртуальные машины. Виртуальные машины могут продолжить работу с момента остановки, так как операционная система сохраняется на виртуальном диске. Конфигурация виртуальной машины может со временем меняться (например, при добавлении памяти). Конфигурационные файлы виртуальных машин необходимо надлежащим образом резервировать и хранить в доступном месте, чтобы иметь возможность воссоздать гостевую виртуальную машину при необходимости.
====

Вывод команды `xl list` подтверждает, что DomU был создан.

[source, shell]
....
# xl list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0  8192     4     r-----  1653.4
freebsd                                      1  1024     1     -b----   663.9
....

Для начала установки базовой операционной системы запустите клиент VNC, указав основной сетевой адрес хоста или IP-адрес, определённый в строке `vnclisten` файла [.filename]#freebsd.cfg#. После установки операционной системы завершите работу DomU и отключите VNC-клиент. Отредактируйте файл [.filename]#freebsd.cfg#, удалив строку с определением `cdrom` или закомментировав её, поставив символ `+#+` в начале строки. Чтобы загрузить новую конфигурацию, необходимо удалить старый DomU командой `xl destroy`, передав в качестве параметра имя или идентификатор. После этого воссоздайте его, используя изменённый файл [.filename]*freebsd.cfg*.

[source, shell]
....
# xl destroy freebsd
# xl create freebsd.cfg
....

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

[[virtualization-host-xen-troubleshooting]]
=== Устранение неполадок

Этот раздел содержит основную информацию, которая поможет в устранении проблем, возникающих при использовании FreeBSD в качестве хоста или гостевой системы Xen™.

[[virtualization-host-xen-troubleshooting-host]]
==== Устранение неполадок при загрузке хоста

Обратите внимание, что следующие советы по устранению неполадок предназначены для Xen(TM) 4.11 или новее. Если вы всё ещё используете Xen(TM) 4.7 и сталкиваетесь с проблемами, рассмотрите возможность перехода на более новую версию Xen(TM).

Для устранения проблем с загрузкой хоста вам, скорее всего, понадобится последовательный кабель или отладочный USB-кабель. Подробный вывод загрузки Xen(TM) можно получить, добавив параметры к опции `xen_cmdline` в файле [.filename]#loader.conf#. Несколько соответствующих отладочных параметров:

* `iommu=debug`: может использоваться для вывода дополнительной диагностической информации о iommu.
* `dom0=verbose`: может использоваться для вывода дополнительной диагностической информации о процессе сборки dom0.
* `sync_console`: флаг для принудительного синхронного вывода на консоль. Полезен при отладке, чтобы избежать потери сообщений из-за ограничения скорости. Никогда не используйте эту опцию в рабочих средах, так как она может позволить злоумышленникам выполнять DoS-атаки на Xen(TM) через консоль.

FreeBSD также следует загружать в подробном режиме для выявления возможных проблем. Чтобы активировать подробную загрузку, выполните следующую команду:

[source, shell]
....
# echo 'boot_verbose="YES"' >> /boot/loader.conf
....

Если ни один из этих вариантов не помог решить проблему, отправьте журнал загрузки по последовательному соединению по адресам mailto:freebsd-xen@FreeBSD.org[freebsd-xen@FreeBSD.org] и mailto:xen-devel@lists.xenproject.org[xen-devel@lists.xenproject.org] для дальнейшего анализа.

[[virtualization-host-xen-troubleshooting-guest]]
==== Устранение неполадок при создании гостевой системы

Проблемы также могут возникать при создании гостевых систем. В следующем разделе представлены рекомендации для диагностики подобных проблем.

Наиболее распространённой причиной сбоев при создании гостевой системы является команда `xl`, которая выдаёт ошибку и завершается с кодом возврата, отличным от 0. Если предоставленного сообщения об ошибке недостаточно для определения проблемы, можно получить более подробный вывод от `xl`, многократно используя опцию `v`.

[source, shell]
....
# xl -vvv create freebsd.cfg
Parsing config from freebsd.cfg
libxl: debug: libxl_create.c:1693:do_domain_create: Domain 0:ao 0x800d750a0: create: how=0x0 callback=0x0 poller=0x800d6f0f0
libxl: debug: libxl_device.c:397:libxl__device_disk_set_backend: Disk vdev=xvda spec.backend=unknown
libxl: debug: libxl_device.c:432:libxl__device_disk_set_backend: Disk vdev=xvda, using backend phy
libxl: debug: libxl_create.c:1018:initiate_domain_create: Domain 1:running bootloader
libxl: debug: libxl_bootloader.c:328:libxl__bootloader_run: Domain 1:not a PV/PVH domain, skipping bootloader
libxl: debug: libxl_event.c:689:libxl__ev_xswatch_deregister: watch w=0x800d96b98: deregister unregistered
domainbuilder: detail: xc_dom_allocate: cmdline="", features=""
domainbuilder: detail: xc_dom_kernel_file: filename="/usr/local/lib/xen/boot/hvmloader"
domainbuilder: detail: xc_dom_malloc_filemap    : 326 kB
libxl: debug: libxl_dom.c:988:libxl__load_hvm_firmware_module: Loading BIOS: /usr/local/share/seabios/bios.bin
...
....

Если подробный вывод не помог диагностировать проблему, также существуют журналы QEMU и инструментов Xen(TM) в [.filename]#/var/log/xen#. Обратите внимание, что имя домена добавляется к имени журнала, поэтому если домен называется `freebsd`, вы найдете файлы [.filename]#/var/log/xen/xl-freebsd.log# и, вероятно, [.filename]#/var/log/xen/qemu-dm-freebsd.log#. Оба файла журналов могут содержать полезную информацию для отладки. Если ничто из этого не помогло решить проблему, пожалуйста, отправьте описание возникшей проблемы и как можно больше информации на адреса mailto:freebsd-xen@FreeBSD.org[freebsd-xen@FreeBSD.org] и mailto:xen-devel@lists.xenproject.org[xen-devel@lists.xenproject.org], чтобы получить помощь.
