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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This will be used by postcopy/incoming part.

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

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)
 {
-- 
1.7.10.4

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


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux