[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH/RFC] Introduce VIR_MIGRATE_FORCE flag to allow for risky migration



Hi,
Migration will be disallowed when the vm uses host devices or has
snapshots (qemuMigrationIsAllowed)[1]. Would it make sense to introduce
a VIR_MIGRATE_FORCE similar to VIR_REVERT_FORCE here?  We could then
introduce error codes similar to the snapshot case
(VIR_ERR_MIGRATE_RISKY).

This path is just to illustrate the idea not to be applied as is.
Cheers,
 -- Guido

[1] Hopefully we can make migration with snapshots safe in the future by
transfering the metadata. A current hack around is to put this onto
shared storage and reread it on the destination side after migration.

>From 4628166c7cbb247da8726248c7e54b265da99a7d Mon Sep 17 00:00:00 2001
From: Guido Guenther <agx sigxcpu org>
Date: Thu, 13 Oct 2011 12:05:08 +0200
Subject: [PATCH] Introduce VIR_MIGRATE_FORCE flag to allow for risky
 migrations

Change errors indicating risky migration to VIR_ERR_MIGRATE_RISKY.
---
 include/libvirt/libvirt.h.in |    3 ++-
 include/libvirt/virterror.h  |    2 ++
 src/qemu/qemu_driver.c       |   10 +++++-----
 src/qemu/qemu_migration.c    |   38 ++++++++++++++++++++++++--------------
 src/qemu/qemu_migration.h    |   13 +++++++++----
 src/util/virterror.c         |    6 ++++++
 6 files changed, 48 insertions(+), 24 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 361881a..1f147f1 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -767,7 +767,8 @@ typedef enum {
     VIR_MIGRATE_CHANGE_PROTECTION = (1 << 8), /* protect for changing domain configuration through the
                                                * whole migration process; this will be used automatically
                                                * when supported */
-
+    VIR_MIGRATE_FORCE             = (1 << 9), /* Force migration even when we have host devices in use
+                                                 or have snapshotes */
 } virDomainMigrateFlags;
 
 /* Domain migration. */
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index a8549b7..cc09ea0 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -240,6 +240,8 @@ typedef enum {
     VIR_ERR_STORAGE_POOL_BUILT = 76,	/* storage pool already built */
     VIR_ERR_SNAPSHOT_REVERT_RISKY = 77,	/* force was not requested for a
                                            risky domain snapshot revert */
+    VIR_ERR_MIGRATE_RISKY = 78,         /* force was not requested for a
+                                           risky domain migration */
 } virErrorNumber;
 
 /**
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6b65716..5e5214d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7881,7 +7881,7 @@ qemudDomainMigratePrepareTunnel(virConnectPtr dconn,
 
     ret = qemuMigrationPrepareTunnel(driver, dconn,
                                      NULL, 0, NULL, NULL, /* No cookies in v2 */
-                                     st, dname, dom_xml);
+                                     st, dname, dom_xml, flags);
 
 cleanup:
     qemuDriverUnlock(driver);
@@ -7941,7 +7941,7 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
     ret = qemuMigrationPrepareDirect(driver, dconn,
                                      NULL, 0, NULL, NULL, /* No cookies */
                                      uri_in, uri_out,
-                                     dname, dom_xml);
+                                     dname, dom_xml, flags);
 
 cleanup:
     qemuDriverUnlock(driver);
@@ -8094,7 +8094,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
         goto endjob;
 
     if (!(xml = qemuMigrationBegin(driver, vm, xmlin, dname,
-                                   cookieout, cookieoutlen)))
+                                   cookieout, cookieoutlen, flags)))
         goto endjob;
 
     if ((flags & VIR_MIGRATE_CHANGE_PROTECTION)) {
@@ -8171,7 +8171,7 @@ qemuDomainMigratePrepare3(virConnectPtr dconn,
                                      cookiein, cookieinlen,
                                      cookieout, cookieoutlen,
                                      uri_in, uri_out,
-                                     dname, dom_xml);
+                                     dname, dom_xml, flags);
 
 cleanup:
     qemuDriverUnlock(driver);
@@ -8216,7 +8216,7 @@ qemuDomainMigratePrepareTunnel3(virConnectPtr dconn,
     ret = qemuMigrationPrepareTunnel(driver, dconn,
                                      cookiein, cookieinlen,
                                      cookieout, cookieoutlen,
-                                     st, dname, dom_xml);
+                                     st, dname, dom_xml, flags);
     qemuDriverUnlock(driver);
 
 cleanup:
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index decb0f2..3263c2f 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -788,18 +788,24 @@ error:
  * the fact that older servers did not do checks on the source. */
 static bool
 qemuMigrationIsAllowed(struct qemud_driver *driver, virDomainObjPtr vm,
-                       virDomainDefPtr def)
+                       virDomainDefPtr def, int flags)
 {
     int nsnapshots;
 
+    /* FIXME: there are different kinds of risk (a missing host device
+       might break the vm entirely while missing snapshots will not */
+    if (flags & VIR_MIGRATE_FORCE) {
+        return true;
+    }
+
     if (vm) {
         if (qemuProcessAutoDestroyActive(driver, vm)) {
-            qemuReportError(VIR_ERR_OPERATION_INVALID,
+            qemuReportError(VIR_ERR_MIGRATE_RISKY,
                             "%s", _("domain is marked for auto destroy"));
             return false;
         }
         if ((nsnapshots = virDomainSnapshotObjListNum(&vm->snapshots, 0))) {
-            qemuReportError(VIR_ERR_OPERATION_INVALID,
+            qemuReportError(VIR_ERR_MIGRATE_RISKY,
                             _("cannot migrate domain with %d snapshots"),
                             nsnapshots);
             return false;
@@ -808,7 +814,7 @@ qemuMigrationIsAllowed(struct qemud_driver *driver, virDomainObjPtr vm,
         def = vm->def;
     }
     if (def->nhostdevs > 0) {
-        qemuReportError(VIR_ERR_OPERATION_INVALID,
+        qemuReportError(VIR_ERR_MIGRATE_RISKY,
             "%s", _("Domain with assigned host devices cannot be migrated"));
         return false;
     }
@@ -1002,7 +1008,8 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
                          const char *xmlin,
                          const char *dname,
                          char **cookieout,
-                         int *cookieoutlen)
+                         int *cookieoutlen,
+                         unsigned long flags)
 {
     char *rv = NULL;
     qemuMigrationCookiePtr mig = NULL;
@@ -1021,7 +1028,7 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
     if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_OUT)
         qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_BEGIN3);
 
-    if (!qemuMigrationIsAllowed(driver, vm, NULL))
+    if (!qemuMigrationIsAllowed(driver, vm, NULL, flags))
         goto cleanup;
 
     if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0)))
@@ -1078,7 +1085,8 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
                         const char *dname,
                         const char *dom_xml,
                         const char *migrateFrom,
-                        virStreamPtr st)
+                        virStreamPtr st,
+                        int flags)
 {
     virDomainDefPtr def = NULL;
     virDomainObjPtr vm = NULL;
@@ -1099,7 +1107,7 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
                                         VIR_DOMAIN_XML_INACTIVE)))
         goto cleanup;
 
-    if (!qemuMigrationIsAllowed(driver, NULL, def))
+    if (!qemuMigrationIsAllowed(driver, NULL, def, flags))
         goto cleanup;
 
     /* Target domain name, maybe renamed. */
@@ -1239,7 +1247,8 @@ qemuMigrationPrepareTunnel(struct qemud_driver *driver,
                            int *cookieoutlen,
                            virStreamPtr st,
                            const char *dname,
-                           const char *dom_xml)
+                           const char *dom_xml,
+                           unsigned long flags)
 {
     int ret;
 
@@ -1253,7 +1262,7 @@ qemuMigrationPrepareTunnel(struct qemud_driver *driver,
      */
     ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen,
                                   cookieout, cookieoutlen, dname, dom_xml,
-                                  "stdio", st);
+                                  "stdio", st, flags);
     return ret;
 }
 
@@ -1268,7 +1277,8 @@ qemuMigrationPrepareDirect(struct qemud_driver *driver,
                            const char *uri_in,
                            char **uri_out,
                            const char *dname,
-                           const char *dom_xml)
+                           const char *dom_xml,
+                           unsigned long flags)
 {
     static int port = 0;
     int this_port;
@@ -1364,7 +1374,7 @@ qemuMigrationPrepareDirect(struct qemud_driver *driver,
 
     ret = qemuMigrationPrepareAny(driver, dconn, cookiein, cookieinlen,
                                   cookieout, cookieoutlen, dname, dom_xml,
-                                  migrateFrom, NULL);
+                                  migrateFrom, NULL, flags);
 cleanup:
     VIR_FREE(hostname);
     if (ret != 0)
@@ -2031,7 +2041,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver,
      * a single job.  */
 
     dom_xml = qemuMigrationBegin(driver, vm, xmlin, dname,
-                                 &cookieout, &cookieoutlen);
+                                 &cookieout, &cookieoutlen, flags);
     if (!dom_xml)
         goto cleanup;
 
@@ -2308,7 +2318,7 @@ qemuMigrationPerformJob(struct qemud_driver *driver,
         goto endjob;
     }
 
-    if (!qemuMigrationIsAllowed(driver, vm, NULL))
+    if (!qemuMigrationIsAllowed(driver, vm, NULL, flags))
         goto cleanup;
 
     resume = virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING;
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index f806ca1..f6491b5 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -35,7 +35,9 @@
      VIR_MIGRATE_PAUSED |                       \
      VIR_MIGRATE_NON_SHARED_DISK |              \
      VIR_MIGRATE_NON_SHARED_INC |               \
-     VIR_MIGRATE_CHANGE_PROTECTION)
+     VIR_MIGRATE_CHANGE_PROTECTION |            \
+     VIR_MIGRATE_FORCE)
+
 
 enum qemuMigrationJobPhase {
     QEMU_MIGRATION_PHASE_NONE = 0,
@@ -81,7 +83,8 @@ char *qemuMigrationBegin(struct qemud_driver *driver,
                          const char *xmlin,
                          const char *dname,
                          char **cookieout,
-                         int *cookieoutlen);
+                         int *cookieoutlen,
+                         unsigned long flags);
 
 int qemuMigrationPrepareTunnel(struct qemud_driver *driver,
                                virConnectPtr dconn,
@@ -91,7 +94,8 @@ int qemuMigrationPrepareTunnel(struct qemud_driver *driver,
                                int *cookieoutlen,
                                virStreamPtr st,
                                const char *dname,
-                               const char *dom_xml);
+                               const char *dom_xml,
+                               unsigned long flags);
 
 int qemuMigrationPrepareDirect(struct qemud_driver *driver,
                                virConnectPtr dconn,
@@ -102,7 +106,8 @@ int qemuMigrationPrepareDirect(struct qemud_driver *driver,
                                const char *uri_in,
                                char **uri_out,
                                const char *dname,
-                               const char *dom_xml);
+                               const char *dom_xml,
+                               unsigned long flags);
 
 int qemuMigrationPerform(struct qemud_driver *driver,
                          virConnectPtr conn,
diff --git a/src/util/virterror.c b/src/util/virterror.c
index 5006fa2..3544208 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -1210,6 +1210,12 @@ virErrorMsg(virErrorNumber error, const char *info)
             else
                 errmsg = _("revert requires force: %s");
             break;
+        case VIR_ERR_MIGRATE_RISKY:
+            if (info == NULL)
+                errmsg = _("migration requires force");
+            else
+                errmsg = _("migration requires force: %s");
+            break;
     }
     return (errmsg);
 }
-- 
1.7.6.3


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]