diff --git a/.gitignore b/.gitignore index 279b827..df9af11 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/qemu-2.8.0.tar.bz2 +SOURCES/qemu-2.12.0.tar.xz diff --git a/.qemu-guest-agent.metadata b/.qemu-guest-agent.metadata index 001aef0..bda0ddd 100644 --- a/.qemu-guest-agent.metadata +++ b/.qemu-guest-agent.metadata @@ -1 +1 @@ -a5602f2ddb51d61b4c0e618b779fdb0dbdc9cc1f SOURCES/qemu-2.8.0.tar.bz2 +5a62c911b2cebbd41decd5c77c524395212411cf SOURCES/qemu-2.12.0.tar.xz diff --git a/SOURCES/build_configure.sh b/SOURCES/build_configure.sh index 00981ee..eff4f9b 100755 --- a/SOURCES/build_configure.sh +++ b/SOURCES/build_configure.sh @@ -35,7 +35,6 @@ shift --with-pkgversion=${nvr} \ --with-confsuffix=/${pkgname} \ --with-coroutine=ucontext \ - --disable-archipelago \ --disable-bluez \ --disable-brlapi \ --disable-cap-ng \ diff --git a/SOURCES/qemuga-qemu-ga-add-guest-get-osinfo-command.patch b/SOURCES/qemuga-qemu-ga-add-guest-get-osinfo-command.patch deleted file mode 100644 index 43e79e9..0000000 --- a/SOURCES/qemuga-qemu-ga-add-guest-get-osinfo-command.patch +++ /dev/null @@ -1,464 +0,0 @@ -From 2db11b426c4e16b64926f78baea594792c183f57 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Thu, 19 Apr 2018 12:33:46 -0300 -Subject: [PATCH 5/7] qemu-ga: add guest-get-osinfo command -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Miroslav Rezanina -Message-id: <032a36a732e654dc0d6e2043a47eb294db3ac75f.1524139831.git.mrezanin@redhat.com> -Patchwork-id: 79704 -O-Subject: [RHEL-7.5.z qemu-guest-agent PATCH 5/7] qemu-ga: add guest-get-osinfo command -Bugzilla: 1598210 -RH-Acked-by: Marc-André Lureau -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Tomáš Golembiovský - -From: Tomáš Golembiovský - -Add a new 'guest-get-osinfo' command for reporting basic information of -the guest operating system. This includes machine architecture, -version and release of the kernel and several fields from os-release -file if it is present (as defined in [1]). - -[1] https://www.freedesktop.org/software/systemd/man/os-release.html - -Signed-off-by: Vinzenz Feenstra -Signed-off-by: Tomáš Golembiovský -* moved declarations to beginning of functions -* dropped unecessary initialization of struct utsname -Signed-off-by: Michael Roth -(cherry picked from commit 9848f79740dc3bd2e0515470d24b8bec53904473) -Signed-off-by: Wainer dos Santos Moschetta ---- - qga/commands-posix.c | 135 ++++++++++++++++++++++++++++++++++++ - qga/commands-win32.c | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++ - qga/qapi-schema.json | 65 ++++++++++++++++++ - 3 files changed, 391 insertions(+) - -diff --git a/qga/commands-posix.c b/qga/commands-posix.c -index 70348aa8c8..add8a51f2b 100644 ---- a/qga/commands-posix.c -+++ b/qga/commands-posix.c -@@ -13,6 +13,7 @@ - - #include "qemu/osdep.h" - #include -+#include - #include - #include - #include "qga/guest-agent-core.h" -@@ -2587,3 +2588,137 @@ GuestUserList *qmp_guest_get_users(Error **errp) - } - - #endif -+ -+/* Replace escaped special characters with theire real values. The replacement -+ * is done in place -- returned value is in the original string. -+ */ -+static void ga_osrelease_replace_special(gchar *value) -+{ -+ gchar *p, *p2, quote; -+ -+ /* Trim the string at first space or semicolon if it is not enclosed in -+ * single or double quotes. */ -+ if ((value[0] != '"') || (value[0] == '\'')) { -+ p = strchr(value, ' '); -+ if (p != NULL) { -+ *p = 0; -+ } -+ p = strchr(value, ';'); -+ if (p != NULL) { -+ *p = 0; -+ } -+ return; -+ } -+ -+ quote = value[0]; -+ p2 = value; -+ p = value + 1; -+ while (*p != 0) { -+ if (*p == '\\') { -+ p++; -+ switch (*p) { -+ case '$': -+ case '\'': -+ case '"': -+ case '\\': -+ case '`': -+ break; -+ default: -+ /* Keep literal backslash followed by whatever is there */ -+ p--; -+ break; -+ } -+ } else if (*p == quote) { -+ *p2 = 0; -+ break; -+ } -+ *(p2++) = *(p++); -+ } -+} -+ -+static GKeyFile *ga_parse_osrelease(const char *fname) -+{ -+ gchar *content = NULL; -+ gchar *content2 = NULL; -+ GError *err = NULL; -+ GKeyFile *keys = g_key_file_new(); -+ const char *group = "[os-release]\n"; -+ -+ if (!g_file_get_contents(fname, &content, NULL, &err)) { -+ slog("failed to read '%s', error: %s", fname, err->message); -+ goto fail; -+ } -+ -+ if (!g_utf8_validate(content, -1, NULL)) { -+ slog("file is not utf-8 encoded: %s", fname); -+ goto fail; -+ } -+ content2 = g_strdup_printf("%s%s", group, content); -+ -+ if (!g_key_file_load_from_data(keys, content2, -1, G_KEY_FILE_NONE, -+ &err)) { -+ slog("failed to parse file '%s', error: %s", fname, err->message); -+ goto fail; -+ } -+ -+ g_free(content); -+ g_free(content2); -+ return keys; -+ -+fail: -+ g_error_free(err); -+ g_free(content); -+ g_free(content2); -+ g_key_file_free(keys); -+ return NULL; -+} -+ -+GuestOSInfo *qmp_guest_get_osinfo(Error **errp) -+{ -+ GuestOSInfo *info = NULL; -+ struct utsname kinfo; -+ GKeyFile *osrelease; -+ -+ info = g_new0(GuestOSInfo, 1); -+ -+ if (uname(&kinfo) != 0) { -+ error_setg_errno(errp, errno, "uname failed"); -+ } else { -+ info->has_kernel_version = true; -+ info->kernel_version = g_strdup(kinfo.version); -+ info->has_kernel_release = true; -+ info->kernel_release = g_strdup(kinfo.release); -+ info->has_machine = true; -+ info->machine = g_strdup(kinfo.machine); -+ } -+ -+ osrelease = ga_parse_osrelease("/etc/os-release"); -+ if (osrelease == NULL) { -+ osrelease = ga_parse_osrelease("/usr/lib/os-release"); -+ } -+ -+ if (osrelease != NULL) { -+ char *value; -+ -+#define GET_FIELD(field, osfield) do { \ -+ value = g_key_file_get_value(osrelease, "os-release", osfield, NULL); \ -+ if (value != NULL) { \ -+ ga_osrelease_replace_special(value); \ -+ info->has_ ## field = true; \ -+ info->field = value; \ -+ } \ -+} while (0) -+ GET_FIELD(id, "ID"); -+ GET_FIELD(name, "NAME"); -+ GET_FIELD(pretty_name, "PRETTY_NAME"); -+ GET_FIELD(version, "VERSION"); -+ GET_FIELD(version_id, "VERSION_ID"); -+ GET_FIELD(variant, "VARIANT"); -+ GET_FIELD(variant_id, "VARIANT_ID"); -+#undef GET_FIELD -+ -+ g_key_file_free(osrelease); -+ } -+ -+ return info; -+} -diff --git a/qga/commands-win32.c b/qga/commands-win32.c -index fa99a8f846..9ae9836df5 100644 ---- a/qga/commands-win32.c -+++ b/qga/commands-win32.c -@@ -1639,3 +1639,194 @@ GuestUserList *qmp_guest_get_users(Error **err) - return NULL; - #endif - } -+ -+typedef struct _ga_matrix_lookup_t { -+ int major; -+ int minor; -+ char const *version; -+ char const *version_id; -+} ga_matrix_lookup_t; -+ -+static ga_matrix_lookup_t const WIN_VERSION_MATRIX[2][8] = { -+ { -+ /* Desktop editions */ -+ { 5, 0, "Microsoft Windows 2000", "2000"}, -+ { 5, 1, "Microsoft Windows XP", "xp"}, -+ { 6, 0, "Microsoft Windows Vista", "vista"}, -+ { 6, 1, "Microsoft Windows 7" "7"}, -+ { 6, 2, "Microsoft Windows 8", "8"}, -+ { 6, 3, "Microsoft Windows 8.1", "8.1"}, -+ {10, 0, "Microsoft Windows 10", "10"}, -+ { 0, 0, 0} -+ },{ -+ /* Server editions */ -+ { 5, 2, "Microsoft Windows Server 2003", "2003"}, -+ { 6, 0, "Microsoft Windows Server 2008", "2008"}, -+ { 6, 1, "Microsoft Windows Server 2008 R2", "2008r2"}, -+ { 6, 2, "Microsoft Windows Server 2012", "2012"}, -+ { 6, 3, "Microsoft Windows Server 2012 R2", "2012r2"}, -+ {10, 0, "Microsoft Windows Server 2016", "2016"}, -+ { 0, 0, 0}, -+ { 0, 0, 0} -+ } -+}; -+ -+static void ga_get_win_version(RTL_OSVERSIONINFOEXW *info, Error **errp) -+{ -+ typedef NTSTATUS(WINAPI * rtl_get_version_t)( -+ RTL_OSVERSIONINFOEXW *os_version_info_ex); -+ -+ info->dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW); -+ -+ HMODULE module = GetModuleHandle("ntdll"); -+ PVOID fun = GetProcAddress(module, "RtlGetVersion"); -+ if (fun == NULL) { -+ error_setg(errp, QERR_QGA_COMMAND_FAILED, -+ "Failed to get address of RtlGetVersion"); -+ return; -+ } -+ -+ rtl_get_version_t rtl_get_version = (rtl_get_version_t)fun; -+ rtl_get_version(info); -+ return; -+} -+ -+static char *ga_get_win_name(OSVERSIONINFOEXW const *os_version, bool id) -+{ -+ DWORD major = os_version->dwMajorVersion; -+ DWORD minor = os_version->dwMinorVersion; -+ int tbl_idx = (os_version->wProductType != VER_NT_WORKSTATION); -+ ga_matrix_lookup_t const *table = WIN_VERSION_MATRIX[tbl_idx]; -+ while (table->version != NULL) { -+ if (major == table->major && minor == table->minor) { -+ if (id) { -+ return g_strdup(table->version_id); -+ } else { -+ return g_strdup(table->version); -+ } -+ } -+ ++table; -+ } -+ slog("failed to lookup Windows version: major=%lu, minor=%lu", -+ major, minor); -+ return g_strdup("N/A"); -+} -+ -+static char *ga_get_win_product_name(Error **errp) -+{ -+ HKEY key = NULL; -+ DWORD size = 128; -+ char *result = g_malloc0(size); -+ LONG err = ERROR_SUCCESS; -+ -+ err = RegOpenKeyA(HKEY_LOCAL_MACHINE, -+ "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", -+ &key); -+ if (err != ERROR_SUCCESS) { -+ error_setg_win32(errp, err, "failed to open registry key"); -+ goto fail; -+ } -+ -+ err = RegQueryValueExA(key, "ProductName", NULL, NULL, -+ (LPBYTE)result, &size); -+ if (err == ERROR_MORE_DATA) { -+ slog("ProductName longer than expected (%lu bytes), retrying", -+ size); -+ g_free(result); -+ result = NULL; -+ if (size > 0) { -+ result = g_malloc0(size); -+ err = RegQueryValueExA(key, "ProductName", NULL, NULL, -+ (LPBYTE)result, &size); -+ } -+ } -+ if (err != ERROR_SUCCESS) { -+ error_setg_win32(errp, err, "failed to retrive ProductName"); -+ goto fail; -+ } -+ -+ return result; -+ -+fail: -+ g_free(result); -+ return NULL; -+} -+ -+static char *ga_get_current_arch(void) -+{ -+ SYSTEM_INFO info; -+ GetNativeSystemInfo(&info); -+ char *result = NULL; -+ switch (info.wProcessorArchitecture) { -+ case PROCESSOR_ARCHITECTURE_AMD64: -+ result = g_strdup("x86_64"); -+ break; -+ case PROCESSOR_ARCHITECTURE_ARM: -+ result = g_strdup("arm"); -+ break; -+ case PROCESSOR_ARCHITECTURE_IA64: -+ result = g_strdup("ia64"); -+ break; -+ case PROCESSOR_ARCHITECTURE_INTEL: -+ result = g_strdup("x86"); -+ break; -+ case PROCESSOR_ARCHITECTURE_UNKNOWN: -+ default: -+ slog("unknown processor architecture 0x%0x", -+ info.wProcessorArchitecture); -+ result = g_strdup("unknown"); -+ break; -+ } -+ return result; -+} -+ -+GuestOSInfo *qmp_guest_get_osinfo(Error **errp) -+{ -+ Error *local_err = NULL; -+ OSVERSIONINFOEXW os_version = {0}; -+ bool server; -+ char *product_name; -+ GuestOSInfo *info; -+ -+ ga_get_win_version(&os_version, &local_err); -+ if (local_err) { -+ error_propagate(errp, local_err); -+ return NULL; -+ } -+ -+ server = os_version.wProductType != VER_NT_WORKSTATION; -+ product_name = ga_get_win_product_name(&local_err); -+ if (product_name == NULL) { -+ error_propagate(errp, local_err); -+ return NULL; -+ } -+ -+ info = g_new0(GuestOSInfo, 1); -+ -+ info->has_kernel_version = true; -+ info->kernel_version = g_strdup_printf("%lu.%lu", -+ os_version.dwMajorVersion, -+ os_version.dwMinorVersion); -+ info->has_kernel_release = true; -+ info->kernel_release = g_strdup_printf("%lu", -+ os_version.dwBuildNumber); -+ info->has_machine = true; -+ info->machine = ga_get_current_arch(); -+ -+ info->has_id = true; -+ info->id = g_strdup("mswindows"); -+ info->has_name = true; -+ info->name = g_strdup("Microsoft Windows"); -+ info->has_pretty_name = true; -+ info->pretty_name = product_name; -+ info->has_version = true; -+ info->version = ga_get_win_name(&os_version, false); -+ info->has_version_id = true; -+ info->version_id = ga_get_win_name(&os_version, true); -+ info->has_variant = true; -+ info->variant = g_strdup(server ? "server" : "client"); -+ info->has_variant_id = true; -+ info->variant_id = g_strdup(server ? "server" : "client"); -+ -+ return info; -+} -diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json -index 5af73fedae..43ce3feeaa 100644 ---- a/qga/qapi-schema.json -+++ b/qga/qapi-schema.json -@@ -1104,3 +1104,68 @@ - ## - { 'command': 'guest-get-timezone', - 'returns': 'GuestTimezone' } -+ -+## -+# @GuestOSInfo: -+# -+# @kernel-release: -+# * POSIX: release field returned by uname(2) -+# * Windows: version number of the OS -+# @kernel-version: -+# * POSIX: version field returned by uname(2) -+# * Windows: build number of the OS -+# @machine: -+# * POSIX: machine field returned by uname(2) -+# * Windows: one of x86, x86_64, arm, ia64 -+# @id: -+# * POSIX: as defined by os-release(5) -+# * Windows: contains string "mswindows" -+# @name: -+# * POSIX: as defined by os-release(5) -+# * Windows: contains string "Microsoft Windows" -+# @pretty-name: -+# * POSIX: as defined by os-release(5) -+# * Windows: product name, e.g. "Microsoft Windows 10 Enterprise" -+# @version: -+# * POSIX: as defined by os-release(5) -+# * Windows: long version string, e.g. "Microsoft Windows Server 2008" -+# @version-id: -+# * POSIX: as defined by os-release(5) -+# * Windows: short version identifier, e.g. "7" or "20012r2" -+# @variant: -+# * POSIX: as defined by os-release(5) -+# * Windows: contains string "server" or "client" -+# @variant-id: -+# * POSIX: as defined by os-release(5) -+# * Windows: contains string "server" or "client" -+# -+# Notes: -+# -+# On POSIX systems the fields @id, @name, @pretty-name, @version, @version-id, -+# @variant and @variant-id follow the definition specified in os-release(5). -+# Refer to the manual page for exact description of the fields. Their values -+# are taken from the os-release file. If the file is not present in the system, -+# or the values are not present in the file, the fields are not included. -+# -+# On Windows the values are filled from information gathered from the system. -+# -+# Since: 2.10 -+## -+{ 'struct': 'GuestOSInfo', -+ 'data': { -+ '*kernel-release': 'str', '*kernel-version': 'str', -+ '*machine': 'str', '*id': 'str', '*name': 'str', -+ '*pretty-name': 'str', '*version': 'str', '*version-id': 'str', -+ '*variant': 'str', '*variant-id': 'str' } } -+ -+## -+# @guest-get-osinfo: -+# -+# Retrieve guest operating system information -+# -+# Returns: @GuestOSInfo -+# -+# Since: 2.10 -+## -+{ 'command': 'guest-get-osinfo', -+ 'returns': 'GuestOSInfo' } --- -2.13.6 - diff --git a/SOURCES/qemuga-qemu-ga-check-if-utmpx.h-is-available-on-the-system.patch b/SOURCES/qemuga-qemu-ga-check-if-utmpx.h-is-available-on-the-system.patch deleted file mode 100644 index 22513cb..0000000 --- a/SOURCES/qemuga-qemu-ga-check-if-utmpx.h-is-available-on-the-system.patch +++ /dev/null @@ -1,122 +0,0 @@ -From f19ba10fbf079a0470ccc0e4b457fd4694c52f7a Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Thu, 19 Apr 2018 12:33:45 -0300 -Subject: [PATCH 4/7] qemu-ga: check if utmpx.h is available on the system -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Miroslav Rezanina -Message-id: -Patchwork-id: 79706 -O-Subject: [RHEL-7.5.z qemu-guest-agent PATCH 4/7] qemu-ga: check if utmpx.h is available on the system -Bugzilla: 1598210 -RH-Acked-by: Marc-André Lureau -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Tomáš Golembiovský - -From: Tomáš Golembiovský - -Commit 161a56a9065 added command guest-get-users and requires the -utmpx.h (defined by POSIX) to work. It is however not always available -(e.g. on OpenBSD) therefor a check for its existence is necessary. - -Signed-off-by: Tomáš Golembiovský -Signed-off-by: Michael Roth - -Conflicts: - configure - Incorrect context due to missing commits - -(cherry picked from commit e674605f9821a275e3ed87ce9accc835d565b753) -Signed-off-by: Wainer dos Santos Moschetta ---- - configure | 19 +++++++++++++++++++ - qga/commands-posix.c | 17 ++++++++++++++++- - 2 files changed, 35 insertions(+), 1 deletion(-) - -diff --git a/configure b/configure -index ccd2a0e230..606368a506 100755 ---- a/configure -+++ b/configure -@@ -4734,6 +4734,21 @@ if test "$modules" = "yes" && test "$LD_REL_FLAGS" = ""; then - fi - - ########################################## -+# check for utmpx.h, it is missing e.g. on OpenBSD -+ -+have_utmpx=no -+cat > $TMPC << EOF -+#include -+struct utmpx user_info; -+int main(void) { -+ return 0; -+} -+EOF -+if compile_prog "" "" ; then -+ have_utmpx=yes -+fi -+ -+########################################## - # End of CC checks - # After here, no more $cc or $ld runs - -@@ -5706,6 +5721,10 @@ if test "$have_af_vsock" = "yes" ; then - echo "CONFIG_AF_VSOCK=y" >> $config_host_mak - fi - -+if test "$have_utmpx" = "yes" ; then -+ echo "HAVE_UTMPX=y" >> $config_host_mak -+fi -+ - # Hold two types of flag: - # CONFIG_THREAD_SETNAME_BYTHREAD - we've got a way of setting the name on - # a thread we have a handle to -diff --git a/qga/commands-posix.c b/qga/commands-posix.c -index 55ac4fe9e7..70348aa8c8 100644 ---- a/qga/commands-posix.c -+++ b/qga/commands-posix.c -@@ -15,7 +15,6 @@ - #include - #include - #include --#include - #include "qga/guest-agent-core.h" - #include "qga-qmp-commands.h" - #include "qapi/qmp/qerror.h" -@@ -25,6 +24,10 @@ - #include "qemu/base64.h" - #include "qemu/cutils.h" - -+#ifdef HAVE_UTMPX -+#include -+#endif -+ - #ifndef CONFIG_HAS_ENVIRON - #ifdef __APPLE__ - #include -@@ -2514,6 +2517,8 @@ void ga_command_state_init(GAState *s, GACommandState *cs) - #endif - } - -+#ifdef HAVE_UTMPX -+ - #define QGA_MICRO_SECOND_TO_SECOND 1000000 - - static double ga_get_login_time(struct utmpx *user_info) -@@ -2572,3 +2577,13 @@ GuestUserList *qmp_guest_get_users(Error **err) - g_hash_table_destroy(cache); - return head; - } -+ -+#else -+ -+GuestUserList *qmp_guest_get_users(Error **errp) -+{ -+ error_setg(errp, QERR_UNSUPPORTED); -+ return NULL; -+} -+ -+#endif --- -2.13.6 - 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-Add-guest-get-host-name-command.patch b/SOURCES/qemuga-qga-Add-guest-get-host-name-command.patch deleted file mode 100644 index 8479003..0000000 --- a/SOURCES/qemuga-qga-Add-guest-get-host-name-command.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 1878782a30dac5279c050a381015d9590d96a22e Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Thu, 19 Apr 2018 12:33:42 -0300 -Subject: [PATCH 1/7] qga: Add 'guest-get-host-name' command -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Miroslav Rezanina -Message-id: -Patchwork-id: 79710 -O-Subject: [RHEL-7.5.z qemu-guest-agent PATCH 1/7] qga: Add 'guest-get-host-name' command -Bugzilla: 1598210 -RH-Acked-by: Marc-André Lureau -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Tomáš Golembiovský - -From: Vinzenz Feenstra - -Retrieving the guest host name is a very useful feature for virtual management -systems. This information can help to have more user friendly VM access -details, instead of an IP there would be the host name. Also the host name -reported can be used to have automated checks for valid SSL certificates. - -virsh # qemu-agent-command F25 '{ "execute": "guest-get-host-name" }' -{"return":{"host-name":"F25.lab.evilissimo.net"}} - -Signed-off-by: Vinzenz Feenstra -* minor whitespace fix-ups -Signed-off-by: Michael Roth -(cherry picked from commit 0a3d197a71b0508f5ca066488fbbbe45a61c44fe) -Signed-off-by: Wainer dos Santos Moschetta ---- - qga/commands.c | 11 +++++++++++ - qga/qapi-schema.json | 26 ++++++++++++++++++++++++++ - 2 files changed, 37 insertions(+) - -diff --git a/qga/commands.c b/qga/commands.c -index edd3e830e6..8c09938e28 100644 ---- a/qga/commands.c -+++ b/qga/commands.c -@@ -499,3 +499,14 @@ int ga_parse_whence(GuestFileWhence *whence, Error **errp) - error_setg(errp, "invalid whence code %"PRId64, whence->u.value); - return -1; - } -+ -+GuestHostName *qmp_guest_get_host_name(Error **err) -+{ -+ GuestHostName *result = NULL; -+ gchar const *hostname = g_get_host_name(); -+ if (hostname != NULL) { -+ result = g_new0(GuestHostName, 1); -+ result->host_name = g_strdup(hostname); -+ } -+ return result; -+} -diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json -index 94c03128fd..8271c1eb84 100644 ---- a/qga/qapi-schema.json -+++ b/qga/qapi-schema.json -@@ -1028,3 +1028,29 @@ - 'data': { 'path': 'str', '*arg': ['str'], '*env': ['str'], - '*input-data': 'str', '*capture-output': 'bool' }, - 'returns': 'GuestExec' } -+ -+ -+## -+# @GuestHostName: -+# @host-name: Fully qualified domain name of the guest OS -+# -+# Since: 2.10 -+## -+{ 'struct': 'GuestHostName', -+ 'data': { 'host-name': 'str' } } -+ -+## -+# @guest-get-host-name: -+# -+# Return a name for the machine. -+# -+# The returned name is not necessarily a fully-qualified domain name, or even -+# present in DNS or some other name service at all. It need not even be unique -+# on your local network or site, but usually it is. -+# -+# Returns: the host name of the machine on success -+# -+# Since: 2.10 -+## -+{ 'command': 'guest-get-host-name', -+ 'returns': 'GuestHostName' } --- -2.13.6 - diff --git a/SOURCES/qemuga-qga-Add-guest-get-timezone-command.patch b/SOURCES/qemuga-qga-Add-guest-get-timezone-command.patch deleted file mode 100644 index d5c002f..0000000 --- a/SOURCES/qemuga-qga-Add-guest-get-timezone-command.patch +++ /dev/null @@ -1,121 +0,0 @@ -From c3d3a693c4bb181f6673071de95e79fd97eda526 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Thu, 19 Apr 2018 12:33:44 -0300 -Subject: [PATCH 3/7] qga: Add `guest-get-timezone` command -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Miroslav Rezanina -Message-id: <605280b778254624582ec8aa72c72155d2206948.1524139831.git.mrezanin@redhat.com> -Patchwork-id: 79705 -O-Subject: [RHEL-7.5.z qemu-guest-agent PATCH 3/7] qga: Add `guest-get-timezone` command -Bugzilla: 1598210 -RH-Acked-by: Marc-André Lureau -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Tomáš Golembiovský - -From: Vinzenz Feenstra - -Adds a new command `guest-get-timezone` reporting the currently -configured timezone on the system. The information on what timezone is -currently is configured is useful in case of Windows VMs where the -offset of the hardware clock is required to have the same offset. This -can be used for management systems like `oVirt` to detect the timezone -difference and warn administrators of the misconfiguration. - -Signed-off-by: Vinzenz Feenstra -Reviewed-by: Sameeh Jubran -Tested-by: Sameeh Jubran -* moved stub implementation to end of function for consistency -* document that timezone names are for informational use only. -Signed-off-by: Michael Roth -(cherry picked from commit 53c58e64d0a27c59d763778faa2b5a522c544719) -Signed-off-by: Wainer dos Santos Moschetta ---- - qga/commands.c | 38 ++++++++++++++++++++++++++++++++++++++ - qga/qapi-schema.json | 25 +++++++++++++++++++++++++ - 2 files changed, 63 insertions(+) - -diff --git a/qga/commands.c b/qga/commands.c -index 8c09938e28..5b73cd0e4d 100644 ---- a/qga/commands.c -+++ b/qga/commands.c -@@ -510,3 +510,41 @@ GuestHostName *qmp_guest_get_host_name(Error **err) - } - return result; - } -+ -+GuestTimezone *qmp_guest_get_timezone(Error **errp) -+{ -+#if GLIB_CHECK_VERSION(2, 28, 0) -+ GuestTimezone *info = NULL; -+ GTimeZone *tz = NULL; -+ gint64 now = 0; -+ gint32 intv = 0; -+ gchar const *name = NULL; -+ -+ info = g_new0(GuestTimezone, 1); -+ tz = g_time_zone_new_local(); -+ if (tz == NULL) { -+ error_setg(errp, QERR_QGA_COMMAND_FAILED, -+ "Couldn't retrieve local timezone"); -+ goto error; -+ } -+ -+ now = g_get_real_time() / G_USEC_PER_SEC; -+ intv = g_time_zone_find_interval(tz, G_TIME_TYPE_UNIVERSAL, now); -+ info->offset = g_time_zone_get_offset(tz, intv); -+ name = g_time_zone_get_abbreviation(tz, intv); -+ if (name != NULL) { -+ info->has_zone = true; -+ info->zone = g_strdup(name); -+ } -+ g_time_zone_unref(tz); -+ -+ return info; -+ -+error: -+ g_free(info); -+ return NULL; -+#else -+ error_setg(errp, QERR_UNSUPPORTED); -+ return NULL; -+#endif -+} -diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json -index 1695afe3a9..5af73fedae 100644 ---- a/qga/qapi-schema.json -+++ b/qga/qapi-schema.json -@@ -1079,3 +1079,28 @@ - ## - { 'command': 'guest-get-users', - 'returns': ['GuestUser'] } -+ -+## -+# @GuestTimezone: -+# -+# @zone: Timezone name. These values may differ depending on guest/OS and -+# should only be used for informational purposes. -+# @offset: Offset to UTC in seconds, negative numbers for time zones west of -+# GMT, positive numbers for east -+# -+# Since: 2.10 -+## -+{ 'struct': 'GuestTimezone', -+ 'data': { '*zone': 'str', 'offset': 'int' } } -+ -+## -+# @guest-get-timezone: -+# -+# Retrieves the timezone information from the guest. -+# -+# Returns: A GuestTimezone dictionary. -+# -+# Since: 2.10 -+## -+{ 'command': 'guest-get-timezone', -+ 'returns': 'GuestTimezone' } --- -2.13.6 - diff --git a/SOURCES/qemuga-qga-Add-guest-get-users-command.patch b/SOURCES/qemuga-qga-Add-guest-get-users-command.patch deleted file mode 100644 index 5e7658d..0000000 --- a/SOURCES/qemuga-qga-Add-guest-get-users-command.patch +++ /dev/null @@ -1,311 +0,0 @@ -From c456b78c44d3f132b06d5b77de0de5e6e81870e7 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Thu, 19 Apr 2018 12:33:43 -0300 -Subject: [PATCH 2/7] qga: Add 'guest-get-users' command -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Miroslav Rezanina -Message-id: <9c0e4bb70a07f0e6cc94bab75d0aedd193f21be8.1524139831.git.mrezanin@redhat.com> -Patchwork-id: 79708 -O-Subject: [RHEL-7.5.z qemu-guest-agent PATCH 2/7] qga: Add 'guest-get-users' command -Bugzilla: 1598210 -RH-Acked-by: Marc-André Lureau -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Tomáš Golembiovský - -From: Vinzenz Feenstra - -A command that will list all currently logged in users, and the time -since when they are logged in. - -Examples: - -virsh # qemu-agent-command F25 '{ "execute": "guest-get-users" }' -{"return":[{"login-time":1490622289.903835,"user":"root"}]} - -virsh # qemu-agent-command Win2k12r2 '{ "execute": "guest-get-users" }' -{"return":[{"login-time":1490351044.670552,"domain":"LADIDA", -"user":"Administrator"}]} - -Signed-off-by: Vinzenz Feenstra -* make g_hash_table_contains compat func inline to avoid - unused warnings -Signed-off-by: Michael Roth -(cherry picked from commit 161a56a9065feb6fa2f69cec6237a5c4e714b9d3) -Signed-off-by: Wainer dos Santos Moschetta ---- - configure | 2 +- - include/glib-compat.h | 6 +++ - qga/commands-posix.c | 60 +++++++++++++++++++++++++++++ - qga/commands-win32.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++ - qga/qapi-schema.json | 25 ++++++++++++ - 5 files changed, 195 insertions(+), 1 deletion(-) - -diff --git a/configure b/configure -index 3770d7c263..ccd2a0e230 100755 ---- a/configure -+++ b/configure -@@ -724,7 +724,7 @@ if test "$mingw32" = "yes" ; then - sysconfdir="\${prefix}" - local_statedir= - confsuffix="" -- libs_qga="-lws2_32 -lwinmm -lpowrprof -liphlpapi -lnetapi32 $libs_qga" -+ libs_qga="-lws2_32 -lwinmm -lpowrprof -lwtsapi32 -liphlpapi -lnetapi32 $libs_qga" - fi - - werror="" -diff --git a/include/glib-compat.h b/include/glib-compat.h -index acf254d2a0..f84ed5d64a 100644 ---- a/include/glib-compat.h -+++ b/include/glib-compat.h -@@ -217,6 +217,12 @@ static inline void g_hash_table_add(GHashTable *hash_table, gpointer key) - { - g_hash_table_replace(hash_table, key, key); - } -+ -+static inline gboolean g_hash_table_contains(GHashTable *hash_table, -+ gpointer key) -+{ -+ return g_hash_table_lookup_extended(hash_table, key, NULL, NULL); -+} - #endif - - #ifndef g_assert_true -diff --git a/qga/commands-posix.c b/qga/commands-posix.c -index ea37c097cf..55ac4fe9e7 100644 ---- a/qga/commands-posix.c -+++ b/qga/commands-posix.c -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include "qga/guest-agent-core.h" - #include "qga-qmp-commands.h" - #include "qapi/qmp/qerror.h" -@@ -2512,3 +2513,62 @@ void ga_command_state_init(GAState *s, GACommandState *cs) - ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup); - #endif - } -+ -+#define QGA_MICRO_SECOND_TO_SECOND 1000000 -+ -+static double ga_get_login_time(struct utmpx *user_info) -+{ -+ double seconds = (double)user_info->ut_tv.tv_sec; -+ double useconds = (double)user_info->ut_tv.tv_usec; -+ useconds /= QGA_MICRO_SECOND_TO_SECOND; -+ return seconds + useconds; -+} -+ -+GuestUserList *qmp_guest_get_users(Error **err) -+{ -+ GHashTable *cache = NULL; -+ GuestUserList *head = NULL, *cur_item = NULL; -+ struct utmpx *user_info = NULL; -+ gpointer value = NULL; -+ GuestUser *user = NULL; -+ GuestUserList *item = NULL; -+ double login_time = 0; -+ -+ cache = g_hash_table_new(g_str_hash, g_str_equal); -+ setutxent(); -+ -+ for (;;) { -+ user_info = getutxent(); -+ if (user_info == NULL) { -+ break; -+ } else if (user_info->ut_type != USER_PROCESS) { -+ continue; -+ } else if (g_hash_table_contains(cache, user_info->ut_user)) { -+ value = g_hash_table_lookup(cache, user_info->ut_user); -+ user = (GuestUser *)value; -+ login_time = ga_get_login_time(user_info); -+ /* We're ensuring the earliest login time to be sent */ -+ if (login_time < user->login_time) { -+ user->login_time = login_time; -+ } -+ continue; -+ } -+ -+ item = g_new0(GuestUserList, 1); -+ item->value = g_new0(GuestUser, 1); -+ item->value->user = g_strdup(user_info->ut_user); -+ item->value->login_time = ga_get_login_time(user_info); -+ -+ g_hash_table_insert(cache, item->value->user, item->value); -+ -+ if (!cur_item) { -+ head = cur_item = item; -+ } else { -+ cur_item->next = item; -+ cur_item = item; -+ } -+ } -+ endutxent(); -+ g_hash_table_destroy(cache); -+ return head; -+} -diff --git a/qga/commands-win32.c b/qga/commands-win32.c -index 19d72b2411..fa99a8f846 100644 ---- a/qga/commands-win32.c -+++ b/qga/commands-win32.c -@@ -11,6 +11,9 @@ - * See the COPYING file in the top-level directory. - */ - -+#ifndef _WIN32_WINNT -+# define _WIN32_WINNT 0x0600 -+#endif - #include "qemu/osdep.h" - #include - #include -@@ -25,6 +28,7 @@ - #include - #endif - #include -+#include - - #include "qga/guest-agent-core.h" - #include "qga/vss-win32.h" -@@ -1536,3 +1540,102 @@ void ga_command_state_init(GAState *s, GACommandState *cs) - ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup); - } - } -+ -+/* MINGW is missing two fields: IncomingFrames & OutgoingFrames */ -+typedef struct _GA_WTSINFOA { -+ WTS_CONNECTSTATE_CLASS State; -+ DWORD SessionId; -+ DWORD IncomingBytes; -+ DWORD OutgoingBytes; -+ DWORD IncomingFrames; -+ DWORD OutgoingFrames; -+ DWORD IncomingCompressedBytes; -+ DWORD OutgoingCompressedBy; -+ CHAR WinStationName[WINSTATIONNAME_LENGTH]; -+ CHAR Domain[DOMAIN_LENGTH]; -+ CHAR UserName[USERNAME_LENGTH + 1]; -+ LARGE_INTEGER ConnectTime; -+ LARGE_INTEGER DisconnectTime; -+ LARGE_INTEGER LastInputTime; -+ LARGE_INTEGER LogonTime; -+ LARGE_INTEGER CurrentTime; -+ -+} GA_WTSINFOA; -+ -+GuestUserList *qmp_guest_get_users(Error **err) -+{ -+#if (_WIN32_WINNT >= 0x0600) -+#define QGA_NANOSECONDS 10000000 -+ -+ GHashTable *cache = NULL; -+ GuestUserList *head = NULL, *cur_item = NULL; -+ -+ DWORD buffer_size = 0, count = 0, i = 0; -+ GA_WTSINFOA *info = NULL; -+ WTS_SESSION_INFOA *entries = NULL; -+ GuestUserList *item = NULL; -+ GuestUser *user = NULL; -+ gpointer value = NULL; -+ INT64 login = 0; -+ double login_time = 0; -+ -+ cache = g_hash_table_new(g_str_hash, g_str_equal); -+ -+ if (WTSEnumerateSessionsA(NULL, 0, 1, &entries, &count)) { -+ for (i = 0; i < count; ++i) { -+ buffer_size = 0; -+ info = NULL; -+ if (WTSQuerySessionInformationA( -+ NULL, -+ entries[i].SessionId, -+ WTSSessionInfo, -+ (LPSTR *)&info, -+ &buffer_size -+ )) { -+ -+ if (strlen(info->UserName) == 0) { -+ WTSFreeMemory(info); -+ continue; -+ } -+ -+ login = info->LogonTime.QuadPart; -+ login -= W32_FT_OFFSET; -+ login_time = ((double)login) / QGA_NANOSECONDS; -+ -+ if (g_hash_table_contains(cache, info->UserName)) { -+ value = g_hash_table_lookup(cache, info->UserName); -+ user = (GuestUser *)value; -+ if (user->login_time > login_time) { -+ user->login_time = login_time; -+ } -+ } else { -+ item = g_new0(GuestUserList, 1); -+ item->value = g_new0(GuestUser, 1); -+ -+ item->value->user = g_strdup(info->UserName); -+ item->value->domain = g_strdup(info->Domain); -+ item->value->has_domain = true; -+ -+ item->value->login_time = login_time; -+ -+ g_hash_table_add(cache, item->value->user); -+ -+ if (!cur_item) { -+ head = cur_item = item; -+ } else { -+ cur_item->next = item; -+ cur_item = item; -+ } -+ } -+ } -+ WTSFreeMemory(info); -+ } -+ WTSFreeMemory(entries); -+ } -+ g_hash_table_destroy(cache); -+ return head; -+#else -+ error_setg(err, QERR_UNSUPPORTED); -+ return NULL; -+#endif -+} -diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json -index 8271c1eb84..1695afe3a9 100644 ---- a/qga/qapi-schema.json -+++ b/qga/qapi-schema.json -@@ -1054,3 +1054,28 @@ - ## - { 'command': 'guest-get-host-name', - 'returns': 'GuestHostName' } -+ -+ -+## -+# @GuestUser: -+# @user: Username -+# @domain: Logon domain (windows only) -+# @login-time: Time of login of this user on the computer. If multiple -+# instances of the user are logged in, the earliest login time is -+# reported. The value is in fractional seconds since epoch time. -+# -+# Since: 2.10 -+## -+{ 'struct': 'GuestUser', -+ 'data': { 'user': 'str', 'login-time': 'number', '*domain': 'str' } } -+ -+## -+# @guest-get-users: -+# Retrieves a list of currently active users on the VM. -+# -+# Returns: A unique list of users. -+# -+# Since: 2.10 -+## -+{ 'command': 'guest-get-users', -+ 'returns': ['GuestUser'] } --- -2.13.6 - 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-test-qga-add-test-for-guest-get-osinfo.patch b/SOURCES/qemuga-test-qga-add-test-for-guest-get-osinfo.patch deleted file mode 100644 index 29baf30..0000000 --- a/SOURCES/qemuga-test-qga-add-test-for-guest-get-osinfo.patch +++ /dev/null @@ -1,159 +0,0 @@ -From e3bfadeaac6a46966becef50302e2ad797c1977a Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Thu, 19 Apr 2018 12:33:48 -0300 -Subject: [PATCH 7/7] test-qga: add test for guest-get-osinfo -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Miroslav Rezanina -Message-id: <4fbd9f39de7c623e464fe5a2fe36b6aa254218ac.1524139831.git.mrezanin@redhat.com> -Patchwork-id: 79709 -O-Subject: [RHEL-7.5.z qemu-guest-agent PATCH 7/7] test-qga: add test for guest-get-osinfo -Bugzilla: 1598210 -RH-Acked-by: Marc-André Lureau -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Tomáš Golembiovský - -From: Tomáš Golembiovský - -Add test for guest-get-osinfo command. - -Qemu-ga was modified to accept QGA_OS_RELEASE environment variable. If -the variable is defined it is interpreted as path to the os-release file -and it is parsed instead of the default paths. - -Signed-off-by: Tomáš Golembiovský -Reviewed-by: Marc-André Lureau -* move declarations to beginning of functions -Signed-off-by: Michael Roth -(cherry picked from commit 339ca68bef9f30dd18e84b7d92398327e3f819a3) -Signed-off-by: Wainer dos Santos Moschetta ---- - qga/commands-posix.c | 13 +++++++--- - tests/data/test-qga-os-release | 7 ++++++ - tests/test-qga.c | 56 ++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 72 insertions(+), 4 deletions(-) - create mode 100644 tests/data/test-qga-os-release - -diff --git a/qga/commands-posix.c b/qga/commands-posix.c -index add8a51f2b..8c38dd3f0a 100644 ---- a/qga/commands-posix.c -+++ b/qga/commands-posix.c -@@ -2677,7 +2677,8 @@ GuestOSInfo *qmp_guest_get_osinfo(Error **errp) - { - GuestOSInfo *info = NULL; - struct utsname kinfo; -- GKeyFile *osrelease; -+ GKeyFile *osrelease = NULL; -+ const char *qga_os_release = g_getenv("QGA_OS_RELEASE"); - - info = g_new0(GuestOSInfo, 1); - -@@ -2692,9 +2693,13 @@ GuestOSInfo *qmp_guest_get_osinfo(Error **errp) - info->machine = g_strdup(kinfo.machine); - } - -- osrelease = ga_parse_osrelease("/etc/os-release"); -- if (osrelease == NULL) { -- osrelease = ga_parse_osrelease("/usr/lib/os-release"); -+ if (qga_os_release != NULL) { -+ osrelease = ga_parse_osrelease(qga_os_release); -+ } else { -+ osrelease = ga_parse_osrelease("/etc/os-release"); -+ if (osrelease == NULL) { -+ osrelease = ga_parse_osrelease("/usr/lib/os-release"); -+ } - } - - if (osrelease != NULL) { -diff --git a/tests/data/test-qga-os-release b/tests/data/test-qga-os-release -new file mode 100644 -index 0000000000..70664eb6ec ---- /dev/null -+++ b/tests/data/test-qga-os-release -@@ -0,0 +1,7 @@ -+ID=qemu-ga-test -+NAME=QEMU-GA -+PRETTY_NAME="QEMU Guest Agent test" -+VERSION="Test 1" -+VERSION_ID=1 -+VARIANT="Unit test \"\'\$\`\\ and \\\\ etc." -+VARIANT_ID=unit-test -diff --git a/tests/test-qga.c b/tests/test-qga.c -index ef8616f89d..3542a015a5 100644 ---- a/tests/test-qga.c -+++ b/tests/test-qga.c -@@ -909,6 +909,60 @@ static void test_qga_guest_exec_invalid(gconstpointer fix) - QDECREF(ret); - } - -+static void test_qga_guest_get_osinfo(gconstpointer data) -+{ -+ TestFixture fixture; -+ const gchar *str; -+ gchar *cwd, *env[2]; -+ QDict *ret, *val; -+ -+ cwd = g_get_current_dir(); -+ env[0] = g_strdup_printf( -+ "QGA_OS_RELEASE=%s%ctests%cdata%ctest-qga-os-release", -+ cwd, G_DIR_SEPARATOR, G_DIR_SEPARATOR, G_DIR_SEPARATOR); -+ env[1] = NULL; -+ g_free(cwd); -+ fixture_setup(&fixture, NULL, env); -+ -+ ret = qmp_fd(fixture.fd, "{'execute': 'guest-get-osinfo'}"); -+ g_assert_nonnull(ret); -+ qmp_assert_no_error(ret); -+ -+ val = qdict_get_qdict(ret, "return"); -+ -+ str = qdict_get_try_str(val, "id"); -+ g_assert_nonnull(str); -+ g_assert_cmpstr(str, ==, "qemu-ga-test"); -+ -+ str = qdict_get_try_str(val, "name"); -+ g_assert_nonnull(str); -+ g_assert_cmpstr(str, ==, "QEMU-GA"); -+ -+ str = qdict_get_try_str(val, "pretty-name"); -+ g_assert_nonnull(str); -+ g_assert_cmpstr(str, ==, "QEMU Guest Agent test"); -+ -+ str = qdict_get_try_str(val, "version"); -+ g_assert_nonnull(str); -+ g_assert_cmpstr(str, ==, "Test 1"); -+ -+ str = qdict_get_try_str(val, "version-id"); -+ g_assert_nonnull(str); -+ g_assert_cmpstr(str, ==, "1"); -+ -+ str = qdict_get_try_str(val, "variant"); -+ g_assert_nonnull(str); -+ g_assert_cmpstr(str, ==, "Unit test \"'$`\\ and \\\\ etc."); -+ -+ str = qdict_get_try_str(val, "variant-id"); -+ g_assert_nonnull(str); -+ g_assert_cmpstr(str, ==, "unit-test"); -+ -+ QDECREF(ret); -+ g_free(env[0]); -+ fixture_tear_down(&fixture, NULL); -+} -+ - int main(int argc, char **argv) - { - TestFixture fix; -@@ -943,6 +997,8 @@ int main(int argc, char **argv) - g_test_add_data_func("/qga/guest-exec", &fix, test_qga_guest_exec); - g_test_add_data_func("/qga/guest-exec-invalid", &fix, - test_qga_guest_exec_invalid); -+ g_test_add_data_func("/qga/guest-get-osinfo", &fix, -+ test_qga_guest_get_osinfo); - - if (g_getenv("QGA_TEST_SIDE_EFFECTING")) { - g_test_add_data_func("/qga/fsfreeze-and-thaw", &fix, --- -2.13.6 - diff --git a/SOURCES/qemuga-test-qga-pass-environemnt-to-qemu-ga.patch b/SOURCES/qemuga-test-qga-pass-environemnt-to-qemu-ga.patch deleted file mode 100644 index 8d08f30..0000000 --- a/SOURCES/qemuga-test-qga-pass-environemnt-to-qemu-ga.patch +++ /dev/null @@ -1,74 +0,0 @@ -From e2cab87d83c5c285132dd036835ac106cb747a05 Mon Sep 17 00:00:00 2001 -From: Miroslav Rezanina -Date: Thu, 19 Apr 2018 12:33:47 -0300 -Subject: [PATCH 6/7] test-qga: pass environemnt to qemu-ga -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -RH-Author: Miroslav Rezanina -Message-id: -Patchwork-id: 79707 -O-Subject: [RHEL-7.5.z qemu-guest-agent PATCH 6/7] test-qga: pass environemnt to qemu-ga -Bugzilla: 1598210 -RH-Acked-by: Marc-André Lureau -RH-Acked-by: Stefan Hajnoczi -RH-Acked-by: Tomáš Golembiovský - -From: Tomáš Golembiovský - -Modify fixture_setup() to pass environemnt variables to spawned qemu-ga -instance. - -Signed-off-by: Tomáš Golembiovský -Reviewed-by: Marc-André Lureau -Signed-off-by: Michael Roth -(cherry picked from commit c28afa76c0e2829d1ebe5ad33062d1697bf2710b) -Signed-off-by: Wainer dos Santos Moschetta ---- - tests/test-qga.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/tests/test-qga.c b/tests/test-qga.c -index 868b02a40f..ef8616f89d 100644 ---- a/tests/test-qga.c -+++ b/tests/test-qga.c -@@ -46,7 +46,7 @@ static void qga_watch(GPid pid, gint status, gpointer user_data) - } - - static void --fixture_setup(TestFixture *fixture, gconstpointer data) -+fixture_setup(TestFixture *fixture, gconstpointer data, gchar **envp) - { - const gchar *extra_arg = data; - GError *error = NULL; -@@ -67,7 +67,7 @@ fixture_setup(TestFixture *fixture, gconstpointer data) - g_shell_parse_argv(cmd, NULL, &argv, &error); - g_assert_no_error(error); - -- g_spawn_async(fixture->test_dir, argv, NULL, -+ g_spawn_async(fixture->test_dir, argv, envp, - G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD, - NULL, NULL, &fixture->pid, &error); - g_assert_no_error(error); -@@ -680,7 +680,7 @@ static void test_qga_blacklist(gconstpointer data) - QDict *ret, *error; - const gchar *class, *desc; - -- fixture_setup(&fix, "-b guest-ping,guest-get-time"); -+ fixture_setup(&fix, "-b guest-ping,guest-get-time", NULL); - - /* check blacklist */ - ret = qmp_fd(fix.fd, "{'execute': 'guest-ping'}"); -@@ -916,7 +916,7 @@ int main(int argc, char **argv) - - setlocale (LC_ALL, ""); - g_test_init(&argc, &argv, NULL); -- fixture_setup(&fix, NULL); -+ fixture_setup(&fix, NULL, NULL); - - g_test_add_data_func("/qga/sync-delimited", &fix, test_qga_sync_delimited); - g_test_add_data_func("/qga/sync", &fix, test_qga_sync); --- -2.13.6 - diff --git a/SPECS/qemu-guest-agent.spec b/SPECS/qemu-guest-agent.spec index 4770f39..297bc69 100644 --- a/SPECS/qemu-guest-agent.spec +++ b/SPECS/qemu-guest-agent.spec @@ -1,6 +1,3 @@ -# Build time setting -%global SLOF_gittagdate 20140630 - %global have_usbredir 1 %global have_spice 1 %global have_fdt 0 @@ -58,11 +55,11 @@ Summary: QEMU guest agent Name: qemu-guest-agent -Version: 2.8.0 -Release: 2%{?dist}.1 +Version: 2.12.0 +Release: 2%{?dist} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 10 -License: GPLv2+ and LGPLv2+ and BSD +License: GPLv2 Group: System Environment/Daemons URL: http://www.qemu.org/ Requires(post): systemd-units @@ -74,27 +71,17 @@ Requires(postun): systemd-units %define _smp_mflags %{nil} %endif -Source0: http://wiki.qemu.org/download/qemu-2.8.0.tar.bz2 +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#1598210 - Backport some features to 2.8 in RHEL 7.5 [rhel-7.5.z] -Patch1: qemuga-qga-Add-guest-get-host-name-command.patch -# For bz#1598210 - Backport some features to 2.8 in RHEL 7.5 [rhel-7.5.z] -Patch2: qemuga-qga-Add-guest-get-users-command.patch -# For bz#1598210 - Backport some features to 2.8 in RHEL 7.5 [rhel-7.5.z] -Patch3: qemuga-qga-Add-guest-get-timezone-command.patch -# For bz#1598210 - Backport some features to 2.8 in RHEL 7.5 [rhel-7.5.z] -Patch4: qemuga-qemu-ga-check-if-utmpx.h-is-available-on-the-system.patch -# For bz#1598210 - Backport some features to 2.8 in RHEL 7.5 [rhel-7.5.z] -Patch5: qemuga-qemu-ga-add-guest-get-osinfo-command.patch -# For bz#1598210 - Backport some features to 2.8 in RHEL 7.5 [rhel-7.5.z] -Patch6: qemuga-test-qga-pass-environemnt-to-qemu-ga.patch -# For bz#1598210 - Backport some features to 2.8 in RHEL 7.5 [rhel-7.5.z] -Patch7: qemuga-test-qga-add-test-for-guest-get-osinfo.patch +# 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 BuildRequires: zlib-devel BuildRequires: glib2-devel @@ -129,6 +116,8 @@ This package does not need to be installed on the host OS. %prep %setup -q -n qemu-%{version} +%patch1 -p1 +%patch2 -p1 # if patch fuzzy patch applying will be forbidden %define with_fuzzy_patches 0 @@ -170,14 +159,6 @@ ApplyOptionalPatch() ApplyOptionalPatch qemu-kvm-test.patch -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 - %build buildarch="%{kvm_target}-softmmu" @@ -278,21 +259,16 @@ install -m 0644 qemu-ga.8 ${RPM_BUILD_ROOT}%{_mandir}/man8/ %changelog -* Tue Jul 17 2018 Wainer dos Santos Moschetta - 2.8.0-2.el7_5.1 -- Corrected the package version from 2.8.0-3.el7 to 2.8.0-2.el7_5.1 -- Resolves: bz#1598210 - (Backport some features to 2.8 in RHEL 7.5 [rhel-7.5.z]) - -* Fri Jul 13 2018 Wainer dos Santos Moschetta - 2.8.0-3.el7 -- qemuga-qga-Add-guest-get-host-name-command.patch [bz#1598210] -- qemuga-qga-Add-guest-get-users-command.patch [bz#1598210] -- qemuga-qga-Add-guest-get-timezone-command.patch [bz#1598210] -- qemuga-qemu-ga-check-if-utmpx.h-is-available-on-the-system.patch [bz#1598210] -- qemuga-qemu-ga-add-guest-get-osinfo-command.patch [bz#1598210] -- qemuga-test-qga-pass-environemnt-to-qemu-ga.patch [bz#1598210] -- qemuga-test-qga-add-test-for-guest-get-osinfo.patch [bz#1598210] -- Resolves: bz#1598210 - (Backport some features to 2.8 in RHEL 7.5 [rhel-7.5.z]) +* 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]