Libvirt uses the Qemu guest agent running inside a VM. This post will elaborate on how the Qemu agent act as a communication channel between KVM host and the guest.

Communication Protocol

The communication protocol used to fetch information of the VM OS or issue commands to the Guest OS is Qemu Machine Protocol(QMP). QMP is a JSON-based protocol.

For example, libvirt uses the guest agent to fetch filesystem details from the guest. To check if the guest agent is working:

# virsh qemu-agent-command >vm_name> '{"execute": "guest-info"}'

For example:

# virsh qemu-agent-command TestVM '{"execute": "guest-get-host-name"}' --pretty
Please enter your authentication name: [email protected]
Please enter your password:
{
"return": {
"host-name": "<VM FQDN>"
}
# virsh qemu-agent-command TestVM '{"execute": "guest-get-osinfo"}' --pretty
Please enter your authentication name: [email protected]
Please enter your password:
{
"return": {
"name": "Oracle Linux Server",
"kernel-release": "4.14.35-1902.300.11.el7uek.x86_64",
"version": "7.8",
"variant": "Server",
"pretty-name": "Oracle Linux Server 7.8",
"version-id": "7.8",
"variant-id": "server",
"kernel-version": "#2 SMP Tue Mar 17 17:11:47 PDT 2020",
"machine": "x86_64",
"id": "ol"
}
}

Communication method

The communication between the guest agent and host happens through virtio-serial and isa-serial channel org.qemu.guest_agen.0.

– From VM guest, here is the qemu.guest_agent process:

# ps auxwww |grep guest
root 811 0.0 0.0 44232 4572 ? Ss Feb22 0:51 /usr/bin/qemu-ga --method=virtio-serial --path=/dev/virtio -ports/org.qemu.guest_agent.0 --blacklist=guest-file-open,guest-file-close,guest-file-read,guest-file-write,guest-file-seek ,guest-file-flush,guest-exec,guest-exec-status -F/etc/qemu-ga/fsfreeze-hook

– From the host, a corresponding socket file will also be created in /var/lib/libvirt/qemu/channels/.org.ovirt.hosted-engine-setup.0:

# file /var/lib/libvirt/qemu/channels/56f42910-82d1-4e14-b4a4-646d220567c7.org.ovirt.hosted-engine-setup.0
/var/lib/libvirt/qemu/channels/56f42910-82d1-4e14-b4a4-646d220567c7.org.ovirt.hosted-engine-setup.0: socket
# virsh -r dumpxml TestVM |grep guest_agent
<source mode="bind" path="/var/lib/libvirt/qemu/channels/56f42910-82d1-4e14-b4a4-646d220567c7.org.qemu.guest_agent.0"/>
<target type="virtio" name="org.qemu.guest_agent.0" state="connected"/>

If the communication is okay, the UNIX socket has ‘ESTAB’ connection:

# ss |grep guest_agent
u_str ESTAB 0 0 /var/lib/libvirt/qemu/channels/56f42910-82d1-4e14-b4a4-646d220567c7.org.qemu.guest_agent.0 82797274 * 82971852
u_str ESTAB 0 0 /var/lib/libvirt/qemu/channels/9c798303-1c30-4965-b447-e1c12588db14.org.qemu.guest_agent.0 82944156 * 82971680

Communication Interval

By default, VDSM polls the QEMU guest agent (qemu-ga) every 5 minutes to fetch information. If the QEMU guest agent is not running and respond within 5 mins, libvirtd will report the error like “Guest agent is not responding: QEMU guest agent is not connected”

Others

QMP’s subnet called’ hmp is also available. “qemu-monitor-command” has the capability of exchanging information in ‘hmp’ format by -hmp options. To check the status of the virtio-serial port connected to the ovirt-guest-agent:

# virsh qemu-monitor-command --hmp <Virtual Machine Name Here> 'info qtree'

For example:

# virsh qemu-monitor-command --hmp TestVM 'info qtree'
Please enter your authentication name: [email protected]
Please enter your password:

dev: virtserialport, id "channel1"
chardev = "charchannel1"
nr = 2 (0x2)
name = "org.qemu.guest_agent.0"
port 2, guest on, host on, throttle off