qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/3] qemu guest agent: support guest-file-* command for Windows
@ 2015-02-06 17:59 Denis V. Lunev
  2015-02-06 17:59 ` [Qemu-devel] [PATCH 1/3] utils: drop strtok_r from envlist_parse Denis V. Lunev
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Denis V. Lunev @ 2015-02-06 17:59 UTC (permalink / raw)
  Cc: Michael Roth, Olga Krishtal, qemu-devel, Denis V. Lunev

This was a part of patchset implemented guest-exec command.
It was suggested to submit it separately by Michael.

The set contains small refactoring to fix mingw 4.9.1 compilation
and safe part of the rework of posix file interface plus main
Windows file commands implementation.

Changes from previous version:
- compilation is fixed by gropping strtok_r at all
- error_setg_win32 is used for error decoding

Signed-off-by: Olga Krishtal <okrishtal@parallels.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Michael Roth <mdroth@linux.vnet.ibm.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH 1/3] utils: drop strtok_r from envlist_parse
  2015-02-06 17:59 [Qemu-devel] [PATCH 0/3] qemu guest agent: support guest-file-* command for Windows Denis V. Lunev
@ 2015-02-06 17:59 ` Denis V. Lunev
  2015-02-06 17:59 ` [Qemu-devel] [PATCH 2/3] guest agent: guest-file-open: refactoring Denis V. Lunev
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Denis V. Lunev @ 2015-02-06 17:59 UTC (permalink / raw)
  Cc: Michael Roth, Olga Krishtal, qemu-devel, Denis V. Lunev

From: Olga Krishtal <okrishtal@parallels.com>

The problem is that mingw 4.9.1 fails to compile the code with the
following warning:

/mingw/include/string.h:88:9: note: previous declaration of 'strtok_r'
was here
   char *strtok_r(char * __restrict__ _Str,
                  const char * __restrict__ _Delim,
                  char ** __restrict__ __last);
/include/sysemu/os-win32.h:83:7: warning: redundant redeclaration of
   'strtok_r' [-Wredundant-decls]
   char *strtok_r(char *str, const char *delim, char **saveptr);

The problem is that compiles just fine on previous versions of mingw.
Compiler version check here is not a good idea. Though fortunately
strtok_r is used only once in the code and we could simply rewrite
the code without it.

Signed-off-by: Olga Krishtal <okrishtal@parallels.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Eric Blake <eblake@redhat.com>
CC: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 include/sysemu/os-win32.h |  1 -
 util/envlist.c            | 32 ++++++++++++++++----------------
 2 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
index af3fbc4..9cc9e08 100644
--- a/include/sysemu/os-win32.h
+++ b/include/sysemu/os-win32.h
@@ -81,7 +81,6 @@ struct tm *gmtime_r(const time_t *timep, struct tm *result);
 #undef localtime_r
 struct tm *localtime_r(const time_t *timep, struct tm *result);
 
-char *strtok_r(char *str, const char *delim, char **saveptr);
 
 static inline void os_setup_signal_handling(void) {}
 static inline void os_daemonize(void) {}
diff --git a/util/envlist.c b/util/envlist.c
index ebc06cf..099a544 100644
--- a/util/envlist.c
+++ b/util/envlist.c
@@ -94,30 +94,30 @@ envlist_parse(envlist_t *envlist, const char *env,
 {
 	char *tmpenv, *envvar;
 	char *envsave = NULL;
-
-	assert(callback != NULL);
+    int ret = 0;
+    assert(callback != NULL);
 
 	if ((envlist == NULL) || (env == NULL))
 		return (EINVAL);
 
-	/*
-	 * We need to make temporary copy of the env string
-	 * as strtok_r(3) modifies it while it tokenizes.
-	 */
 	if ((tmpenv = strdup(env)) == NULL)
 		return (errno);
-
-	envvar = strtok_r(tmpenv, ",", &envsave);
-	while (envvar != NULL) {
-		if ((*callback)(envlist, envvar) != 0) {
-			free(tmpenv);
-			return (errno);
+    envsave = tmpenv;
+
+    do {
+        envvar = strchr(tmpenv, ',');
+        if (envvar != NULL) {
+            *envvar = '\0';
+        }
+        if ((*callback)(envlist, tmpenv) != 0) {
+            ret = errno;
+            break;
 		}
-		envvar = strtok_r(NULL, ",", &envsave);
-	}
+        tmpenv = envvar + 1;
+    } while (envvar != NULL);
 
-	free(tmpenv);
-	return (0);
+    free(envsave);
+    return ret;
 }
 
 /*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH 2/3] guest agent: guest-file-open: refactoring
  2015-02-06 17:59 [Qemu-devel] [PATCH 0/3] qemu guest agent: support guest-file-* command for Windows Denis V. Lunev
  2015-02-06 17:59 ` [Qemu-devel] [PATCH 1/3] utils: drop strtok_r from envlist_parse Denis V. Lunev
@ 2015-02-06 17:59 ` Denis V. Lunev
  2015-02-06 17:59 ` [Qemu-devel] [PATCH 3/3] qga: implement file commands for Windows guest Denis V. Lunev
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Denis V. Lunev @ 2015-02-06 17:59 UTC (permalink / raw)
  Cc: Denis V. Lunev, qemu-devel, Simon Zolin, Michael Roth

From: Simon Zolin <szolin@parallels.com>

Moved the code that sets non-blocking flag on fd into a separate function.

Signed-off-by: Simon Zolin <szolin@parallels.com>
Reviewed-by: Roman Kagan <rkagan@parallels.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Michael Roth <mdroth@linux.vnet.ibm.com>
CC: Eric Blake <eblake@redhat.com>
---
 qga/commands-posix.c | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index f6f3e3c..b645724 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -376,13 +376,33 @@ safe_open_or_create(const char *path, const char *mode, Error **errp)
     return NULL;
 }
 
+static int guest_file_toggle_flags(int fd, int flags, bool set, Error **err)
+{
+    int ret, old_flags;
+
+    old_flags = fcntl(fd, F_GETFL);
+    if (old_flags == -1) {
+        error_set_errno(err, errno, QERR_QGA_COMMAND_FAILED,
+                        "failed to fetch filehandle flags");
+        return -1;
+    }
+
+    ret = fcntl(fd, F_SETFL, set ? (old_flags | flags) : (old_flags & ~flags));
+    if (ret == -1) {
+        error_set_errno(err, errno, QERR_QGA_COMMAND_FAILED,
+                        "failed to set filehandle flags");
+        return -1;
+    }
+
+    return ret;
+}
+
 int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode,
                             Error **errp)
 {
     FILE *fh;
     Error *local_err = NULL;
-    int fd;
-    int64_t ret = -1, handle;
+    int64_t handle;
 
     if (!has_mode) {
         mode = "r";
@@ -397,12 +417,7 @@ int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode,
     /* set fd non-blocking to avoid common use cases (like reading from a
      * named pipe) from hanging the agent
      */
-    fd = fileno(fh);
-    ret = fcntl(fd, F_GETFL);
-    ret = fcntl(fd, F_SETFL, ret | O_NONBLOCK);
-    if (ret == -1) {
-        error_setg_errno(errp, errno, "failed to make file '%s' non-blocking",
-                         path);
+    if (guest_file_toggle_flags(fileno(fh), O_NONBLOCK, true, errp) < 0) {
         fclose(fh);
         return -1;
     }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH 3/3] qga: implement file commands for Windows guest
  2015-02-06 17:59 [Qemu-devel] [PATCH 0/3] qemu guest agent: support guest-file-* command for Windows Denis V. Lunev
  2015-02-06 17:59 ` [Qemu-devel] [PATCH 1/3] utils: drop strtok_r from envlist_parse Denis V. Lunev
  2015-02-06 17:59 ` [Qemu-devel] [PATCH 2/3] guest agent: guest-file-open: refactoring Denis V. Lunev
@ 2015-02-06 17:59 ` Denis V. Lunev
  2015-02-13  7:51 ` [Qemu-devel] [PATCH 0/3] qemu guest agent: support guest-file-* command for Windows Denis V. Lunev
  2015-02-17  2:07 ` Michael Roth
  4 siblings, 0 replies; 6+ messages in thread
From: Denis V. Lunev @ 2015-02-06 17:59 UTC (permalink / raw)
  Cc: Michael Roth, Olga Krishtal, qemu-devel, Denis V. Lunev

From: Olga Krishtal <okrishtal@parallels.com>

The following commands are implemented:
- guest_file_open
- guest_file_close
- guest_file_write
- guest_file_read
- guest_file_seek
- guest_file_flush

Motivation is quite simple: Windows guests should be supported with the
same set of features as Linux one. Also this patch is a prerequisite for
Windows guest-exec command support.

Signed-off-by: Olga Krishtal <okrishtal@parallels.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 qga/commands-win32.c | 271 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 250 insertions(+), 21 deletions(-)

diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 3bcbeae..dda43cc 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -14,10 +14,13 @@
 #include <glib.h>
 #include <wtypes.h>
 #include <powrprof.h>
+#include <stdio.h>
+#include <string.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"
 
 #ifndef SHTDN_REASON_FLAG_PLANNED
 #define SHTDN_REASON_FLAG_PLANNED 0x80000000
@@ -29,6 +32,146 @@
                        (365 * (1970 - 1601) +       \
                         (1970 - 1601) / 4 - 3))
 
+#define INVALID_SET_FILE_POINTER ((DWORD)-1)
+
+typedef struct GuestFileHandle {
+    int64_t id;
+    HANDLE fh;
+    QTAILQ_ENTRY(GuestFileHandle) next;
+} GuestFileHandle;
+
+static struct {
+    QTAILQ_HEAD(, GuestFileHandle) filehandles;
+} guest_file_state;
+
+
+typedef struct OpenFlags {
+    const char *forms;
+    DWORD desired_access;
+    DWORD creation_disposition;
+} OpenFlags;
+static OpenFlags guest_file_open_modes[] = {
+    {"r",   GENERIC_READ,               OPEN_EXISTING},
+    {"rb",  GENERIC_READ,               OPEN_EXISTING},
+    {"w",   GENERIC_WRITE,              CREATE_ALWAYS},
+    {"wb",  GENERIC_WRITE,              CREATE_ALWAYS},
+    {"a",   GENERIC_WRITE,              OPEN_ALWAYS  },
+    {"r+",  GENERIC_WRITE|GENERIC_READ, OPEN_EXISTING},
+    {"rb+", GENERIC_WRITE|GENERIC_READ, OPEN_EXISTING},
+    {"r+b", GENERIC_WRITE|GENERIC_READ, OPEN_EXISTING},
+    {"w+",  GENERIC_WRITE|GENERIC_READ, CREATE_ALWAYS},
+    {"wb+", GENERIC_WRITE|GENERIC_READ, CREATE_ALWAYS},
+    {"w+b", GENERIC_WRITE|GENERIC_READ, CREATE_ALWAYS},
+    {"a+",  GENERIC_WRITE|GENERIC_READ, OPEN_ALWAYS  },
+    {"ab+", GENERIC_WRITE|GENERIC_READ, OPEN_ALWAYS  },
+    {"a+b", GENERIC_WRITE|GENERIC_READ, OPEN_ALWAYS  }
+};
+
+static OpenFlags *find_open_flag(const char *mode_str)
+{
+    int mode;
+    Error **errp = NULL;
+
+    for (mode = 0; mode < ARRAY_SIZE(guest_file_open_modes); ++mode) {
+        OpenFlags *flags = guest_file_open_modes + mode;
+
+        if (strcmp(flags->forms, mode_str) == 0) {
+            return flags;
+        }
+    }
+
+    error_setg(errp, "invalid file open mode '%s'", mode_str);
+    return NULL;
+}
+
+static int64_t guest_file_handle_add(HANDLE fh, Error **errp)
+{
+    GuestFileHandle *gfh;
+    int64_t handle;
+
+    handle = ga_get_fd_handle(ga_state, errp);
+    if (handle < 0) {
+        return -1;
+    }
+    gfh = g_malloc0(sizeof(GuestFileHandle));
+    gfh->id = handle;
+    gfh->fh = fh;
+    QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next);
+
+    return handle;
+}
+
+static GuestFileHandle *guest_file_handle_find(int64_t id, Error **errp)
+{
+    GuestFileHandle *gfh;
+    QTAILQ_FOREACH(gfh, &guest_file_state.filehandles, next) {
+        if (gfh->id == id) {
+            return gfh;
+        }
+    }
+    error_setg(errp, "handle '%" PRId64 "' has not been found", id);
+    return NULL;
+}
+
+int64_t qmp_guest_file_open(const char *path, bool has_mode,
+                            const char *mode, Error **errp)
+{
+    int64_t fd;
+    HANDLE fh;
+    HANDLE templ_file = NULL;
+    DWORD share_mode = FILE_SHARE_READ;
+    DWORD flags_and_attr = FILE_ATTRIBUTE_NORMAL;
+    LPSECURITY_ATTRIBUTES sa_attr = NULL;
+    OpenFlags *guest_flags;
+
+    if (!has_mode) {
+        mode = "r";
+    }
+    slog("guest-file-open called, filepath: %s, mode: %s", path, mode);
+    guest_flags = find_open_flag(mode);
+    if (guest_flags == NULL) {
+        error_setg(errp, "invalid file open mode");
+        return -1;
+    }
+
+    fh = CreateFile(path, guest_flags->desired_access, share_mode, sa_attr,
+                    guest_flags->creation_disposition, flags_and_attr,
+                    templ_file);
+    if (fh == INVALID_HANDLE_VALUE) {
+        error_setg_win32(errp, GetLastError(), "failed to open file '%s'",
+                         path);
+        return -1;
+    }
+
+    fd = guest_file_handle_add(fh, errp);
+    if (fd < 0) {
+        CloseHandle(&fh);
+        error_setg(errp, "failed to add handle to qmp handle table");
+        return -1;
+    }
+
+    slog("guest-file-open, handle: % " PRId64, fd);
+    return fd;
+}
+
+void qmp_guest_file_close(int64_t handle, Error **errp)
+{
+    bool ret;
+    GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
+    slog("guest-file-close called, handle: %" PRId64, handle);
+    if (gfh == NULL) {
+        return;
+    }
+    ret = CloseHandle(gfh->fh);
+    if (!ret) {
+        error_setg_win32(errp, GetLastError(), "failed close handle");
+        return;
+    }
+
+    QTAILQ_REMOVE(&guest_file_state.filehandles, gfh, next);
+    g_free(gfh);
+}
+
 static void acquire_privilege(const char *name, Error **errp)
 {
     HANDLE token = NULL;
@@ -113,43 +256,130 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp)
     }
 }
 
-int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode,
-                            Error **errp)
-{
-    error_set(errp, QERR_UNSUPPORTED);
-    return 0;
-}
-
-void qmp_guest_file_close(int64_t handle, Error **errp)
-{
-    error_set(errp, QERR_UNSUPPORTED);
-}
-
 GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count,
                                    int64_t count, Error **errp)
 {
-    error_set(errp, QERR_UNSUPPORTED);
-    return 0;
+    GuestFileRead *read_data = NULL;
+    guchar *buf;
+    HANDLE fh;
+    bool is_ok;
+    DWORD read_count;
+    GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
+
+    if (!gfh) {
+        return NULL;
+    }
+    if (!has_count) {
+        count = QGA_READ_COUNT_DEFAULT;
+    } else if (count < 0) {
+        error_setg(errp, "value '%" PRId64
+                   "' is invalid for argument count", count);
+        return NULL;
+    }
+
+    fh = gfh->fh;
+    buf = g_malloc0(count+1);
+    is_ok = ReadFile(fh, buf, count, &read_count, NULL);
+    if (!is_ok) {
+        error_setg_win32(errp, GetLastError(), "failed to read file");
+        slog("guest-file-read failed, handle %" PRId64, handle);
+    } else {
+        buf[read_count] = 0;
+        read_data = g_malloc0(sizeof(GuestFileRead));
+        read_data->count = (size_t)read_count;
+        read_data->eof = read_count == 0;
+
+        if (read_count != 0) {
+            read_data->buf_b64 = g_base64_encode(buf, read_count);
+        }
+    }
+    g_free(buf);
+
+    return read_data;
 }
 
 GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
                                      bool has_count, int64_t count,
                                      Error **errp)
 {
-    error_set(errp, QERR_UNSUPPORTED);
-    return 0;
+    GuestFileWrite *write_data = NULL;
+    guchar *buf;
+    gsize buf_len;
+    bool is_ok;
+    DWORD write_count;
+    GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
+    HANDLE fh;
+
+    if (!gfh) {
+        return NULL;
+    }
+    fh = gfh->fh;
+    buf = g_base64_decode(buf_b64, &buf_len);
+
+    if (!has_count) {
+        count = buf_len;
+    } else if (count < 0 || count > buf_len) {
+        error_setg(errp, "value '%" PRId64
+                   "' is invalid for argument count", count);
+        goto done;
+    }
+
+    is_ok = WriteFile(fh, buf, count, &write_count, NULL);
+    if (!is_ok) {
+        error_setg_win32(errp, GetLastError(), "failed to write to file");
+        slog("guest-file-write-failed, handle: %" PRId64, handle);
+    } else {
+        write_data = g_malloc0(sizeof(GuestFileWrite));
+        write_data->count = (size_t) write_count;
+    }
+
+done:
+    g_free(buf);
+    return write_data;
 }
 
 GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
                                    int64_t whence, Error **errp)
 {
-    error_set(errp, QERR_UNSUPPORTED);
-    return 0;
+    GuestFileHandle *gfh;
+    GuestFileSeek *seek_data;
+    HANDLE fh;
+    LARGE_INTEGER new_pos, off_pos;
+    off_pos.QuadPart = offset;
+    BOOL res;
+    gfh = guest_file_handle_find(handle, errp);
+    if (!gfh) {
+        return NULL;
+    }
+
+    fh = gfh->fh;
+    res = SetFilePointerEx(fh, off_pos, &new_pos, whence);
+    if (!res) {
+        error_setg_win32(errp, GetLastError(), "failed to seek file");
+        return NULL;
+    }
+    seek_data = g_new0(GuestFileSeek, 1);
+    seek_data->position = new_pos.QuadPart;
+    return seek_data;
 }
 
 void qmp_guest_file_flush(int64_t handle, Error **errp)
 {
-    error_set(errp, QERR_UNSUPPORTED);
+    HANDLE fh;
+    GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
+    if (!gfh) {
+        return;
+    }
+
+    fh = gfh->fh;
+    if (!FlushFileBuffers(fh)) {
+        error_setg_win32(errp, GetLastError(), "failed to flush file");
+    }
+}
+
+static void guest_file_init(void)
+{
+    QTAILQ_INIT(&guest_file_state.filehandles);
 }
 
 GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp)
@@ -450,8 +680,6 @@ int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp)
 GList *ga_command_blacklist_init(GList *blacklist)
 {
     const char *list_unsupported[] = {
-        "guest-file-open", "guest-file-close", "guest-file-read",
-        "guest-file-write", "guest-file-seek", "guest-file-flush",
         "guest-suspend-hybrid", "guest-network-get-interfaces",
         "guest-get-vcpus", "guest-set-vcpus",
         "guest-fsfreeze-freeze-list", "guest-get-fsinfo",
@@ -482,4 +710,5 @@ void ga_command_state_init(GAState *s, GACommandState *cs)
     if (!vss_initialized()) {
         ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup);
     }
+    ga_command_state_add(cs, guest_file_init, NULL);
 }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH 0/3] qemu guest agent: support guest-file-* command for Windows
  2015-02-06 17:59 [Qemu-devel] [PATCH 0/3] qemu guest agent: support guest-file-* command for Windows Denis V. Lunev
                   ` (2 preceding siblings ...)
  2015-02-06 17:59 ` [Qemu-devel] [PATCH 3/3] qga: implement file commands for Windows guest Denis V. Lunev
@ 2015-02-13  7:51 ` Denis V. Lunev
  2015-02-17  2:07 ` Michael Roth
  4 siblings, 0 replies; 6+ messages in thread
From: Denis V. Lunev @ 2015-02-13  7:51 UTC (permalink / raw)
  Cc: Olga Krishtal, qemu-devel, Michael Roth

On 06/02/15 20:59, Denis V. Lunev wrote:
> This was a part of patchset implemented guest-exec command.
> It was suggested to submit it separately by Michael.
>
> The set contains small refactoring to fix mingw 4.9.1 compilation
> and safe part of the rework of posix file interface plus main
> Windows file commands implementation.
>
> Changes from previous version:
> - compilation is fixed by gropping strtok_r at all
> - error_setg_win32 is used for error decoding
>
> Signed-off-by: Olga Krishtal <okrishtal@parallels.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Michael Roth <mdroth@linux.vnet.ibm.com>
>
ping

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH 0/3] qemu guest agent: support guest-file-* command for Windows
  2015-02-06 17:59 [Qemu-devel] [PATCH 0/3] qemu guest agent: support guest-file-* command for Windows Denis V. Lunev
                   ` (3 preceding siblings ...)
  2015-02-13  7:51 ` [Qemu-devel] [PATCH 0/3] qemu guest agent: support guest-file-* command for Windows Denis V. Lunev
@ 2015-02-17  2:07 ` Michael Roth
  4 siblings, 0 replies; 6+ messages in thread
From: Michael Roth @ 2015-02-17  2:07 UTC (permalink / raw)
  To: Denis V. Lunev; +Cc: Olga Krishtal, qemu-devel

Quoting Denis V. Lunev (2015-02-06 11:59:52)
> This was a part of patchset implemented guest-exec command.
> It was suggested to submit it separately by Michael.
> 
> The set contains small refactoring to fix mingw 4.9.1 compilation
> and safe part of the rework of posix file interface plus main
> Windows file commands implementation.

Thanks, applied to QGA tree:

https://github.com/mdroth/qemu/commits/qga

> 
> Changes from previous version:
> - compilation is fixed by gropping strtok_r at all
> - error_setg_win32 is used for error decoding
> 
> Signed-off-by: Olga Krishtal <okrishtal@parallels.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Michael Roth <mdroth@linux.vnet.ibm.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-02-17  2:09 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-06 17:59 [Qemu-devel] [PATCH 0/3] qemu guest agent: support guest-file-* command for Windows Denis V. Lunev
2015-02-06 17:59 ` [Qemu-devel] [PATCH 1/3] utils: drop strtok_r from envlist_parse Denis V. Lunev
2015-02-06 17:59 ` [Qemu-devel] [PATCH 2/3] guest agent: guest-file-open: refactoring Denis V. Lunev
2015-02-06 17:59 ` [Qemu-devel] [PATCH 3/3] qga: implement file commands for Windows guest Denis V. Lunev
2015-02-13  7:51 ` [Qemu-devel] [PATCH 0/3] qemu guest agent: support guest-file-* command for Windows Denis V. Lunev
2015-02-17  2:07 ` 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).