QEMU Guest Agent

The QEMU Guest Agent (QGA) is a binary file located within a VM which receives QEMU Machine Protocol (QMP) messages and can be used to perform actions within the virtual machine. The QGA is the primary way in which the VM Resource Handler communicates with VMs and enables the completion of VM resources. Therefore, in order for a VM image to be “FIREWHEEL-compatible” the QGA should be installed on the system and set to run as a service on system start.

When a VM is launched, a virtual serial port that is added which enables the QGA to communicate to FIREWHEEL via the QemuGuestAgentDriver, which then works with the VM Resource Handler for scheduling and executing VMRs within the VM.

See also

For more information on creating a VM Resource Handler-compatible image see the Image Creation Tutorial.

QGA Modifications

While it is possible to use the existing QGA code to work with FIREWHEEL, we have provided some small changes which enhance the behavior for Emulytics environments. Namely, Python, by default, aggressively buffers stdout, so printed output doesn’t show up immediately on guest agent outputs unless explicitly flushed. Therefore, we provide a small patch which changes the behavior of the QEMU Guest Agent such that output from executed binaries is not simply buffered until exit, but will be returned on each status request.

Patching QEMU

Before compiling the QGA for any one VM, it needs to be patched. To do this, you can clone the QEMU code, checkout the correct version (i.e. the version for which the patch was created), and apply the patch. The code below will show you how to do this. We saved the QGA Patch File as 0001-Allow-exceed-processes-to-ret-data-on-every-status.patch.

git clone https://github.com/qemu/qemu.git
cd qemu
git checkout v5.0.0
patch -p1 < ../0001-Allow-exceed-processes-to-ret-data-on-every-status.patch

Building the QGA for Linux

  1. Install the following prerequisite packages when building the QEMU Guest Agent on an Ubuntu system. Other packages might be required. We refer users to the official QEMU documentation for more details: https://wiki.qemu.org/Hosts/Linux#Building_QEMU_for_Linux.

    sudo apt-get install -y pkgconf glib-2.0 libglib2.0-dev libsdl1.2-dev libaio-dev libcap-dev gcc libattr1-dev libpixman-1-dev make libffi-dev
    
  2. Configure the system with the following parameters:

    ./configure --target-list="x86_64-softmmu" --static --enable-guest-agent
    
  3. Finally, build the binary:

    make qemu-ga -j
    
  4. The binary is located at ./qemu-ga. We recommend renaming it to qemu-ga-patched-static as a reminder that this binary has been statically compiled and patched.

    mv qemu-ga qemu-ga-patched-static
    

Building the QGA for Windows

