diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..df9af11 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/qemu-2.12.0.tar.xz diff --git a/.qemu-guest-agent.metadata b/.qemu-guest-agent.metadata new file mode 100644 index 0000000..bda0ddd --- /dev/null +++ b/.qemu-guest-agent.metadata @@ -0,0 +1 @@ +5a62c911b2cebbd41decd5c77c524395212411cf SOURCES/qemu-2.12.0.tar.xz diff --git a/SOURCES/99-qemu-guest-agent.rules b/SOURCES/99-qemu-guest-agent.rules new file mode 100644 index 0000000..8a290ab --- /dev/null +++ b/SOURCES/99-qemu-guest-agent.rules @@ -0,0 +1,2 @@ +SUBSYSTEM=="virtio-ports", ATTR{name}=="org.qemu.guest_agent.0", \ + TAG+="systemd" ENV{SYSTEMD_WANTS}="qemu-guest-agent.service" diff --git a/SOURCES/build_configure.sh b/SOURCES/build_configure.sh new file mode 100755 index 0000000..eff4f9b --- /dev/null +++ b/SOURCES/build_configure.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +_prefix=$1 +shift +_libdir=$1 +shift +_sysconfdir=$1 +shift +_localstatedir=$1 +shift +_libexecdir=$1 +shift +pkgname=$1 +shift +arch=$1 +shift +nvr=$1 +shift +optflags=$1 +shift +have_fdt=$1 +shift +have_tcmalloc=$1 +shift + +./configure \ + --prefix=${_prefix} \ + --libdir=${_libdir} \ + --sysconfdir=${_sysconfdir} \ + --interp-prefix=${_prefix}/qemu-%M \ + --localstatedir=${_localstatedir} \ + --libexecdir=${_libexecdir} \ + --extra-ldflags="$extraldflags -pie -Wl,-z,relro -Wl,-z,now" \ + --extra-cflags="${optflags} -fPIE -DPIE" \ + --with-pkgversion=${nvr} \ + --with-confsuffix=/${pkgname} \ + --with-coroutine=ucontext \ + --disable-bluez \ + --disable-brlapi \ + --disable-cap-ng \ + --enable-coroutine-pool \ + --disable-curl \ + --disable-curses \ + --disable-debug-tcg \ + --enable-docs \ + --disable-gtk \ + --enable-kvm \ + --disable-libiscsi \ + --disable-libnfs \ + --disable-libssh2 \ + --disable-libusb \ + --disable-bzip2 \ + --disable-linux-aio \ + --disable-lzo \ + --disable-opengl \ + --enable-pie \ + --disable-qom-cast-debug \ + --disable-sdl \ + --disable-smartcard \ + --disable-snappy \ + --disable-sparse \ + --disable-strip \ + --disable-tpm \ + --enable-trace-backend=dtrace \ + --disable-vde \ + --disable-vhdx \ + --disable-vhost-scsi \ + --disable-virtfs \ + --disable-vnc-jpeg \ + --disable-vte \ + --disable-vnc-png \ + --disable-vnc-sasl \ + --enable-werror \ + --disable-xen \ + --disable-xfsctl \ + --${have_fdt}-fdt \ + --disable-glusterfs \ + --enable-guest-agent \ + --disable-numa \ + --disable-rbd \ + --disable-rdma \ + --disable-seccomp \ + --disable-spice \ + --disable-usb-redir \ + --${have_tcmalloc}-tcmalloc \ + --disable-system \ + --disable-tools \ + "$@" diff --git a/SOURCES/qemu-ga.sysconfig b/SOURCES/qemu-ga.sysconfig new file mode 100644 index 0000000..67bad0c --- /dev/null +++ b/SOURCES/qemu-ga.sysconfig @@ -0,0 +1,19 @@ +# This is a systemd environment file, not a shell script. +# It provides settings for "/lib/systemd/system/qemu-guest-agent.service". + +# Comma-separated blacklist of RPCs to disable, or empty list to enable all. +# +# You can get the list of RPC commands using "qemu-ga --blacklist='?'". +# There should be no spaces between commas and commands in the blacklist. +BLACKLIST_RPC=guest-file-open,guest-file-close,guest-file-read,guest-file-write,guest-file-seek,guest-file-flush,guest-exec,guest-exec-status + +# Fsfreeze hook script specification. +# +# FSFREEZE_HOOK_PATHNAME=/dev/null : disables the feature. +# +# FSFREEZE_HOOK_PATHNAME=/path/to/executable : enables the feature with the +# specified binary or shell script. +# +# FSFREEZE_HOOK_PATHNAME= : enables the feature with the +# default value (invoke "qemu-ga --help" to interrogate). +FSFREEZE_HOOK_PATHNAME=/etc/qemu-ga/fsfreeze-hook diff --git a/SOURCES/qemu-guest-agent.service b/SOURCES/qemu-guest-agent.service new file mode 100644 index 0000000..ab50e75 --- /dev/null +++ b/SOURCES/qemu-guest-agent.service @@ -0,0 +1,21 @@ +[Unit] +Description=QEMU Guest Agent +BindsTo=dev-virtio\x2dports-org.qemu.guest_agent.0.device +After=dev-virtio\x2dports-org.qemu.guest_agent.0.device +IgnoreOnIsolate=True + +[Service] +UMask=0077 +EnvironmentFile=/etc/sysconfig/qemu-ga +ExecStart=/usr/bin/qemu-ga \ + --method=virtio-serial \ + --path=/dev/virtio-ports/org.qemu.guest_agent.0 \ + --blacklist=${BLACKLIST_RPC} \ + -F${FSFREEZE_HOOK_PATHNAME} +StandardError=syslog +Restart=always +RestartSec=0 + +[Install] +WantedBy=dev-virtio\x2dports-org.qemu.guest_agent.0.device + diff --git a/SOURCES/qemuga-configure-add-test-for-libudev.patch b/SOURCES/qemuga-configure-add-test-for-libudev.patch new file mode 100644 index 0000000..719d739 --- /dev/null +++ b/SOURCES/qemuga-configure-add-test-for-libudev.patch @@ -0,0 +1,95 @@ +From e7f6b98b4f9d3205fadf2bb5e978a0f516ac3056 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Fri, 23 Nov 2018 15:16:53 +0100 +Subject: [PATCH 3/5] configure: add test for libudev +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20181123151655.23498-3-marcandre.lureau@redhat.com> +Patchwork-id: 83152 +O-Subject: [RHEL-7.7 qemu-guest-agent PATCH 2/4] configure: add test for libudev +Bugzilla: 1635571 +RH-Acked-by: Markus Armbruster +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Laurent Vivier + +From: Tomáš Golembiovský + +Signed-off-by: Tomáš Golembiovský +Reviewed-by: Marc-André Lureau +*make libudev optional to avoid breaking existing build/test environments +*disable libudev for --static builds +Signed-off-by: Michael Roth + +(cherry picked from commit 3efac6ebb88e4d099f07fef65178ebaa595ae770) +[ Various simple conflicts due to upstream changes ] +Signed-off-by: Marc-André Lureau + +Signed-off-by: Miroslav Rezanina +--- + configure | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/configure b/configure +index 0a19b03..62aa775 100755 +--- a/configure ++++ b/configure +@@ -451,6 +451,7 @@ jemalloc="no" + replication="yes" + vxhs="" + libxml2="" ++libudev="no" + + supported_cpu="no" + supported_os="no" +@@ -819,6 +820,7 @@ Linux) + vhost_vsock="yes" + QEMU_INCLUDES="-I\$(SRC_PATH)/linux-headers -I$(pwd)/linux-headers $QEMU_INCLUDES" + supported_os="yes" ++ libudev="yes" + ;; + esac + +@@ -5456,6 +5458,17 @@ if test "$libnfs" != "no" ; then + fi + fi + ++########################################## ++# Do we have libudev ++if test "$libudev" != "no" ; then ++ if $pkg_config libudev && test "$static" != "yes"; then ++ libudev="yes" ++ libudev_libs=$($pkg_config --libs libudev) ++ else ++ libudev="no" ++ fi ++fi ++ + # Now we've finished running tests it's OK to add -Werror to the compiler flags + if test "$werror" = "yes"; then + QEMU_CFLAGS="-Werror $QEMU_CFLAGS" +@@ -5874,6 +5887,7 @@ echo "avx2 optimization $avx2_opt" + echo "replication support $replication" + echo "VxHS block device $vxhs" + echo "capstone $capstone" ++echo "libudev $libudev" + + if test "$sdl_too_old" = "yes"; then + echo "-> Your SDL version is too old - please upgrade to have SDL support" +@@ -6697,6 +6711,11 @@ if test "$gcov" = "yes" ; then + echo "GCOV=$gcov_tool" >> $config_host_mak + fi + ++if test "$libudev" != "no"; then ++ echo "CONFIG_LIBUDEV=y" >> $config_host_mak ++ echo "LIBUDEV_LIBS=$libudev_libs" >> $config_host_mak ++fi ++ + # use included Linux headers + if test "$linux" = "yes" ; then + mkdir -p linux-headers +-- +1.8.3.1 + diff --git a/SOURCES/qemuga-qemu-ga-make-get-fsinfo-work-over-pci-bridges.patch b/SOURCES/qemuga-qemu-ga-make-get-fsinfo-work-over-pci-bridges.patch new file mode 100644 index 0000000..3ce8879 --- /dev/null +++ b/SOURCES/qemuga-qemu-ga-make-get-fsinfo-work-over-pci-bridges.patch @@ -0,0 +1,92 @@ +From 6ae51b4e290e2c6043d028987a8c27651c6c08fa Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Wed, 18 Jul 2018 12:56:41 +0200 +Subject: [PATCH 1/2] qemu-ga: make get-fsinfo work over pci bridges +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20180718125642.11815-2-marcandre.lureau@redhat.com> +Patchwork-id: 81391 +O-Subject: [RHEL-7.6 qemu-guest-agent PATCH 1/2] qemu-ga: make get-fsinfo work over pci bridges +Bugzilla: 1567041 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Markus Armbruster +RH-Acked-by: Miroslav Rezanina + +Iterate over the PCI bridges to lookup the PCI device associated with +the block device. + +This allows to lookup the driver under the following syspath: +/sys/devices/pci0000:00/0000:00:02.2/0000:03:00.0/virtio2/block/vda/vda3 + +It also works with an "old-style" Q35 libvirt hierarchy: root complex +-> DMI-PCI bridge -> PCI-PCI bridge -> virtio controller, ex: +/sys/devices/pci0000:00/0000:00:03.0/0000:01:01.0/0000:02:01.0/virtio1/block/vda/vda3 + +The setup can be reproduced with the following qemu command line +(Thanks Marcel for help): + +qemu-system-x86_64 -M q35 \ + -device i82801b11-bridge,id=dmi2pci_bridge,bus=pcie.0 + -device pci-bridge,id=pci_bridge,bus=dmi2pci_bridge,addr=0x1,chassis_nr=1 + -device virtio-blk-pci,scsi=off,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1,bus=pci_bridge,addr=0x1 + +For consistency with other syspath-related debug messages, replace a +\"%s\" in the message with '%s'. + +Fixes: +https://bugzilla.redhat.com/show_bug.cgi?id=1567041 + +Signed-off-by: Marc-André Lureau +Reviewed-by: Laszlo Ersek +Signed-off-by: Michael Roth + +(cherry picked from commit 743c71d03c20d64f2bae5fba6f26cdf5e4b1bda6) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + qga/commands-posix.c | 23 +++++++++++++++++++---- + 1 file changed, 19 insertions(+), 4 deletions(-) + +diff --git a/qga/commands-posix.c b/qga/commands-posix.c +index 0dc219d..624b0dc 100644 +--- a/qga/commands-posix.c ++++ b/qga/commands-posix.c +@@ -875,13 +875,28 @@ static void build_guest_fsinfo_for_real_device(char const *syspath, + p = strstr(syspath, "/devices/pci"); + if (!p || sscanf(p + 12, "%*x:%*x/%x:%x:%x.%x%n", + pci, pci + 1, pci + 2, pci + 3, &pcilen) < 4) { +- g_debug("only pci device is supported: sysfs path \"%s\"", syspath); ++ g_debug("only pci device is supported: sysfs path '%s'", syspath); + return; + } + +- driver = get_pci_driver(syspath, (p + 12 + pcilen) - syspath, errp); +- if (!driver) { +- goto cleanup; ++ p += 12 + pcilen; ++ while (true) { ++ driver = get_pci_driver(syspath, p - syspath, errp); ++ if (driver && (g_str_equal(driver, "ata_piix") || ++ g_str_equal(driver, "sym53c8xx") || ++ g_str_equal(driver, "virtio-pci") || ++ g_str_equal(driver, "ahci"))) { ++ break; ++ } ++ ++ if (sscanf(p, "/%x:%x:%x.%x%n", ++ pci, pci + 1, pci + 2, pci + 3, &pcilen) == 4) { ++ p += pcilen; ++ continue; ++ } ++ ++ g_debug("unsupported driver or sysfs path '%s'", syspath); ++ return; + } + + p = strstr(syspath, "/target"); +-- +1.8.3.1 + diff --git a/SOURCES/qemuga-qga-fix-driver-leak-in-guest-get-fsinfo.patch b/SOURCES/qemuga-qga-fix-driver-leak-in-guest-get-fsinfo.patch new file mode 100644 index 0000000..91f9d2b --- /dev/null +++ b/SOURCES/qemuga-qga-fix-driver-leak-in-guest-get-fsinfo.patch @@ -0,0 +1,48 @@ +From 57d2a0742d2e37089a848e843203c7783ea9902e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Wed, 18 Jul 2018 12:56:42 +0200 +Subject: [PATCH 2/2] qga: fix 'driver' leak in guest-get-fsinfo +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20180718125642.11815-3-marcandre.lureau@redhat.com> +Patchwork-id: 81389 +O-Subject: [RHEL-7.6 qemu-guest-agent PATCH 2/2] qga: fix 'driver' leak in guest-get-fsinfo +Bugzilla: 1567041 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Markus Armbruster +RH-Acked-by: Miroslav Rezanina + +'driver' is leaked when the loop is not broken. + +Leak introduced by commit 743c71d03c20d64f2bae5fba6f26cdf5e4b1bda6, +spotted by ASAN. + +Signed-off-by: Marc-André Lureau +Reviewed-by: Laszlo Ersek +Signed-off-by: Michael Roth + +(cherry picked from commit bb23a7362a7942739f080990a53e44afc319e36c) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + qga/commands-posix.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/qga/commands-posix.c b/qga/commands-posix.c +index 624b0dc..26c1863 100644 +--- a/qga/commands-posix.c ++++ b/qga/commands-posix.c +@@ -889,6 +889,7 @@ static void build_guest_fsinfo_for_real_device(char const *syspath, + break; + } + ++ g_free(driver); + if (sscanf(p, "/%x:%x:%x.%x%n", + pci, pci + 1, pci + 2, pci + 3, &pcilen) == 4) { + p += pcilen; +-- +1.8.3.1 + diff --git a/SOURCES/qemuga-qga-ignore-non-present-cpus-when-handling-qmp_guest_.patch b/SOURCES/qemuga-qga-ignore-non-present-cpus-when-handling-qmp_guest_.patch new file mode 100644 index 0000000..57bb363 --- /dev/null +++ b/SOURCES/qemuga-qga-ignore-non-present-cpus-when-handling-qmp_guest_.patch @@ -0,0 +1,199 @@ +From 34ff13c0974bf94c3e61b0b8af8134a6933194ea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Thu, 15 Nov 2018 09:45:19 +0100 +Subject: [PATCH 1/5] qga: ignore non present cpus when handling + qmp_guest_get_vcpus() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20181115094519.22641-1-marcandre.lureau@redhat.com> +Patchwork-id: 83030 +O-Subject: [RHEL-7.7 qemu-guest-agent PATCH] qga: ignore non present cpus when handling qmp_guest_get_vcpus() +Bugzilla: 1611062 +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Igor Mammedov +RH-Acked-by: Markus Armbruster + +From: Igor Mammedov + +If VM has VCPUs plugged sparselly (for example a VM started with +3 VCPUs (cpu0, cpu1 and cpu2) and then cpu1 was hotunplugged so +only cpu0 and cpu2 are present), QGA will rise a error + error: internal error: unable to execute QEMU agent command 'guest-get-vcpus': + open("/sys/devices/system/cpu/cpu1/"): No such file or directory +when + virsh vcpucount FOO --guest +is executed. +Fix it by ignoring non present CPUs when fetching CPUs status from sysfs. + +Signed-off-by: Igor Mammedov +Reviewed-by: Laszlo Ersek +Reviewed-by: Marc-André Lureau +Signed-off-by: Michael Roth + +BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1611062 +Brew: https://brewweb.engineering.redhat.com/brew/taskinfo?taskID=19189361 + +(cherry picked from commit b4bf912a6c19449e68af7b4173a8c6da21904d99) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + qga/commands-posix.c | 115 ++++++++++++++++++++++++++------------------------- + 1 file changed, 59 insertions(+), 56 deletions(-) + +diff --git a/qga/commands-posix.c b/qga/commands-posix.c +index 26c1863..f4d9380 100644 +--- a/qga/commands-posix.c ++++ b/qga/commands-posix.c +@@ -1913,61 +1913,56 @@ static long sysconf_exact(int name, const char *name_str, Error **errp) + * Written members remain unmodified on error. + */ + static void transfer_vcpu(GuestLogicalProcessor *vcpu, bool sys2vcpu, +- Error **errp) ++ char *dirpath, Error **errp) + { +- char *dirpath; ++ int fd; ++ int res; + int dirfd; ++ static const char fn[] = "online"; + +- dirpath = g_strdup_printf("/sys/devices/system/cpu/cpu%" PRId64 "/", +- vcpu->logical_id); + dirfd = open(dirpath, O_RDONLY | O_DIRECTORY); + if (dirfd == -1) { + error_setg_errno(errp, errno, "open(\"%s\")", dirpath); +- } else { +- static const char fn[] = "online"; +- int fd; +- int res; +- +- fd = openat(dirfd, fn, sys2vcpu ? O_RDONLY : O_RDWR); +- if (fd == -1) { +- if (errno != ENOENT) { +- error_setg_errno(errp, errno, "open(\"%s/%s\")", dirpath, fn); +- } else if (sys2vcpu) { +- vcpu->online = true; +- vcpu->can_offline = false; +- } else if (!vcpu->online) { +- error_setg(errp, "logical processor #%" PRId64 " can't be " +- "offlined", vcpu->logical_id); +- } /* otherwise pretend successful re-onlining */ +- } else { +- unsigned char status; +- +- res = pread(fd, &status, 1, 0); +- if (res == -1) { +- error_setg_errno(errp, errno, "pread(\"%s/%s\")", dirpath, fn); +- } else if (res == 0) { +- error_setg(errp, "pread(\"%s/%s\"): unexpected EOF", dirpath, +- fn); +- } else if (sys2vcpu) { +- vcpu->online = (status != '0'); +- vcpu->can_offline = true; +- } else if (vcpu->online != (status != '0')) { +- status = '0' + vcpu->online; +- if (pwrite(fd, &status, 1, 0) == -1) { +- error_setg_errno(errp, errno, "pwrite(\"%s/%s\")", dirpath, +- fn); +- } +- } /* otherwise pretend successful re-(on|off)-lining */ ++ return; ++ } + +- res = close(fd); +- g_assert(res == 0); +- } ++ fd = openat(dirfd, fn, sys2vcpu ? O_RDONLY : O_RDWR); ++ if (fd == -1) { ++ if (errno != ENOENT) { ++ error_setg_errno(errp, errno, "open(\"%s/%s\")", dirpath, fn); ++ } else if (sys2vcpu) { ++ vcpu->online = true; ++ vcpu->can_offline = false; ++ } else if (!vcpu->online) { ++ error_setg(errp, "logical processor #%" PRId64 " can't be " ++ "offlined", vcpu->logical_id); ++ } /* otherwise pretend successful re-onlining */ ++ } else { ++ unsigned char status; ++ ++ res = pread(fd, &status, 1, 0); ++ if (res == -1) { ++ error_setg_errno(errp, errno, "pread(\"%s/%s\")", dirpath, fn); ++ } else if (res == 0) { ++ error_setg(errp, "pread(\"%s/%s\"): unexpected EOF", dirpath, ++ fn); ++ } else if (sys2vcpu) { ++ vcpu->online = (status != '0'); ++ vcpu->can_offline = true; ++ } else if (vcpu->online != (status != '0')) { ++ status = '0' + vcpu->online; ++ if (pwrite(fd, &status, 1, 0) == -1) { ++ error_setg_errno(errp, errno, "pwrite(\"%s/%s\")", dirpath, ++ fn); ++ } ++ } /* otherwise pretend successful re-(on|off)-lining */ + +- res = close(dirfd); ++ res = close(fd); + g_assert(res == 0); + } + +- g_free(dirpath); ++ res = close(dirfd); ++ g_assert(res == 0); + } + + GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) +@@ -1985,17 +1980,21 @@ GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) + while (local_err == NULL && current < sc_max) { + GuestLogicalProcessor *vcpu; + GuestLogicalProcessorList *entry; +- +- vcpu = g_malloc0(sizeof *vcpu); +- vcpu->logical_id = current++; +- vcpu->has_can_offline = true; /* lolspeak ftw */ +- transfer_vcpu(vcpu, true, &local_err); +- +- entry = g_malloc0(sizeof *entry); +- entry->value = vcpu; +- +- *link = entry; +- link = &entry->next; ++ int64_t id = current++; ++ char *path = g_strdup_printf("/sys/devices/system/cpu/cpu%" PRId64 "/", ++ id); ++ ++ if (g_file_test(path, G_FILE_TEST_EXISTS)) { ++ vcpu = g_malloc0(sizeof *vcpu); ++ vcpu->logical_id = id; ++ vcpu->has_can_offline = true; /* lolspeak ftw */ ++ transfer_vcpu(vcpu, true, path, &local_err); ++ entry = g_malloc0(sizeof *entry); ++ entry->value = vcpu; ++ *link = entry; ++ link = &entry->next; ++ } ++ g_free(path); + } + + if (local_err == NULL) { +@@ -2016,7 +2015,11 @@ int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) + + processed = 0; + while (vcpus != NULL) { +- transfer_vcpu(vcpus->value, false, &local_err); ++ char *path = g_strdup_printf("/sys/devices/system/cpu/cpu%" PRId64 "/", ++ vcpus->value->logical_id); ++ ++ transfer_vcpu(vcpus->value, false, path, &local_err); ++ g_free(path); + if (local_err != NULL) { + break; + } +-- +1.8.3.1 + diff --git a/SOURCES/qemuga-qga-linux-report-disk-serial-number.patch b/SOURCES/qemuga-qga-linux-report-disk-serial-number.patch new file mode 100644 index 0000000..3249e7e --- /dev/null +++ b/SOURCES/qemuga-qga-linux-report-disk-serial-number.patch @@ -0,0 +1,151 @@ +From 67a5f203179a6ed491b127a851fdbd6bc3ac5a0c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Fri, 23 Nov 2018 15:16:54 +0100 +Subject: [PATCH 4/5] qga: linux: report disk serial number +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20181123151655.23498-4-marcandre.lureau@redhat.com> +Patchwork-id: 83151 +O-Subject: [RHEL-7.7 qemu-guest-agent PATCH 3/4] qga: linux: report disk serial number +Bugzilla: 1635571 +RH-Acked-by: Markus Armbruster +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Laurent Vivier + +From: Tomáš Golembiovský + +Add reporting of disk serial number on Linux guests. The feature depends +on libudev. + +Example: + + { + "name": "dm-2", + "mountpoint": "/", + ... + "disk": [ + { + "serial": "SAMSUNG_MZ7LN512HCHP-000L1_S1ZKNXAG822493", + ... + } + ], + } + +Signed-off-by: Tomáš Golembiovský +Signed-off-by: Michael Roth + +(cherry picked from commit b616105a904bc350a409e12c39af0ae210900124) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + qga/Makefile.objs | 1 + + qga/commands-posix.c | 32 ++++++++++++++++++++++++++++++-- + qga/qapi-schema.json | 4 +++- + 3 files changed, 34 insertions(+), 3 deletions(-) + +diff --git a/qga/Makefile.objs b/qga/Makefile.objs +index ed08c59..80e6bb3 100644 +--- a/qga/Makefile.objs ++++ b/qga/Makefile.objs +@@ -1,3 +1,4 @@ ++commands-posix.o-libs := $(LIBUDEV_LIBS) + qga-obj-y = commands.o guest-agent-command-state.o main.o + qga-obj-$(CONFIG_POSIX) += commands-posix.o channel-posix.o + qga-obj-$(CONFIG_WIN32) += commands-win32.o channel-win32.o service-win32.o +diff --git a/qga/commands-posix.c b/qga/commands-posix.c +index f4d9380..c0430e6 100644 +--- a/qga/commands-posix.c ++++ b/qga/commands-posix.c +@@ -47,6 +47,10 @@ extern char **environ; + #include + #include + ++#ifdef CONFIG_LIBUDEV ++#include ++#endif ++ + #ifdef FIFREEZE + #define CONFIG_FSFREEZE + #endif +@@ -871,6 +875,10 @@ static void build_guest_fsinfo_for_real_device(char const *syspath, + GuestDiskAddressList *list = NULL; + bool has_ata = false, has_host = false, has_tgt = false; + char *p, *q, *driver = NULL; ++#ifdef CONFIG_LIBUDEV ++ struct udev *udev = NULL; ++ struct udev_device *udevice = NULL; ++#endif + + p = strstr(syspath, "/devices/pci"); + if (!p || sscanf(p + 12, "%*x:%*x/%x:%x:%x.%x%n", +@@ -935,6 +943,21 @@ static void build_guest_fsinfo_for_real_device(char const *syspath, + list = g_malloc0(sizeof(*list)); + list->value = disk; + ++#ifdef CONFIG_LIBUDEV ++ udev = udev_new(); ++ udevice = udev_device_new_from_syspath(udev, syspath); ++ if (udev == NULL || udevice == NULL) { ++ g_debug("failed to query udev"); ++ } else { ++ const char *serial; ++ serial = udev_device_get_property_value(udevice, "ID_SERIAL"); ++ if (serial != NULL && *serial != 0) { ++ disk->serial = g_strdup(serial); ++ disk->has_serial = true; ++ } ++ } ++#endif ++ + if (strcmp(driver, "ata_piix") == 0) { + /* a host per ide bus, target*:0::0 */ + if (!has_host || !has_tgt) { +@@ -994,14 +1017,19 @@ static void build_guest_fsinfo_for_real_device(char const *syspath, + + list->next = fs->disk; + fs->disk = list; +- g_free(driver); +- return; ++ goto out; + + cleanup: + if (list) { + qapi_free_GuestDiskAddressList(list); + } ++out: + g_free(driver); ++#ifdef CONFIG_LIBUDEV ++ udev_unref(udev); ++ udev_device_unref(udevice); ++#endif ++ return; + } + + static void build_guest_fsinfo_for_device(char const *devpath, +diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json +index 17884c7..426528c 100644 +--- a/qga/qapi-schema.json ++++ b/qga/qapi-schema.json +@@ -832,13 +832,15 @@ + # @bus: bus id + # @target: target id + # @unit: unit id ++# @serial: serial number (since: 3.1) + # + # Since: 2.2 + ## + { 'struct': 'GuestDiskAddress', + 'data': {'pci-controller': 'GuestPCIAddress', + 'bus-type': 'GuestDiskBusType', +- 'bus': 'int', 'target': 'int', 'unit': 'int'} } ++ 'bus': 'int', 'target': 'int', 'unit': 'int', ++ '*serial': 'str'} } + + ## + # @GuestFilesystemInfo: +-- +1.8.3.1 + diff --git a/SOURCES/qemuga-qga-linux-return-disk-device-in-guest-get-fsinfo.patch b/SOURCES/qemuga-qga-linux-return-disk-device-in-guest-get-fsinfo.patch new file mode 100644 index 0000000..be14fcd --- /dev/null +++ b/SOURCES/qemuga-qga-linux-return-disk-device-in-guest-get-fsinfo.patch @@ -0,0 +1,75 @@ +From 00665748e4495bcb0b45dd5e15a7a9cc8331c77f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Fri, 23 Nov 2018 15:16:55 +0100 +Subject: [PATCH 5/5] qga: linux: return disk device in guest-get-fsinfo +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20181123151655.23498-5-marcandre.lureau@redhat.com> +Patchwork-id: 83153 +O-Subject: [RHEL-7.7 qemu-guest-agent PATCH 4/4] qga: linux: return disk device in guest-get-fsinfo +Bugzilla: 1635571 +RH-Acked-by: Markus Armbruster +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Laurent Vivier + +From: Tomáš Golembiovský + +Report device node of the disk on Linux (e.g. "/dev/sda2"). +Requirs libudev. + +Signed-off-by: Tomáš Golembiovský +Signed-off-by: Michael Roth + +(cherry picked from commit 6589ce35734e7e71463485650e5fb6e4bbe64729) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + qga/commands-posix.c | 7 ++++++- + qga/qapi-schema.json | 3 ++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/qga/commands-posix.c b/qga/commands-posix.c +index c0430e6..09884d7 100644 +--- a/qga/commands-posix.c ++++ b/qga/commands-posix.c +@@ -949,7 +949,12 @@ static void build_guest_fsinfo_for_real_device(char const *syspath, + if (udev == NULL || udevice == NULL) { + g_debug("failed to query udev"); + } else { +- const char *serial; ++ const char *devnode, *serial; ++ devnode = udev_device_get_devnode(udevice); ++ if (devnode != NULL) { ++ disk->dev = g_strdup(devnode); ++ disk->has_dev = true; ++ } + serial = udev_device_get_property_value(udevice, "ID_SERIAL"); + if (serial != NULL && *serial != 0) { + disk->serial = g_strdup(serial); +diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json +index 426528c..ca022ad 100644 +--- a/qga/qapi-schema.json ++++ b/qga/qapi-schema.json +@@ -833,6 +833,7 @@ + # @target: target id + # @unit: unit id + # @serial: serial number (since: 3.1) ++# @dev: device node (POSIX) or device UNC (Windows) (since: 3.1) + # + # Since: 2.2 + ## +@@ -840,7 +841,7 @@ + 'data': {'pci-controller': 'GuestPCIAddress', + 'bus-type': 'GuestDiskBusType', + 'bus': 'int', 'target': 'int', 'unit': 'int', +- '*serial': 'str'} } ++ '*serial': 'str', '*dev': 'str'} } + + ## + # @GuestFilesystemInfo: +-- +1.8.3.1 + diff --git a/SPECS/qemu-guest-agent.spec b/SPECS/qemu-guest-agent.spec new file mode 100644 index 0000000..f194165 --- /dev/null +++ b/SPECS/qemu-guest-agent.spec @@ -0,0 +1,359 @@ +%global have_usbredir 1 +%global have_spice 1 +%global have_fdt 0 +%global have_gluster 1 +%global have_numa 1 +%global have_librdma 1 +%global have_seccomp 1 +%global have_tcmalloc 1 + +%ifnarch %{ix86} x86_64 aarch64 + %global have_seccomp 0 +%endif + +%ifnarch %{ix86} x86_64 + %global have_usbredir 0 +%endif + +%ifarch s390 s390x + %global have_librdma 0 + %global have_numa 0 + %global have_tcmalloc 0 +%endif + +%ifarch %{ix86} + %global kvm_target i386 +%endif +%ifarch x86_64 + %global kvm_target x86_64 +%else + %global have_spice 0 + %global have_gluster 0 +%endif +%ifarch %{power64} + %global kvm_target ppc64 + %global have_fdt 1 +%endif +%ifarch s390 + %global kvm_target s390 +%endif +%ifarch s390x + %global kvm_target s390x +%endif +%ifarch ppc + %global kvm_target ppc + %global have_fdt 1 +%endif +%ifarch aarch64 + %global kvm_target aarch64 + %global have_fdt 1 +%endif + +#Versions of various parts: + +%define pkgname qemu-kvm + +Summary: QEMU guest agent +Name: qemu-guest-agent +Version: 2.12.0 +Release: 3%{?dist} +# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped +Epoch: 10 +License: GPLv2 +Group: System Environment/Daemons +URL: http://www.qemu.org/ +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units + +# OOM killer breaks builds with parallel make on s390(x) +%ifarch s390 s390x + %define _smp_mflags %{nil} +%endif + +Source0: http://wiki.qemu.org/download/qemu-2.12.0.tar.xz + +Source1: qemu-guest-agent.service +Source2: 99-qemu-guest-agent.rules +Source3: qemu-ga.sysconfig +Source4: build_configure.sh + +# For bz#1567041 - qemu-guest-agent does not parse PCI bridge links in "build_guest_fsinfo_for_real_device" (q35) +Patch1: qemuga-qemu-ga-make-get-fsinfo-work-over-pci-bridges.patch +# For bz#1567041 - qemu-guest-agent does not parse PCI bridge links in "build_guest_fsinfo_for_real_device" (q35) +Patch2: qemuga-qga-fix-driver-leak-in-guest-get-fsinfo.patch +# For bz#1611062 - "virsh vcpucount --guest" fails after hotunplug a vcpu with intermediate order by "setvcpu" +Patch3: qemuga-qga-ignore-non-present-cpus-when-handling-qmp_guest_.patch +# For bz#1635571 - [RFE] Report disk device name and serial number (qemu-guest-agent on Linux) +Patch5: qemuga-configure-add-test-for-libudev.patch +# For bz#1635571 - [RFE] Report disk device name and serial number (qemu-guest-agent on Linux) +Patch6: qemuga-qga-linux-report-disk-serial-number.patch +# For bz#1635571 - [RFE] Report disk device name and serial number (qemu-guest-agent on Linux) +Patch7: qemuga-qga-linux-return-disk-device-in-guest-get-fsinfo.patch + +BuildRequires: zlib-devel +BuildRequires: glib2-devel +BuildRequires: systemd +BuildRequires: systemd-devel +BuildRequires: python +BuildRequires: systemtap-sdt-devel +BuildRequires: perl-podlators +BuildRequires: texinfo +%if 0%{have_tcmalloc} +BuildRequires: gperftools-devel +%endif + +%define qemudocdir %{_docdir}/%{pkgname} + +%description +qemu-kvm is an open source virtualizer that provides hardware emulation for +the KVM hypervisor. + +This package provides an agent to run inside guests, which communicates +with the host over a virtio-serial channel named "org.qemu.guest_agent.0" + +This package does not need to be installed on the host OS. + +%post +%systemd_post qemu-guest-agent.service + +%preun +%systemd_preun qemu-guest-agent.service + +%postun +%systemd_postun_with_restart qemu-guest-agent.service + +%prep +%setup -q -n qemu-%{version} +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 + +# if patch fuzzy patch applying will be forbidden +%define with_fuzzy_patches 0 +%if %{with_fuzzy_patches} + patch_command='patch -p1 -s' +%else + patch_command='patch -p1 -F1 -s' +%endif + +ApplyPatch() +{ + local patch=$1 + shift + if [ ! -f $RPM_SOURCE_DIR/$patch ]; then + exit 1 + fi + case "$patch" in + *.bz2) bunzip2 < "$RPM_SOURCE_DIR/$patch" | $patch_command ${1+"$@"} ;; + *.gz) gunzip < "$RPM_SOURCE_DIR/$patch" | $patch_command ${1+"$@"} ;; + *) $patch_command ${1+"$@"} < "$RPM_SOURCE_DIR/$patch" ;; + esac +} + +# don't apply patch if it's empty or does not exist +ApplyOptionalPatch() +{ + local patch=$1 + shift + if [ ! -f $RPM_SOURCE_DIR/$patch ]; then + return 0 + fi + local C=$(wc -l $RPM_SOURCE_DIR/$patch | awk '{print $1}') + if [ "$C" -gt 9 ]; then + ApplyPatch $patch ${1+"$@"} + fi +} + + + +ApplyOptionalPatch qemu-kvm-test.patch + +%build +buildarch="%{kvm_target}-softmmu" + +# --build-id option is used for giving info to the debug packages. +extraldflags="-Wl,--build-id"; +buildldflags="VL_LDFLAGS=-Wl,--build-id" + +# QEMU already knows how to set _FORTIFY_SOURCE +%global optflags %(echo %{optflags} | sed 's/-Wp,-D_FORTIFY_SOURCE=2//') + +%ifarch s390 + # drop -g flag to prevent memory exhaustion by linker + %global optflags %(echo %{optflags} | sed 's/-g//') + sed -i.debug 's/"-g $CFLAGS"/"$CFLAGS"/g' configure +%endif + +cp %{SOURCE4} build_configure.sh +./build_configure.sh \ + "%{_prefix}" \ + "%{_libdir}" \ + "%{_sysconfdir}" \ + "%{_localstatedir}" \ + "%{_libexecdir}" \ + "qemu-ga" \ + "%{kvm_target}" \ + "%{name}-%{version}-%{release}" \ + "%{optflags}" \ +%if 0%{have_fdt} + enable \ +%else + disable \ +%endif +%if 0%{have_tcmalloc} + enable \ +%else + disable \ +%endif + --target-list= \ + --cpu="%{kvm_target}" + +echo "config-host.mak contents:" +echo "===" +cat config-host.mak +echo "===" + +make qemu-ga %{?_smp_mflags} $buildldflags +make qemu-ga.8 + +%install +%define _udevdir %(pkg-config --variable=udevdir udev)/rules.d + + +# For the qemu-guest-agent subpackage, install: +# - the systemd service file and the udev rules: +mkdir -p $RPM_BUILD_ROOT%{_unitdir} +mkdir -p $RPM_BUILD_ROOT%{_udevdir} +install -m 0644 %{SOURCE1} $RPM_BUILD_ROOT%{_unitdir} +install -m 0644 %{SOURCE2} $RPM_BUILD_ROOT%{_udevdir} + +# - the environment file for the systemd service: +install -D -p -m 0644 %{SOURCE3} \ + $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/qemu-ga + +# - the fsfreeze hook script: +install -D --preserve-timestamps \ + scripts/qemu-guest-agent/fsfreeze-hook \ + $RPM_BUILD_ROOT%{_sysconfdir}/qemu-ga/fsfreeze-hook + +# - the directory for user scripts: +mkdir $RPM_BUILD_ROOT%{_sysconfdir}/qemu-ga/fsfreeze-hook.d + +# - and the fsfreeze script samples: +mkdir --parents $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/qemu-ga/fsfreeze-hook.d/ +install --preserve-timestamps --mode=0644 \ + scripts/qemu-guest-agent/fsfreeze-hook.d/*.sample \ + $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/qemu-ga/fsfreeze-hook.d/ + +# - Install dedicated log directory: +mkdir -p -v $RPM_BUILD_ROOT%{_localstatedir}/log/qemu-ga/ + +mkdir -p $RPM_BUILD_ROOT%{_bindir} +install -c -m 0755 qemu-ga ${RPM_BUILD_ROOT}%{_bindir}/qemu-ga + +mkdir -p $RPM_BUILD_ROOT%{_mandir}/man8 +install -m 0644 qemu-ga.8 ${RPM_BUILD_ROOT}%{_mandir}/man8/ + +%files + %defattr(-,root,root,-) + %doc COPYING README + %{_bindir}/qemu-ga + %{_unitdir}/qemu-guest-agent.service + %{_udevdir}/99-qemu-guest-agent.rules + %config(noreplace) %{_sysconfdir}/sysconfig/qemu-ga + %{_sysconfdir}/qemu-ga + %{_datadir}/%{pkgname}/qemu-ga + %{_mandir}/man8/qemu-ga.8* + %dir %{_localstatedir}/log/qemu-ga + + +%changelog +* Wed Dec 12 2018 Miroslav Rezanina - 2.12.0-3.el7 +- qemuga-qga-ignore-non-present-cpus-when-handling-qmp_guest_.patch [bz#1611062] +- qemuga-qemu-guest-agent.spec-add-systemd-devel-dependency.patch [bz#1635571] +- qemuga-configure-add-test-for-libudev.patch [bz#1635571] +- qemuga-qga-linux-report-disk-serial-number.patch [bz#1635571] +- qemuga-qga-linux-return-disk-device-in-guest-get-fsinfo.patch [bz#1635571] +- Resolves: bz#1611062 + ("virsh vcpucount --guest" fails after hotunplug a vcpu with intermediate order by "setvcpu") +- Resolves: bz#1635571 + ([RFE] Report disk device name and serial number (qemu-guest-agent on Linux)) + +* Tue Jul 24 2018 Miroslav Rezanina - 2.12.0-2.el7 +- qemuga-qemu-ga-make-get-fsinfo-work-over-pci-bridges.patch [bz#1567041] +- qemuga-qga-fix-driver-leak-in-guest-get-fsinfo.patch [bz#1567041] +- Resolves: bz#1567041 + (qemu-guest-agent does not parse PCI bridge links in "build_guest_fsinfo_for_real_device" (q35)) + +* Wed May 02 2018 Miroslav Rezanina - 2.12.0-1.el7 +- Rebase to 2.12.0 base [bz#1562218] +- Resolves: bz#1562218 + (Rebase qemu-guest-agent for RHEL-7.6) + +* Fri May 19 2017 Miroslav Rezanina - 2.8.0-2.el7 +- qemuga-Remove-unnecessary-dependencies.patch [bz#1441999] +- Resolves: bz#1441999 + (Clean qemu-ga dependencies) + +* Tue Feb 07 2017 Miroslav Rezanina - 2.8.0-1.el7 +- Rebase to 2.8.0 base [bz#1414676] +- Resolves: bz#1414676 + (Rebase qemu-guest-agent to 2.8.0 base) + +* Thu Sep 01 2016 Miroslav Rezanina - 2.5.0-3.el7 +- qemuga-spec-add-qemu-ga-man-page.patch [bz#1101556] +- Resolves: bz#1101556 + ([RFE] qemu-ga should have a config file) + +* Wed Jun 15 2016 Miroslav Rezanina - 2.5.0-2.el7 +- qemuga-redhat-blacklist-guest-exec-commands.patch [bz#1340346] +- Resolves: bz#1340346 + (blacklist guest-exec in newer version of qemu-guest-agent) + +* Tue Jan 12 2016 Miroslav Rezanina - 2.5.0-1.el7 +- Rebase to QEMU 2.5.0 [bz#1297673] +- Resolves: bz#1297673 + (Rebase to QEMU 2.5) +* Tue Aug 25 2015 Miroslav Rezanina - 2.3.0-3.el7 +- qemuga-Do-not-stop-qemu-guest-agent-service-on-target-switc.patch [bz#1160930] +- Resolves: bz#1160930 + (The guest agent service in rhel7 guest will be stopped after run the init command) + +* Mon Jul 13 2015 Miroslav Rezanina - 2.3.0-2.el7 +- synchronized with qemu-kvm-rhev-2.3.0-9.el7 +- qemuga-Change-fsreeze-hook-default-location.patch [bz#1210707] +- qemuga-qga-commands-posix-Fix-bug-in-guest-fstrim.patch [bz#1211973] +- Resolves: bz#1210707 + (The default path '/etc/qemu/fsfreeze-hook' for 'fsfreeze-hook' script doesn't exist) +- Resolves: bz#1211973 + ('guest-fstrim' failed for guest with os on spapr-vscsi disk) + +* Tue Apr 28 2015 Miroslav Rezanina - 2.3.0-1.el7 +- Rebase to 2.3.0 [bz#1194152] +- Resolves: bz#1194152 + (Rebase to 2.3.0) + +* Tue Oct 21 2014 Miroslav Rezanina - 2.1.0-4.el7 +- kvm-Mark-etc-sysconfig-qemu-ga-as-config-noreplace.patch [bz#1150924] +- Resolves: bz#1150924 + (/etc/sysconfig/qemu-ga is replaced when updated) + +* Thu Aug 28 2014 Miroslav Rezanina - 2.1.0-3.el7 +- Allow building qemu-guest-agent on ppc64le +- Synchronize with qemu-kvm-rhev-2.1.0-3.el7 +- Resolves: bz#1132718 + (qemu-guest-agent fails to build for ppc64le) + +* Sat Aug 02 2014 Miroslav Rezanina - 2.1.0-2.el7 +- Create separate qemu-guest-agent package based on qemu-kvm-rhev-2.1.0-1.el7 [bz#1117096] +- Resolves: #bz1117096 + +* Sat Aug 02 2014 Miroslav Rezanina - 2.1.0-1.el7 +- Rebase to 2.1.0 [bz#1121609] +- Resolves: bz#1121609 + (Rebase qemu-kvm-rhev to qemu 2.1) +