From: Olga Krishtal <okrishtal@parallels.com>
To: Kirk Allan <kallan@suse.com>,
qemu-devel@nongnu.org, "Denis V. Lunev" <den@openvz.org>
Cc: sw@weilnetz.de, mdroth@linux.vnet.ibm.com
Subject: Re: [Qemu-devel] [PATCH v3 2/2] qga: win32 implementation of qmp_guest_network_get_interfaces
Date: Wed, 3 Jun 2015 13:35:07 +0300 [thread overview]
Message-ID: <556ED85B.2050500@parallels.com> (raw)
In-Reply-To: <556ED494.7010302@parallels.com>
[-- Attachment #1: Type: text/plain, Size: 20912 bytes --]
On 03/06/15 13:19, Olga Krishtal wrote:
> On 29/05/15 19:46, Kirk Allan wrote:
>> >>>
>>> On 28/05/15 23:54, Denis V. Lunev wrote:
>>>> On 28/05/15 21:41, Kirk Allan wrote:
>>>>> By default, IP addresses and prefixes will be derived from
>>>>> information
>>>>> obtained by various calls and structures. IPv4 prefixes can be found
>>>>> 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 Visa/2008 guests and newer, it is possible to use
>>>>> inet_ntop()
>>>>> and OnLinkPrefixLength to get IPv4 and IPv6 addresses and prefixes.
>>>>> Setting *extra-cflags in the build configuration to
>>>>> *- D_WIN32_WINNT-0x600 -DWINVER=0x600* or greater enables this
>>>>> functionality
>>>>> for those guests. Setting *ectra-cflags is not required and if not
>>>>> used,
>>>>> the default approach will be taken.
>>>>>
>>>>> Signed-off-by: Kirk Allan<kallan@suse.com>
>>>>> ---
>>>>> qga/commands-win32.c | 292
>>>>> ++++++++++++++++++++++++++++++++++++++++++++++++++-
>>>>> 1 file changed, 290 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/qga/commands-win32.c b/qga/commands-win32.c
>>>>> index 3ef0549..3bf9011 100644
>>>>> --- a/qga/commands-win32.c
>>>>> +++ b/qga/commands-win32.c
>>>>> @@ -16,11 +16,17 @@
>>>>> #include <powrprof.h>
>>>>> #include <stdio.h>
>>>>> #include <string.h>
>>>>> +#include <winsock2.h>
>>>>> +#include <ws2tcpip.h>
>>>>> +#include <ws2ipdef.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
>>>>> @@ -589,9 +595,291 @@ void qmp_guest_suspend_hybrid(Error **errp)
>>>>> error_set(errp, QERR_UNSUPPORTED);
>>>>> }
>>>>>
>>>>> +static DWORD guest_get_adapters_addresses(IP_ADAPTER_ADDRESSES
>>>>> **adptr_addrs)
>>>>> +{
>>>>> + ULONG adptr_addrs_len = 0;
>>>>> + DWORD ret = ERROR_SUCCESS;
>>>>> +
>>>>> + /* Call the first time to get the adptr_addrs_len. */
>>>>> + *adptr_addrs = NULL;
>>>>> + GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX,
>>>>> + NULL, *adptr_addrs, &adptr_addrs_len);
>>>>> +
>>>>> + *adptr_addrs = g_malloc(adptr_addrs_len);
>>>>> + if (*adptr_addrs == NULL) {
>>>>> + ret = ERROR_NOT_ENOUGH_MEMORY;
>>>>> + } else {
>>>>> + ret = GetAdaptersAddresses(AF_UNSPEC,
>>>>> GAA_FLAG_INCLUDE_PREFIX,
>>>>> + NULL, *adptr_addrs,
>>>>> &adptr_addrs_len);
>>>>> + if (ret != ERROR_SUCCESS) {
>>>>> + g_free(*adptr_addrs);
>>>>> + *adptr_addrs = NULL;
>>>>> + }
>>>>> + }
>>>>> + return ret;
>>>> https://developer.gnome.org/glib/2.28/glib-Memory-Allocation.html#g-malloc
>>>>
>>>>
>>>> g_malloc never fail
>>>>
>>>> If any call to allocate memory fails, the application is terminated.
>>>> This also means that there is no need to check if the call succeeded.
>>>>
>> I'll cleanup all the g_malloc testing for failures.
>>
>>>> this means that IP_ADAPTER_ADDRESSES could be returned from function
>>> I think that check is still necessary, because we may suffer some other
>>> problems:
>>> *ERROR_ADDRESS_NOT_ASSOCIATED*
>>> *ERROR_INVALID_PARAMETER*
>>> and even *Other*, according to MSDN.
>>>
>>> From my point of view, the prototype of function should be smth
>>> like this:
>>> static IP_ADAPTER_ADDRESSES *guest_get_adapters_addresses()
>>> {
>>>
>>> PIP_ADAPTER_ADDRESSES ip_add = NULL;
>>> /* Memory allocation, etc */
>>> ......
>>> if (GetAdaptersAddresses(....)) {
>>> error_setg_win32(errp, GetLastError(), "Failed smth");
>>> .....
>>> }
>>>
>>> return ip_add;
>>>
>>> }
>> I'll make this change. It does mean that errp will need to be passed
>> in and then do something like
>> ret = GetAdaptersAddresses(....);
>> if (ret != ERROR_SUCCESS) {
>> error_setg_win32(errp, ret, "Failed smth");
>> .....
>> }
>> because GetAdpatersAddress is not documented to set last error.
> Oh, yes. Sorry, but still I think that such prototype is better.
>>> **
>>>>> +}
>>>>> +
>>>>> +#if (_WIN32_WINNT < 0x0600)
>>>> are you correct with the condition? according to MSDN
>>>>
>>>> On Windows XP and later: Use the GetAdaptersAddresses function
>>>> instead of GetAdaptersInfo.
>>>>
>>>> Thus you should have above branch of code undefined.
>>>>
>>> It is better to use #ifdef (smth), #else and #endif to separate win
>>> version.
>> I'll redo the #ifdefs so that for the < 0x0600 case,
>> guest_get_adapters_info and guest_ip_prefix will be together to
>> better show what is happening for the XP and 2003 case.
>>
>>> Den is right, the first func will be compiled always, and the winxp
>>> variation
>>> will be compiled for winserver 2003, and winxp. Have you tested if for
>>> 2003 server?
>> I have tested on Windows 2003 with no issue. The only way I have
>> found to find the correct prefix on XP and 2003 is to use
>> GetAdaptersInfo and do the matching. The prefixes can be obtained
>> from GetAdaptersAddresses but the order is not specified. That's why
>> I am just returning on ipv6 and calling GetAdaptersInfo to match
>> addresses for ipv4. Rather than do all this matching using
>> GetAdaptersInfo, I could just return -1 as in the ipv6 case. What do
>> you recommend?
> Actually, I have looked more attentive at GetAdaptersInfo :
>
> Minimum supported client
>
> Windows 2000 Professional [desktop apps only]
>
> Minimum supported server
>
> Windows 2000 Server [desktop apps only]
>
> and GetAdaptersAddresses:
>
> Minimum supported client
>
> Windows XP [desktop apps only]
>
> Minimum supported server
>
> Windows Server 2003 [desktop apps only]
>
> May be we should drop the support of 2000 and do this functionality
> starting with XP. As the result we will not need this #ifdef thing.
I have been looking through the list of function with *minimum supported
client **Win 2003:*
OpenProcessToken, AdjustTokenPrivileges in qmp_guest_shutdown
SetFilePointerEx in qmp_guest_file_seek
BOOL WINAPI FlushFileBuffers in qmp_guest_file_flush
BOOL WINAPI GetExitCodeProcess im qmp_guest_exec
Some IOCLS such as IOCTL_STORAGE_QUERY_PROPERTY
and etc.
As you can see at the moment support of Windows 2000 is very questionable.
I wonder if we could just drop it?
>>>>> +static DWORD guest_get_adapters_info(IP_ADAPTER_INFO **adptr_info)
>>>>> +{
>>>>> + ULONG adptr_info_len = 0;
>>>>> + DWORD ret = ERROR_SUCCESS;
>>>>> +
>>>>> + /* Call the first time to get the adptr_info_len. */
>>>>> + *adptr_info = NULL;
>>>>> + GetAdaptersInfo(*adptr_info, &adptr_info_len);
>>>>> +
>>>>> + *adptr_info = g_malloc(adptr_info_len);
>>>>> + if (*adptr_info == NULL) {
>>>>> + ret = ERROR_NOT_ENOUGH_MEMORY;
>>>>> + } else {
>>>>> + ret = GetAdaptersInfo(*adptr_info, &adptr_info_len);
>>>>> + if (ret != ERROR_SUCCESS) {
>>>>> + g_free(*adptr_info);
>>>>> + *adptr_info = NULL;
>>>>> + }
>>>>> + }
>>>> same note about the allocation
>>> Same prototype as before.
>> I'll clean up all the memory allocation checks.
>>>>> + return ret;
>>>>> +}
>>>>> +#endif
>>>>> +
>>>>> +static char *guest_wctomb_dup(WCHAR *wstr)
>>>>> +{
>>>>> + char *str;
>>>>> + size_t i;
>>>>> +
>>>>> + i = wcslen(wstr) + 1;
>>>>> + str = g_malloc(i);
>>>>> + if (str) {
>>>>> + WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
>>>>> + wstr, -1, str, i, NULL, NULL);
>>>>> + }
>>>> same allocation
>> I'll clean up all the memory allocation checks.
>>>>> + return str;
>>>>> +}
>>>>> +
>>>>> +static char *guest_inet_ntop(int af, void *cp, char *buf, size_t
>>>>> len)
>>>>> +{
>>>>> +#if (_WIN32_WINNT >= 0x0600) && defined(ARCH_x86_64)
>>>>> + /* If built for 64 bit Windows Vista/2008 or newer,
>>>>> inet_ntop() is
>>>>> + * available for use. Otherwise, do our best to derive it.
>>>>> + */
>>>> nothing about 64bit only is present here. This seems strange to me
>>>>
>>> https://msdn.microsoft.com/ru-ru/library/windows/desktop/cc805843(v=vs.85).as
>>>
>>> px
>> You're right, I'll remove the defined(ARCH_x86_64)
>>> If you will use glib utility: nm_utils_inet4/6_ntop() you won't need
>>> this separation.
>> This would work, but I'm not seeing the header or lib to compile this
>> in for Windows. Maybe I'm missing some part of the environment?
> I have searched rpm with nm-utils.h and the result is disappointing:
> NetworkManager-libnm-devel.XXX.rpm.
> It would be too difficult task to take all this functionality to Windows.
> Pls, look through this and say is it possible to support usage
> of nm-utils functions in win32 realization. (I will do it too, but a
> bit latter).
> However, we still can look at how it was implemented.
>>>>> + return (char *)InetNtop(af, cp, buf, len);
>>>>> +#else
>>>>> + u_char *p;
>> I'll change to use uint8_t.
>>>>> +
>>>>> + p = (u_char *)cp;
>>>>> + if (af == AF_INET) {
>>>>> + snprintf(buf, len, "%u.%u.%u.%u", p[0], p[1], p[2], p[3]);
>>>>> + } else if (af == AF_INET6) {
>> What do you recommend here? I'm not finding a form of inet_ntop for
>> all flavors of Window. The purpose of this code is to do the address
>> compression. For the XP and 2003 case, I could just simply produce
>> the string of the full address. Although not optimal, it would
>> eliminate complexity and the need for the string manipulation.
>>>>> + int i, compressed_zeros, added_to_buf;
>>>>> + char t[sizeof "::ffff"];
>>>> sizeof without braces and from string could be tricky but I am not
>>>> quite sure
>> Tests have shown that this isn't an issue, but I can add the ().
>>>>> +
>>>>> + buf[0] = '\0';
>>>>> + compressed_zeros = 0;
>>>>> + added_to_buf = 0;
>>>>> + for (i = 0; i < 16; i += 2) {
>>>>> + if (p[i] != 0 || p[i + 1] != 0) {
>>>>> + if (compressed_zeros) {
>>>>> + if (len > sizeof "::") {
>>>>> + strcat(buf, "::");
>>>>> + len -= sizeof "::" - 1;
>>>> with len == 1 you will definitely have problem with wrong conversion
>>>>
>>>>> + }
>>>>> + added_to_buf++;
>>>>> + } else {
>>>>> + if (added_to_buf) {
>>>>> + if (len > 1) {
>>>>> + strcat(buf, ":");
>>>>> + len--;
>>>>> + }
>>>>> + }
>>>>> + added_to_buf++;
>>>>> + }
>>>>> +
>>>>> + /* Take into account leading zeros. */
>>>>> + if (p[i]) {
>>>>> + len -= snprintf(t, sizeof(t), "%x%02x", p[i],
>>>>> p[i+1]);
>>>>> + } else {
>>>>> + len -= snprintf(t, sizeof(t), "%x", p[i+1]);
>>>>> + }
>>>> snprintf can produce non-zero terminated character arrays
>>>> and the same problem with length...
>>>>
>>>>> +
>>>>> + /* Ensure there's enough room for the NULL. */
>>>>> + if (len > 0) {
>>>>> + strcat(buf, t);
>>>>> + }
>>>>> + compressed_zeros = 0;
>>>>> + } else {
>>>>> + compressed_zeros++;
>>>>> + }
>>>>> + }
>>>>> + if (compressed_zeros && !added_to_buf) {
>>>>> + /* The address was all zeros. */
>>>>> + strcat(buf, "::");
>>>> there is not length check here
>>>>
>>>>> + }
>>>>> + }
>>>>> + return buf;
>>>>> +#endif
>>>>> +}
>>>>> +
>>> I still recommend to think over this function, here useful link
>>> https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html
>>>
>>> glib provides a lot of function to work with strings, and there you do
>>> not need think
>>> about memory allocations and etc. Pls, look.
>>>
>>>>> +static int64_t guest_ip_prefix(IP_ADAPTER_UNICAST_ADDRESS *ip_addr)
>>>>> +{
>>>>> +#if (_WIN32_WINNT >= 0x0600)
>>>>> + /* If built for Windows Vista/2008 or newer, use the
>>>>> OnLinkPrefixLength
>>>>> + * field to obtain the prefix. Otherwise, do our best to figure
>>>>> it out.
>>>>> + */
>>>>> + return ip_addr->OnLinkPrefixLength;
>>>>> +#else
>>>>> + 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) {
>>>> why not to return immediately? You will have 1 less indent
>> I'll do that.
>>>>> + if (guest_get_adapters_info(&adptr_info) != ERROR_SUCCESS) {
>>>>> + return prefix;
>>>>> + }
>>> adptr_info = guest_get_adapters_info();
>>> if(adptr_info == NULL )
>>> goto out;
>>> If you will use the prototypes, I have written before it will be
>>> easier.
>> I'll make the changes.
>>>>> + /* 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 && prefix == -1; 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));
>>>>> + break;
>>>> why not goto here. Moving out from inner loop with goto is a good
>>>> thing.
>>>> There is no necessity to use prefix == -1 above in this case
>> I'll do that.
>>>>> + }
>>>>> + }
>>>>> + }
>>>>> + g_free(adptr_info);
>>>>> + }
>>>>> + return prefix;
>>>>> +#endif
>>>>> +}
>>>>> +
>>>>> GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error
>>>>> **errp)
>>>>> {
>>>>> - error_set(errp, QERR_UNSUPPORTED);
>>>>> + 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;
>>>>> + void *p;
>>>>> + char addr4[INET_ADDRSTRLEN];
>>>>> + char addr6[INET6_ADDRSTRLEN];
>>>>> + DWORD ret;
>>>>> +
>>> May be you should return pointer to structure by
>>> guest_get_adapters_addresses, and
>>> make this function take void? As the result you won't need if (ret !=
>>> ERROR_SUCCESS)
>>> It will be smth like this:
>>> adptr_addrs = guest_get_adapters_addresses();
>>> if (adptr_addrs == NULL)
>>> goto out;
>>> And all error, that may happen in guest_get_adapters_addresses will be
>>> held there.
>> I'll do that.
>>>>> + ret = guest_get_adapters_addresses(&adptr_addrs);
>>>>> + if (ret != ERROR_SUCCESS) {
>>>>> + error_setg(errp, "failed to get adapter addresses %lu",
>>>>> ret);
>>>>> + return NULL;
>>>>> + }
>>>>> +
>>>>> + for (addr = adptr_addrs; addr; addr = addr->Next) {
>>>>> + info = g_malloc0(sizeof(*info));
>>>>> + if (!info) {
>>>> no need to check, see above
>> I'll fix all the memory checks.
>>>>> + error_setg(errp, "failed to alloc a network interface
>>>>> list");
>>>>> + goto error;
>>>>> + }
>>>>> +
>>>>> + if (!cur_item) {
>>>> it is better to reserve ! condition to logical checks. For pointers it
>>>> is better to check using != NULL
>>>>
>> I'll fix these
>>>>> + head = cur_item = info;
>>>>> + } else {
>>>>> + cur_item->next = info;
>>>>> + cur_item = info;
>>>>> + }
>>>>> +
>>>>> + info->value = g_malloc0(sizeof(*info->value));
>>>>> + if (!info->value) {
>>>> same
>>>>
>>>>> + error_setg(errp, "failed to alloc a network interface");
>>>>> + goto error;
>>>>> + }
>>>>> + info->value->name = guest_wctomb_dup(addr->FriendlyName);
>>>>> +
>>>>> + if (addr->PhysicalAddressLength) {
>>>> same for check
>>>>
>>>>> + 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) {
>>>>> + address_item = g_malloc0(sizeof(*address_item));
>>>>> + if (!address_item) {
>>>>> + error_setg(errp, "failed to alloc an Ip address
>>>>> list");
>>>>> + goto error;
>>>>> + }
>>>>> +
>>> no need check if (!address_item), as Den had explained before.
>>>>> + 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));
>>>>> + if (!address_item->value) {
>>>>> + error_setg(errp, "failed to alloc an Ip address");
>>>>> + goto error;
>>>>> + }
>>>>> +
>>>>> + if (ip_addr->Address.lpSockaddr->sa_family == AF_INET) {
>>>>> + p = &((struct sockaddr_in *)
>>>>> + ip_addr->Address.lpSockaddr)->sin_addr;
>>>>> +
>>>>> + if (!guest_inet_ntop(AF_INET, p, addr4,
>>>>> sizeof(addr4))) {
>>>>> + error_setg_win32(errp, WSAGetLastError(),
>>>>> + "failed address presentation form
>>>>> conversion");
>>>>> + goto error;
>>>>> + }
>>>>> +
>>>>> + address_item->value->ip_address = g_strdup(addr4);
>>>>> + address_item->value->ip_address_type =
>>>>> + GUEST_IP_ADDRESS_TYPE_IPV4;
>>>>> + } else if (ip_addr->Address.lpSockaddr->sa_family ==
>>>>> AF_INET6) {
>>>>> + p = &((struct sockaddr_in6 *)
>>>>> + ip_addr->Address.lpSockaddr)->sin6_addr;
>>>>> +
>>>>> + if (!guest_inet_ntop(AF_INET6, p, addr6,
>>>>> sizeof(addr6))) {
>>>>> + error_setg_win32(errp, WSAGetLastError(),
>>>>> + "failed address presentation form
>>>>> conversion");
>>>>> + goto error;
>>>>> + }
>>>>> +
>>>>> + address_item->value->ip_address = g_strdup(addr6);
>>>>> + address_item->value->ip_address_type =
>>>>> + GUEST_IP_ADDRESS_TYPE_IPV6;
>>>>> + }
>>>>> + address_item->value->prefix = guest_ip_prefix(ip_addr);
>>>>> + }
>>>>> + if (head_addr) {
>>>>> + info->value->has_ip_addresses = true;
>>>>> + info->value->ip_addresses = head_addr;
>>>>> + }
>>>>> + }
>>>>> +
>>>>> + if (adptr_addrs) {
>>>>> + g_free(adptr_addrs);
>>>> if is not needed
>> I'll clean up all the memory allocation checks.
>>>> https://developer.gnome.org/glib/stable/glib-Memory-Allocation.html#g-free
>>>>
>>>>
>>>>> + }
>>>>> + return head;
>>>>> +
>>>>> +error:
>>>>> + if (adptr_addrs) {
>>>>> + g_free(adptr_addrs);
>>>>> + }
>>>>> + if (head) {
>>>>> + qapi_free_GuestNetworkInterfaceList(head);
>>>>> + }
>>>>> return NULL;
>>>>> }
>>>>>
>>>>> @@ -707,7 +995,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",
>>>>>
>
>
[-- Attachment #2: Type: text/html, Size: 41769 bytes --]
next prev parent reply other threads:[~2015-06-03 10:42 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-28 18:40 [Qemu-devel] [PATCH v3 0/2] qga: qmp_guest_network_get_interfaces for win32 Kirk Allan
2015-05-28 18:41 ` [Qemu-devel] [PATCH v3 1/2] qga: add additional win32 cflags and libraries Kirk Allan
2015-05-28 22:51 ` Eric Blake
2015-05-29 16:42 ` Kirk Allan
2015-05-28 18:41 ` [Qemu-devel] [PATCH v3 2/2] qga: win32 implementation of qmp_guest_network_get_interfaces Kirk Allan
2015-05-28 20:54 ` Denis V. Lunev
2015-05-29 10:39 ` Olga Krishtal
[not found] ` <5568437C020000760012F8A9@prv-mh.provo.novell.com>
2015-06-03 10:19 ` Olga Krishtal
2015-06-03 10:35 ` Olga Krishtal [this message]
2015-05-28 22:56 ` Eric Blake
2015-05-29 9:59 ` Olga Krishtal
2015-06-03 10:11 ` Olga Krishtal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=556ED85B.2050500@parallels.com \
--to=okrishtal@parallels.com \
--cc=den@openvz.org \
--cc=kallan@suse.com \
--cc=mdroth@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=sw@weilnetz.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).