Patchwork [1/5] migrate: add migration blockers

login
register
mail settings
Submitter Anthony Liguori
Date Nov. 14, 2011, 9:09 p.m.
Message ID <1321304987-23041-1-git-send-email-aliguori@us.ibm.com>
Download mbox | patch
Permalink /patch/125613/
State New
Headers show

Comments

Anthony Liguori - Nov. 14, 2011, 9:09 p.m.
This lets different subsystems register an Error that is thrown whenever
migration is attempted.  This works nicely because it gracefully supports
things like hotplug.

Right now, if multiple errors are registered, only one of them is reported.
I expect that for 1.1, we'll extend query-migrate to return all of the reasons
why migration is disabled at any given point in time.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 migration.c |   18 ++++++++++++++++++
 migration.h |   15 +++++++++++++++
 2 files changed, 33 insertions(+), 0 deletions(-)
Anthony Liguori - Nov. 14, 2011, 9:29 p.m.
This series allows live migration to work with image formats.  This series has
two parts.  The first part adds a new error infrastructure to migration which
allows for different subsystems (other than qdev) to block migration when
specific features are in use.

The second part adds block interfaces to flush metadata with image formats.

The migration error infrastructure is a no brainer for 1.0.  It significantly
improves the user experience and prevents a user from doing things that will
cause a VM to crash during migration.

I'm less comfortable with the block interface for flushing metadata for 1.0.
The code is completely isolated to the image formats and live migration.  It
should have no impact on normal use of an image format or live migration with
raw images.  That makes the risk for this very, very low.

Moreover, I'm sympathetic to the argument that this is a required feature for a
1.0 release.  Image formats are a fairly normal way to use QEMU and not
supporting live migration in this scenario means that live migration won't work
for a large portion of QEMU's users.
Anthony Liguori - Nov. 22, 2011, 12:21 a.m.
On 11/14/2011 03:09 PM, Anthony Liguori wrote:
> This lets different subsystems register an Error that is thrown whenever
> migration is attempted.  This works nicely because it gracefully supports
> things like hotplug.
>
> Right now, if multiple errors are registered, only one of them is reported.
> I expect that for 1.1, we'll extend query-migrate to return all of the reasons
> why migration is disabled at any given point in time.
>
> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>

Applied.

Regards,

Anthony Liguori

> ---
>   migration.c |   18 ++++++++++++++++++
>   migration.h |   15 +++++++++++++++
>   2 files changed, 33 insertions(+), 0 deletions(-)
>
> diff --git a/migration.c b/migration.c
> index 41c3c24..6764d3a 100644
> --- a/migration.c
> +++ b/migration.c
> @@ -398,6 +398,18 @@ static MigrationState *migrate_init(Monitor *mon, int detach, int blk, int inc)
>       return s;
>   }
>
> +static GSList *migration_blockers;
> +
> +void migrate_add_blocker(Error *reason)
> +{
> +    migration_blockers = g_slist_prepend(migration_blockers, reason);
> +}
> +
> +void migrate_del_blocker(Error *reason)
> +{
> +    migration_blockers = g_slist_remove(migration_blockers, reason);
> +}
> +
>   int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
>   {
>       MigrationState *s = migrate_get_current();
> @@ -417,6 +429,12 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
>           return -1;
>       }
>
> +    if (migration_blockers) {
> +        Error *err = migration_blockers->data;
> +        qerror_report_err(err);
> +        return -1;
> +    }
> +
>       s = migrate_init(mon, detach, blk, inc);
>
>       if (strstart(uri, "tcp:",&p)) {
> diff --git a/migration.h b/migration.h
> index 1b8ee58..0682179 100644
> --- a/migration.h
> +++ b/migration.h
> @@ -17,6 +17,7 @@
>   #include "qdict.h"
>   #include "qemu-common.h"
>   #include "notify.h"
> +#include "error.h"
>
>   typedef struct MigrationState MigrationState;
>
> @@ -89,4 +90,18 @@ int ram_load(QEMUFile *f, void *opaque, int version_id);
>
>   extern int incoming_expected;
>
> +/**
> + * @migrate_add_blocker - prevent migration from proceeding
> + *
> + * @reason - an error to be returned whenever migration is attempted
> + */
> +void migrate_add_blocker(Error *reason);
> +
> +/**
> + * @migrate_del_blocker - remove a blocking error from migration
> + *
> + * @reason - the error blocking migration
> + */
> +void migrate_del_blocker(Error *reason);
> +
>   #endif

Patch

diff --git a/migration.c b/migration.c
index 41c3c24..6764d3a 100644
--- a/migration.c
+++ b/migration.c
@@ -398,6 +398,18 @@  static MigrationState *migrate_init(Monitor *mon, int detach, int blk, int inc)
     return s;
 }
 
+static GSList *migration_blockers;
+
+void migrate_add_blocker(Error *reason)
+{
+    migration_blockers = g_slist_prepend(migration_blockers, reason);
+}
+
+void migrate_del_blocker(Error *reason)
+{
+    migration_blockers = g_slist_remove(migration_blockers, reason);
+}
+
 int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
 {
     MigrationState *s = migrate_get_current();
@@ -417,6 +429,12 @@  int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
         return -1;
     }
 
+    if (migration_blockers) {
+        Error *err = migration_blockers->data;
+        qerror_report_err(err);
+        return -1;
+    }
+
     s = migrate_init(mon, detach, blk, inc);
 
     if (strstart(uri, "tcp:", &p)) {
diff --git a/migration.h b/migration.h
index 1b8ee58..0682179 100644
--- a/migration.h
+++ b/migration.h
@@ -17,6 +17,7 @@ 
 #include "qdict.h"
 #include "qemu-common.h"
 #include "notify.h"
+#include "error.h"
 
 typedef struct MigrationState MigrationState;
 
@@ -89,4 +90,18 @@  int ram_load(QEMUFile *f, void *opaque, int version_id);
 
 extern int incoming_expected;
 
+/**
+ * @migrate_add_blocker - prevent migration from proceeding
+ *
+ * @reason - an error to be returned whenever migration is attempted
+ */
+void migrate_add_blocker(Error *reason);
+
+/**
+ * @migrate_del_blocker - remove a blocking error from migration
+ *
+ * @reason - the error blocking migration
+ */
+void migrate_del_blocker(Error *reason);
+
 #endif