--- /dev/null
+run vma_writer_close_stream inside coroutine
+
+Newer qemu (> 2.2.0-rc2) runs pvebackup_complete_cb from main loop,
+
+But vma_writer_close_stream triggers an async write (flush), which uses qemu_coroutine_yield(). This only works if called from a coroutine.
+
+
+Index: new/blockdev.c
+===================================================================
+--- new.orig/blockdev.c 2014-11-20 12:17:17.000000000 +0100
++++ new/blockdev.c 2014-11-20 12:17:23.000000000 +0100
+@@ -2059,6 +2059,13 @@
+ }
+ }
+
++static void coroutine_fn backup_close_vma_stream(void *opaque)
++{
++ PVEBackupDevInfo *di = opaque;
++
++ vma_writer_close_stream(backup_state.vmaw, di->dev_id);
++}
++
+ static void pvebackup_complete_cb(void *opaque, int ret)
+ {
+ PVEBackupDevInfo *di = opaque;
+@@ -2076,7 +2083,8 @@
+ di->target = NULL;
+
+ if (backup_state.vmaw) {
+- vma_writer_close_stream(backup_state.vmaw, di->dev_id);
++ Coroutine *co = qemu_coroutine_create(backup_close_vma_stream);
++ qemu_coroutine_enter(co, di);
+ }
+
+ block_job_cb(bs, ret);
+Index: new/vma-writer.c
+===================================================================
+--- new.orig/vma-writer.c 2014-11-20 12:17:17.000000000 +0100
++++ new/vma-writer.c 2014-11-20 12:17:23.000000000 +0100
+@@ -706,6 +706,10 @@
+
+ int i;
+
++ while (vmaw->co_writer) {
++ aio_poll(qemu_get_aio_context(), true);
++ }
++
+ assert(vmaw->co_writer == NULL);
+
+ if (vmaw->cmd) {
Index: new/vma-reader.c
===================================================================
---- new.orig/vma-reader.c 2014-11-20 07:34:34.000000000 +0100
-+++ new/vma-reader.c 2014-11-20 07:54:47.000000000 +0100
+--- new.orig/vma-reader.c 2014-11-20 12:17:11.000000000 +0100
++++ new/vma-reader.c 2014-11-20 12:17:39.000000000 +0100
@@ -334,11 +334,6 @@
}
}
return ret;
Index: new/vma-writer.c
===================================================================
---- new.orig/vma-writer.c 2014-11-20 07:49:23.000000000 +0100
-+++ new/vma-writer.c 2014-11-20 07:54:47.000000000 +0100
+--- new.orig/vma-writer.c 2014-11-20 12:17:23.000000000 +0100
++++ new/vma-writer.c 2014-11-20 12:17:39.000000000 +0100
@@ -258,7 +258,7 @@
}
return open_drives;
Index: new/vma.c
===================================================================
---- new.orig/vma.c 2014-11-20 07:34:32.000000000 +0100
-+++ new/vma.c 2014-11-20 07:54:47.000000000 +0100
+--- new.orig/vma.c 2014-11-20 12:17:11.000000000 +0100
++++ new/vma.c 2014-11-20 12:17:39.000000000 +0100
@@ -33,7 +33,7 @@
"\n"
"vma list <filename>\n"
BlockDriver *drv = NULL;
Error *errp = NULL;
-@@ -550,37 +562,42 @@
+@@ -546,37 +558,42 @@
int percent = 0;
int last_percent = -1;
bdrv_drain_all();
Index: new/vma.h
===================================================================
---- new.orig/vma.h 2014-11-20 07:49:17.000000000 +0100
-+++ new/vma.h 2014-11-20 07:54:47.000000000 +0100
+--- new.orig/vma.h 2014-11-20 12:17:11.000000000 +0100
++++ new/vma.h 2014-11-20 12:17:39.000000000 +0100
@@ -128,6 +128,7 @@
size_t *zero_bytes);
backup-do-not-return-errors-in-dump-callback.patch
backup-vma-correctly-propagate-error.patch
backup-vma-remove-async-queue.patch
+backup-run-flush-inside-coroutine.patch
internal-snapshot-async.patch
disable-efi-enable-pxe-roms.patch
backup-vma-allow-empty-backups.patch