Под капотом · Виртуализация · Работа и остановка

ВМ просто работает

Пользователь смотрит на работающую ВМ и её счётчики. Для этого он вводит команды:

Команда
virsh domstate vm1
virsh domstats vm1
libvirt API virDomainGetInfo(dom) QMP query-status

После выполнения команд видно, что происходит внутри:

  • Команда domstate называет состояние домена;
  • Команда domstats отдаёт счётчики по дискам, памяти и vCPU;
  • Гость всё это время исполняется прямо на процессоре.
  • пользователь 1. Пользователь работает внутри гостя
    запускает программу в гостевой ОС
    # для гипервизора это просто поток инструкций

    Гость не знает, что он гость, пока не наткнётся на привилегированную операцию или устройство.

  • гость 2. Код исполняется в гостевом режиме CPU
    CPU в режиме VMX non-root / SVM guest

    Аппаратный режим виртуализации: гость думает, что владеет процессором.

  • KVM 3. Ядро фиксирует выход из гостя
    kvm_run->exit_reason =
      KVM_EXIT_IO | KVM_EXIT_MMIO | KVM_EXIT_HLT | …

    Причина выхода пишется в общую область памяти kvm_run, её читает QEMU.

  • QEMU 4. QEMU обслуживает обращение
    эмуляция доступа к устройству
    → обновление состояния → снова ioctl(KVM_RUN)

    Каждый такой цикл - переключение режимов процессора. Это и есть цена виртуализации.

  • QEMU 5. Параллельно идёт остальная жизнь
    основной цикл: I/O, таймеры, устройства,
    block jobs, команды QMP

    Пока vCPU-потоки «спят» в KVM_RUN, основной цикл обрабатывает всё остальное.

  • libvirt 6. Демон следит за состоянием
    {"execute":"query-status"}
    события: STOP / RESUME / …

    libvirt кэширует состояние и рассылает события клиентам, чтобы каждый клиент не опрашивал QEMU сам.

  • пользователь 7. Пользователь видит статус
    virsh domstate vm1 → running
    virsh domstats vm1

    Если хост грузится на 100%, а гость «спит» - ищите шторм выходов: эмуляция вместо virtio или неверный irqchip.