Qemu guest agent windows что это

Резервное копирование виртуальных машин KVM без остановки

Есть хост CentOS 7, KVM, гость vm1 (Windows 7 x64, но что Windows, что Linux, отличаться по сути будет только установка драйвера внутри гостевой vm). Пока виртуальная машина работает, копировать ее диск — идея неправильная. Непонятно, что будет скопировано и непонятно, восстановится ли потом. Идея live backup (т.е. backup без остановки) состоит в следующем — делаем снапшот виртуальной машины, при этом чтение/запись начинает выполняться в этот снапшот. Сразу после создания снапшота исходный диск виртуальной машины уже ничем не занят — все новое копируется в файл снапшота. Можно спокойно скопировать этот диск. Это займет какое-то время, в течении которого vm работает, что-то записывается, удаляется. После того, как мы спокойно скопируем диск, нужно будет дать команду все из снапшота залить в основной диск vm. Снапшот нам нужен был только как временная мера.

Снепшот -> бекап диска -> объединение снепшота с бекапом диска:

# virsh snapshot-create-as —domain vm1 —name vm1-snapshot —disk-only —atomic —quiesce –no-metadata

Бекап диска vm1:

# cp /vms/vm1.iso /backup/vms/vm1/

# virsh blockcommit vm1 vda —active —verbose —pivot

где vda — это устройство (сокет системного диска) vm1, на котором установлена гостевая OS:

Т.е. в работающей vm1 файл диска — /vms/vm1.iso, устройство — vda.

Но прямо с первой команды мы получим ошибку:
error: argument unsupported: QEMU guest agent is not configured

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

  1. указать в конфиге vm агента QEMU
  2. в гостевой vm установить службу агента QEMU
  3. убедиться, что хост и агент взаимодействуют.
  4. делать бекапы.

Готовим виртуальную машину к установке агента QEMU

Способ первый (с выключением гостевой виртуальной машины).

В конфигурацию гостевой vm нужно добавить специальное устройство — агент QEMU.

В параметре source указывается имя сокета, которое должно быть уникальным в рамках хоста. Также надо отметить, что при включенном SELinux могут быть проблемы с соединением к этому сокету, из-за чего может возникать ошибка «QEMU guest agent is not connected».

# virsh edit vm1
Domain vm1 XML configuration edited.

Внимание! Выключить и включить гостевую виртуальную машину (перезагрузка может не помочь).

Второй способ (без выключения виртуальной машины):

Этот способ я нашел позднее и не проверял лично, но, тем не менее, он указан в руководстве Red Hat.

Готовим файл agent-win7.xml:

# virsh attach-device vm1 agent-win7.xml

Применительно к CentOS/RedHat указывать уникальный путь bind не требуется, поэтому шаблон может быть одинаковым для разных vm. Итак, готовим файл agent.xml:

# virsh attach-device vm1 agent.xml

Установка драйверов агента QEMU

. в гостевой виртуальной машине CentOS

# yum install qemu-guest-agent
# systemctl start qemu-guest-agent

. в гостевой виртуальной машине Debian/Ubuntu

# apt install qemu-guest-agent

. в гостевой виртуальной машине Windows (VirtIO Serial driver)

Установить virtio-win драйверы в гостевую vm:

# virsh attach-disk vm1 /usr/share/virtio-win/virtio-win-0.1.171.iso hda —type cdrom —mode readonly
Disk attached successfully

Внутри гостевой виртуальной машины:

1) Установите CD-Drive:\guest-agent\qemu-ga-x64 (или x86).

2) В диспетчере устройств обновите драйвер внутри vm и перезагрузите ее (перезагрузка может и не потребоваться, но надо будет запустить службы QEMU Guest Agent и QEMU Guest Agent VSS Provider):

QEMU guest agent is not connected

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

error: Guest agent is not responding: QEMU guest agent is not connected

Если сделать дамп состояния vm1, то видно, что агент не подключен (disconnected):

Это может быть из-за:

  1. ошибки запуска агента в гостевой vm1 (например, виртуальная машина не была перезагружена или не были запущены службы QEMU Guest Agent и QEMU Guest Agent VSS Provider);
  2. из-за включенного SELinux на хосте (попробуйте отключить «setenforce 0 » и посмотреть, будет connected или нет)
  3. или еще из-за чего-нибудь.

