@@ -170,9 +170,9 @@ libqemuutil.a: $(util-obj-y)
qemu-img.o: qemu-img-cmds.h
-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 cmd.o $(block-obj-y) libqemuutil.a libqemustub.a
+qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a migration-flush-hooks.o
+qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a migration-flush-hooks.o
+qemu-io$(EXESUF): qemu-io.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a migration-flush-hooks.o
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
@@ -57,7 +57,7 @@ common-obj-$(CONFIG_POSIX) += os-posix.o
common-obj-$(CONFIG_LINUX) += fsdev/
-common-obj-y += migration.o migration-tcp.o
+common-obj-y += migration.o migration-tcp.o migration-flush-hooks.o
common-obj-y += qemu-char.o #aio.o
common-obj-y += block-migration.o
common-obj-y += page_cache.o xbzrle.o
@@ -34,6 +34,7 @@
#include "block/coroutine.h"
#include "qmp-commands.h"
#include "qemu/timer.h"
+#include "migration/migration-flush-hooks.h"
#ifdef CONFIG_BSD
#include <sys/types.h>
@@ -4131,8 +4132,15 @@ BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
return &acb->common;
}
+static void bdrv_migration_flush_hook(void)
+{
+ bdrv_drain_all();
+ bdrv_flush_all();
+}
+
void bdrv_init(void)
{
+ register_migration_flush_hook(bdrv_migration_flush_hook);
module_call_init(MODULE_INIT_BLOCK);
}
@@ -38,6 +38,8 @@
#include "qemu/main-loop.h"
#include "qemu/bitmap.h"
+#include "migration/migration-flush-hooks.h"
+
#ifndef _WIN32
#include "qemu/compatfd.h"
#endif
@@ -444,8 +446,8 @@ static void do_vm_stop(RunState state)
pause_all_vcpus();
runstate_set(state);
vm_state_notify(0, state);
- bdrv_drain_all();
- bdrv_flush_all();
+ /* Here we will flush remaining ios */
+ exec_migration_flush_hooks();
monitor_protocol_event(QEVENT_STOP, NULL);
}
}
new file mode 100644
@@ -0,0 +1,30 @@
+/*
+ * QEMU live pre migration flush hooks
+ *
+ * Copyright Nodalink, SARL. 2013
+ *
+ * Authors:
+ * Benoît Canet <benoit@irqsave.net>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_MIGRATION_FLUSH_HOOKS_H
+#define QEMU_MIGRATION_FLUSH_HOOKS_H
+
+#include "qemu/queue.h"
+
+typedef struct MigrationFlushHookEntry {
+ void (*flush_hook)(void);
+ QTAILQ_ENTRY(MigrationFlushHookEntry) node;
+} MigrationFlushHookEntry;
+
+void init_migration_flush_hooks(void);
+
+void register_migration_flush_hook(void (*fn)(void));
+
+void exec_migration_flush_hooks(void);
+
+#endif
new file mode 100644
@@ -0,0 +1,62 @@
+/*
+ * QEMU live pre migration flush hooks
+ *
+ * Copyright Nodalink, SARL. 2013
+ *
+ * Modeled after utils/modules.c
+ *
+ * Authors:
+ * Benoît Canet <benoit@irqsave.net>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * The purpose of this file is to allow various part of QEMU to register hooks
+ * used to flush ios after vcpus are paused on live migration preparation.
+ *
+ */
+#include <glib.h>
+#include "migration/migration-flush-hooks.h"
+
+
+typedef QTAILQ_HEAD(, MigrationFlushHookEntry) FlushHookList;
+
+/* the static NULL pointer will disable the feature if not initialized */
+static FlushHookList *flush_hooks;
+
+void init_migration_flush_hooks(void)
+{
+ if (flush_hooks) {
+ return;
+ }
+
+ flush_hooks = g_new0(FlushHookList, 1);
+ QTAILQ_INIT(flush_hooks);
+}
+
+void register_migration_flush_hook(void (*fn)(void))
+{
+ MigrationFlushHookEntry *e;
+
+ if (!flush_hooks) {
+ return;
+ }
+
+ e = g_new0(MigrationFlushHookEntry, 1);
+ e->flush_hook = fn;
+
+ QTAILQ_INSERT_TAIL(flush_hooks, e, node);
+}
+
+void exec_migration_flush_hooks(void)
+{
+ MigrationFlushHookEntry *e;
+
+ if (!flush_hooks) {
+ return;
+ }
+
+ QTAILQ_FOREACH(e, flush_hooks, node) {
+ e->flush_hook();
+ }
+}
@@ -139,6 +139,7 @@ int main(int argc, char **argv)
#include "sysemu/blockdev.h"
#include "hw/block-common.h"
#include "migration/block.h"
+#include "migration/migration-flush-hooks.h"
#include "tpm/tpm.h"
#include "sysemu/dma.h"
#include "audio/audio.h"
@@ -2941,6 +2942,11 @@ int main(int argc, char **argv, char **envp)
nb_numa_nodes = 0;
nb_nics = 0;
+ /* Initialize the list containing pre migration flush hooks before
+ * registeriring the first hook in bdrv_init().
+ */
+ init_migration_flush_hooks();
+
bdrv_init_with_whitelist();
autostart= 1;
This patch will allow the block layer and virtio-9p to cleanly register io flush hooks to be executed by cpus.c. Signed-off-by: Benoit Canet <benoit@irqsave.net> --- Makefile | 6 +-- Makefile.objs | 2 +- block.c | 8 ++++ cpus.c | 6 ++- include/migration/migration-flush-hooks.h | 30 ++++++++++++++ migration-flush-hooks.c | 62 +++++++++++++++++++++++++++++ vl.c | 6 +++ 7 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 include/migration/migration-flush-hooks.h create mode 100644 migration-flush-hooks.c