Patchwork [1/4] migration: Create the pre migration flush hook infrastructure.

login
register
mail settings
Submitter Benoît Canet
Date April 11, 2013, 12:14 p.m.
Message ID <1365682468-12301-2-git-send-email-benoit@irqsave.net>
Download mbox | patch
Permalink /patch/235716/
State New
Headers show

Comments

Benoît Canet - April 11, 2013, 12:14 p.m.
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
Peter Maydell - April 11, 2013, 12:16 p.m.
On 11 April 2013 13:14, Benoît Canet <benoit@irqsave.net> wrote:
> --- /dev/null
> +++ b/include/migration/migration-flush-hooks.h
> @@ -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);

As this is a new public (ie exposed to the rest of QEMU) API
please could you provide documentation comments for these
functions?

thanks
-- PMM
Paolo Bonzini - April 11, 2013, 12:34 p.m.
Il 11/04/2013 14:14, Benoît Canet ha scritto:
> diff --git a/include/migration/migration-flush-hooks.h b/include/migration/migration-flush-hooks.h
> new file mode 100644
> index 0000000..be9e597
> --- /dev/null
> +++ b/include/migration/migration-flush-hooks.h
> @@ -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);

Note that the point where you execute this (do_vm_stop) is not just for
migration.

So, can you just use a VMState change notifier?

If not, please make this a Notifier instead of using your own data
structure.

Paolo

> +#endif

Patch

diff --git a/Makefile b/Makefile
index 80344d9..bb11da5 100644
--- a/Makefile
+++ b/Makefile
@@ -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
 
diff --git a/Makefile.objs b/Makefile.objs
index f99841c..707faa4 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -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
diff --git a/block.c b/block.c
index 0ae2e93..b8d8ccc 100644
--- a/block.c
+++ b/block.c
@@ -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);
 }
 
diff --git a/cpus.c b/cpus.c
index e919dd7..9beaebc 100644
--- a/cpus.c
+++ b/cpus.c
@@ -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);
     }
 }
diff --git a/include/migration/migration-flush-hooks.h b/include/migration/migration-flush-hooks.h
new file mode 100644
index 0000000..be9e597
--- /dev/null
+++ b/include/migration/migration-flush-hooks.h
@@ -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
diff --git a/migration-flush-hooks.c b/migration-flush-hooks.c
new file mode 100644
index 0000000..b8e1bf4
--- /dev/null
+++ b/migration-flush-hooks.c
@@ -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();
+    }
+}
diff --git a/vl.c b/vl.c
index e2c9706..b4fbcf7 100644
--- a/vl.c
+++ b/vl.c
@@ -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;