Currently qemu_fopen_ops accepts both get_buffer and put_buffer, but
if both are given (non NULL) we encounter problems:
  1. There is only one buffer and index, which may mean data corruption.
  2. qemu_flush (which is also called by qemu_fclose) is writing ("flushing")
     some of the data that was read (for the reader part).

Currently qemu_fopen_fd registers both get_buffer and put_buffer functions.

This breaks migration for tcp and ssh migration protocols.

The following patch fix the above by:
  1. It makes sure that at most one of get_buffer and put_buffer is
     given to qemu_fopen_ops.
  2. It changes qemu_fopen_fd to register only get_buffer for a reader
     and only put_buffer for a writer (adding a 'reader' parameter).
  3. The incoming fd migration code calls qemu_fopen_fd as a reader only.

Signed-off-by: Uri Lublin <[EMAIL PROTECTED]>
---
 qemu/hw/hw.h     |    2 +-
 qemu/migration.c |    2 +-
 qemu/vl.c        |   12 ++++++++++--
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/qemu/hw/hw.h b/qemu/hw/hw.h
index c9390c1..d965c47 100644
--- a/qemu/hw/hw.h
+++ b/qemu/hw/hw.h
@@ -34,7 +34,7 @@ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc 
*put_buffer,
                          QEMUFileCloseFunc *close,
                          QEMUFileRateLimit *rate_limit);
 QEMUFile *qemu_fopen(const char *filename, const char *mode);
-QEMUFile *qemu_fopen_fd(int fd);
+QEMUFile *qemu_fopen_fd(int fd, int reader);
 void qemu_fflush(QEMUFile *f);
 int qemu_fclose(QEMUFile *f);
 void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
diff --git a/qemu/migration.c b/qemu/migration.c
index 44cb9eb..587c67e 100644
--- a/qemu/migration.c
+++ b/qemu/migration.c
@@ -820,7 +820,7 @@ static int migrate_incoming_page(QEMUFile *f, uint32_t addr)
 static int migrate_incoming_fd(int fd)
 {
     int ret = 0;
-    QEMUFile *f = qemu_fopen_fd(fd);
+    QEMUFile *f = qemu_fopen_fd(fd, 1);
     uint32_t addr, size;
     extern void qemu_announce_self(void);
     unsigned char running;
diff --git a/qemu/vl.c b/qemu/vl.c
index 36e3bb7..1ce188b 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -6712,7 +6712,7 @@ static int fd_close(void *opaque)
     return 0;
 }
 
-QEMUFile *qemu_fopen_fd(int fd)
+QEMUFile *qemu_fopen_fd(int fd, int reader)
 {
     QEMUFileFD *s = qemu_mallocz(sizeof(QEMUFileFD));
 
@@ -6720,7 +6720,10 @@ QEMUFile *qemu_fopen_fd(int fd)
         return NULL;
 
     s->fd = fd;
-    s->file = qemu_fopen_ops(s, fd_put_buffer, fd_get_buffer, fd_close, NULL);
+    if (reader)
+        s->file = qemu_fopen_ops(s, NULL, fd_get_buffer, fd_close, NULL);
+    else
+        s->file = qemu_fopen_ops(s, fd_put_buffer, NULL, fd_close, NULL);
     return s->file;
 }
 
@@ -6826,6 +6829,11 @@ QEMUFile *qemu_fopen_ops(void *opaque, 
QEMUFilePutBufferFunc *put_buffer,
 {
     QEMUFile *f;
 
+    if (put_buffer && get_buffer) {
+        fprintf(stderr, "%s: only one of get_buffer and put_buffer "
+                "functions may be given\n", __FUNCTION__);
+        return NULL;
+    }
     f = qemu_mallocz(sizeof(QEMUFile));
     if (!f)
         return NULL;
-- 
1.5.5.1

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to