we use qemu-aio instead to avoid problems in bdrv_drain_all().
# also update debian/changelog
KVMVER=1.3
-KVMPKGREL=14
+KVMPKGREL=15
KVMPACKAGE=pve-qemu-kvm
KVMDIR=qemu-kvm
+pve-qemu-kvm (1.3-15) unstable; urgency=low
+
+ * update backup patches - removed threaded code - we use qemu-aio
+ instead to avoid problems in bdrv_drain_all().
+
+ -- Proxmox Support Team <support@proxmox.com> Tue, 22 Jan 2013 10:37:59 +0100
+
pve-qemu-kvm (1.3-14) unstable; urgency=low
* update backup patches
From f4a34368cdc254ea7602c5913c50506f61e7652e Mon Sep 17 00:00:00 2001
From: Dietmar Maurer <dietmar@proxmox.com>
Date: Tue, 13 Nov 2012 09:24:50 +0100
-Subject: [PATCH v3 1/7] RFC: Efficient VM backup for qemu
+Subject: [PATCH v3 1/6] RFC: Efficient VM backup for qemu
This series provides a way to efficiently backup VMs.
-From 577b000e947d817cf4e0189615c0d0257cb20259 Mon Sep 17 00:00:00 2001
+From 4374768a3a4d92f0ac0a77688cb7f65ff108ef83 Mon Sep 17 00:00:00 2001
From: Dietmar Maurer <dietmar@proxmox.com>
Date: Tue, 13 Nov 2012 10:03:52 +0100
-Subject: [PATCH v3 2/7] add basic backup support to block driver
+Subject: [PATCH v3 2/6] add basic backup support to block driver
Function backup_job_create() creates a block job to backup a block device.
The coroutine is started with backup_job_start().
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---
Makefile.objs | 1 +
- backup.c | 308 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ backup.c | 334 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
backup.h | 32 ++++++
- block.c | 71 ++++++++++++-
+ block.c | 71 +++++++++++-
block.h | 2 +
blockjob.h | 10 ++
- 6 files changed, 418 insertions(+), 6 deletions(-)
+ 6 files changed, 444 insertions(+), 6 deletions(-)
create mode 100644 backup.c
create mode 100644 backup.h
block-obj-$(CONFIG_WIN32) += event_notifier-win32.o aio-win32.o
diff --git a/backup.c b/backup.c
new file mode 100644
-index 0000000..2c13e21
+index 0000000..af511c7
--- /dev/null
+++ b/backup.c
-@@ -0,0 +1,308 @@
+@@ -0,0 +1,334 @@
+/*
+ * QEMU backup
+ *
+#include "block.h"
+#include "block_int.h"
+#include "blockjob.h"
++#include "qemu/ratelimit.h"
+#include "backup.h"
+
+#define DEBUG_BACKUP 0
+
+
+#define BITS_PER_LONG (sizeof(unsigned long) * 8)
++#define SLICE_TIME 100000000ULL /* ns */
+
+typedef struct BackupBlockJob {
+ BlockJob common;
++ RateLimit limit;
++ uint64_t sectors_read;
+ unsigned long *bitmap;
+ int bitmap_size;
+ BackupDumpFunc *backup_dump_cb;
+ ret = drv->bdrv_co_readv(bs, start * BACKUP_BLOCKS_PER_CLUSTER,
+ BACKUP_BLOCKS_PER_CLUSTER,
+ &bounce_qiov);
++
++ job->sectors_read += BACKUP_BLOCKS_PER_CLUSTER;
++
+ if (ret < 0) {
+ DPRINTF("brdv_co_backup_cow bdrv_read C%zd failed\n", start);
+ goto out;
+ return backup_do_cow(bs, sector_num, nb_sectors);
+}
+
++static void backup_set_speed(BlockJob *job, int64_t speed, Error **errp)
++{
++ BackupBlockJob *s = container_of(job, BackupBlockJob, common);
++
++ if (speed < 0) {
++ error_set(errp, QERR_INVALID_PARAMETER, "speed");
++ return;
++ }
++ ratelimit_set_speed(&s->limit, speed / BDRV_SECTOR_SIZE, SLICE_TIME);
++}
+
+static BlockJobType backup_job_type = {
+ .instance_size = sizeof(BackupBlockJob),
+ .before_read = backup_before_read,
+ .before_write = backup_before_write,
-+ .job_type = "backup",
++ .job_type = "backup",
++ .set_speed = backup_set_speed,
+};
+
+static void coroutine_fn backup_run(void *opaque)
+ break;
+ }
+
-+ if (backup_get_bitmap(job, start)) {
-+ continue; /* already copied */
-+ }
-+
+ /* we need to yield so that qemu_aio_flush() returns.
+ * (without, VM does not reboot)
-+ * todo: can we avoid that?
+ * Note: use 1000 instead of 0 (0 priorize this task too much)
+ */
-+ block_job_sleep_ns(&job->common, rt_clock, 1000);
++ if (job->common.speed) {
++ uint64_t delay_ns = ratelimit_calculate_delay(
++ &job->limit, job->sectors_read);
++ job->sectors_read = 0;
++ block_job_sleep_ns(&job->common, rt_clock, delay_ns);
++ } else {
++ block_job_sleep_ns(&job->common, rt_clock, 1000);
++ }
++
+ if (block_job_is_cancelled(&job->common)) {
+ ret = -1;
+ break;
+ }
++
++ if (backup_get_bitmap(job, start)) {
++ continue; /* already copied */
++ }
++
+ DPRINTF("backup_run loop C%zd\n", start);
+
+ /**
+int
+backup_job_create(BlockDriverState *bs, BackupDumpFunc *backup_dump_cb,
+ BlockDriverCompletionFunc *backup_complete_cb,
-+ void *opaque)
++ void *opaque, int64_t speed)
+{
+ assert(bs);
+ assert(backup_dump_cb);
+ DPRINTF("bdrv_backup_init %s\n", bdrv_get_device_name(bs));
+
+ Error *errp;
-+ BackupBlockJob *job = block_job_create(&backup_job_type, bs, 0,
++ BackupBlockJob *job = block_job_create(&backup_job_type, bs, speed,
+ backup_job_cleanup_cb, bs, &errp);
+
+ job->common.cluster_size = BACKUP_CLUSTER_SIZE;
+}
diff --git a/backup.h b/backup.h
new file mode 100644
-index 0000000..87b9942
+index 0000000..a5f85e6
--- /dev/null
+++ b/backup.h
@@ -0,0 +1,32 @@
+
+int backup_job_create(BlockDriverState *bs, BackupDumpFunc *backup_dump_cb,
+ BlockDriverCompletionFunc *backup_complete_cb,
-+ void *opaque);
++ void *opaque, int64_t speed);
+
+#endif /* QEMU_BACKUP_H */
diff --git a/block.c b/block.c
-From 7d2906f7da677d2f2533d1455453dc328cb65590 Mon Sep 17 00:00:00 2001
+From b9c06929cb9e9583b002fa6de76ad3c318c89f35 Mon Sep 17 00:00:00 2001
From: Dietmar Maurer <dietmar@proxmox.com>
Date: Tue, 13 Nov 2012 11:27:56 +0100
-Subject: [PATCH v3 3/7] add backup related monitor commands
+Subject: [PATCH v3 3/6] add backup related monitor commands
We use a generic BackupDriver struct to encapsulate all archive format
related function.
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---
- backup.h | 13 ++
- blockdev.c | 410 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ backup.h | 12 ++
+ blockdev.c | 412 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
hmp-commands.hx | 31 ++++
- hmp.c | 63 +++++++++
+ hmp.c | 63 ++++++++
hmp.h | 3 +
monitor.c | 7 +
qapi-schema.json | 91 ++++++++++++
qmp-commands.hx | 27 ++++
- 8 files changed, 645 insertions(+), 0 deletions(-)
+ 8 files changed, 646 insertions(+), 0 deletions(-)
diff --git a/backup.h b/backup.h
-index 87b9942..c6e5d3c 100644
+index a5f85e6..c9c20c9 100644
--- a/backup.h
+++ b/backup.h
-@@ -29,4 +29,17 @@ int backup_job_create(BlockDriverState *bs, BackupDumpFunc *backup_dump_cb,
+@@ -29,4 +29,16 @@ int backup_job_create(BlockDriverState *bs, BackupDumpFunc *backup_dump_cb,
BlockDriverCompletionFunc *backup_complete_cb,
- void *opaque);
+ void *opaque, int64_t speed);
+typedef struct BackupDriver {
+ const char *format;
-+ void *(*open_cb)(const char *filename, uuid_t uuid, int64_t speed,
-+ Error **errp);
++ void *(*open_cb)(const char *filename, uuid_t uuid, Error **errp);
+ int (*close_cb)(void *opaque, Error **errp);
+ int (*register_config_cb)(void *opaque, const char *name, gpointer data,
+ size_t data_len);
+
#endif /* QEMU_BACKUP_H */
diff --git a/blockdev.c b/blockdev.c
-index e73fd6e..37edb75 100644
+index e73fd6e..bd2198e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -20,6 +20,7 @@
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
-@@ -1321,6 +1322,415 @@ void qmp_drive_mirror(const char *device, const char *target,
+@@ -1321,6 +1322,417 @@ void qmp_drive_mirror(const char *device, const char *target,
drive_get_ref(drive_get_by_blockdev(bs));
}
+ Error *error;
+ uuid_t uuid;
+ char uuid_str[37];
++ int64_t speed;
+ time_t start_time;
+ time_t end_time;
+ char *backupfile;
+ l = g_list_next(l);
+
+ if (backup_job_create(bcb->bs, backup_dump_cb, backup_complete_cb,
-+ bcb) != 0) {
++ bcb, backup_state.speed) != 0) {
+ error_setg(&backup_state.error, "backup_job_create failed");
+ backup_cancel();
+ return;
+
+ uuid_generate(uuid);
+
-+ writer = driver->open_cb(backupfile, uuid, has_speed ? speed : 0,
-+ &local_err);
++ writer = driver->open_cb(backupfile, uuid, &local_err);
+ if (!writer) {
+ if (error_is_set(&local_err)) {
+ error_propagate(errp, local_err);
+
+ backup_state.driver = driver;
+
++ backup_state.speed = (has_speed && speed > 0) ? speed : 0;
++
+ backup_state.start_time = time(NULL);
+ backup_state.end_time = 0;
+
-From 69a3f26bdbe445ce01f096b9d5e1aaf45ad98b81 Mon Sep 17 00:00:00 2001
+From bb18514bdcb93d9b2906bfb2a8aa9fd6c2265710 Mon Sep 17 00:00:00 2001
From: Dietmar Maurer <dietmar@proxmox.com>
Date: Tue, 13 Nov 2012 11:11:38 +0100
-Subject: [PATCH v3 4/7] introduce new vma archive format
+Subject: [PATCH v3 4/6] introduce new vma archive format
This is a very simple archive format, see docs/specs/vma_spec.txt
Makefile.objs | 2 +-
blockdev.c | 6 +-
docs/specs/vma_spec.txt | 24 ++
- vma-reader.c | 801 ++++++++++++++++++++++++++++++++++++++++
- vma-writer.c | 931 +++++++++++++++++++++++++++++++++++++++++++++++
- vma.c | 561 ++++++++++++++++++++++++++++
- vma.h | 146 ++++++++
- 8 files changed, 2470 insertions(+), 4 deletions(-)
+ vma-reader.c | 801 +++++++++++++++++++++++++++++++++++++++++
+ vma-writer.c | 914 +++++++++++++++++++++++++++++++++++++++++++++++
+ vma.c | 561 +++++++++++++++++++++++++++++
+ vma.h | 145 ++++++++
+ 8 files changed, 2452 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-$(CONFIG_POSIX) += event_notifier-posix.o aio-posix.o
block-obj-$(CONFIG_WIN32) += event_notifier-win32.o aio-win32.o
diff --git a/blockdev.c b/blockdev.c
-index 37edb75..0632c57 100644
+index bd2198e..99f3e02 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -21,6 +21,7 @@
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
-@@ -1507,10 +1508,11 @@ char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
+@@ -1508,10 +1509,11 @@ char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
/* Todo: try to auto-detect format based on file name */
format = has_format ? format : BACKUP_FORMAT_VMA;
+
diff --git a/vma-writer.c b/vma-writer.c
new file mode 100644
-index 0000000..688af4b
+index 0000000..3f5bbd5
--- /dev/null
+++ b/vma-writer.c
-@@ -0,0 +1,931 @@
+@@ -0,0 +1,914 @@
+/*
+ * VMA: Virtual Machine Archive
+ *
+#include "qemu_socket.h"
+#include "qemu-coroutine.h"
+#include "qemu-aio.h"
-+#include "qemu/ratelimit.h"
+#include "vma.h"
+#include "block.h"
+#include "monitor.h"
+ CoMutex writer_lock;
+ CoMutex flush_lock;
+ Coroutine *co_writer;
-+ RateLimit limit;
+
+ /* drive informations */
+ VmaStreamInfo stream_info[256];
+ return bytes;
+}
+
-+VmaWriter *vma_writer_create(const char *filename, uuid_t uuid, int64_t speed,
-+ Error **errp)
++VmaWriter *vma_writer_create(const char *filename, uuid_t uuid, Error **errp)
+{
+ const char *p;
+
+
+ uuid_copy(vmaw->uuid, uuid);
+
-+ if (speed <= 0) {
-+ speed = 10*1024*1024*1024LLU; /* default 10GB/s */
-+ }
-+
-+ ratelimit_set_speed(&vmaw->limit, speed, 100000000ULL /* 0.1 sec */);
-+
+ return vmaw;
+
+err:
+
+ qemu_co_mutex_lock(&vmaw->flush_lock);
+
-+ /* rate limit */
-+ uint64_t delay_ns = ratelimit_calculate_delay(&vmaw->limit, bytes);
-+ if (delay_ns) {
-+ DPRINTF("DELAY %zd\n", delay_ns);
-+ co_sleep_ns(rt_clock, delay_ns);
-+ }
-+
+ /* wait until buffer is available */
+ while (vmaw->outbuf_count >= (VMA_BLOCKS_PER_EXTENT - 1)) {
+ ret = vma_writer_flush(vmaw);
+ return vma_writer_add_config(vmaw, name, data, data_len);
+}
+
-+static void *vma_open_cb(const char *filename, uuid_t uuid, int64_t speed,
-+ Error **errp)
++static void *vma_open_cb(const char *filename, uuid_t uuid, Error **errp)
+{
-+ return vma_writer_create(filename, uuid, speed, errp);
++ return vma_writer_create(filename, uuid, errp);
+}
+
+const BackupDriver backup_vma_driver = {
+
diff --git a/vma.c b/vma.c
new file mode 100644
-index 0000000..9b47b92
+index 0000000..5d13906
--- /dev/null
+++ b/vma.c
@@ -0,0 +1,561 @@
+ uuid_generate(uuid);
+
+ Error *local_err = NULL;
-+ VmaWriter *vmaw = vma_writer_create(archivename, uuid, 0, &local_err);
++ VmaWriter *vmaw = vma_writer_create(archivename, uuid, &local_err);
+
+ if (vmaw == NULL) {
+ g_error("%s", error_get_pretty(local_err));
+ bcb->dev_id = dev_id;
+
+ if (backup_job_create(bs, backup_dump_cb, backup_complete_cb,
-+ bcb) < 0) {
++ bcb, 0) < 0) {
+ unlink(archivename);
+ g_error("backup_job_start failed");
+ } else {
+}
diff --git a/vma.h b/vma.h
new file mode 100644
-index 0000000..689e639
+index 0000000..76d0dc8
--- /dev/null
+++ b/vma.h
-@@ -0,0 +1,146 @@
+@@ -0,0 +1,145 @@
+/*
+ * VMA: Virtual Machine Archive
+ *
+
+extern const BackupDriver backup_vma_driver;
+
-+VmaWriter *vma_writer_create(const char *filename, uuid_t uuid, int64_t speed,
-+ Error **errp);
++VmaWriter *vma_writer_create(const char *filename, uuid_t uuid, Error **errp);
+int vma_writer_close(VmaWriter *vmaw, Error **errp);
+void vma_writer_destroy(VmaWriter *vmaw);
+int vma_writer_add_config(VmaWriter *vmaw, const char *name, gpointer data,
-From 6df0d37601a8dd765bb30ae456e194155a85d0a4 Mon Sep 17 00:00:00 2001
+From 59bc6b7cd95ff518bb415ae49bc3078c145003f3 Mon Sep 17 00:00:00 2001
From: Dietmar Maurer <dietmar@proxmox.com>
Date: Wed, 14 Nov 2012 09:57:04 +0100
-Subject: [PATCH v3 5/7] add regression tests for backup
+Subject: [PATCH v3 5/6] add regression tests for backup
Simple regression tests using vma-reader and vma-writer.
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---
tests/Makefile | 11 +-
- tests/backup-test.c | 515 +++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 524 insertions(+), 2 deletions(-)
+ tests/backup-test.c | 516 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 525 insertions(+), 2 deletions(-)
create mode 100644 tests/backup-test.c
diff --git a/tests/Makefile b/tests/Makefile
-include $(wildcard tests/*.d)
diff --git a/tests/backup-test.c b/tests/backup-test.c
new file mode 100644
-index 0000000..813590e
+index 0000000..d816ffa
--- /dev/null
+++ b/tests/backup-test.c
-@@ -0,0 +1,515 @@
+@@ -0,0 +1,516 @@
+/*
+ * QEMU backup test suit
+ *
+
+ unlink(TEST_VMA_NAME);
+
-+ VmaWriter *vmaw = vma_writer_create(TEST_VMA_NAME, uuid, speed, &err);
++ VmaWriter *vmaw = vma_writer_create(TEST_VMA_NAME, uuid, &err);
+ if (!vmaw) {
+ g_error("%s", error_get_pretty(err));
+ }
+ bcb.vmaw = vmaw;
+ bcb.dev_id = vma_writer_register_stream(vmaw, bdrv_get_device_name(bs),
+ bdrv_getlength(bs));
-+ if (backup_job_create(bs, backup_dump_cb, backup_complete_cb, &bcb) < 0) {
++ if (backup_job_create(bs, backup_dump_cb, backup_complete_cb, &bcb,
++ speed) < 0) {
+ g_error("backup_job_create failed");
+ } else {
+ backup_job_start(bs);
-From 4f629e5e088e63ea8e73d69e4e4beabc251d31a1 Mon Sep 17 00:00:00 2001
+From 9901e8c82fb25ce5ce82c9e18276d8190bb4aca7 Mon Sep 17 00:00:00 2001
From: Dietmar Maurer <dietmar@proxmox.com>
Date: Thu, 29 Nov 2012 10:46:49 +0100
-Subject: [PATCH v3 6/7] add vm state to backups
+Subject: [PATCH v3 6/6] add vm state to backups
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
3 files changed, 200 insertions(+), 5 deletions(-)
diff --git a/blockdev.c b/blockdev.c
-index 0632c57..f19eb02 100644
+index 99f3e02..cb9293b 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -22,6 +22,8 @@
static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
-@@ -1340,6 +1342,10 @@ static struct GenericBackupState {
+@@ -1341,6 +1343,10 @@ static struct GenericBackupState {
size_t total;
size_t transferred;
size_t zero_bytes;
} backup_state;
typedef struct BackupCB {
-@@ -1493,10 +1499,170 @@ static void backup_start_jobs(void)
+@@ -1494,10 +1500,170 @@ static void backup_start_jobs(void)
backup_run_next_job();
}
{
BlockDriverState *bs;
Error *local_err = NULL;
-@@ -1505,6 +1671,8 @@ char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
+@@ -1506,6 +1672,8 @@ char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
gchar **devs = NULL;
GList *bcblist = NULL;
l = bcblist;
while (l) {
BackupCB *bcb = l->data;
-@@ -1649,6 +1833,9 @@ char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
+@@ -1651,6 +1835,9 @@ char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
backup_state.total = total;
backup_state.transferred = 0;
backup_state.zero_bytes = 0;
/* Grab a reference so hotplug does not delete the
* BlockDriverState from underneath us.
-@@ -1660,7 +1847,12 @@ char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
+@@ -1662,7 +1849,12 @@ char *qmp_backup(const char *backupfile, bool has_format, BackupFormat format,
drive_get_ref(drive_get_by_blockdev(bcb->bs));
}
0004-introduce-new-vma-archive-format.patch
0005-add-regression-tests-for-backup.patch
0006-add-vm-state-to-backups.patch
-0007-use-extra-thread-for-vma-writer.patch
virtio-balloon-drop-old-stats-code.patch
virtio-balloon-re-enable-balloon-stats.patch
virtio-balloon-document-stats.patch
always-update-expected-downtime.patch
e1000-discard-oversized-packets.patch
fix-aio-poll.patch
-