]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Extend v3 migration protocol to allow app supplied XML for target
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 18 May 2011 09:26:30 +0000 (05:26 -0400)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 25 May 2011 15:47:47 +0000 (11:47 -0400)
This extends the v3 migration protocol such that the
virDomainMigrateBegin3 and virDomainMigratePerform3
methods accept an application supplied XML config for
the target VM.

If the 'xmlin' parameter is NULL, then Begin3 uses the
current guest XML as normal. A driver implementing the
Begin3 method should either reject all non-NULL 'xmlin'
parameters, or strictly validate that the app supplied
XML does not change guest ABI.

The Perform3 method also needed the xmlin parameter to
cope with the Peer2Peer migration sequence.

NB it is not yet possible to use this capability since
neither of the public virDomainMigrate/virDomainMigrateToURI
methods have a way to pass in XML.

* daemon/remote.c, src/remote/remote_driver.c,
  src/remote/remote_protocol.x, src/remote_protocol-structs:
  Add 'remote_string xmlin' parameter to begin3/perform3
  RPC messages
* src/libvirt.c, src/driver.h, src/libvirt_internal.h: Add
  'const char *xmlin' parameter to Begin3/Perform3 methods
* src/qemu/qemu_driver.c, src/qemu/qemu_migration.c,
  src/qemu/qemu_migration.h: Pass xmlin parameter around
  migration methods

daemon/remote.c
src/driver.h
src/libvirt.c
src/libvirt_internal.h
src/qemu/qemu_driver.c
src/qemu/qemu_migration.c
src/qemu/qemu_migration.h
src/remote/remote_driver.c
src/remote/remote_protocol.x
src/remote_protocol-structs

