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