Index: new/Makefile
===================================================================
---- new.orig/Makefile 2013-11-29 08:45:24.000000000 +0100
-+++ new/Makefile 2013-11-29 10:08:41.000000000 +0100
+--- new.orig/Makefile 2013-12-04 12:07:18.000000000 +0100
++++ new/Makefile 2013-12-04 12:07:25.000000000 +0100
@@ -128,7 +128,7 @@
include $(SRC_PATH)/libcacard/Makefile
endif
qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a
qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a
qemu-io$(EXESUF): qemu-io.o $(block-obj-y) libqemuutil.a libqemustub.a
-+vma$(EXESUF): vma.o vma-writer.o vma-reader.o $(block-obj-y) libqemuutil.a libqemustub.a
++vma$(EXESUF): vma.o vma-reader.o $(block-obj-y) libqemuutil.a libqemustub.a
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
Index: new/docs/specs/vma_spec.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ new/docs/specs/vma_spec.txt 2013-11-29 10:08:41.000000000 +0100
-@@ -0,0 +1,24 @@
-+=Virtual Machine Archive format (VMA)=
++++ new/docs/specs/vma_spec.txt 2013-12-05 08:14:11.000000000 +0100
+@@ -0,0 +1,132 @@
++= Virtual Machine Archive format (VMA) =
+
+This format contains a header which includes the VM configuration as
+binary blobs, and a list of devices (dev_id, name).
+extent headers includes that uuid and a MD5 checksum (over header
+data).
+
++All numbers in VMA archive are stored in Big Endian byte order.
++
++== VMA Header ==
++
++ Byte 0 - 3: magic
++ VMA magic string ("VMA\x00")
++
++ 4 - 7: version
++ Version number (valid value is 1)
++
++ 8 - 23: uuid
++ Unique ID, Same uuid is used to mark extents.
++
++ 24 - 31: ctime
++ Backup time stamp (seconds since epoch)
++
++ 32 - 47: md5sum
++ Header checksum (from byte 0 to header_size). This field
++ is filled with zero to generate the checksum.
++
++ 48 - 51: blob_buffer_offset
++ Start of blob buffer (multiple of 512)
++
++ 52 - 55: blob_buffer_size
++ Size of blob buffer (multiple of 512)
++
++ 56 - 59: header_size
++ Overall size of this header (multiple of 512)
++
++ 60 - 2043: reserved
++
++ 2044 - 3067: uint32_t config_names[256]
++ Offsets into blob_buffer table
++
++ 3068 - 4091: uint32_t config_data[256]
++ Offsets into blob_buffer table
++
++ 4092 - 4095: reserved
++
++ 4096 - 12287: VmaDeviceInfoHeader dev_info[256]
++ The offset in this table is used as 'dev_id' inside
++ the data streams.
++
++ 12288 - header_size: Blob buffer
++
++
++=== Devive Info Header (VmaDeviceInfoHeader) ===
++
++This is use to store details about the contained disk images.
++
++ Byte 0 - 3: devive name (offsets into blob_buffer table)
++
++ 4 - 7: reserved
++
++ 8 - 15: device size in bytes
++
++ 16 - 31: reserved
++
++Note: Devive name 'vmstate' is reserved to store VM RAM state.
++
++=== Blob buffer ===
++
++The blob buffer is used to store both configuration file names and
++configuration data.
++
++This region contain a list of binary data blobs. Each blob starts with
++a 2 byte size field, followed by the actual data.
++
++== Image Data Streams ==
++
++The VMA header is followed by the image data stream. Image data is grouped
++with extents, which contains up to 59 clusters from different images.
++
++=== VMA Extent Header ===
++
++ Byte 0 - 3: magic
++ VMA extent magic string ("VMAE")
++
++ 4 - 5: reserved
++
++ 6 - 7: block_count
++ Overall number of contained 4K block
++
++ 8 - 23: uuid
++ Unique ID, Same uuid as used in the VMA header.
++
++ 24 - 39: md5sum
++ Header checksum (from byte 0 to header_size). This field
++ is filled with zero to generate the checksum.
++
++ 40 - 511: blockinfo[59]
++
++
++Each 'blockinfo' (8 bytes) give further details about contained clusters:
++
++ Byte 0 - 1: mask
++ Bitmap used to indicate non-zero 4K blocks inside the
++ cluster.
++
++ 2: reserved
++
++ 3: dev_id
++ Device ID (offset into dev_info table)
++
++ 4 - 7: cluster_num
++
++The extend header if followed by the actual cluster data, where we only
++store non-zero 4K blocks.
+
Index: new/vma-reader.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ new/vma-reader.c 2013-11-29 10:13:24.000000000 +0100
++++ new/vma-reader.c 2013-12-04 12:07:25.000000000 +0100
@@ -0,0 +1,799 @@
+/*
+ * VMA: Virtual Machine Archive
Index: new/vma-writer.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ new/vma-writer.c 2013-11-29 10:08:41.000000000 +0100
-@@ -0,0 +1,869 @@
++++ new/vma-writer.c 2013-12-04 14:26:06.000000000 +0100
+@@ -0,0 +1,875 @@
+/*
+ * VMA: Virtual Machine Archive
+ *
+ assert(data);
+ assert(len);
+
-+ uint32_t name_ptr = allocate_header_string(vmaw, name);
++ gchar *basename = g_path_get_basename(name);
++ uint32_t name_ptr = allocate_header_string(vmaw, basename);
++ g_free(basename);
++
+ if (!name_ptr) {
+ return -1;
+ }
+ const char *p;
+
+ assert(sizeof(VmaHeader) == (4096 + 8192));
++ assert(G_STRUCT_OFFSET(VmaHeader, config_names) == 2044);
++ assert(G_STRUCT_OFFSET(VmaHeader, config_data) == 3068);
++ assert(G_STRUCT_OFFSET(VmaHeader, dev_info) == 4096);
+ assert(sizeof(VmaExtentHeader) == 512);
+
+ VmaWriter *vmaw = g_new0(VmaWriter, 1);
Index: new/vma.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ new/vma.c 2013-11-29 10:14:29.000000000 +0100
-@@ -0,0 +1,623 @@
++++ new/vma.c 2013-12-04 12:07:25.000000000 +0100
+@@ -0,0 +1,579 @@
+/*
+ * VMA: Virtual Machine Archive
+ *
+ uint8_t dev_id;
+} BackupJob;
+
-+/*
-+static int backup_dump_cb(void *opaque, BlockDriverState *bs,
-+ int64_t cluster_num, unsigned char *buf)
-+{
-+ BackupCB *bcb = opaque;
-+ size_t zb = 0;
-+ if (vma_writer_write(bcb->vmaw, bcb->dev_id, cluster_num, buf, &zb) < 0) {
-+ g_warning("backup_dump_cb vma_writer_write failed");
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static void backup_complete_cb(void *opaque, int ret)
-+{
-+ BackupCB *bcb = opaque;
-+
-+ if (ret < 0) {
-+ vma_writer_set_error(bcb->vmaw, "backup_complete_cb %d", ret);
-+ }
-+
-+ if (vma_writer_close_stream(bcb->vmaw, bcb->dev_id) <= 0) {
-+ Error *err = NULL;
-+ if (vma_writer_close(bcb->vmaw, &err) != 0) {
-+ g_warning("vma_writer_close failed %s", error_get_pretty(err));
-+ }
-+ }
-+}
-+*/
-+
+#define BACKUP_SECTORS_PER_CLUSTER (VMA_CLUSTER_SIZE / BDRV_SECTOR_SIZE)
+
+static void coroutine_fn backup_run(void *opaque)
+
+ Coroutine *co = qemu_coroutine_create(backup_run);
+ qemu_coroutine_enter(co, job);
-+
-+ //BlockDriverState *target = NULL;
-+ //backup_start(bs, target, 0, MIRROR_SYNC_MODE_FULL,
-+ // BLOCKDEV_ON_ERROR_STOP, BLOCKDEV_ON_ERROR_STOP,
-+ // NULL, bcb, &errp);
-+
-+ //if (backup_job_create(bs, backup_dump_cb, backup_complete_cb,
-+ // bcb, 0) < 0) {
-+ // unlink(archivename);
-+ // g_error("backup_job_start failed");
-+ //} else {
-+ // backup_job_start(bs, false);
-+ // }
+ }
+
+ VmaStatus vmastat;
Index: new/vma.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ new/vma.h 2013-11-29 10:13:24.000000000 +0100
-@@ -0,0 +1,144 @@
++++ new/vma.h 2013-12-04 14:27:56.000000000 +0100
+@@ -0,0 +1,146 @@
+/*
+ * VMA: Virtual Machine Archive
+ *
+ uint32_t config_names[VMA_MAX_CONFIGS]; /* offset into blob_buffer table */
+ uint32_t config_data[VMA_MAX_CONFIGS]; /* offset into blob_buffer table */
+
++ uint32_t reserved1;
++
+ VmaDeviceInfoHeader dev_info[256];
+} VmaHeader;
+
+ Error **errp);
+
+#endif /* BACKUP_VMA_H */
+Index: new/Makefile.objs
+===================================================================
+--- new.orig/Makefile.objs 2013-12-04 12:07:18.000000000 +0100
++++ new/Makefile.objs 2013-12-04 12:07:25.000000000 +0100
+@@ -14,6 +14,7 @@
+ block-obj-y += block/
+ block-obj-y += qapi-types.o qapi-visit.o
+ block-obj-y += qemu-io-cmds.o
++block-obj-y += vma-writer.o
+
+ block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
+ block-obj-y += qemu-coroutine-sleep.o