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