* [Qemu-devel] [PATCH 05/11] qga: win32 qmp_guest_network_get_interfaces implementation
2015-07-08 1:43 [Qemu-devel] [PULL v2 " Michael Roth
@ 2015-07-08 1:43 ` Michael Roth
0 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 1:43 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Kirk Allan
From: Kirk Allan <kallan@suse.com>
By default, IPv4 prefixes will be derived by matching the address
to those returned by GetAdaptersInfo. IPv6 prefixes can not be
matched this way due to the unpredictable order of entries.
In Windows Vista/2008 guests and newer, both IPv4 and IPv6 prefixes
can be retrieved from OnLinkPrefixLength. Setting --extra-cflags
in the build configuration to "-D_WIN32_WINNT=0x600"
or greater makes OnLinkPrefixLength available. Setting --extra-cflags
is not required and if not set, the default approach to get the prefix
will be taken.
Signed-off-by: Kirk Allan <kallan@suse.com>
* drop ws2ipdef.h, it's missing on old mingw, and ws2tcpip.h already
includes it automatically on new builds
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
qga/commands-win32.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 216 insertions(+), 3 deletions(-)
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 13679a1..4275f8a 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -16,11 +16,16 @@
#include <powrprof.h>
#include <stdio.h>
#include <string.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <iptypes.h>
+#include <iphlpapi.h>
#include "qga/guest-agent-core.h"
#include "qga/vss-win32.h"
#include "qga-qmp-commands.h"
#include "qapi/qmp/qerror.h"
#include "qemu/queue.h"
+#include "qemu/host-utils.h"
#ifndef SHTDN_REASON_FLAG_PLANNED
#define SHTDN_REASON_FLAG_PLANNED 0x80000000
@@ -591,12 +596,220 @@ void qmp_guest_suspend_hybrid(Error **errp)
error_setg(errp, QERR_UNSUPPORTED);
}
-GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
+static IP_ADAPTER_ADDRESSES *guest_get_adapters_addresses(Error **errp)
{
- error_setg(errp, QERR_UNSUPPORTED);
+ IP_ADAPTER_ADDRESSES *adptr_addrs = NULL;
+ ULONG adptr_addrs_len = 0;
+ DWORD ret;
+
+ /* Call the first time to get the adptr_addrs_len. */
+ GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX,
+ NULL, adptr_addrs, &adptr_addrs_len);
+
+ adptr_addrs = g_malloc(adptr_addrs_len);
+ ret = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX,
+ NULL, adptr_addrs, &adptr_addrs_len);
+ if (ret != ERROR_SUCCESS) {
+ error_setg_win32(errp, ret, "failed to get adapters addresses");
+ g_free(adptr_addrs);
+ adptr_addrs = NULL;
+ }
+ return adptr_addrs;
+}
+
+static char *guest_wctomb_dup(WCHAR *wstr)
+{
+ char *str;
+ size_t i;
+
+ i = wcslen(wstr) + 1;
+ str = g_malloc(i);
+ WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
+ wstr, -1, str, i, NULL, NULL);
+ return str;
+}
+
+static char *guest_addr_to_str(IP_ADAPTER_UNICAST_ADDRESS *ip_addr,
+ Error **errp)
+{
+ char addr_str[INET6_ADDRSTRLEN + INET_ADDRSTRLEN];
+ DWORD len;
+ int ret;
+
+ if (ip_addr->Address.lpSockaddr->sa_family == AF_INET ||
+ ip_addr->Address.lpSockaddr->sa_family == AF_INET6) {
+ len = sizeof(addr_str);
+ ret = WSAAddressToString(ip_addr->Address.lpSockaddr,
+ ip_addr->Address.iSockaddrLength,
+ NULL,
+ addr_str,
+ &len);
+ if (ret != 0) {
+ error_setg_win32(errp, WSAGetLastError(),
+ "failed address presentation form conversion");
+ return NULL;
+ }
+ return g_strdup(addr_str);
+ }
return NULL;
}
+#if (_WIN32_WINNT >= 0x0600)
+static int64_t guest_ip_prefix(IP_ADAPTER_UNICAST_ADDRESS *ip_addr)
+{
+ /* For Windows Vista/2008 and newer, use the OnLinkPrefixLength
+ * field to obtain the prefix.
+ */
+ return ip_addr->OnLinkPrefixLength;
+}
+#else
+/* When using the Windows XP and 2003 build environment, do the best we can to
+ * figure out the prefix.
+ */
+static IP_ADAPTER_INFO *guest_get_adapters_info(void)
+{
+ IP_ADAPTER_INFO *adptr_info = NULL;
+ ULONG adptr_info_len = 0;
+ DWORD ret;
+
+ /* Call the first time to get the adptr_info_len. */
+ GetAdaptersInfo(adptr_info, &adptr_info_len);
+
+ adptr_info = g_malloc(adptr_info_len);
+ ret = GetAdaptersInfo(adptr_info, &adptr_info_len);
+ if (ret != ERROR_SUCCESS) {
+ g_free(adptr_info);
+ adptr_info = NULL;
+ }
+ return adptr_info;
+}
+
+static int64_t guest_ip_prefix(IP_ADAPTER_UNICAST_ADDRESS *ip_addr)
+{
+ int64_t prefix = -1; /* Use for AF_INET6 and unknown/undetermined values. */
+ IP_ADAPTER_INFO *adptr_info, *info;
+ IP_ADDR_STRING *ip;
+ struct in_addr *p;
+
+ if (ip_addr->Address.lpSockaddr->sa_family != AF_INET) {
+ return prefix;
+ }
+ adptr_info = guest_get_adapters_info();
+ if (adptr_info == NULL) {
+ return prefix;
+ }
+
+ /* Match up the passed in ip_addr with one found in adaptr_info.
+ * The matching one in adptr_info will have the netmask.
+ */
+ p = &((struct sockaddr_in *)ip_addr->Address.lpSockaddr)->sin_addr;
+ for (info = adptr_info; info; info = info->Next) {
+ for (ip = &info->IpAddressList; ip; ip = ip->Next) {
+ if (p->S_un.S_addr == inet_addr(ip->IpAddress.String)) {
+ prefix = ctpop32(inet_addr(ip->IpMask.String));
+ goto out;
+ }
+ }
+ }
+out:
+ g_free(adptr_info);
+ return prefix;
+}
+#endif
+
+GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
+{
+ IP_ADAPTER_ADDRESSES *adptr_addrs, *addr;
+ IP_ADAPTER_UNICAST_ADDRESS *ip_addr = NULL;
+ GuestNetworkInterfaceList *head = NULL, *cur_item = NULL;
+ GuestIpAddressList *head_addr, *cur_addr;
+ GuestNetworkInterfaceList *info;
+ GuestIpAddressList *address_item = NULL;
+ unsigned char *mac_addr;
+ char *addr_str;
+ WORD wsa_version;
+ WSADATA wsa_data;
+ int ret;
+
+ adptr_addrs = guest_get_adapters_addresses(errp);
+ if (adptr_addrs == NULL) {
+ return NULL;
+ }
+
+ /* Make WSA APIs available. */
+ wsa_version = MAKEWORD(2, 2);
+ ret = WSAStartup(wsa_version, &wsa_data);
+ if (ret != 0) {
+ error_setg_win32(errp, ret, "failed socket startup");
+ goto out;
+ }
+
+ for (addr = adptr_addrs; addr; addr = addr->Next) {
+ info = g_malloc0(sizeof(*info));
+
+ if (cur_item == NULL) {
+ head = cur_item = info;
+ } else {
+ cur_item->next = info;
+ cur_item = info;
+ }
+
+ info->value = g_malloc0(sizeof(*info->value));
+ info->value->name = guest_wctomb_dup(addr->FriendlyName);
+
+ if (addr->PhysicalAddressLength != 0) {
+ mac_addr = addr->PhysicalAddress;
+
+ info->value->hardware_address =
+ g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x",
+ (int) mac_addr[0], (int) mac_addr[1],
+ (int) mac_addr[2], (int) mac_addr[3],
+ (int) mac_addr[4], (int) mac_addr[5]);
+
+ info->value->has_hardware_address = true;
+ }
+
+ head_addr = NULL;
+ cur_addr = NULL;
+ for (ip_addr = addr->FirstUnicastAddress;
+ ip_addr;
+ ip_addr = ip_addr->Next) {
+ addr_str = guest_addr_to_str(ip_addr, errp);
+ if (addr_str == NULL) {
+ continue;
+ }
+
+ address_item = g_malloc0(sizeof(*address_item));
+
+ if (!cur_addr) {
+ head_addr = cur_addr = address_item;
+ } else {
+ cur_addr->next = address_item;
+ cur_addr = address_item;
+ }
+
+ address_item->value = g_malloc0(sizeof(*address_item->value));
+ address_item->value->ip_address = addr_str;
+ address_item->value->prefix = guest_ip_prefix(ip_addr);
+ if (ip_addr->Address.lpSockaddr->sa_family == AF_INET) {
+ address_item->value->ip_address_type =
+ GUEST_IP_ADDRESS_TYPE_IPV4;
+ } else if (ip_addr->Address.lpSockaddr->sa_family == AF_INET6) {
+ address_item->value->ip_address_type =
+ GUEST_IP_ADDRESS_TYPE_IPV6;
+ }
+ }
+ if (head_addr) {
+ info->value->has_ip_addresses = true;
+ info->value->ip_addresses = head_addr;
+ }
+ }
+ WSACleanup();
+out:
+ g_free(adptr_addrs);
+ return head;
+}
+
int64_t qmp_guest_get_time(Error **errp)
{
SYSTEMTIME ts = {0};
@@ -709,7 +922,7 @@ GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp)
GList *ga_command_blacklist_init(GList *blacklist)
{
const char *list_unsupported[] = {
- "guest-suspend-hybrid", "guest-network-get-interfaces",
+ "guest-suspend-hybrid",
"guest-get-vcpus", "guest-set-vcpus",
"guest-set-user-password",
"guest-get-memory-blocks", "guest-set-memory-blocks",
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0
@ 2015-07-08 2:11 Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 01/11] qga/commands-posix: Fix bug in guest-fstrim Michael Roth
` (11 more replies)
0 siblings, 12 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
Hi Peter,
Please ignore the just-posted v2, the configure check was missing
an include which resulted in the feature *always* being disabled.
Sorry for all the noise.
This adds win32 implementations of:
guest-get-fsinfo
guest-network-get-interfaces
and modifies guest-fstrim to return per-mount results and continue on to other
mounts even when a failure is encountered.
There's also bug fixes for guest-fstrim and guest-set-time.
The following changes since commit 7ce0f7dc87e50ebf58ac756ff6be17ec97d3ba4e:
Merge remote-tracking branch 'remotes/agraf/tags/signed-ppc-for-upstream' into staging (2015-07-07 21:16:06 +0100)
are available in the git repository at:
git://github.com/mdroth/qemu.git tags/qga-pull-2015-07-06-v3-tag
for you to fetch changes up to c54e1eb4928d4e6762c7100d1d1ef5f08ddf922b:
qga: added GuestPCIAddress information (2015-07-07 20:59:04 -0500)
----------------------------------------------------------------
tag for qga-pull-2015-07-06-v3
v3:
- fix missing <windows.h> in configure test program.
v2:
- added configure check for guest-get-fs-info to avoid breakage on older
MinGWs
- removed extraneous include of ws2ipdef.h in w32
guest-network-get-interfaces. ws2tcpip.h already provides those
definitions, and older MinGWs don't have it.
- rebased on latest master
----------------------------------------------------------------
Justin Ossevoort (2):
qga/commands-posix: Fix bug in guest-fstrim
qga/qmp_guest_fstrim: Return per path fstrim result
Kirk Allan (2):
qga: add win32 library iphlpapi
qga: win32 qmp_guest_network_get_interfaces implementation
Marc-André Lureau (1):
qga: fail early for invalid time
Markus Armbruster (1):
Revert "guest agent: remove g_strcmp0 usage"
Michael Roth (2):
configure: add configure check for ntdddisk.h
qga: added GuestPCIAddress information
Olga Krishtal (3):
qga: added empty qmp_quest_get_fsinfo functionality.
qga: added mountpoint and filesystem type for single volume
qga: added bus type and disk location path
configure | 27 ++-
qga/commands-posix.c | 70 +++++--
qga/commands-win32.c | 530 ++++++++++++++++++++++++++++++++++++++++++++++++++-
qga/main.c | 2 +-
qga/qapi-schema.json | 44 ++++-
5 files changed, 642 insertions(+), 31 deletions(-)
^ permalink raw reply [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 01/11] qga/commands-posix: Fix bug in guest-fstrim
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
@ 2015-07-08 2:11 ` Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 02/11] qga/qmp_guest_fstrim: Return per path fstrim result Michael Roth
` (10 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Justin Ossevoort
From: Justin Ossevoort <justin@quarantainenet.nl>
The FITRIM ioctl updates the fstrim_range structure it receives. This
way the caller can determine how many bytes were trimmed. The
guest-fstrim logic reuses the same fstrim_range for each filesystem,
effectively limiting each filesystem to trim at most as much as the
previous was able to trim.
If a previous filesystem would have trimmed 0 bytes, than the next
filesystem would report an error 'Invalid argument' because a FITRIM
request with length 0 is not valid.
This change resets the fstrim_range structure for each filesystem.
Signed-off-by: Justin Ossevoort <justin@quarantainenet.nl>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
qga/commands-posix.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index befd00b..9ff33ec 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1332,11 +1332,7 @@ void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
struct FsMount *mount;
int fd;
Error *local_err = NULL;
- struct fstrim_range r = {
- .start = 0,
- .len = -1,
- .minlen = has_minimum ? minimum : 0,
- };
+ struct fstrim_range r;
slog("guest-fstrim called");
@@ -1360,6 +1356,9 @@ void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
* error means an unexpected error, so return it in those cases. In
* some other cases ENOTTY will be reported (e.g. CD-ROMs).
*/
+ r.start = 0;
+ r.len = -1;
+ r.minlen = has_minimum ? minimum : 0;
ret = ioctl(fd, FITRIM, &r);
if (ret == -1) {
if (errno != ENOTTY && errno != EOPNOTSUPP) {
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 02/11] qga/qmp_guest_fstrim: Return per path fstrim result
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 01/11] qga/commands-posix: Fix bug in guest-fstrim Michael Roth
@ 2015-07-08 2:11 ` Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 03/11] Revert "guest agent: remove g_strcmp0 usage" Michael Roth
` (9 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Justin Ossevoort
From: Justin Ossevoort <justin@quarantainenet.nl>
The current guest-fstrim support only returns an error if some
mountpoint was unable to be trimmed, skipping any possible additional
mountpoints. The result of the TRIM operation itself is also discarded.
This change returns a per mountpoint result of the TRIM operation. If an
error occurs on some mountpoints that error is returned and the
guest-fstrim continue with any additional mountpoints.
The returned values for errors, minimum and trimmed are dependant on the
filesystem, storage stacks and kernel version.
Signed-off-by: Justin Ossevoort <justin@quarantainenet.nl>
* s/type/struct/ in schema type definitions
* moved version annotation for new guest-fstrim return field to
the field itself rather than applying to the entire command
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
qga/commands-posix.c | 54 ++++++++++++++++++++++++++++++++++++++--------------
qga/commands-win32.c | 4 +++-
qga/qapi-schema.json | 30 +++++++++++++++++++++++++++--
3 files changed, 71 insertions(+), 17 deletions(-)
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 9ff33ec..c349d4b 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1325,8 +1325,12 @@ static void guest_fsfreeze_cleanup(void)
/*
* Walk list of mounted file systems in the guest, and trim them.
*/
-void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
+GuestFilesystemTrimResponse *
+qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
{
+ GuestFilesystemTrimResponse *response;
+ GuestFilesystemTrimResultList *list;
+ GuestFilesystemTrimResult *result;
int ret = 0;
FsMountList mounts;
struct FsMount *mount;
@@ -1340,39 +1344,59 @@ void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
build_fs_mount_list(&mounts, &local_err);
if (local_err) {
error_propagate(errp, local_err);
- return;
+ return NULL;
}
+ response = g_malloc0(sizeof(*response));
+
QTAILQ_FOREACH(mount, &mounts, next) {
+ result = g_malloc0(sizeof(*result));
+ result->path = g_strdup(mount->dirname);
+
+ list = g_malloc0(sizeof(*list));
+ list->value = result;
+ list->next = response->paths;
+ response->paths = list;
+
fd = qemu_open(mount->dirname, O_RDONLY);
if (fd == -1) {
- error_setg_errno(errp, errno, "failed to open %s", mount->dirname);
- goto error;
+ result->error = g_strdup_printf("failed to open: %s",
+ strerror(errno));
+ result->has_error = true;
+ continue;
}
/* We try to cull filesytems we know won't work in advance, but other
* filesytems may not implement fstrim for less obvious reasons. These
- * will report EOPNOTSUPP; we simply ignore these errors. Any other
- * error means an unexpected error, so return it in those cases. In
- * some other cases ENOTTY will be reported (e.g. CD-ROMs).
+ * will report EOPNOTSUPP; while in some other cases ENOTTY will be
+ * reported (e.g. CD-ROMs).
+ * Any other error means an unexpected error.
*/
r.start = 0;
r.len = -1;
r.minlen = has_minimum ? minimum : 0;
ret = ioctl(fd, FITRIM, &r);
if (ret == -1) {
- if (errno != ENOTTY && errno != EOPNOTSUPP) {
- error_setg_errno(errp, errno, "failed to trim %s",
- mount->dirname);
- close(fd);
- goto error;
+ result->has_error = true;
+ if (errno == ENOTTY || errno == EOPNOTSUPP) {
+ result->error = g_strdup("trim not supported");
+ } else {
+ result->error = g_strdup_printf("failed to trim: %s",
+ strerror(errno));
}
+ close(fd);
+ continue;
}
+
+ result->has_minimum = true;
+ result->minimum = r.minlen;
+ result->has_trimmed = true;
+ result->trimmed = r.len;
close(fd);
}
-error:
free_fs_mount_list(&mounts);
+ return response;
}
#endif /* CONFIG_FSTRIM */
@@ -2401,9 +2425,11 @@ int64_t qmp_guest_fsfreeze_thaw(Error **errp)
#endif /* CONFIG_FSFREEZE */
#if !defined(CONFIG_FSTRIM)
-void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
+GuestFilesystemTrimResponse *
+qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
{
error_setg(errp, QERR_UNSUPPORTED);
+ return NULL;
}
#endif
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index fbddc8b..13679a1 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -493,9 +493,11 @@ static void guest_fsfreeze_cleanup(void)
* Walk list of mounted file systems in the guest, and discard unused
* areas.
*/
-void qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
+GuestFilesystemTrimResponse *
+qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
{
error_setg(errp, QERR_UNSUPPORTED);
+ return NULL;
}
typedef enum {
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index b446dc7..58cbf66 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -425,6 +425,30 @@
'returns': 'int' }
##
+# @GuestFilesystemTrimResult
+#
+# @path: path that was trimmed
+# @error: an error message when trim failed
+# @trimmed: bytes trimmed for this path
+# @minimum: reported effective minimum for this path
+#
+# Since: 2.4
+##
+{ 'struct': 'GuestFilesystemTrimResult',
+ 'data': {'path': 'str',
+ '*trimmed': 'int', '*minimum': 'int', '*error': 'str'} }
+
+##
+# @GuestFilesystemTrimResponse
+#
+# @paths: list of @GuestFilesystemTrimResult per path that was trimmed
+#
+# Since: 2.4
+##
+{ 'struct': 'GuestFilesystemTrimResponse',
+ 'data': {'paths': ['GuestFilesystemTrimResult']} }
+
+##
# @guest-fstrim:
#
# Discard (or "trim") blocks which are not in use by the filesystem.
@@ -437,12 +461,14 @@
# fragmented free space, although not all blocks will be discarded.
# The default value is zero, meaning "discard every free block".
#
-# Returns: Nothing.
+# Returns: A @GuestFilesystemTrimResponse which contains the
+# status of all trimmed paths. (since 2.4)
#
# Since: 1.2
##
{ 'command': 'guest-fstrim',
- 'data': { '*minimum': 'int' } }
+ 'data': { '*minimum': 'int' },
+ 'returns': 'GuestFilesystemTrimResponse' }
##
# @guest-suspend-disk
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 03/11] Revert "guest agent: remove g_strcmp0 usage"
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 01/11] qga/commands-posix: Fix bug in guest-fstrim Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 02/11] qga/qmp_guest_fstrim: Return per path fstrim result Michael Roth
@ 2015-07-08 2:11 ` Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 04/11] qga: add win32 library iphlpapi Michael Roth
` (8 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Markus Armbruster
From: Markus Armbruster <armbru@redhat.com>
Since we now require GLib 2.22+ (commit f40685c), we don't have to
work around lack of g_strcmp0() anymore.
This reverts commit 8f4774789947bc4bc4c8d026a289fe980d3d2ee1.
Conflicts:
qemu-ga.c
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
qga/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qga/main.c b/qga/main.c
index 23cde01..791982e 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -274,7 +274,7 @@ static void ga_log(const gchar *domain, GLogLevelFlags level,
level &= G_LOG_LEVEL_MASK;
#ifndef _WIN32
- if (domain && strcmp(domain, "syslog") == 0) {
+ if (g_strcmp0(domain, "syslog") == 0) {
syslog(LOG_INFO, "%s: %s", level_str, msg);
} else if (level & s->log_level) {
#else
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 04/11] qga: add win32 library iphlpapi
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
` (2 preceding siblings ...)
2015-07-08 2:11 ` [Qemu-devel] [PATCH 03/11] Revert "guest agent: remove g_strcmp0 usage" Michael Roth
@ 2015-07-08 2:11 ` Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 05/11] qga: win32 qmp_guest_network_get_interfaces implementation Michael Roth
` (7 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Kirk Allan
From: Kirk Allan <kallan@suse.com>
Add the iphlpapi library to use APIs such as GetAdaptersInfo and
GetAdaptersAddresses.
Signed-off-by: Kirk Allan <kallan@suse.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
configure | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure b/configure
index 3063739..3bb5e55 100755
--- a/configure
+++ b/configure
@@ -732,7 +732,7 @@ if test "$mingw32" = "yes" ; then
sysconfdir="\${prefix}"
local_statedir=
confsuffix=""
- libs_qga="-lws2_32 -lwinmm -lpowrprof $libs_qga"
+ libs_qga="-lws2_32 -lwinmm -lpowrprof -liphlpapi $libs_qga"
fi
werror=""
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 05/11] qga: win32 qmp_guest_network_get_interfaces implementation
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
` (3 preceding siblings ...)
2015-07-08 2:11 ` [Qemu-devel] [PATCH 04/11] qga: add win32 library iphlpapi Michael Roth
@ 2015-07-08 2:11 ` Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 06/11] qga: fail early for invalid time Michael Roth
` (6 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Kirk Allan
From: Kirk Allan <kallan@suse.com>
By default, IPv4 prefixes will be derived by matching the address
to those returned by GetAdaptersInfo. IPv6 prefixes can not be
matched this way due to the unpredictable order of entries.
In Windows Vista/2008 guests and newer, both IPv4 and IPv6 prefixes
can be retrieved from OnLinkPrefixLength. Setting --extra-cflags
in the build configuration to "-D_WIN32_WINNT=0x600"
or greater makes OnLinkPrefixLength available. Setting --extra-cflags
is not required and if not set, the default approach to get the prefix
will be taken.
Signed-off-by: Kirk Allan <kallan@suse.com>
* drop ws2ipdef.h, it's missing on old mingw, and ws2tcpip.h already
includes it automatically on new builds
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
qga/commands-win32.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 216 insertions(+), 3 deletions(-)
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 13679a1..4275f8a 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -16,11 +16,16 @@
#include <powrprof.h>
#include <stdio.h>
#include <string.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <iptypes.h>
+#include <iphlpapi.h>
#include "qga/guest-agent-core.h"
#include "qga/vss-win32.h"
#include "qga-qmp-commands.h"
#include "qapi/qmp/qerror.h"
#include "qemu/queue.h"
+#include "qemu/host-utils.h"
#ifndef SHTDN_REASON_FLAG_PLANNED
#define SHTDN_REASON_FLAG_PLANNED 0x80000000
@@ -591,12 +596,220 @@ void qmp_guest_suspend_hybrid(Error **errp)
error_setg(errp, QERR_UNSUPPORTED);
}
-GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
+static IP_ADAPTER_ADDRESSES *guest_get_adapters_addresses(Error **errp)
{
- error_setg(errp, QERR_UNSUPPORTED);
+ IP_ADAPTER_ADDRESSES *adptr_addrs = NULL;
+ ULONG adptr_addrs_len = 0;
+ DWORD ret;
+
+ /* Call the first time to get the adptr_addrs_len. */
+ GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX,
+ NULL, adptr_addrs, &adptr_addrs_len);
+
+ adptr_addrs = g_malloc(adptr_addrs_len);
+ ret = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX,
+ NULL, adptr_addrs, &adptr_addrs_len);
+ if (ret != ERROR_SUCCESS) {
+ error_setg_win32(errp, ret, "failed to get adapters addresses");
+ g_free(adptr_addrs);
+ adptr_addrs = NULL;
+ }
+ return adptr_addrs;
+}
+
+static char *guest_wctomb_dup(WCHAR *wstr)
+{
+ char *str;
+ size_t i;
+
+ i = wcslen(wstr) + 1;
+ str = g_malloc(i);
+ WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
+ wstr, -1, str, i, NULL, NULL);
+ return str;
+}
+
+static char *guest_addr_to_str(IP_ADAPTER_UNICAST_ADDRESS *ip_addr,
+ Error **errp)
+{
+ char addr_str[INET6_ADDRSTRLEN + INET_ADDRSTRLEN];
+ DWORD len;
+ int ret;
+
+ if (ip_addr->Address.lpSockaddr->sa_family == AF_INET ||
+ ip_addr->Address.lpSockaddr->sa_family == AF_INET6) {
+ len = sizeof(addr_str);
+ ret = WSAAddressToString(ip_addr->Address.lpSockaddr,
+ ip_addr->Address.iSockaddrLength,
+ NULL,
+ addr_str,
+ &len);
+ if (ret != 0) {
+ error_setg_win32(errp, WSAGetLastError(),
+ "failed address presentation form conversion");
+ return NULL;
+ }
+ return g_strdup(addr_str);
+ }
return NULL;
}
+#if (_WIN32_WINNT >= 0x0600)
+static int64_t guest_ip_prefix(IP_ADAPTER_UNICAST_ADDRESS *ip_addr)
+{
+ /* For Windows Vista/2008 and newer, use the OnLinkPrefixLength
+ * field to obtain the prefix.
+ */
+ return ip_addr->OnLinkPrefixLength;
+}
+#else
+/* When using the Windows XP and 2003 build environment, do the best we can to
+ * figure out the prefix.
+ */
+static IP_ADAPTER_INFO *guest_get_adapters_info(void)
+{
+ IP_ADAPTER_INFO *adptr_info = NULL;
+ ULONG adptr_info_len = 0;
+ DWORD ret;
+
+ /* Call the first time to get the adptr_info_len. */
+ GetAdaptersInfo(adptr_info, &adptr_info_len);
+
+ adptr_info = g_malloc(adptr_info_len);
+ ret = GetAdaptersInfo(adptr_info, &adptr_info_len);
+ if (ret != ERROR_SUCCESS) {
+ g_free(adptr_info);
+ adptr_info = NULL;
+ }
+ return adptr_info;
+}
+
+static int64_t guest_ip_prefix(IP_ADAPTER_UNICAST_ADDRESS *ip_addr)
+{
+ int64_t prefix = -1; /* Use for AF_INET6 and unknown/undetermined values. */
+ IP_ADAPTER_INFO *adptr_info, *info;
+ IP_ADDR_STRING *ip;
+ struct in_addr *p;
+
+ if (ip_addr->Address.lpSockaddr->sa_family != AF_INET) {
+ return prefix;
+ }
+ adptr_info = guest_get_adapters_info();
+ if (adptr_info == NULL) {
+ return prefix;
+ }
+
+ /* Match up the passed in ip_addr with one found in adaptr_info.
+ * The matching one in adptr_info will have the netmask.
+ */
+ p = &((struct sockaddr_in *)ip_addr->Address.lpSockaddr)->sin_addr;
+ for (info = adptr_info; info; info = info->Next) {
+ for (ip = &info->IpAddressList; ip; ip = ip->Next) {
+ if (p->S_un.S_addr == inet_addr(ip->IpAddress.String)) {
+ prefix = ctpop32(inet_addr(ip->IpMask.String));
+ goto out;
+ }
+ }
+ }
+out:
+ g_free(adptr_info);
+ return prefix;
+}
+#endif
+
+GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
+{
+ IP_ADAPTER_ADDRESSES *adptr_addrs, *addr;
+ IP_ADAPTER_UNICAST_ADDRESS *ip_addr = NULL;
+ GuestNetworkInterfaceList *head = NULL, *cur_item = NULL;
+ GuestIpAddressList *head_addr, *cur_addr;
+ GuestNetworkInterfaceList *info;
+ GuestIpAddressList *address_item = NULL;
+ unsigned char *mac_addr;
+ char *addr_str;
+ WORD wsa_version;
+ WSADATA wsa_data;
+ int ret;
+
+ adptr_addrs = guest_get_adapters_addresses(errp);
+ if (adptr_addrs == NULL) {
+ return NULL;
+ }
+
+ /* Make WSA APIs available. */
+ wsa_version = MAKEWORD(2, 2);
+ ret = WSAStartup(wsa_version, &wsa_data);
+ if (ret != 0) {
+ error_setg_win32(errp, ret, "failed socket startup");
+ goto out;
+ }
+
+ for (addr = adptr_addrs; addr; addr = addr->Next) {
+ info = g_malloc0(sizeof(*info));
+
+ if (cur_item == NULL) {
+ head = cur_item = info;
+ } else {
+ cur_item->next = info;
+ cur_item = info;
+ }
+
+ info->value = g_malloc0(sizeof(*info->value));
+ info->value->name = guest_wctomb_dup(addr->FriendlyName);
+
+ if (addr->PhysicalAddressLength != 0) {
+ mac_addr = addr->PhysicalAddress;
+
+ info->value->hardware_address =
+ g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x",
+ (int) mac_addr[0], (int) mac_addr[1],
+ (int) mac_addr[2], (int) mac_addr[3],
+ (int) mac_addr[4], (int) mac_addr[5]);
+
+ info->value->has_hardware_address = true;
+ }
+
+ head_addr = NULL;
+ cur_addr = NULL;
+ for (ip_addr = addr->FirstUnicastAddress;
+ ip_addr;
+ ip_addr = ip_addr->Next) {
+ addr_str = guest_addr_to_str(ip_addr, errp);
+ if (addr_str == NULL) {
+ continue;
+ }
+
+ address_item = g_malloc0(sizeof(*address_item));
+
+ if (!cur_addr) {
+ head_addr = cur_addr = address_item;
+ } else {
+ cur_addr->next = address_item;
+ cur_addr = address_item;
+ }
+
+ address_item->value = g_malloc0(sizeof(*address_item->value));
+ address_item->value->ip_address = addr_str;
+ address_item->value->prefix = guest_ip_prefix(ip_addr);
+ if (ip_addr->Address.lpSockaddr->sa_family == AF_INET) {
+ address_item->value->ip_address_type =
+ GUEST_IP_ADDRESS_TYPE_IPV4;
+ } else if (ip_addr->Address.lpSockaddr->sa_family == AF_INET6) {
+ address_item->value->ip_address_type =
+ GUEST_IP_ADDRESS_TYPE_IPV6;
+ }
+ }
+ if (head_addr) {
+ info->value->has_ip_addresses = true;
+ info->value->ip_addresses = head_addr;
+ }
+ }
+ WSACleanup();
+out:
+ g_free(adptr_addrs);
+ return head;
+}
+
int64_t qmp_guest_get_time(Error **errp)
{
SYSTEMTIME ts = {0};
@@ -709,7 +922,7 @@ GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp)
GList *ga_command_blacklist_init(GList *blacklist)
{
const char *list_unsupported[] = {
- "guest-suspend-hybrid", "guest-network-get-interfaces",
+ "guest-suspend-hybrid",
"guest-get-vcpus", "guest-set-vcpus",
"guest-set-user-password",
"guest-get-memory-blocks", "guest-set-memory-blocks",
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 06/11] qga: fail early for invalid time
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
` (4 preceding siblings ...)
2015-07-08 2:11 ` [Qemu-devel] [PATCH 05/11] qga: win32 qmp_guest_network_get_interfaces implementation Michael Roth
@ 2015-07-08 2:11 ` Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 07/11] qga: added empty qmp_quest_get_fsinfo functionality Michael Roth
` (5 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell, Marc-André Lureau
From: Marc-André Lureau <marcandre.lureau@redhat.com>
It's possible to set system time with dates after 2070, however, it's
not possible to set the RTC. It has limitation to up to year
2070 (1970+100). In order to keep both clock in sync and before the
kernel complains on invalid values, bail out early.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
qga/commands-posix.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index c349d4b..675f4b4 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -154,6 +154,8 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
/* If user has passed a time, validate and set it. */
if (has_time) {
+ GDate date = { 0, };
+
/* year-2038 will overflow in case time_t is 32bit */
if (time_ns / 1000000000 != (time_t)(time_ns / 1000000000)) {
error_setg(errp, "Time %" PRId64 " is too large", time_ns);
@@ -162,6 +164,11 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
tv.tv_sec = time_ns / 1000000000;
tv.tv_usec = (time_ns % 1000000000) / 1000;
+ g_date_set_time_t(&date, tv.tv_sec);
+ if (date.year < 1970 || date.year >= 2070) {
+ error_setg_errno(errp, errno, "Invalid time");
+ return;
+ }
ret = settimeofday(&tv, NULL);
if (ret < 0) {
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 07/11] qga: added empty qmp_quest_get_fsinfo functionality.
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
` (5 preceding siblings ...)
2015-07-08 2:11 ` [Qemu-devel] [PATCH 06/11] qga: fail early for invalid time Michael Roth
@ 2015-07-08 2:11 ` Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 08/11] qga: added mountpoint and filesystem type for single volume Michael Roth
` (4 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Denis V. Lunev, peter.maydell, Olga Krishtal
From: Olga Krishtal <okrishtal@virtuozzo.com>
We need qmp_quest_get_fsinfo togather with vss-provider, which works with
volumes. The call to this function is implemented via
FindFirst/NextVolumes. Moreover, volumes in Windows OS are filesystem unit,
so it will be more effective to work with them rather with devices.
Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Eric Blake <eblake@redhat.com>
CC: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
qga/commands-win32.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 4275f8a..a283129 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -389,8 +389,29 @@ static void guest_file_init(void)
GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp)
{
- error_setg(errp, QERR_UNSUPPORTED);
- return NULL;
+ HANDLE vol_h;
+ GuestFilesystemInfoList *new, *ret = NULL;
+ char guid[256];
+
+ vol_h = FindFirstVolume(guid, sizeof(guid));
+ if (vol_h == INVALID_HANDLE_VALUE) {
+ error_setg_win32(errp, GetLastError(), "failed to find any volume");
+ return NULL;
+ }
+
+ do {
+ new = g_malloc(sizeof(*ret));
+ new->value = build_guest_fsinfo(guid, errp);
+ new->next = ret;
+ ret = new;
+ } while (FindNextVolume(vol_h, guid, sizeof(guid)));
+
+ if (GetLastError() != ERROR_NO_MORE_FILES) {
+ error_setg_win32(errp, GetLastError(), "failed to find next volume");
+ }
+
+ FindVolumeClose(vol_h);
+ return ret;
}
/*
@@ -927,7 +948,7 @@ GList *ga_command_blacklist_init(GList *blacklist)
"guest-set-user-password",
"guest-get-memory-blocks", "guest-set-memory-blocks",
"guest-get-memory-block-size",
- "guest-fsfreeze-freeze-list", "guest-get-fsinfo",
+ "guest-fsfreeze-freeze-list",
"guest-fstrim", NULL};
char **p = (char **)list_unsupported;
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 08/11] qga: added mountpoint and filesystem type for single volume
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
` (6 preceding siblings ...)
2015-07-08 2:11 ` [Qemu-devel] [PATCH 07/11] qga: added empty qmp_quest_get_fsinfo functionality Michael Roth
@ 2015-07-08 2:11 ` Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 09/11] configure: add configure check for ntdddisk.h Michael Roth
` (3 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Denis V. Lunev, peter.maydell, Olga Krishtal
From: Olga Krishtal <okrishtal@virtuozzo.com>
We should use GetVolumeXXX api to work with volumes. This will help us to
resolve the situation with volumes without drive letter, i.e. when the
volume is mounted as a folder. Such volume is called mounted folder.
This volume is a regular mounted volume from all other points of view.
The information about non mounted volume is reported as System Reserved.
This volume is not mounted and thus it is not writable.
GuestDiskAddressList API is not used because operations are performed with
volumes but no with disks. This means that spanned disk will
be counted and handled as a single volume. It is worth mentioning
that the information about every disk in the volume can be queried
via IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS.
Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Eric Blake <eblake@redhat.com>
CC: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
qga/commands-win32.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index a283129..d39c0b2 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -387,6 +387,54 @@ static void guest_file_init(void)
QTAILQ_INIT(&guest_file_state.filehandles);
}
+static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp)
+{
+ DWORD info_size;
+ char mnt, *mnt_point;
+ char fs_name[32];
+ char vol_info[MAX_PATH+1];
+ size_t len;
+ GuestFilesystemInfo *fs = NULL;
+
+ GetVolumePathNamesForVolumeName(guid, (LPCH)&mnt, 0, &info_size);
+ if (GetLastError() != ERROR_MORE_DATA) {
+ error_setg_win32(errp, GetLastError(), "failed to get volume name");
+ return NULL;
+ }
+
+ mnt_point = g_malloc(info_size + 1);
+ if (!GetVolumePathNamesForVolumeName(guid, mnt_point, info_size,
+ &info_size)) {
+ error_setg_win32(errp, GetLastError(), "failed to get volume name");
+ goto free;
+ }
+
+ len = strlen(mnt_point);
+ mnt_point[len] = '\\';
+ mnt_point[len+1] = 0;
+ if (!GetVolumeInformation(mnt_point, vol_info, sizeof(vol_info), NULL, NULL,
+ NULL, (LPSTR)&fs_name, sizeof(fs_name))) {
+ if (GetLastError() != ERROR_NOT_READY) {
+ error_setg_win32(errp, GetLastError(), "failed to get volume info");
+ }
+ goto free;
+ }
+
+ fs_name[sizeof(fs_name) - 1] = 0;
+ fs = g_malloc(sizeof(*fs));
+ fs->name = g_strdup(guid);
+ if (len == 0) {
+ fs->mountpoint = g_strdup("System Reserved");
+ } else {
+ fs->mountpoint = g_strndup(mnt_point, len);
+ }
+ fs->type = g_strdup(fs_name);
+ fs->disk = NULL;
+free:
+ g_free(mnt_point);
+ return fs;
+}
+
GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp)
{
HANDLE vol_h;
@@ -400,8 +448,12 @@ GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp)
}
do {
+ GuestFilesystemInfo *info = build_guest_fsinfo(guid, errp);
+ if (info == NULL) {
+ continue;
+ }
new = g_malloc(sizeof(*ret));
- new->value = build_guest_fsinfo(guid, errp);
+ new->value = info;
new->next = ret;
ret = new;
} while (FindNextVolume(vol_h, guid, sizeof(guid)));
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 09/11] configure: add configure check for ntdddisk.h
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
` (7 preceding siblings ...)
2015-07-08 2:11 ` [Qemu-devel] [PATCH 08/11] qga: added mountpoint and filesystem type for single volume Michael Roth
@ 2015-07-08 2:11 ` Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 10/11] qga: added bus type and disk location path Michael Roth
` (2 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: peter.maydell
This header file provides w32 ioctl definitions for working with disk
devices. Older versions of mingw do not expose this in a useable way,
so add a configure check and report it via CONFIG_QGA_NTDDSCSI.
Subsequent patches will use this macro to stub out functionality that
relies on this in cases where it's not available.
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
configure | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/configure b/configure
index 3bb5e55..62fa05d 100755
--- a/configure
+++ b/configure
@@ -315,6 +315,7 @@ snappy=""
bzip2=""
guest_agent=""
guest_agent_with_vss="no"
+guest_agent_ntddscsi="no"
guest_agent_msi=""
vss_win32_sdk=""
win_sdk="no"
@@ -3820,6 +3821,25 @@ if test "$mingw32" = "yes" -a "$guest_agent" != "no" -a "$guest_agent_with_vss"
fi
##########################################
+# check if mingw environment provides a recent ntddscsi.h
+if test "$mingw32" = "yes" -a "$guest_agent" != "no"; then
+ cat > $TMPC << EOF
+#include <windows.h>
+#include <ntddscsi.h>
+int main(void) {
+#if !defined(IOCTL_SCSI_GET_ADDRESS)
+#error Missing required ioctl definitions
+#endif
+ SCSI_ADDRESS addr = { .Lun = 0, .TargetId = 0, .PathId = 0 };
+ return addr.Lun;
+}
+EOF
+ if compile_prog "" "" ; then
+ guest_agent_ntddscsi=yes
+ fi
+fi
+
+##########################################
# Guest agent Window MSI package
if test "$guest_agent" != yes; then
@@ -4489,6 +4509,7 @@ echo "libiscsi support $libiscsi"
echo "libnfs support $libnfs"
echo "build guest agent $guest_agent"
echo "QGA VSS support $guest_agent_with_vss"
+echo "QGA w32 disk info $guest_agent_ntddscsi"
echo "seccomp support $seccomp"
echo "coroutine backend $coroutine"
echo "coroutine pool $coroutine_pool"
@@ -4566,6 +4587,9 @@ if test "$mingw32" = "yes" ; then
echo "CONFIG_QGA_VSS=y" >> $config_host_mak
echo "WIN_SDK=\"$win_sdk\"" >> $config_host_mak
fi
+ if test "$guest_agent_ntddscsi" = "yes" ; then
+ echo "CONFIG_QGA_NTDDDISK=y" >> $config_host_mak
+ fi
if test "$guest_agent_msi" != "no"; then
echo "QEMU_GA_MSI_ENABLED=yes" >> $config_host_mak
echo "QEMU_GA_MSI_MINGW_DLL_PATH=${QEMU_GA_MSI_MINGW_DLL_PATH}" >> $config_host_mak
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 10/11] qga: added bus type and disk location path
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
` (8 preceding siblings ...)
2015-07-08 2:11 ` [Qemu-devel] [PATCH 09/11] configure: add configure check for ntdddisk.h Michael Roth
@ 2015-07-08 2:11 ` Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 11/11] qga: added GuestPCIAddress information Michael Roth
2015-07-08 12:35 ` [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Peter Maydell
11 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Denis V. Lunev, peter.maydell, Olga Krishtal
From: Olga Krishtal <okrishtal@virtuozzo.com>
According to Microsoft disk location path can be obtained via
IOCTL_SCSI_GET_ADDRESS. Unfortunately this ioctl can not be used for all
devices. There are certain bus types which could be obtained with this
API. Please, refer to the following link for more details
https://technet.microsoft.com/en-us/library/ee851589(v=ws.10).aspx
Bus type could be obtained using IOCTL_STORAGE_QUERY_PROPERTY. Enum
STORAGE_BUS_TYPE describes all buses supported by OS.
Windows defines more bus types than Linux. Thus some values have been added
to GuestDiskBusType.
Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Eric Blake <eblake@redhat.com>
CC: Michael Roth <mdroth@linux.vnet.ibm.com>
* fixed warning in CreateFile due to use of NULL instead of 0
* only provide disk info when CONFIG_QGA_NTDDSCSI=y
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
qga/commands-win32.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++-
qga/qapi-schema.json | 14 +++++-
2 files changed, 147 insertions(+), 2 deletions(-)
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index d39c0b2..2bcc4a5 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -20,6 +20,10 @@
#include <ws2tcpip.h>
#include <iptypes.h>
#include <iphlpapi.h>
+#ifdef CONFIG_QGA_NTDDSCSI
+#include <winioctl.h>
+#include <ntddscsi.h>
+#endif
#include "qga/guest-agent-core.h"
#include "qga/vss-win32.h"
#include "qga-qmp-commands.h"
@@ -387,6 +391,135 @@ static void guest_file_init(void)
QTAILQ_INIT(&guest_file_state.filehandles);
}
+#ifdef CONFIG_QGA_NTDDSCSI
+
+static STORAGE_BUS_TYPE win2qemu[] = {
+ [BusTypeUnknown] = GUEST_DISK_BUS_TYPE_UNKNOWN,
+ [BusTypeScsi] = GUEST_DISK_BUS_TYPE_SCSI,
+ [BusTypeAtapi] = GUEST_DISK_BUS_TYPE_IDE,
+ [BusTypeAta] = GUEST_DISK_BUS_TYPE_IDE,
+ [BusType1394] = GUEST_DISK_BUS_TYPE_IEEE1394,
+ [BusTypeSsa] = GUEST_DISK_BUS_TYPE_SSA,
+ [BusTypeFibre] = GUEST_DISK_BUS_TYPE_SSA,
+ [BusTypeUsb] = GUEST_DISK_BUS_TYPE_USB,
+ [BusTypeRAID] = GUEST_DISK_BUS_TYPE_RAID,
+#if (_WIN32_WINNT >= 0x0600)
+ [BusTypeiScsi] = GUEST_DISK_BUS_TYPE_ISCSI,
+ [BusTypeSas] = GUEST_DISK_BUS_TYPE_SAS,
+ [BusTypeSata] = GUEST_DISK_BUS_TYPE_SATA,
+ [BusTypeSd] = GUEST_DISK_BUS_TYPE_SD,
+ [BusTypeMmc] = GUEST_DISK_BUS_TYPE_MMC,
+#endif
+#if (_WIN32_WINNT >= 0x0601)
+ [BusTypeVirtual] = GUEST_DISK_BUS_TYPE_VIRTUAL,
+ [BusTypeFileBackedVirtual] = GUEST_DISK_BUS_TYPE_FILE_BACKED_VIRTUAL,
+#endif
+};
+
+static GuestDiskBusType find_bus_type(STORAGE_BUS_TYPE bus)
+{
+ if (bus > ARRAY_SIZE(win2qemu) || (int)bus < 0) {
+ return GUEST_DISK_BUS_TYPE_UNKNOWN;
+ }
+ return win2qemu[(int)bus];
+}
+
+static GuestPCIAddress *get_pci_info(char *guid, Error **errp)
+{
+ return NULL;
+}
+
+static int get_disk_bus_type(HANDLE vol_h, Error **errp)
+{
+ STORAGE_PROPERTY_QUERY query;
+ STORAGE_DEVICE_DESCRIPTOR *dev_desc, buf;
+ DWORD received;
+
+ dev_desc = &buf;
+ dev_desc->Size = sizeof(buf);
+ query.PropertyId = StorageDeviceProperty;
+ query.QueryType = PropertyStandardQuery;
+
+ if (!DeviceIoControl(vol_h, IOCTL_STORAGE_QUERY_PROPERTY, &query,
+ sizeof(STORAGE_PROPERTY_QUERY), dev_desc,
+ dev_desc->Size, &received, NULL)) {
+ error_setg_win32(errp, GetLastError(), "failed to get bus type");
+ return -1;
+ }
+
+ return dev_desc->BusType;
+}
+
+/* VSS provider works with volumes, thus there is no difference if
+ * the volume consist of spanned disks. Info about the first disk in the
+ * volume is returned for the spanned disk group (LVM) */
+static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp)
+{
+ GuestDiskAddressList *list = NULL;
+ GuestDiskAddress *disk;
+ SCSI_ADDRESS addr, *scsi_ad;
+ DWORD len;
+ int bus;
+ HANDLE vol_h;
+
+ scsi_ad = &addr;
+ char *name = g_strndup(guid, strlen(guid)-1);
+
+ vol_h = CreateFile(name, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ 0, NULL);
+ if (vol_h == INVALID_HANDLE_VALUE) {
+ error_setg_win32(errp, GetLastError(), "failed to open volume");
+ goto out_free;
+ }
+
+ bus = get_disk_bus_type(vol_h, errp);
+ if (bus < 0) {
+ goto out_close;
+ }
+
+ disk = g_malloc0(sizeof(*disk));
+ disk->bus_type = find_bus_type(bus);
+ if (bus == BusTypeScsi || bus == BusTypeAta || bus == BusTypeRAID
+#if (_WIN32_WINNT >= 0x0600)
+ /* This bus type is not supported before Windows Server 2003 SP1 */
+ || bus == BusTypeSas
+#endif
+ ) {
+ /* We are able to use the same ioctls for different bus types
+ * according to Microsoft docs
+ * https://technet.microsoft.com/en-us/library/ee851589(v=ws.10).aspx */
+ if (DeviceIoControl(vol_h, IOCTL_SCSI_GET_ADDRESS, NULL, 0, scsi_ad,
+ sizeof(SCSI_ADDRESS), &len, NULL)) {
+ disk->unit = addr.Lun;
+ disk->target = addr.TargetId;
+ disk->bus = addr.PathId;
+ disk->pci_controller = get_pci_info(name, errp);
+ }
+ /* We do not set error in this case, because we still have enough
+ * information about volume. */
+ } else {
+ disk->pci_controller = NULL;
+ }
+
+ list = g_malloc0(sizeof(*list));
+ list->value = disk;
+ list->next = NULL;
+out_close:
+ CloseHandle(vol_h);
+out_free:
+ g_free(name);
+ return list;
+}
+
+#else
+
+static GuestDiskAddressList *build_guest_disk_info(char *guid, Error **errp)
+{
+ return NULL;
+}
+
+#endif /* CONFIG_QGA_NTDDSCSI */
+
static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp)
{
DWORD info_size;
@@ -429,7 +562,7 @@ static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp)
fs->mountpoint = g_strndup(mnt_point, len);
}
fs->type = g_strdup(fs_name);
- fs->disk = NULL;
+ fs->disk = build_guest_disk_info(guid, errp);;
free:
g_free(mnt_point);
return fs;
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 58cbf66..8a9b818 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -703,12 +703,24 @@
# @uml: UML disks
# @sata: SATA disks
# @sd: SD cards
+# @unknown: Unknown bus type
+# @ieee1394: Win IEEE 1394 bus type
+# @ssa: Win SSA bus type
+# @fibre: Win fiber channel bus type
+# @raid: Win RAID bus type
+# @iscsi: Win iScsi bus type
+# @sas: Win serial-attaches SCSI bus type
+# @mmc: Win multimedia card (MMC) bus type
+# @virtual: Win virtual bus type
+# @file-backed virtual: Win file-backed bus type
#
# Since: 2.2
##
{ 'enum': 'GuestDiskBusType',
'data': [ 'ide', 'fdc', 'scsi', 'virtio', 'xen', 'usb', 'uml', 'sata',
- 'sd' ] }
+ 'sd', 'unknown', 'ieee1394', 'ssa', 'fibre', 'raid', 'iscsi',
+ 'sas', 'mmc', 'virtual', 'file-backed-virtual' ] }
+
##
# @GuestPCIAddress:
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [Qemu-devel] [PATCH 11/11] qga: added GuestPCIAddress information
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
` (9 preceding siblings ...)
2015-07-08 2:11 ` [Qemu-devel] [PATCH 10/11] qga: added bus type and disk location path Michael Roth
@ 2015-07-08 2:11 ` Michael Roth
2015-07-08 12:35 ` [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Peter Maydell
11 siblings, 0 replies; 14+ messages in thread
From: Michael Roth @ 2015-07-08 2:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Denis V. Lunev, peter.maydell, Olga Krishtal
PCIAddress inforfation is obtained via SetupApi, which provides the
information about address, bus, etc. We look throught entire device tree
in the system and try to find device object for given volume. For this PDO
SetupDiGetDeviceRegistryProperty is called, which reads PCI configuration
for a given devicei if it is possible.
This is the most convinient way for a userspace service. The lookup is
performed for every volume available. However, this information is
not mandatory for vss-provider.
In order to use SetupApi we need to notify linker about it. We do not need
to install additional libs, so we do not make separate configuration
option to use libsetupapi.su
SetupApi gives as the same information as kernel driver
with IRP_MN_QUERY_INTERFACE.
https://support.microsoft.com/en-us/kb/253232
Signed-off-by: Olga Krishtal <okrishtal@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Eric Blake <eblake@redhat.com>
CC: Michael Roth <mdroth@linux.vnet.ibm.com>
* stub out get_pci_info if !CONFIG_QGA_NTDDSCSI
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
configure | 1 +
qga/commands-win32.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 97 insertions(+), 1 deletion(-)
diff --git a/configure b/configure
index 62fa05d..c89b1ea 100755
--- a/configure
+++ b/configure
@@ -3836,6 +3836,7 @@ int main(void) {
EOF
if compile_prog "" "" ; then
guest_agent_ntddscsi=yes
+ libs_qga="-lsetupapi $libs_qga"
fi
fi
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 2bcc4a5..a7822d5 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -23,6 +23,8 @@
#ifdef CONFIG_QGA_NTDDSCSI
#include <winioctl.h>
#include <ntddscsi.h>
+#include <setupapi.h>
+#include <initguid.h>
#endif
#include "qga/guest-agent-core.h"
#include "qga/vss-win32.h"
@@ -424,9 +426,102 @@ static GuestDiskBusType find_bus_type(STORAGE_BUS_TYPE bus)
return win2qemu[(int)bus];
}
+DEFINE_GUID(GUID_DEVINTERFACE_VOLUME,
+ 0x53f5630dL, 0xb6bf, 0x11d0, 0x94, 0xf2,
+ 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
+
static GuestPCIAddress *get_pci_info(char *guid, Error **errp)
{
- return NULL;
+ HDEVINFO dev_info;
+ SP_DEVINFO_DATA dev_info_data;
+ DWORD size = 0;
+ int i;
+ char dev_name[MAX_PATH];
+ char *buffer = NULL;
+ GuestPCIAddress *pci = NULL;
+ char *name = g_strdup(&guid[4]);
+
+ if (!QueryDosDevice(name, dev_name, ARRAY_SIZE(dev_name))) {
+ error_setg_win32(errp, GetLastError(), "failed to get dos device name");
+ goto out;
+ }
+
+ dev_info = SetupDiGetClassDevs(&GUID_DEVINTERFACE_VOLUME, 0, 0,
+ DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
+ if (dev_info == INVALID_HANDLE_VALUE) {
+ error_setg_win32(errp, GetLastError(), "failed to get devices tree");
+ goto out;
+ }
+
+ dev_info_data.cbSize = sizeof(SP_DEVINFO_DATA);
+ for (i = 0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) {
+ DWORD addr, bus, slot, func, dev, data, size2;
+ while (!SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data,
+ SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,
+ &data, (PBYTE)buffer, size,
+ &size2)) {
+ size = MAX(size, size2);
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ g_free(buffer);
+ /* Double the size to avoid problems on
+ * W2k MBCS systems per KB 888609.
+ * https://support.microsoft.com/en-us/kb/259695 */
+ buffer = g_malloc(size * 2);
+ } else {
+ error_setg_win32(errp, GetLastError(),
+ "failed to get device name");
+ goto out;
+ }
+ }
+
+ if (g_strcmp0(buffer, dev_name)) {
+ continue;
+ }
+
+ /* There is no need to allocate buffer in the next functions. The size
+ * is known and ULONG according to
+ * https://support.microsoft.com/en-us/kb/253232
+ * https://msdn.microsoft.com/en-us/library/windows/hardware/ff543095(v=vs.85).aspx
+ */
+ if (!SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data,
+ SPDRP_BUSNUMBER, &data, (PBYTE)&bus, size, NULL)) {
+ break;
+ }
+
+ /* The function retrieves the device's address. This value will be
+ * transformed into device function and number */
+ if (!SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data,
+ SPDRP_ADDRESS, &data, (PBYTE)&addr, size, NULL)) {
+ break;
+ }
+
+ /* This call returns UINumber of DEVICE_CAPABILITIES structure.
+ * This number is typically a user-perceived slot number. */
+ if (!SetupDiGetDeviceRegistryProperty(dev_info, &dev_info_data,
+ SPDRP_UI_NUMBER, &data, (PBYTE)&slot, size, NULL)) {
+ break;
+ }
+
+ /* SetupApi gives us the same information as driver with
+ * IoGetDeviceProperty. According to Microsoft
+ * https://support.microsoft.com/en-us/kb/253232
+ * FunctionNumber = (USHORT)((propertyAddress) & 0x0000FFFF);
+ * DeviceNumber = (USHORT)(((propertyAddress) >> 16) & 0x0000FFFF);
+ * SPDRP_ADDRESS is propertyAddress, so we do the same.*/
+
+ func = addr & 0x0000FFFF;
+ dev = (addr >> 16) & 0x0000FFFF;
+ pci = g_malloc0(sizeof(*pci));
+ pci->domain = dev;
+ pci->slot = slot;
+ pci->function = func;
+ pci->bus = bus;
+ break;
+ }
+out:
+ g_free(buffer);
+ g_free(name);
+ return pci;
}
static int get_disk_bus_type(HANDLE vol_h, Error **errp)
--
1.9.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
` (10 preceding siblings ...)
2015-07-08 2:11 ` [Qemu-devel] [PATCH 11/11] qga: added GuestPCIAddress information Michael Roth
@ 2015-07-08 12:35 ` Peter Maydell
11 siblings, 0 replies; 14+ messages in thread
From: Peter Maydell @ 2015-07-08 12:35 UTC (permalink / raw)
To: Michael Roth; +Cc: QEMU Developers
On 8 July 2015 at 03:11, Michael Roth <mdroth@linux.vnet.ibm.com> wrote:
> Hi Peter,
>
> Please ignore the just-posted v2, the configure check was missing
> an include which resulted in the feature *always* being disabled.
> Sorry for all the noise.
>
> This adds win32 implementations of:
> guest-get-fsinfo
> guest-network-get-interfaces
>
> and modifies guest-fstrim to return per-mount results and continue on to other
> mounts even when a failure is encountered.
>
> There's also bug fixes for guest-fstrim and guest-set-time.
>
> The following changes since commit 7ce0f7dc87e50ebf58ac756ff6be17ec97d3ba4e:
>
> Merge remote-tracking branch 'remotes/agraf/tags/signed-ppc-for-upstream' into staging (2015-07-07 21:16:06 +0100)
>
> are available in the git repository at:
>
>
> git://github.com/mdroth/qemu.git tags/qga-pull-2015-07-06-v3-tag
>
> for you to fetch changes up to c54e1eb4928d4e6762c7100d1d1ef5f08ddf922b:
>
> qga: added GuestPCIAddress information (2015-07-07 20:59:04 -0500)
>
> ----------------------------------------------------------------
> tag for qga-pull-2015-07-06-v3
>
> v3:
> - fix missing <windows.h> in configure test program.
>
> v2:
> - added configure check for guest-get-fs-info to avoid breakage on older
> MinGWs
> - removed extraneous include of ws2ipdef.h in w32
> guest-network-get-interfaces. ws2tcpip.h already provides those
> definitions, and older MinGWs don't have it.
> - rebased on latest master
>
Applied, thanks.
-- PMM
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2015-07-08 12:36 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-08 2:11 [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 01/11] qga/commands-posix: Fix bug in guest-fstrim Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 02/11] qga/qmp_guest_fstrim: Return per path fstrim result Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 03/11] Revert "guest agent: remove g_strcmp0 usage" Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 04/11] qga: add win32 library iphlpapi Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 05/11] qga: win32 qmp_guest_network_get_interfaces implementation Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 06/11] qga: fail early for invalid time Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 07/11] qga: added empty qmp_quest_get_fsinfo functionality Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 08/11] qga: added mountpoint and filesystem type for single volume Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 09/11] configure: add configure check for ntdddisk.h Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 10/11] qga: added bus type and disk location path Michael Roth
2015-07-08 2:11 ` [Qemu-devel] [PATCH 11/11] qga: added GuestPCIAddress information Michael Roth
2015-07-08 12:35 ` [Qemu-devel] [PULL v3 00/11] qemu-ga patches for 2.4.0 Peter Maydell
-- strict thread matches above, loose matches on Subject: below --
2015-07-08 1:43 [Qemu-devel] [PULL v2 " Michael Roth
2015-07-08 1:43 ` [Qemu-devel] [PATCH 05/11] qga: win32 qmp_guest_network_get_interfaces implementation Michael Roth
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).