Под капотом · Виртуализация · Создание и запуск
Включение ВМ
Пользователь запускает ВМ, которая уже определена в libvirt. Для этого он вводит команду:
virsh start vm1
После выполнения команды идёт самая длинная цепочка - окружение, QEMU, инициализация KVM, выходы из гостя.
-
пользователь 1. Пользователь вводит команду включения
virDomainCreate(dom)
Клиент отправляет один RPC-вызов и ждёт результат - всё остальное делает демон.
-
libvirt 2. Демон готовит окружение
тома и диски → TAP/bridge → cgroup auid/gid → метки SELinux/AppArmor → SMBIOS
Это та «невидимая» работа, которой нет в аргументах QEMU и которая чаще всего ломается.
-
libvirt 3. Демон запускает процесс QEMU
fork/exec qemu-system-x86_64 \ -machine q35 -accel kvm \ -drive …, -netdev …, -qmp unix:…
Командная строка собирается из XML; часть ресурсов передаётся уже открытыми файловыми дескрипторами.
-
QEMU 4. QEMU собирает машину
чипсет, RAM, устройства, прошивка (SeaBIOS/UEFI)
Один процесс QEMU = одна ВМ. Внутри - основной цикл плюс по потоку на каждый vCPU.
-
KVM 5. QEMU получает доступ к KVM
open("/dev/kvm") KVM_GET_API_VERSION → 12 // иначе userspace обязан отказаться KVM_CHECK_EXTENSION(KVM_CAP_*)API стабилен с Linux 2.6.22; новые возможности проверяются запросом, а не версией ядра.
-
KVM 6. Ядро создаёт виртуальную машину
KVM_CREATE_VM → vm fd KVM_SET_USER_MEMORY_REGION → слоты памяти гостя
У новой VM нет ни памяти, ни процессоров: и то и другое добавляется отдельными шагами.
-
KVM 7. Появляются прерывания и vCPU
KVM_CREATE_IRQCHIP // PIC + IOAPIC + LAPIC в ядре KVM_CREATE_VCPU × N → по fd на каждый vCPU
in-kernel irqchip убирает часть выходов в userspace; kernel-irqchip=split - компромисс между безопасностью и скоростью.
-
QEMU 8. Потоки vCPU входят в главный цикл
на каждый vCPU: mmap(kvm_run) loop { ioctl(KVM_RUN) → обработать exit }Пока гость делает «разрешённое», поток хоста не выходит из ioctl(KVM_RUN).
-
libvirt 9. Демон проверяет, что это действительно KVM
{"execute":"qmp_capabilities"} {"execute":"query-kvm"} ← {"return":{"enabled":true,"present":true}}Так отличают аппаратную виртуализацию от эмуляции инструкций (TCG).
-
гость 10. Гость начинает загрузку
прошивка → загрузчик → ОС
Первые обращения к эмулируемым устройствам становятся выходами из гостя - QEMU их обслуживает.