index 80783b30fa689fca0eecfdf57c5c3592dc4e34fa..60f01b48429b6214aee1719f0af252fb69ffdc21 100644 (file)
@@ -3128,6 +3128,7 @@ remoteDispatchDomainMigrateBegin3(struct qemud_server *server ATTRIBUTE_UNUSED,
     char *xml = NULL;
     virDomainPtr dom = NULL;
     char *dname;
+    char *xmlin;
     char *cookieout = NULL;
     int cookieoutlen = 0;
     int rv = -1;
@@ -3140,9 +3141,10 @@ remoteDispatchDomainMigrateBegin3(struct qemud_server *server ATTRIBUTE_UNUSED,
     if (!(dom = get_nonnull_domain(conn, args->dom)))
         goto cleanup;
 
+    xmlin = args->xmlin == NULL ? NULL : *args->xmlin;
     dname = args->dname == NULL ? NULL : *args->dname;
 
-    if (!(xml = virDomainMigrateBegin3(dom,
+    if (!(xml = virDomainMigrateBegin3(dom, xmlin,
                                        &cookieout, &cookieoutlen,
                                        args->flags, dname, args->resource)))
         goto cleanup;
@@ -3288,6 +3290,7 @@ remoteDispatchDomainMigratePerform3(struct qemud_server *server ATTRIBUTE_UNUSED
                                     remote_domain_migrate_perform3_ret *ret)
 {
     virDomainPtr dom = NULL;
+    char *xmlin;
     char *dname;
     char *cookieout = NULL;
     int cookieoutlen = 0;
@@ -3301,9 +3304,10 @@ remoteDispatchDomainMigratePerform3(struct qemud_server *server ATTRIBUTE_UNUSED
     if (!(dom = get_nonnull_domain(conn, args->dom)))
         goto cleanup;
 
+    xmlin = args->xmlin == NULL ? NULL : *args->xmlin;
     dname = args->dname == NULL ? NULL : *args->dname;
 
-    if (virDomainMigratePerform3(dom,
+    if (virDomainMigratePerform3(dom, xmlin,
                                  args->cookie_in.cookie_in_val,
                                  args->cookie_in.cookie_in_len,
                                  &cookieout, &cookieoutlen,
index 450dd5362d363d0d61ac9b158d7c9c6fe49fc1da..a1468e8ba4549ca1486e9115980cc2af8b337846 100644 (file)
@@ -538,6 +538,7 @@ typedef int
 typedef char *
     (*virDrvDomainMigrateBegin3)
                     (virDomainPtr domain,
+                     const char *xmlin,
                      char **cookieout,
                      int *cookieoutlen,
                      unsigned long flags,
@@ -575,6 +576,7 @@ typedef int
 typedef int
     (*virDrvDomainMigratePerform3)
                     (virDomainPtr dom,
+                     const char *xmlin,
                      const char *cookiein,
                      int cookieinlen,
                      char **cookieout,
index ff16c48ceeda40c921aa7133478232c839156dbe..7b7323ee9283d3516af72abd0017cfa39e154761 100644 (file)
@@ -3719,6 +3719,7 @@ finish:
 static virDomainPtr
 virDomainMigrateVersion3(virDomainPtr domain,
                          virConnectPtr dconn,
+                         const char *xmlin,
                          unsigned long flags,
                          const char *dname,
                          const char *uri,
@@ -3748,8 +3749,8 @@ virDomainMigrateVersion3(virDomainPtr domain,
 
     VIR_DEBUG("Begin3 %p", domain->conn);
     dom_xml = domain->conn->driver->domainMigrateBegin3
-        (domain, &cookieout, &cookieoutlen, flags, dname,
-         bandwidth);
+        (domain, xmlin, &cookieout, &cookieoutlen,
+         flags, dname, bandwidth);
     if (!dom_xml)
         goto done;
 
@@ -3792,7 +3793,8 @@ virDomainMigrateVersion3(virDomainPtr domain,
     cookieout = NULL;
     cookieoutlen = 0;
     ret = domain->conn->driver->domainMigratePerform3
-        (domain, cookiein, cookieinlen, &cookieout, &cookieoutlen,
+        (domain, NULL, cookiein, cookieinlen,
+         &cookieout, &cookieoutlen,
          uri, flags, dname, bandwidth);
 
     /* Perform failed. Make sure Finish doesn't overwrite the error */
@@ -3872,6 +3874,7 @@ finish:
   */
 static int
 virDomainMigratePeer2Peer (virDomainPtr domain,
+                           const char *xmlin,
                            unsigned long flags,
                            const char *dname,
                            const char *uri,
@@ -3907,6 +3910,7 @@ virDomainMigratePeer2Peer (virDomainPtr domain,
                                  VIR_DRV_FEATURE_MIGRATION_V3)) {
         VIR_DEBUG("Using migration protocol 3");
         return domain->conn->driver->domainMigratePerform3(domain,
+                                                           xmlin,
                                                            NULL, /* cookiein */
                                                            0,    /* cookieinlen */
                                                            NULL, /* cookieoutlen */
@@ -3917,6 +3921,11 @@ virDomainMigratePeer2Peer (virDomainPtr domain,
                                                            bandwidth);
     } else {
         VIR_DEBUG("Using migration protocol 2");
+        if (xmlin) {
+            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("Unable to change target guest XML during migration"));
+            return -1;
+        }
         return domain->conn->driver->domainMigratePerform(domain,
                                                           NULL, /* cookie */
                                                           0,    /* cookielen */
@@ -3941,6 +3950,7 @@ virDomainMigratePeer2Peer (virDomainPtr domain,
  */
 static int
 virDomainMigrateDirect (virDomainPtr domain,
+                        const char *xmlin,
                         unsigned long flags,
                         const char *dname,
                         const char *uri,
@@ -3959,6 +3969,7 @@ virDomainMigrateDirect (virDomainPtr domain,
                                  VIR_DRV_FEATURE_MIGRATION_V3)) {
         VIR_DEBUG("Using migration protocol 3");
         return domain->conn->driver->domainMigratePerform3(domain,
+                                                           xmlin,
                                                            NULL, /* cookiein */
                                                            0,    /* cookieinlen */
                                                            NULL, /* cookieoutlen */
@@ -3969,6 +3980,11 @@ virDomainMigrateDirect (virDomainPtr domain,
                                                            bandwidth);
     } else {
         VIR_DEBUG("Using migration protocol 2");
+        if (xmlin) {
+            virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("Unable to change target guest XML during migration"));
+            return -1;
+        }
         return domain->conn->driver->domainMigratePerform(domain,
                                                           NULL, /* cookie */
                                                           0,    /* cookielen */
@@ -4093,7 +4109,8 @@ virDomainMigrate (virDomainPtr domain,
             }
 
             VIR_DEBUG("Using peer2peer migration");
-            if (virDomainMigratePeer2Peer(domain, flags, dname, uri ? uri : dstURI, bandwidth) < 0) {
+            if (virDomainMigratePeer2Peer(domain, NULL, flags, dname,
+                                          uri ? uri : dstURI, bandwidth) < 0) {
                 VIR_FREE(dstURI);
                 goto error;
             }
@@ -4118,7 +4135,7 @@ virDomainMigrate (virDomainPtr domain,
             VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
                                      VIR_DRV_FEATURE_MIGRATION_V3)) {
             VIR_DEBUG("Using migration protocol 3");
-            ddomain = virDomainMigrateVersion3(domain, dconn, flags, dname, uri, bandwidth);
+            ddomain = virDomainMigrateVersion3(domain, dconn, NULL, flags, dname, uri, bandwidth);
         } else if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
                                             VIR_DRV_FEATURE_MIGRATION_V2) &&
                    VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
@@ -4238,7 +4255,8 @@ virDomainMigrateToURI (virDomainPtr domain,
         if (VIR_DRV_SUPPORTS_FEATURE (domain->conn->driver, domain->conn,
                                       VIR_DRV_FEATURE_MIGRATION_P2P)) {
             VIR_DEBUG("Using peer2peer migration");
-            if (virDomainMigratePeer2Peer (domain, flags, dname, duri, bandwidth) < 0)
+            if (virDomainMigratePeer2Peer(domain, NULL, flags,
+                                          dname, duri, bandwidth) < 0)
                 goto error;
         } else {
             /* No peer to peer migration supported */
@@ -4249,7 +4267,8 @@ virDomainMigrateToURI (virDomainPtr domain,
         if (VIR_DRV_SUPPORTS_FEATURE (domain->conn->driver, domain->conn,
                                       VIR_DRV_FEATURE_MIGRATION_DIRECT)) {
             VIR_DEBUG("Using direct migration");
-            if (virDomainMigrateDirect (domain, flags, dname, duri, bandwidth) < 0)
+            if (virDomainMigrateDirect(domain, NULL, flags,
+                                       dname, duri, bandwidth) < 0)
                 goto error;
         } else {
             /* Cannot do a migration with only the perform step */
@@ -4567,6 +4586,7 @@ error:
  */
 char *
 virDomainMigrateBegin3(virDomainPtr domain,
+                       const char *xmlin,
                        char **cookieout,
                        int *cookieoutlen,
                        unsigned long flags,
@@ -4575,9 +4595,9 @@ virDomainMigrateBegin3(virDomainPtr domain,
 {
     virConnectPtr conn;
 
-    VIR_DOMAIN_DEBUG(domain, "cookieout=%p, cookieoutlen=%p, "
+    VIR_DOMAIN_DEBUG(domain, "xmlin=%s cookieout=%p, cookieoutlen=%p, "
                      "flags=%lu, dname=%s, bandwidth=%lu",
-                     cookieout, cookieoutlen, flags,
+                     NULLSTR(xmlin), cookieout, cookieoutlen, flags,
                      NULLSTR(dname), bandwidth);
 
     virResetLastError();
@@ -4596,7 +4616,7 @@ virDomainMigrateBegin3(virDomainPtr domain,
 
     if (conn->driver->domainMigrateBegin3) {
         char *xml;
-        xml = conn->driver->domainMigrateBegin3(domain,
+        xml = conn->driver->domainMigrateBegin3(domain, xmlin,
                                                 cookieout, cookieoutlen,
                                                 flags, dname, bandwidth);
         VIR_DEBUG("xml %s", NULLSTR(xml));
@@ -4733,6 +4753,7 @@ error:
  */
 int
 virDomainMigratePerform3(virDomainPtr domain,
+                         const char *xmlin,
                          const char *cookiein,
                          int cookieinlen,
                          char **cookieout,
@@ -4744,9 +4765,11 @@ virDomainMigratePerform3(virDomainPtr domain,
 {
     virConnectPtr conn;
 
-    VIR_DOMAIN_DEBUG(domain, "cookiein=%p, cookieinlen=%d, cookieout=%p, cookieoutlen=%p,"
+    VIR_DOMAIN_DEBUG(domain, "xmlin=%s cookiein=%p, cookieinlen=%d, "
+                     "cookieout=%p, cookieoutlen=%p, "
                      "uri=%s, flags=%lu, dname=%s, bandwidth=%lu",
-                     cookiein, cookieinlen, cookieout, cookieoutlen,
+                     NULLSTR(xmlin), cookiein, cookieinlen,
+                     cookieout, cookieoutlen,
                      uri, flags, NULLSTR(dname), bandwidth);
 
     virResetLastError();
@@ -4765,7 +4788,7 @@ virDomainMigratePerform3(virDomainPtr domain,
 
     if (conn->driver->domainMigratePerform3) {
         int ret;
-        ret = conn->driver->domainMigratePerform3(domain,
+        ret = conn->driver->domainMigratePerform3(domain, xmlin,
                                                   cookiein, cookieinlen,
                                                   cookieout, cookieoutlen,
                                                   uri,
index 81d0c56e938774ec74878d606c0dc12c0a06b1c2..c7c1932a40261bf599134eb4a1aabf29d8dfe255 100644 (file)
@@ -124,6 +124,7 @@ int virDomainMigratePrepareTunnel(virConnectPtr dconn,
 
 
 char *virDomainMigrateBegin3(virDomainPtr domain,
+                             const char *xmlin,
                              char **cookieout,
                              int *cookieoutlen,
                              unsigned long flags,
@@ -155,6 +156,7 @@ int virDomainMigratePrepareTunnel3(virConnectPtr dconn,
 
 
 int virDomainMigratePerform3(virDomainPtr dom,
+                             const char *xmlin,
                              const char *cookiein,
                              int cookieinlen,
                              char **cookieout,
index 576393e81696472bbf142e1b77b8ffb762ba1133..b7e4e55c0b468281aa539a4a54f1900b78f444b1 100644 (file)
@@ -5973,7 +5973,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
      * Consume any cookie we were able to decode though
      */
     ret = qemuMigrationPerform(driver, dom->conn, vm,
-                               uri, cookie, cookielen,
+                               NULL, uri, cookie, cookielen,
                                NULL, NULL, /* No output cookies in v2 */
                                flags, dname, resource, true);
 
@@ -6042,6 +6042,7 @@ cleanup:
 
 static char *
 qemuDomainMigrateBegin3(virDomainPtr domain,
+                        const char *xmlin,
                         char **cookieout,
                         int *cookieoutlen,
                         unsigned long flags,
@@ -6071,7 +6072,7 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
         goto cleanup;
     }
 
-    xml = qemuMigrationBegin(driver, vm,
+    xml = qemuMigrationBegin(driver, vm, xmlin,
                              cookieout, cookieoutlen);
 
 cleanup:
@@ -6188,6 +6189,7 @@ cleanup:
 
 static int
 qemuDomainMigratePerform3(virDomainPtr dom,
+                          const char *xmlin,
                           const char *cookiein,
                           int cookieinlen,
                           char **cookieout,
@@ -6220,7 +6222,7 @@ qemuDomainMigratePerform3(virDomainPtr dom,
         goto cleanup;
     }
 
-    ret = qemuMigrationPerform(driver, dom->conn, vm,
+    ret = qemuMigrationPerform(driver, dom->conn, vm, xmlin,
                                uri, cookiein, cookieinlen,
                                cookieout, cookieoutlen,
                                flags, dname, resource, false);
index 97138b5665cb7327a5f9ce91c86e205b5ba1e161..6044b873c0cb35ba28de1d29517bc25953e19fc0 100644 (file)
@@ -863,12 +863,19 @@ qemuDomainMigrateGraphicsRelocate(struct qemud_driver *driver,
 
 char *qemuMigrationBegin(struct qemud_driver *driver,
                          virDomainObjPtr vm,
+                         const char *xmlin,
                          char **cookieout,
                          int *cookieoutlen)
 {
     char *rv = NULL;
     qemuMigrationCookiePtr mig = NULL;
 
+    if (xmlin) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR,
+                        "%s", _("Passing XML for the target VM is not yet supported"));
+        goto cleanup;
+    }
+
     if (!virDomainObjIsActive(vm)) {
         qemuReportError(VIR_ERR_OPERATION_INVALID,
                         "%s", _("domain is not running"));
@@ -1779,6 +1786,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver,
                                virConnectPtr sconn,
                                virConnectPtr dconn,
                                virDomainObjPtr vm,
+                               const char *xmlin,
                                const char *uri,
                                unsigned long flags,
                                const char *dname,
@@ -1797,7 +1805,7 @@ static int doPeer2PeerMigrate3(struct qemud_driver *driver,
     virStreamPtr st = NULL;
 
     VIR_DEBUG("Begin3 %p", sconn);
-    dom_xml = qemuMigrationBegin(driver, vm,
+    dom_xml = qemuMigrationBegin(driver, vm, xmlin,
                                  &cookieout, &cookieoutlen);
     if (!dom_xml)
         goto cleanup;
@@ -1943,6 +1951,7 @@ finish:
 static int doPeer2PeerMigrate(struct qemud_driver *driver,
                               virConnectPtr sconn,
                               virDomainObjPtr vm,
+                              const char *xmlin,
                               const char *uri,
                               unsigned long flags,
                               const char *dname,
@@ -1987,7 +1996,7 @@ static int doPeer2PeerMigrate(struct qemud_driver *driver,
     }
 
     if (v3)
-        ret = doPeer2PeerMigrate3(driver, sconn, dconn, vm,
+        ret = doPeer2PeerMigrate3(driver, sconn, dconn, vm, xmlin,
                                   uri, flags, dname, resource);
     else
         ret = doPeer2PeerMigrate2(driver, sconn, dconn, vm,
@@ -2006,6 +2015,7 @@ cleanup:
 int qemuMigrationPerform(struct qemud_driver *driver,
                          virConnectPtr conn,
                          virDomainObjPtr vm,
+                         const char *xmlin,
                          const char *uri,
                          const char *cookiein,
                          int cookieinlen,
@@ -2048,7 +2058,8 @@ int qemuMigrationPerform(struct qemud_driver *driver,
             goto endjob;
         }
 
-        if (doPeer2PeerMigrate(driver, conn, vm, uri, flags, dname, resource) < 0)
+        if (doPeer2PeerMigrate(driver, conn, vm, xmlin,
+                               uri, flags, dname, resource) < 0)
             /* doPeer2PeerMigrate already set the error, so just get out */
             goto endjob;
     } else {
index 781e58cefff00ed57e1d195d3e3dbaf108762959..ece13502fbeded0c87c9db79efc0526d41199365 100644 (file)
@@ -34,6 +34,7 @@ int qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr
 
 char *qemuMigrationBegin(struct qemud_driver *driver,
                          virDomainObjPtr vm,
+                         const char *xmlin,
                          char **cookieout,
                          int *cookieoutlen);
 
@@ -61,6 +62,7 @@ int qemuMigrationPrepareDirect(struct qemud_driver *driver,
 int qemuMigrationPerform(struct qemud_driver *driver,
                          virConnectPtr conn,
                          virDomainObjPtr vm,
+                         const char *xmlin,
                          const char *uri,
                          const char *cookiein,
                          int cookieinlen,
index 1691dab6ee7af17830e82fe4d9572b8eb21a0bb9..66393fbbfaed8b2288edfeff56fcf79e15464f64 100644 (file)
@@ -4982,6 +4982,7 @@ done:
 
 static char *
 remoteDomainMigrateBegin3(virDomainPtr domain,
+                          const char *xmlin,
                           char **cookieout,
                           int *cookieoutlen,
                           unsigned long flags,
@@ -4999,6 +5000,7 @@ remoteDomainMigrateBegin3(virDomainPtr domain,
     memset(&ret, 0, sizeof(ret));
 
     make_nonnull_domain (&args.dom, domain);
+    args.xmlin = xmlin == NULL ? NULL : (char **) &xmlin;
     args.flags = flags;
     args.dname = dname == NULL ? NULL : (char **) &dname;
     args.resource = resource;
@@ -5167,6 +5169,7 @@ error:
 
 static int
 remoteDomainMigratePerform3(virDomainPtr dom,
+                            const char *xmlin,
                             const char *cookiein,
                             int cookieinlen,
                             char **cookieout,
@@ -5188,6 +5191,7 @@ remoteDomainMigratePerform3(virDomainPtr dom,
 
     make_nonnull_domain(&args.dom, dom);
 
+    args.xmlin = xmlin == NULL ? NULL : (char **) &xmlin;
     args.cookie_in.cookie_in_val = (char *)cookiein;
     args.cookie_in.cookie_in_len = cookieinlen;
     args.uri = (char *) uri;
index f0da95d065450a1e7b8ca13fe8fe40436af36873..842fd0b4a82d4fecc4945dd6b569b81aa5e2602d 100644 (file)
@@ -1973,6 +1973,7 @@ struct remote_domain_get_state_ret {
 
 struct remote_domain_migrate_begin3_args {
     remote_nonnull_domain dom;
+    remote_string xmlin;
     unsigned hyper flags;
     remote_string dname;
     unsigned hyper resource;
@@ -2011,6 +2012,7 @@ struct remote_domain_migrate_prepare_tunnel3_ret {
 
 struct remote_domain_migrate_perform3_args {
     remote_nonnull_domain dom;
+    remote_string xmlin;
     opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
     remote_nonnull_string uri;
     unsigned hyper flags;
index 414b4d5b89ff13d81a1905936edeb4b9a3ad2c94..971f53a89d08c697de8f5cfbfc3b9ed1322fd6c1 100644 (file)
@@ -1457,6 +1457,7 @@ struct remote_domain_get_state_ret {
 };
 struct remote_domain_migrate_begin3_args {
         remote_nonnull_domain      dom;
+        remote_string              xmlin;
         uint64_t                   flags;
         remote_string              dname;
         uint64_t                   resource;
@@ -1504,6 +1505,7 @@ struct remote_domain_migrate_prepare_tunnel3_ret {
 };
 struct remote_domain_migrate_perform3_args {
         remote_nonnull_domain      dom;
+        remote_string              xmlin;
         struct {
                 u_int              cookie_in_len;
                 char *             cookie_in_val;