diff mbox

[v3,10/35] savevm/QEMUFile: add read/write QEMUFile on memory buffer

Message ID d9b4abd672572433a6646bce331389889c72c43c.1351582535.git.yamahata@valinux.co.jp
State New
Headers show

Commit Message

Isaku Yamahata Oct. 30, 2012, 8:32 a.m. UTC
This will be used by postcopy/incoming part.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
 qemu-file.h |    4 ++++
 savevm.c    |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)
diff mbox

Patch

diff --git a/qemu-file.h b/qemu-file.h
index 94557ea..452efcd 100644
--- a/qemu-file.h
+++ b/qemu-file.h
@@ -71,6 +71,10 @@  QEMUFile *qemu_fopen_socket(int fd);
 QEMUFile *qemu_fopen_fd(int fd, const char *mode);
 QEMUFile *qemu_popen(FILE *popen_file, const char *mode);
 QEMUFile *qemu_popen_cmd(const char *command, const char *mode);
+struct QEMUFileBuf;
+typedef struct QEMUFileBuf QEMUFileBuf;
+QEMUFileBuf *qemu_fopen_buf_write(void);
+QEMUFile *qemu_fopen_buf_read(uint8_t *buf, size_t size);
 int qemu_file_fd(QEMUFile *f);
 int qemu_fclose(QEMUFile *f);
 int qemu_fflush(QEMUFile *f);
diff --git a/savevm.c b/savevm.c
index 712b7ae..7e55dce 100644
--- a/savevm.c
+++ b/savevm.c
@@ -368,6 +368,66 @@  QEMUFile *qemu_fopen_fd(int fd, const char *mode)
     return s->file;
 }
 
+struct QEMUFileBuf {
+    QEMUFile *file;
+    uint8_t *buffer;
+    size_t buffer_size;
+    size_t buffer_capacity;
+};
+
+static int buf_close(void *opaque)
+{
+    QEMUFileBuf *s = opaque;
+    g_free(s->buffer);
+    g_free(s);
+    return 0;
+}
+
+static int buf_put_buffer(void *opaque,
+                          const uint8_t *buf, int64_t pos, int size)
+{
+    QEMUFileBuf *s = opaque;
+
+    int inc = size - (s->buffer_capacity - s->buffer_size);
+    if (inc > 0) {
+        s->buffer_capacity += DIV_ROUND_UP(inc, IO_BUF_SIZE) * IO_BUF_SIZE;
+        s->buffer = g_realloc(s->buffer, s->buffer_capacity);
+    }
+    memcpy(s->buffer + s->buffer_size, buf, size);
+    s->buffer_size += size;
+
+    return size;
+}
+
+QEMUFileBuf *qemu_fopen_buf_write(void)
+{
+    QEMUFileBuf *s = g_malloc0(sizeof(*s));
+    s->file = qemu_fopen_ops(s,  buf_put_buffer, NULL, buf_close,
+                             NULL, NULL, NULL);
+    return s;
+}
+
+static int buf_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
+{
+    QEMUFileBuf *s = opaque;
+    ssize_t len = MIN(size, s->buffer_capacity - s->buffer_size);
+    memcpy(buf, s->buffer + s->buffer_size, len);
+    s->buffer_size += len;
+    return len;
+}
+
+/* This gets the ownership of buf. */
+QEMUFile *qemu_fopen_buf_read(uint8_t *buf, size_t size)
+{
+    QEMUFileBuf *s = g_malloc0(sizeof(*s));
+    s->buffer = buf;
+    s->buffer_size = 0; /* this is used as index to read */
+    s->buffer_capacity = size;
+    s->file = qemu_fopen_ops(s, NULL, buf_get_buffer, buf_close,
+                             NULL, NULL, NULL);
+    return s->file;
+}
+
 static int file_put_buffer(void *opaque, const uint8_t *buf,
                             int64_t pos, int size)
 {