Исправляем и пробуем наконец-то сделать бекап виртуальной машины без ее остановки:

# virsh snapshot-create-as —domain vm1 —name vm1.snap —disk-only —atomic —quiesce –no-metadata
Domain snapshot snapshot created

# cp /vms/vm1.iso /backup/vms/vm1/

# virsh dumpxml vm1 > /backup/vms/vm1/vm1-dumpxml.xml

Слияние снапшота с копией

# virsh blockcommit vm1 vda —active —verbose —pivot
Block commit: [100 %]
Successfully pivoted

Читайте также:  Если не успел активировать windows

Теперь данные будут записываться в основной диск vm1, а в backup будет копия диска и конфиг, восстановиться из которых можно с помощью virsh create.

Тут живет фура ¯\_(ツ)_/¯

воскресенье, 4 сентября 2016 г.

KVM qemu-agent настройка, выполнение команд (guest-exec)

Подготовка.

Исполнение команд guest-exec

Теперь мы можем использовать агент и делать с виртуалкой «все что захотим».
Начнем с выполнения команд внутри данной виртуальной машины.
Например установим пакет dstat, в котором находится утилита dstat.
Для этого на хост машине выполним команду:
на вывод команда выдаст что-то вроде:
используя этот pid узнаем чем закончилось дело:

  • exited:true — говорит о том что программа закончила свое выполнение
  • exitcode:0 — указывает код возврата программы (0 как правило говорит о успешном выполнении)

Обращаю внимание на то, что агрументы передавались каждый в отдельной строке
«arg»:[«install», «dstat», «-y»]
казалось бы — можно упростить и написать аргументы в одной строке не разделяя:
но нет:
Для получения помимо exitcode вывода команды (stdout), нужно добавить в arguments опцию capture-output и установить ее в true:

Вывод команды находится в out-data, он закодирован в base64, для раскодирования можно воспользоваться любым онлайн сервисом, я использовал https://www.base64decode.org или утилитой base64 из состава пакета coreutils. Пример:
в обоих случаях получается примерно такой вывод:

Теперь предлагаю рассмотреть вариант, когда скрипт или команда выполняется не мгновенно:
Если запросить статус такой команды, в процессе выполнения, то в ответе будет exited: false:
Внутри виртуальной машины в этот момент ситуация выглядит примерно так:
Т.е. qemu агент является родительским процессом для наших команд.
Выполним еще раз — ага, пока выполняется:
И наконец, когда команда или скрипт завершаются, в ответе будет «стандартный» статус :
Обращаю внимание, что пока команда не выполнилась, можно запрашивать ее статус по pid’у неограниченное кол-во раз.
Но после выполнения первый запрос к данным статуса, очищает эту информацию и повторное обращение выдаст ошибку:
Этот момент очень важен для организации скриптов-обёрток или других систем, использользующих данные команды или их выводы.

Отлично, с этим разобрались. Теперь предлагаю посмотреть, что происходит если выполняемая программа завершается не успешно, например запуск sleep с опцией -1:
Вывод ошибки помещается в err-data и кодируется base64:
в err-data помещается все что попадает на stderr’a:

Переменные out-data и err-data заполняются потоками stdout и stderr (если те не пустые), т.е. даже при успешном выполнении команды, которая что-то выводит на stderr, в status’e будет фигурировать err-data.
Например вывод статуса команды:
вернет нам заполненные err-data и out-data одновременно.

В следующий раз я расскажу о чтении\редактировании файлов и других возможностях qemu-agent.

Qemu-guest-agent

Contents

Introduction — What is qemu-guest-agent

The qemu-guest-agent is a helper daemon, which is installed in the guest. It is used to exchange information between the host and guest, and to execute command in the guest.

In Proxmox VE, the qemu-guest-agent is used for mainly two things:

  1. To properly shutdown the guest, instead of relying on ACPI commands or windows policies
  2. To freeze the guest file system when making a backup (on windows, use the volume shadow copy service VSS).

Installation

You have to install guest-agent in each VM and then enable it, you can do that in the Proxmox VE Webinterface (GUI)

or via CLI: qm set VMID —agent 1

Guest

Linux

On Linux you have to simply install the qemu-guest-agent, please refer to the documentation of your system.

