-From 5476ae43806488e74cd293bbaa17f130aa53d402 Mon Sep 17 00:00:00 2001
+From ec5c25c57d35ea662f70382a074620ef2abd0627 Mon Sep 17 00:00:00 2001
From: Dietmar Maurer <dietmar@proxmox.com>
Date: Tue, 13 Nov 2012 11:11:38 +0100
-Subject: [PATCH v4 4/6] introduce new vma archive format
+Subject: [PATCH v5 4/6] introduce new vma archive format
This is a very simple archive format, see docs/specs/vma_spec.txt
---
Makefile | 3 +-
Makefile.objs | 2 +-
- backup.h | 1 +
blockdev.c | 6 +-
docs/specs/vma_spec.txt | 24 ++
vma-reader.c | 799 ++++++++++++++++++++++++++++++++++++++++
- vma-writer.c | 932 +++++++++++++++++++++++++++++++++++++++++++++++
- vma.c | 559 ++++++++++++++++++++++++++++
+ vma-writer.c | 940 +++++++++++++++++++++++++++++++++++++++++++++++
+ vma.c | 561 ++++++++++++++++++++++++++++
vma.h | 145 ++++++++
- 9 files changed, 2467 insertions(+), 4 deletions(-)
+ 8 files changed, 2476 insertions(+), 4 deletions(-)
create mode 100644 docs/specs/vma_spec.txt
create mode 100644 vma-reader.c
create mode 100644 vma-writer.c
block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
block-obj-y += qemu-coroutine-sleep.o
-diff --git a/backup.h b/backup.h
-index c8ba153..406f011 100644
---- a/backup.h
-+++ b/backup.h
-@@ -15,6 +15,7 @@
- #define QEMU_BACKUP_H
-
- #include <uuid/uuid.h>
-+#include "block/block.h"
-
- #define BACKUP_CLUSTER_BITS 16
- #define BACKUP_CLUSTER_SIZE (1<<BACKUP_CLUSTER_BITS)
diff --git a/blockdev.c b/blockdev.c
-index c340fde..1cfc780 100644
+index 84f598d..683f7da 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -21,6 +21,7 @@
}
diff --git a/docs/specs/vma_spec.txt b/docs/specs/vma_spec.txt
new file mode 100644
-index 0000000..052c629
+index 0000000..9b715f2
--- /dev/null
+++ b/docs/specs/vma_spec.txt
@@ -0,0 +1,24 @@
+cluster in the header to store the following information:
+
+* 1 byte dev_id (to identity the drive)
++* 1 byte not used (reserved)
+* 2 bytes zero indicator (mark zero regions (16x4096))
+* 4 bytes cluster number
-+* 1 byte not used (reserved)
+
+We only store non-zero blocks (such block is 4096 bytes).
+
+
diff --git a/vma-reader.c b/vma-reader.c
new file mode 100644
-index 0000000..7e81847
+index 0000000..6d5a9ba
--- /dev/null
+++ b/vma-reader.c
@@ -0,0 +1,799 @@
+#include "vma.h"
+#include "block/block.h"
+
-+#define BITS_PER_LONG (sizeof(unsigned long) * 8)
++#define BITS_PER_LONG (sizeof(unsigned long) * CHAR_BIT)
+
+static unsigned char zero_vma_block[VMA_BLOCK_SIZE];
+
+
diff --git a/vma-writer.c b/vma-writer.c
new file mode 100644
-index 0000000..761d7ca
+index 0000000..c292851
--- /dev/null
+++ b/vma-writer.c
-@@ -0,0 +1,932 @@
+@@ -0,0 +1,940 @@
+/*
+ * VMA: Virtual Machine Archive
+ *
+
+ DPRINTF("VMA WRITE %d %zd\n", dev_id, cluster_num);
+
-+ int i;
-+ int bit = 1;
+ uint16_t mask = 0;
-+ for (i = 0; i < 16; i++) {
-+ unsigned char *vmablock = buf + (i*VMA_BLOCK_SIZE);
-+ if (!buffer_is_zero(vmablock, VMA_BLOCK_SIZE)) {
-+ mask |= bit;
-+ memcpy(vmaw->outbuf + vmaw->outbuf_pos, vmablock, VMA_BLOCK_SIZE);
-+ vmaw->outbuf_pos += VMA_BLOCK_SIZE;
-+ } else {
-+ DPRINTF("VMA WRITE %zd ZERO BLOCK %d\n", cluster_num, i);
-+ vmaw->stream_info[dev_id].zero_bytes += VMA_BLOCK_SIZE;
-+ *zero_bytes += VMA_BLOCK_SIZE;
-+ }
+
-+ bit = bit << 1;
++ if (buf) {
++ int i;
++ int bit = 1;
++ for (i = 0; i < 16; i++) {
++ unsigned char *vmablock = buf + (i*VMA_BLOCK_SIZE);
++ if (!buffer_is_zero(vmablock, VMA_BLOCK_SIZE)) {
++ mask |= bit;
++ memcpy(vmaw->outbuf + vmaw->outbuf_pos, vmablock,
++ VMA_BLOCK_SIZE);
++ vmaw->outbuf_pos += VMA_BLOCK_SIZE;
++ } else {
++ DPRINTF("VMA WRITE %zd ZERO BLOCK %d\n", cluster_num, i);
++ vmaw->stream_info[dev_id].zero_bytes += VMA_BLOCK_SIZE;
++ *zero_bytes += VMA_BLOCK_SIZE;
++ }
++
++ bit = bit << 1;
++ }
++ } else {
++ DPRINTF("VMA WRITE %zd ZERO CLUSTER\n", cluster_num);
++ vmaw->stream_info[dev_id].zero_bytes += VMA_CLUSTER_SIZE;
++ *zero_bytes += VMA_CLUSTER_SIZE;
+ }
+
+ uint64_t block_info = ((uint64_t)mask) << (32+16);
+
+const BackupDriver backup_vma_driver = {
+ .format = "vma",
-+ .open_cb = vma_open_cb,
-+ .close_cb = vma_close_cb,
-+ .register_config_cb = vma_register_config_cb,
-+ .register_stream_cb = vma_register_stream_cb,
-+ .dump_cb = vma_dump_cb,
-+ .complete_cb = vma_complete_cb,
++ .open = vma_open_cb,
++ .close = vma_close_cb,
++ .register_config = vma_register_config_cb,
++ .register_stream = vma_register_stream_cb,
++ .dump = vma_dump_cb,
++ .complete = vma_complete_cb,
+};
+
diff --git a/vma.c b/vma.c
new file mode 100644
-index 0000000..b2e276c
+index 0000000..d3fe39c
--- /dev/null
+++ b/vma.c
-@@ -0,0 +1,559 @@
+@@ -0,0 +1,561 @@
+/*
+ * VMA: Virtual Machine Archive
+ *
+ }
+ percent = (transferred*100)/total;
+ if (percent != last_percent) {
-+ printf("progress %d%% %zd/%zd %zd\n", percent,
-+ transferred, total, zero_bytes);
++ fprintf(stderr, "progress %d%% %zd/%zd %zd\n", percent,
++ transferred, total, zero_bytes);
++ fflush(stderr);
+
+ last_percent = percent;
+ }
+ for (i = 0; i < 256; i++) {
+ VmaStreamInfo *si = &vmastat.stream_info[i];
+ if (si->size) {
-+ printf("image %s: size=%zd zeros=%zd saved=%zd\n", si->devname,
-+ si->size, si->zero_bytes, si->size - si->zero_bytes);
++ fprintf(stderr, "image %s: size=%zd zeros=%zd saved=%zd\n",
++ si->devname, si->size, si->zero_bytes,
++ si->size - si->zero_bytes);
+ }
+ }
+ }