The Windows installer for the QEMU Guest Agent can be built using Cygwin.

  1. Download Cygwin.

  2. Install Cygwin and when prompted to install packages, select the following:

    mingw64-x86_64-atk1.0
    mingw64-x86_64-atkmm1.6
    mingw64-x86_64-babl0.1
    mingw64-x86_64-binutils
    mingw64-x86_64-bzip2
    mingw64-x86_64-cairo
    mingw64-x86_64-cairomm1.0
    mingw64-x86_64-celt051
    mingw64-x86_64-crypt
    mingw64-x86_64-expat
    mingw64-x86_64-flac
    mingw64-x86_64-fontconfig
    mingw64-x86_64-freeglut
    mingw64-x86_64-freetype2
    mingw64-x86_64-fribidi
    mingw64-x86_64-gc
    mingw64-x86_64-gcc-core
    mingw64-x86_64-gcc-g++
    mingw64-x86_64-gdk-pixbuf2.0
    mingw64-x86_64-gdl3
    mingw64-x86_64-gegl0.2
    mingw64-x86_64-gettext
    mingw64-x86_64-glib2.0
    mingw64-x86_64-glib2.0-networking
    mingw64-x86_64-glibmm2.4
    mingw64-x86_64-gmp
    mingw64-x86_64-gnutls
    mingw64-x86_64-gsettings-desktop-schemas
    mingw64-x86_64-gstreamer1.0
    mingw64-x86_64-gstreamer1.0-plugins-base
    mingw64-x86_64-gtk3
    mingw64-x86_64-gtkmm3.0
    mingw64-x86_64-harfbuzz
    mingw64-x86_64-headers
    mingw64-x86_64-icu
    mingw64-x86_64-ilmbase
    mingw64-x86_64-jasper
    mingw64-x86_64-jbigkit
    mingw64-x86_64-libcdio
    mingw64-x86_64-libcdio-paranoia
    mingw64-x86_64-libcroco0.6
    mingw64-x86_64-libepoxy
    mingw64-x86_64-libffi
    mingw64-x86_64-libgcrypt
    mingw64-x86_64-libgnurx
    mingw64-x86_64-libgpg-error
    mingw64-x86_64-libjpeg-turbo
    mingw64-x86_64-libmodplug
    mingw64-x86_64-libmpc
    mingw64-x86_64-libogg
    mingw64-x86_64-libpng
    mingw64-x86_64-libproxy
    mingw64-x86_64-librsvg2
    mingw64-x86_64-libsigc++2.0
    mingw64-x86_64-libssh2
    mingw64-x86_64-libtasn1
    mingw64-x86_64-libtheora
    mingw64-x86_64-libusb1.0
    mingw64-x86_64-libvorbis
    mingw64-x86_64-libwebp
    mingw64-x86_64-libxml++2.6
    mingw64-x86_64-libxml2
    mingw64-x86_64-libxslt
    mingw64-x86_64-libzip
    mingw64-x86_64-lzo2
    mingw64-x86_64-mpfr
    mingw64-x86_64-ncurses
    mingw64-x86_64-nettle
    mingw64-x86_64-openexr
    mingw64-x86_64-openjpeg
    mingw64-x86_64-openssl
    mingw64-x86_64-opus
    mingw64-x86_64-orc0.4
    mingw64-x86_64-p11-kit
    mingw64-x86_64-pango1.0
    mingw64-x86_64-pangomm1.4
    mingw64-x86_64-pcre
    mingw64-x86_64-pixman
    mingw64-x86_64-pkg-config
    mingw64-x86_64-pthreads
    mingw64-x86_64-readline
    mingw64-x86_64-runtime
    mingw64-x86_64-spice-glib2.0
    mingw64-x86_64-spice-gtk3.0
    mingw64-x86_64-tiff
    mingw64-x86_64-usbredir
    mingw64-x86_64-win-iconv
    mingw64-x86_64-windows-default-manifest
    mingw64-x86_64-winpthreads
    mingw64-x86_64-xz
    mingw64-x86_64-zlib
    girepository-msi0-0.95-1
    libmsi-devel-0.95-1
    libmsi0-0.95-1
    msitools-0.95-1
    vala-msi0-0.95-1
    wixl-0.95-1
    gcab-0.7-1
    girepository-gcab1.0-0.7-1
    libgcab-devel-0.7-1
    libgcab-doc-0.7-1
    libgcab1.0_0-0.7-1
    vala-gcab1.0-0.7-1
    
  3. Other necessary packages that need to be installed can be searched for in Cygwin. These include:

    make
    git
    bison
    flex
    vim
    
  4. Install the MS Volume Shadow Copy Service (VSS) SDK. The link to download it is here: https://learn.microsoft.com/en-us/windows/win32/vss/volume-shadow-copy-service-portal.

  5. Configure the build with the following (make sure to update the paths with your username):

    ./configure --target-list="x86_64-softmmu" --cc=x86_64-w64-mingw32-gcc --cxx=x86_64-w64-mingw32-g++ --host-cc=/usr/bin/gcc --cross-prefix=x86_64-w64-mingw32- --prefix="/home/username/Documents/Qemu-windows" --with-confsuffix=/Bios --docdir="/home/username/Documents/Qemu-windows/Doc" --disable-sdl --enable-gtk --with-gtkabi=3.0 --disable-libusb --enable-guest-agent --enable-guest-agent-msi --with-vss-sdk="C:\Program Files (x86)\Microsoft\VSSSDK72" --disable-werror --disable-strip $*
    
  6. Finally, build the guest agent:

    make -j
    
  7. This will result in the creation of a MSI installer as well as an executable. To install the guest agent, copy the MSI installer to the VM and run it.

Note

Users that would like to install an unmodified QGA on Windows can find a link to download the latest qemu-ga.msi via the virtio-win-pkg-scipts GitHub page.

Running QGA as a Service

In this section, we have provided several methods for running the QGA as a service. We assume that the QGA binary was renamed to qemu-ga-patched-static.

systemd

You can save the following file as qemu-guest-agent.service.

[Unit]
Description=Qemu Guest Agent

[Service]
Type=simple
Restart=always
RestartSec=5
ExecStart=/usr/sbin/qemu-ga-patched-static
LimitNOFILE=102400

[Install]
WantedBy=multi-user.target

sysvinit

You can save the following file as qemu-guest-agent.

#!/bin/bash

case "$1" in
start)
    /usr/sbin/qemu-ga-patched-static &
    echo $!>/usr/local/var/run/qga.pid
    ;;
stop)
    kill `cat /usr/local/var/run/qga.pid`
    rm /usr/local/var/run/qga.pid
    ;;
restart)
    $0 stop
    $0 start
    ;;
status)
    if [ -e /usr/local/var/run/qga.pid ]; then
        echo qemu-guest-agent is running, pid=`cat /usr/local/var/run/qga.pid`
    else
        echo qemu-guest-agent is NOT running
        exit 1
    fi
    ;;
*)
    echo "Usage: $0 {start|stop|status|restart}"
esac

exit 0

upstart

You can save the following file as qemu-guest-agent.

description "Qemu Guest Agent"
author "FIREWHEEL Developers"
start on runlevel [2345]

respawn

exec /usr/sbin/qemu-ga-patched-static