-From 04b6468a295871877b55fe792c566839e2afe29c Mon Sep 17 00:00:00 2001
+From c1338b34ccac2c5e6d7d1aca3ca3e3457a3f744c Mon Sep 17 00:00:00 2001
From: Dietmar Maurer <dietmar@proxmox.com>
Date: Tue, 13 Nov 2012 11:11:38 +0100
-Subject: [PATCH 11/41] introduce new vma archive format
+Subject: [PATCH 11/47] introduce new vma archive format
This is a very simple archive format, see docs/specs/vma_spec.txt
---
Makefile | 3 +-
Makefile.objs | 1 +
- vma-reader.c | 799 ++++++++++++++++++++++++++++++++++++++++++++++++++++
- vma-writer.c | 876 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- vma.c | 582 ++++++++++++++++++++++++++++++++++++++
+ vma-reader.c | 797 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ vma-writer.c | 870 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ vma.c | 586 +++++++++++++++++++++++++++++++++++++++
vma.h | 146 ++++++++++
- 6 files changed, 2406 insertions(+), 1 deletion(-)
+ 6 files changed, 2402 insertions(+), 1 deletion(-)
create mode 100644 vma-reader.c
create mode 100644 vma-writer.c
create mode 100644 vma.c
create mode 100644 vma.h
diff --git a/Makefile b/Makefile
-index 930ac27..6cedc40 100644
+index 6c359b2..edbc8b5 100644
--- a/Makefile
+++ b/Makefile
-@@ -166,7 +166,7 @@ ifneq ($(wildcard config-host.mak),)
- include $(SRC_PATH)/tests/Makefile
+@@ -284,7 +284,7 @@ ifneq ($(wildcard config-host.mak),)
+ include $(SRC_PATH)/tests/Makefile.include
endif
-all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all modules
+all: $(DOCS) $(TOOLS) vma$(EXESUF) $(HELPERS-y) recurse-all modules
- config-host.h: config-host.h-timestamp
- config-host.h-timestamp: config-host.mak
-@@ -235,6 +235,7 @@ qemu-img.o: qemu-img-cmds.h
- qemu-img$(EXESUF): qemu-img.o $(block-obj-y) $(crypto-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
- qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) $(crypto-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
- qemu-io$(EXESUF): qemu-io.o $(block-obj-y) $(crypto-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
-+vma$(EXESUF): vma.o vma-reader.o $(block-obj-y) $(crypto-obj-y) $(qom-obj-y) libqemuutil.a libqemustub.a
+ qemu-version.h: FORCE
+ $(call quiet-command, \
+@@ -377,6 +377,7 @@ qemu-img.o: qemu-img-cmds.h
+ qemu-img$(EXESUF): qemu-img.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+ qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
+ qemu-io$(EXESUF): qemu-io.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
++vma$(EXESUF): vma.o vma-reader.o $(block-obj-y) $(crypto-obj-y) $(io-obj-y) $(qom-obj-y) $(COMMON_LDADDS)
- qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
+ qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o $(COMMON_LDADDS)
diff --git a/Makefile.objs b/Makefile.objs
-index 77be052..97d2bcc 100644
+index 6167e7b..9b12ee6 100644
--- a/Makefile.objs
+++ b/Makefile.objs
-@@ -14,6 +14,7 @@ block-obj-$(CONFIG_POSIX) += aio-posix.o
- block-obj-$(CONFIG_WIN32) += aio-win32.o
+@@ -14,6 +14,7 @@ block-obj-y += block.o blockjob.o
block-obj-y += block/
block-obj-y += qemu-io-cmds.o
+ block-obj-$(CONFIG_REPLICATION) += replication.o
+block-obj-y += vma-writer.o
block-obj-m = block/
diff --git a/vma-reader.c b/vma-reader.c
new file mode 100644
-index 0000000..bc36cba
+index 0000000..51dd8fe
--- /dev/null
+++ b/vma-reader.c
-@@ -0,0 +1,799 @@
+@@ -0,0 +1,797 @@
+/*
+ * VMA: Virtual Machine Archive
+ *
+ *
+ */
+
-+#include <stdio.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
++#include "qemu/osdep.h"
+#include <glib.h>
+#include <uuid/uuid.h>
+
+#include "qemu/ratelimit.h"
+#include "vma.h"
+#include "block/block.h"
-+
-+#define BITS_PER_LONG (sizeof(unsigned long) * CHAR_BIT)
++#include "sysemu/block-backend.h"
+
+static unsigned char zero_vma_block[VMA_BLOCK_SIZE];
+
+ assert(vmar->rstate[dev_id].bs == NULL);
+
+ int64_t size = bdrv_getlength(bs);
-+ if (size != vmar->devinfo[dev_id].size) {
++ int64_t size_diff = size - vmar->devinfo[dev_id].size;
++
++ /* storage types can have different size restrictions, so it
++ * is not always possible to create an image with exact size.
++ * So we tolerate a size difference up to 4MB.
++ */
++ if ((size_diff < 0) || (size_diff > 4*1024*1024)) {
+ error_setg(errp, "vma_reader_register_bs for stream %s failed - "
+ "unexpected size %zd != %zd", vmar->devinfo[dev_id].devname,
+ size, vmar->devinfo[dev_id].size);
+
diff --git a/vma-writer.c b/vma-writer.c
new file mode 100644
-index 0000000..8a3fa1c
+index 0000000..b0cf529
--- /dev/null
+++ b/vma-writer.c
-@@ -0,0 +1,876 @@
+@@ -0,0 +1,870 @@
+/*
+ * VMA: Virtual Machine Archive
+ *
+ *
+ */
+
-+#include <stdio.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
++#include "qemu/osdep.h"
+#include <glib.h>
+#include <uuid/uuid.h>
+
-+#include "qemu-common.h"
+#include "vma.h"
+#include "block/block.h"
+#include "monitor/monitor.h"
+#include "qemu/main-loop.h"
++#include "qemu/coroutine.h"
++#include "qemu/cutils.h"
+
+#define DEBUG_VMA 0
+
+ VmaWriter *vmaw = opaque;
+
+ DPRINTF("vma_co_continue_write\n");
-+ qemu_coroutine_enter(vmaw->co_writer, NULL);
++ qemu_coroutine_enter(vmaw->co_writer);
+}
+
+static ssize_t coroutine_fn
+
+ vmaw->co_writer = qemu_coroutine_self();
+
-+ aio_set_fd_handler(qemu_get_aio_context(), vmaw->fd, NULL, vma_co_continue_write, vmaw);
++ aio_set_fd_handler(qemu_get_aio_context(), vmaw->fd, false, NULL, vma_co_continue_write, vmaw);
+
+ DPRINTF("vma_co_write wait until writable\n");
+ qemu_coroutine_yield();
+ }
+ }
+
-+ aio_set_fd_handler(qemu_get_aio_context(), vmaw->fd, NULL, NULL, NULL);
++ aio_set_fd_handler(qemu_get_aio_context(), vmaw->fd, false, NULL, NULL, NULL);
+
+ vmaw->co_writer = NULL;
+
+}
diff --git a/vma.c b/vma.c
new file mode 100644
-index 0000000..86c117b
+index 0000000..8732bfa
--- /dev/null
+++ b/vma.c
-@@ -0,0 +1,582 @@
+@@ -0,0 +1,586 @@
+/*
+ * VMA: Virtual Machine Archive
+ *
+ *
+ */
+
-+#include <stdio.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
++#include "qemu/osdep.h"
+#include <glib.h>
+
+#include "vma.h"
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "qemu/main-loop.h"
++#include "qapi/qmp/qstring.h"
++#include "sysemu/char.h" /* qstring_from_str */
+
+static void help(void)
+{
+ }
+
+ BlockDriverState *bs = bdrv_new();
-+ if (errp || bdrv_open(&bs, devfn, NULL, NULL, flags, NULL, &errp)) {
++ if (errp || bdrv_open(&bs, devfn, NULL, NULL, flags, &errp)) {
+ g_error("can't open file %s - %s", devfn,
+ error_get_pretty(errp));
+ }
+
+static int create_archive(int argc, char **argv)
+{
-+ int i, c, res;
++ int i, c;
+ int verbose = 0;
+ const char *archivename;
+ GList *config_files = NULL;
+ char *devname = NULL;
+ path = extract_devname(path, &devname, ind++);
+
-+ BlockDriver *drv = NULL;
+ Error *errp = NULL;
-+ BlockDriverState *bs = bdrv_new();
++ BlockDriverState *bs;
+
-+ res = bdrv_open(&bs, path, NULL, NULL, BDRV_O_CACHE_WB , drv, &errp);
-+ if (res < 0) {
++ bs = bdrv_open(path, NULL, NULL, 0, &errp);
++ if (!bs) {
+ unlink(archivename);
+ g_error("bdrv_open '%s' failed - %s", path, error_get_pretty(errp));
+ }
+ job->vmaw = vmaw;
+ job->dev_id = dev_id;
+
-+ Coroutine *co = qemu_coroutine_create(backup_run);
-+ qemu_coroutine_enter(co, job);
++ Coroutine *co = qemu_coroutine_create(backup_run, job);
++ qemu_coroutine_enter(co);
+ }
+
+ VmaStatus vmastat;
+ if (vmastat.closed) {
+ break;
+ }
++ } else {
++ Coroutine *co = qemu_coroutine_create(backup_run_empty, vmaw);
++ qemu_coroutine_enter(co);
++ while (1) {
++ main_loop_wait(false);
++ vma_writer_get_status(vmaw, &vmastat);
++ if (vmastat.closed) {
++ break;
++ }
++ }
+ }
+
+ bdrv_drain_all();