We show here the commands for Debian/Ubuntu and Redhat based systems:

on Debian/Ubuntu based systems (with apt-get) run:

and on Redhat based systems (with yum):

Depending on the distribution, the guest agent might not start automatically after the installation.

Start it either directly with

(should work for most distributions) or reboot the guest.

Windows

First you have to download the virtio-win driver iso (see Windows VirtIO Drivers).

Then install the virtio-serial driver:

  1. Attach the ISO to your windows VM (virtio-*.iso)
  2. Go to the windows Device Manager
  3. Look for «PCI Simple Communications Controller»
  4. Right Click -> Update Driver and select on the mounted iso in DRIVE:\vioserial\ \ where is your Windows Version (e.g. 2k12R2 for Windows 2012 R2)

After that, you have to install the qemu-guest-agent:

  1. Go to the mounted ISO in explorer
  2. The guest agent installer is in the directory guest-agent
  3. Execute the installer with double click (either qemu-ga-x86_64.msi (64-bit) or qemu-ga-i386.msi (32-bit)

After that the qemu-guest-agent should be up and running. You can validate this in the list of Window Services, or in a PowerShell with:

Читайте также:  Выскакивает установить windows 10

If it is not running, you can use the Services control panel to start it and make sure that it will start automatically on the next boot.

Testing that the communication with the guest agent is working

The communication with the guest agent takes place over a unix socket located in /var/run/qemu-server/ .qga You can test the communication qm agent:

if the qemu-guest-agent is correctly runnning in the VM, it will return without an error message.

Features/GuestAgent

Contents

Summary

Implement support for QMP commands and events that terminate and originate respectively within the guest using an agent built as part of QEMU.

Detailed Summary

Ultimately the QEMU Guest Agent aims to provide access to a system-level agent via standard QMP commands.

This support is targeted for a future QAPI-based rework of QMP, however, so currently, for QEMU 0.15, the guest agent is exposed to the host via a separate QEMU chardev device (generally, a unix socket) that communicates with the agent using the QMP wire protocol (minus the negotiation) over a virtio-serial or isa-serial channel to the guest. Assuming the agent will be listening inside the guest using the virtio-serial device at /dev/virtio-ports/org.qemu.guest_agent.0 (the default), the corresponding host-side QEMU invocation would be something:

Commands would be then be issued by connecting to /tmp/qga.sock, writing the QMP-formatted guest agent command, reading the QMP-formatted response, then disconnecting from the socket. (It’s not strictly necessary to disconnect after a command, but should be done to allow sharing of the guest agent with multiple client when exposing it as a standalone service in this fashion. When guest agent passthrough support is added to QMP, QEMU/QMP will handle arbitration between multiple clients).

When QAPI-based QMP is available (somewhere around the QEMU 0.16 timeframe), a different host-side invocation that doesn’t involve access to the guest agent outside of QMP will be used. Something like:

Currently this is planned to be done as a pseudo-chardev that only QEMU/QMP sees or interacts with, but the ultimate implementation may vary to some degree. The net effect should the same however: guest agent commands will be exposed in the same manner as QMP commands using the same QMP server, and communication with the agent will be handled by QEMU, transparently to the client.

The current list of supported RPCs is documented in qemu.git/qapi-schema-guest.json.

Example usage

use guest agent:

Example using vsock

start guest (cid = 3):

start guest agent using vsock device:

Schema Definition

All guest commands will use a guest- prefix to distinguish the fact that the commands are handled by the guest. Type names (complex types and enums) do not require a special prefix. The following is an example of the proposed guest agent schema:

This would result is types being created as described for QAPI, with signatures as follows:

libqmp

In libqmp, the code generated for a guest command is nearly identical to the code generated for a normal command.

For instance, the guest-info command will have the following signature:

The only role QEMU plays in guest commands is unmarshalling and remarshalling the input and output. This means that data from the guest is not being sent directly to a management tool which significantly decreases the guest attack surface.

Here is an example of the code that will be generated handle agent commands:

QEMU Guest Agent Protocol

In general, qemu-ga uses the same protocol as QMP. There are a couple issues regarding it’s isa-serial/virtio-serial transport that incur some additional caveats, however:

Because of 1) and 2), a qemu-ga channel must be treated as «always-on», even if qemu-ga hasn’t even been installed on the guest. We could add start-up notifications to the agent, but there’s no way of detecting if, after a notification, qemu-ga was stopped and uninstalled, and the machine subsequently rebooted (we can probe for the this, but that only tells use the state for that exact instance in time. Stop notifications would be needed to build any notion of a «session» around such events, but there’s no way to guarantee a stop notification’s delivery before agent shutdown or device/buffer reset).

This means robust clients *must* implement a client-side timeout mechanism when attempting to communicate with the agent. It also means that when a client connects, or after a client times out waiting for a response to a request, there may be garbage received due to the agent starting up and responding to requests that were queued by previous client connections, or to stale requests from the current client connection that had timed-out on the client-side.

Читайте также:  Инвертированные цвета windows 10

It also means that, due to 4), a client can block indefinitely when writing to a channel that’s been throttled due to a backlog of unhandled/queued requests, and so should be written with this possibility in mind (separate thread, event loop, etc.).

qemu-ga uses the guest-sync or guest-sync-delimited command to address the problem of re-sync’ing the channel after [re-]connection or client-side timeouts. These are described below.

guest-sync

The guest-sync request/response exchange is simple. The client provides a unique numerical token, the agent sends it back in a response:

A successful exchange guarantees that the channel is now in sync and no unexpected data/responses will be sent.

Note that for the reasons mentioned above there’s no guarantee this request will be answered, so a client should implement a timeout and re-issue this periodically until a response is received for the most recent request.

This alone does not handle synchronisation for all cases, however. For instance, if qemu-ga’s parser previously received a partial request from a previous client connection, subsequent attempts to issue the guest-sync request can be misconstrued as being part of the previous partial request. Eventually qemu-ga will hit it’s recursion or token size limit and flush its parser state, at which point it will begin processing the backlog of requests, but there’s no guarantee this will occur before the channel is throttled due to exhausting all available buffers. Thus there is potential for a deadlock situation occurring for certain instances.

To avoid this, qemu-ga/QEMU’s JSON parser have special handling for the 0xFF byte, which is an invalid UTF-8 character. Clients should precede the guest-sync request with to ensure that qemu-ga flushes it’s parser state as soon as possible. So long as all clients abide by this, the deadlock state should be reliably avoidable.

A similar situation can happen WRT to qemu-ga attempting to communicate with a client, however. If the client receives a partial response from a previous qemu-ga instance, the client might misconstrue responses to guest-sync as being part of this previous request. For client implementations that treat newlines as a delimiter for qemu-ga responses, this is easy to recover from (one valid response may be lost, but we can recover on the subsequent try).

For some implementations, in particular, JSON stream-based implementations which do not rely on newline delimiters, it may be invasive to implement a client’s response/JSON handling in a such a way that this same deadlock scenario can be avoided on the client-side. To make this situation easier to deal with, the guest-sync-delimited command can be used to tell qemu-ga to send precede the response with this same 0xFF character.

guest-sync-delimited

Actual hex values sent:

As stated above, the request should also be preceded with a 0xFF to flush qemu-ga’s parser state.

Guest Agent

The guest agent will be a daemon that connects to a virtio-serial device and feeds the input to a JSON parser. When a new command is received, it will hand the command over to the QAPI generated dispatch routines.

The guest agent will implement the server side of the QMP commands using the native signature for the function.

Asynchronous Commands

Since QEMU cannot rely on the guest agent responding immediately to a command (it is in fact impossible for it to do so), all guest commands most be implemented as asynchronous commands within QEMU. This does not change anything from a protocol visible perspective but is simply an implementation detail within QEMU.

These details will be worked out in the context of QAPI-based QMP. The current, standalone host service requires that clients provide for their own timeout mechanisms. The reset mechanism descibed under «virtio-serial Transport» should be employed upon each connection to the guest agent to re-sync the streams with the guest agent in case a timeout from a client left the stream in a bad state.

Security Considerations

The following security issues need to be resolved in QMP:

  1. The JSON parser uses a recursive decent parser. Malicious input could potentially cause a stack overflow. Either implement a recursion depth counter, or switch the parser to only use tail recursion.
  2. The JSON parser may not handle premature EOI all that well. I think I’ve worked out most of these issues but more rigorous testing is needed.
Оцените статью