[libvirt] [PATCH 03/16] Remote driver implementation of new migration API

Daniel P. Berrange berrange at redhat.com
Thu Apr 21 16:32:42 UTC 2011


* src/remote/remote_protocol.x: Define wire protocol for migration
  protocol v3
* daemon/remote.c: Server side dispatch
* src/remote/remote_driver.c: Client side serialization
* src/remote/remote_protocol.c, src/remote/remote_protocol.h,
  daemon/remote_dispatch_args.h, daemon/remote_dispatch_prototypes.h,
  daemon/remote_dispatch_ret.h, daemon/remote_dispatch_table.h:
  Re-generate files
* src/remote_protocol-structs: Declare new ABIs
---
 daemon/remote.c                     |  315 +++++++++++++++++++++++++++++
 daemon/remote_dispatch_args.h       |    6 +
 daemon/remote_dispatch_prototypes.h |   48 +++++
 daemon/remote_dispatch_ret.h        |    5 +
 daemon/remote_dispatch_table.h      |   30 +++
 src/remote/remote_driver.c          |  371 ++++++++++++++++++++++++++++++++++-
 src/remote/remote_protocol.c        |  163 +++++++++++++++
 src/remote/remote_protocol.h        |  140 +++++++++++++
 src/remote/remote_protocol.x        |   79 ++++++++-
 src/remote_protocol-structs         |   90 +++++++++
 10 files changed, 1240 insertions(+), 7 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 54fef64..98de0a7 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -76,6 +76,7 @@ static virStorageVolPtr get_nonnull_storage_vol(virConnectPtr conn, remote_nonnu
 static virSecretPtr get_nonnull_secret(virConnectPtr conn, remote_nonnull_secret secret);
 static virNWFilterPtr get_nonnull_nwfilter(virConnectPtr conn, remote_nonnull_nwfilter nwfilter);
 static virDomainSnapshotPtr get_nonnull_domain_snapshot(virDomainPtr dom, remote_nonnull_domain_snapshot snapshot);
+static int make_domain(remote_domain *dom_dst, virDomainPtr dom_src);
 static void make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr dom_src);
 static void make_nonnull_network(remote_nonnull_network *net_dst, virNetworkPtr net_src);
 static void make_nonnull_interface(remote_nonnull_interface *interface_dst, virInterfacePtr interface_src);
@@ -8736,6 +8737,305 @@ cleanup:
 }
 
 
+static int
+remoteDispatchDomainMigrateBegin3(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                  struct qemud_client *client ATTRIBUTE_UNUSED,
+                                  virConnectPtr conn,
+                                  remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                  remote_error *rerr,
+                                  remote_domain_migrate_begin3_args *args,
+                                  remote_domain_migrate_begin3_ret *ret)
+{
+    char *xml = NULL;
+    virDomainPtr dom = NULL;
+    char *dname;
+    char *cookieout = NULL;
+    int cookieoutlen = 0;
+    int rv = -1;
+
+    if (!conn) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+        goto cleanup;
+    }
+
+    if (!(dom = get_nonnull_domain(conn, args->dom)))
+        goto cleanup;
+
+    dname = args->dname == NULL ? NULL : *args->dname;
+
+    if (!(xml = virDomainMigrateBegin3(dom,
+                                       &cookieout, &cookieoutlen,
+                                       args->flags, dname, args->resource)))
+        goto cleanup;
+
+    /* remoteDispatchClientRequest will free cookie and
+     * the xml string if there is one.
+     */
+    ret->cookie_out.cookie_out_len = cookieoutlen;
+    ret->cookie_out.cookie_out_val = cookieout;
+    ret->xml = xml;
+
+    rv = 0;
+
+cleanup:
+    if (rv < 0)
+        remoteDispatchError(rerr);
+    if (dom)
+        virDomainFree(dom);
+    return rv;
+}
+
+
+static int
+remoteDispatchDomainMigratePrepare3(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                    struct qemud_client *client ATTRIBUTE_UNUSED,
+                                    virConnectPtr conn,
+                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                    remote_error *rerr,
+                                    remote_domain_migrate_prepare3_args *args,
+                                    remote_domain_migrate_prepare3_ret *ret)
+{
+    char *cookieout = NULL;
+    int cookieoutlen = 0;
+    char *uri_in;
+    char **uri_out;
+    char *dname;
+    int rv = -1;
+
+    if (!conn) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+        goto cleanup;
+    }
+
+    uri_in = args->uri_in == NULL ? NULL : *args->uri_in;
+    dname = args->dname == NULL ? NULL : *args->dname;
+
+    /* Wacky world of XDR ... */
+    if (VIR_ALLOC(uri_out) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (virDomainMigratePrepare3(conn,
+                                 args->cookie_in.cookie_in_val,
+                                 args->cookie_in.cookie_in_len,
+                                 &cookieout, &cookieoutlen,
+                                 uri_in, uri_out,
+                                 args->flags, dname, args->resource,
+                                 args->dom_xml) < 0)
+        goto cleanup;
+
+    /* remoteDispatchClientRequest will free cookie, uri_out and
+     * the string if there is one.
+     */
+    ret->cookie_out.cookie_out_len = cookieoutlen;
+    ret->cookie_out.cookie_out_val = cookieout;
+    ret->uri_out = *uri_out == NULL ? NULL : uri_out;
+
+    rv = 0;
+
+cleanup:
+    if (rv < 0) {
+        remoteDispatchError(rerr);
+        VIR_FREE(uri_out);
+    }
+    return rv;
+}
+
+static int
+remoteDispatchDomainMigratePrepareTunnel3(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                          struct qemud_client *client,
+                                          virConnectPtr conn,
+                                          remote_message_header *hdr,
+                                          remote_error *rerr,
+                                          remote_domain_migrate_prepare_tunnel3_args *args,
+                                          remote_domain_migrate_prepare_tunnel3_ret *ret)
+{
+    char *dname;
+    char *cookieout = NULL;
+    int cookieoutlen = 0;
+    struct qemud_client_stream *stream = NULL;
+    int rv = -1;
+
+    if (!conn) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+        goto cleanup;
+    }
+
+    dname = args->dname == NULL ? NULL : *args->dname;
+
+    if (!(stream = remoteCreateClientStream(conn, hdr))) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if (virDomainMigratePrepareTunnel3(conn, stream->st,
+                                       args->cookie_in.cookie_in_val,
+                                       args->cookie_in.cookie_in_len,
+                                       &cookieout, &cookieoutlen,
+                                       args->flags, dname, args->resource,
+                                       args->dom_xml) < 0)
+        goto cleanup;
+
+    if (remoteAddClientStream(client, stream, 0) < 0)
+        goto cleanup;
+
+    /* remoteDispatchClientRequest will free cookie
+     */
+    ret->cookie_out.cookie_out_len = cookieoutlen;
+    ret->cookie_out.cookie_out_val = cookieout;
+
+    rv = 0;
+
+cleanup:
+    if (rv < 0) {
+        remoteDispatchError(rerr);
+        VIR_FREE(cookieout);
+    }
+    if (stream && rv < 0) {
+        virStreamAbort(stream->st);
+        remoteFreeClientStream(client, stream);
+    }
+    return rv;
+}
+
+static int
+remoteDispatchDomainMigratePerform3(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                    struct qemud_client *client ATTRIBUTE_UNUSED,
+                                    virConnectPtr conn,
+                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                    remote_error *rerr,
+                                    remote_domain_migrate_perform3_args *args,
+                                    remote_domain_migrate_perform3_ret *ret)
+{
+    virDomainPtr dom = NULL;
+    char *dname;
+    char *cookieout = NULL;
+    int cookieoutlen = 0;
+    int rv = -1;
+
+    if (!conn) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+        goto cleanup;
+    }
+
+    if (!(dom = get_nonnull_domain(conn, args->dom)))
+        goto cleanup;
+
+    dname = args->dname == NULL ? NULL : *args->dname;
+
+    if (virDomainMigratePerform3(dom,
+                                 args->cookie_in.cookie_in_val,
+                                 args->cookie_in.cookie_in_len,
+                                 &cookieout, &cookieoutlen,
+                                 args->uri,
+                                 args->flags, dname, args->resource) < 0)
+        goto cleanup;
+
+    /* remoteDispatchClientRequest will free cookie
+     */
+    ret->cookie_out.cookie_out_len = cookieoutlen;
+    ret->cookie_out.cookie_out_val = cookieout;
+
+    rv = 0;
+
+cleanup:
+    if (rv < 0)
+        remoteDispatchError(rerr);
+    if (dom)
+        virDomainFree(dom);
+    return rv;
+}
+
+
+static int
+remoteDispatchDomainMigrateFinish3(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                   struct qemud_client *client ATTRIBUTE_UNUSED,
+                                   virConnectPtr conn,
+                                   remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                   remote_error *rerr,
+                                   remote_domain_migrate_finish3_args *args,
+                                   remote_domain_migrate_finish3_ret *ret)
+{
+    virDomainPtr dom = NULL;
+    char *cookieout = NULL;
+    int cookieoutlen = 0;
+    int rv = -1;
+
+    if (!conn) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+        goto cleanup;
+    }
+
+    if (virDomainMigrateFinish3(conn, args->dname,
+                                args->cookie_in.cookie_in_val,
+                                args->cookie_in.cookie_in_len,
+                                &cookieout, &cookieoutlen,
+                                args->uri,
+                                args->flags,
+                                args->cancelled,
+                                &dom) < 0)
+        goto cleanup;
+
+    if (dom &&
+        make_domain(&ret->ddom, dom) < 0)
+        goto cleanup;
+
+    /* remoteDispatchClientRequest will free cookie
+     */
+    ret->cookie_out.cookie_out_len = cookieoutlen;
+    ret->cookie_out.cookie_out_val = cookieout;
+
+    rv = 0;
+
+cleanup:
+    if (rv < 0) {
+        remoteDispatchError(rerr);
+        VIR_FREE(cookieout);
+    }
+    if (dom)
+        virDomainFree(dom);
+    return rv;
+}
+
+
+static int
+remoteDispatchDomainMigrateConfirm3(struct qemud_server *server ATTRIBUTE_UNUSED,
+                                    struct qemud_client *client ATTRIBUTE_UNUSED,
+                                    virConnectPtr conn,
+                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                    remote_error *rerr,
+                                    remote_domain_migrate_confirm3_args *args,
+                                    void *ret ATTRIBUTE_UNUSED)
+{
+    virDomainPtr dom = NULL;
+    int rv = -1;
+
+    if (!conn) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+        goto cleanup;
+    }
+
+    if (!(dom = get_nonnull_domain(conn, args->dom)))
+        goto cleanup;
+
+    if (virDomainMigrateConfirm3(dom,
+                                 args->cookie_in.cookie_in_val,
+                                 args->cookie_in.cookie_in_len,
+                                 args->flags, args->cancelled) < 0)
+        goto cleanup;
+
+    rv = 0;
+
+cleanup:
+    if (rv < 0)
+        remoteDispatchError(rerr);
+    if (dom)
+        virDomainFree(dom);
+    return rv;
+}
+
+
 /*----- Helpers. -----*/
 
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
@@ -8801,6 +9101,21 @@ get_nonnull_domain_snapshot(virDomainPtr dom, remote_nonnull_domain_snapshot sna
 }
 
 /* Make remote_nonnull_domain and remote_nonnull_network. */
+static int
+make_domain(remote_domain *dom_dst, virDomainPtr dom_src)
+{
+    remote_domain rdom;
+    if (VIR_ALLOC(rdom) < 0)
+        return -1;
+
+    rdom->id = dom_src->id;
+    rdom->name = strdup(dom_src->name);
+    memcpy(rdom->uuid, dom_src->uuid, VIR_UUID_BUFLEN);
+
+    *dom_dst = rdom;
+    return 0;
+}
+
 static void
 make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr dom_src)
 {
diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h
index f9537d7..07c666e 100644
--- a/daemon/remote_dispatch_args.h
+++ b/daemon/remote_dispatch_args.h
@@ -178,3 +178,9 @@
     remote_domain_migrate_set_max_speed_args val_remote_domain_migrate_set_max_speed_args;
     remote_storage_vol_upload_args val_remote_storage_vol_upload_args;
     remote_storage_vol_download_args val_remote_storage_vol_download_args;
+    remote_domain_migrate_begin3_args val_remote_domain_migrate_begin3_args;
+    remote_domain_migrate_prepare3_args val_remote_domain_migrate_prepare3_args;
+    remote_domain_migrate_prepare_tunnel3_args val_remote_domain_migrate_prepare_tunnel3_args;
+    remote_domain_migrate_perform3_args val_remote_domain_migrate_perform3_args;
+    remote_domain_migrate_finish3_args val_remote_domain_migrate_finish3_args;
+    remote_domain_migrate_confirm3_args val_remote_domain_migrate_confirm3_args;
diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h
index 18bf41d..3dceb74 100644
--- a/daemon/remote_dispatch_prototypes.h
+++ b/daemon/remote_dispatch_prototypes.h
@@ -426,6 +426,22 @@ static int remoteDispatchDomainMemoryStats(
     remote_error *err,
     remote_domain_memory_stats_args *args,
     remote_domain_memory_stats_ret *ret);
+static int remoteDispatchDomainMigrateBegin3(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_domain_migrate_begin3_args *args,
+    remote_domain_migrate_begin3_ret *ret);
+static int remoteDispatchDomainMigrateConfirm3(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_domain_migrate_confirm3_args *args,
+    void *ret);
 static int remoteDispatchDomainMigrateFinish(
     struct qemud_server *server,
     struct qemud_client *client,
@@ -442,6 +458,14 @@ static int remoteDispatchDomainMigrateFinish2(
     remote_error *err,
     remote_domain_migrate_finish2_args *args,
     remote_domain_migrate_finish2_ret *ret);
+static int remoteDispatchDomainMigrateFinish3(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_domain_migrate_finish3_args *args,
+    remote_domain_migrate_finish3_ret *ret);
 static int remoteDispatchDomainMigratePerform(
     struct qemud_server *server,
     struct qemud_client *client,
@@ -450,6 +474,14 @@ static int remoteDispatchDomainMigratePerform(
     remote_error *err,
     remote_domain_migrate_perform_args *args,
     void *ret);
+static int remoteDispatchDomainMigratePerform3(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_domain_migrate_perform3_args *args,
+    remote_domain_migrate_perform3_ret *ret);
 static int remoteDispatchDomainMigratePrepare(
     struct qemud_server *server,
     struct qemud_client *client,
@@ -466,6 +498,14 @@ static int remoteDispatchDomainMigratePrepare2(
     remote_error *err,
     remote_domain_migrate_prepare2_args *args,
     remote_domain_migrate_prepare2_ret *ret);
+static int remoteDispatchDomainMigratePrepare3(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_domain_migrate_prepare3_args *args,
+    remote_domain_migrate_prepare3_ret *ret);
 static int remoteDispatchDomainMigratePrepareTunnel(
     struct qemud_server *server,
     struct qemud_client *client,
@@ -474,6 +514,14 @@ static int remoteDispatchDomainMigratePrepareTunnel(
     remote_error *err,
     remote_domain_migrate_prepare_tunnel_args *args,
     void *ret);
+static int remoteDispatchDomainMigratePrepareTunnel3(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_domain_migrate_prepare_tunnel3_args *args,
+    remote_domain_migrate_prepare_tunnel3_ret *ret);
 static int remoteDispatchDomainMigrateSetMaxDowntime(
     struct qemud_server *server,
     struct qemud_client *client,
diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h
index 114e832..6e5049a 100644
--- a/daemon/remote_dispatch_ret.h
+++ b/daemon/remote_dispatch_ret.h
@@ -140,3 +140,8 @@
     remote_domain_is_updated_ret val_remote_domain_is_updated_ret;
     remote_get_sysinfo_ret val_remote_get_sysinfo_ret;
     remote_domain_get_blkio_parameters_ret val_remote_domain_get_blkio_parameters_ret;
+    remote_domain_migrate_begin3_ret val_remote_domain_migrate_begin3_ret;
+    remote_domain_migrate_prepare3_ret val_remote_domain_migrate_prepare3_ret;
+    remote_domain_migrate_prepare_tunnel3_ret val_remote_domain_migrate_prepare_tunnel3_ret;
+    remote_domain_migrate_perform3_ret val_remote_domain_migrate_perform3_ret;
+    remote_domain_migrate_finish3_ret val_remote_domain_migrate_finish3_ret;
diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h
index b39f7c2..a76eccb 100644
--- a/daemon/remote_dispatch_table.h
+++ b/daemon/remote_dispatch_table.h
@@ -1052,3 +1052,33 @@
     .args_filter = (xdrproc_t) xdr_remote_storage_vol_download_args,
     .ret_filter = (xdrproc_t) xdr_void,
 },
+{   /* DomainMigrateBegin3 => 210 */
+    .fn = (dispatch_fn) remoteDispatchDomainMigrateBegin3,
+    .args_filter = (xdrproc_t) xdr_remote_domain_migrate_begin3_args,
+    .ret_filter = (xdrproc_t) xdr_remote_domain_migrate_begin3_ret,
+},
+{   /* DomainMigratePrepare3 => 211 */
+    .fn = (dispatch_fn) remoteDispatchDomainMigratePrepare3,
+    .args_filter = (xdrproc_t) xdr_remote_domain_migrate_prepare3_args,
+    .ret_filter = (xdrproc_t) xdr_remote_domain_migrate_prepare3_ret,
+},
+{   /* DomainMigratePrepareTunnel3 => 212 */
+    .fn = (dispatch_fn) remoteDispatchDomainMigratePrepareTunnel3,
+    .args_filter = (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_args,
+    .ret_filter = (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_ret,
+},
+{   /* DomainMigratePerform3 => 213 */
+    .fn = (dispatch_fn) remoteDispatchDomainMigratePerform3,
+    .args_filter = (xdrproc_t) xdr_remote_domain_migrate_perform3_args,
+    .ret_filter = (xdrproc_t) xdr_remote_domain_migrate_perform3_ret,
+},
+{   /* DomainMigrateFinish3 => 214 */
+    .fn = (dispatch_fn) remoteDispatchDomainMigrateFinish3,
+    .args_filter = (xdrproc_t) xdr_remote_domain_migrate_finish3_args,
+    .ret_filter = (xdrproc_t) xdr_remote_domain_migrate_finish3_ret,
+},
+{   /* DomainMigrateConfirm3 => 215 */
+    .fn = (dispatch_fn) remoteDispatchDomainMigrateConfirm3,
+    .args_filter = (xdrproc_t) xdr_remote_domain_migrate_confirm3_args,
+    .ret_filter = (xdrproc_t) xdr_void,
+},
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 0d7c144..bed6a15 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -245,6 +245,7 @@ static int remoteAuthPolkit (virConnectPtr conn, struct private_data *priv, int
     virReportErrorHelper(VIR_FROM_REMOTE, code, __FILE__,         \
                          __FUNCTION__, __LINE__, __VA_ARGS__)
 
+static virDomainPtr get_domain (virConnectPtr conn, remote_domain domain);
 static virDomainPtr get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain domain);
 static virNetworkPtr get_nonnull_network (virConnectPtr conn, remote_nonnull_network network);
 static virNWFilterPtr get_nonnull_nwfilter (virConnectPtr conn, remote_nonnull_nwfilter nwfilter);
@@ -3480,6 +3481,7 @@ error:
     goto done;
 }
 
+
 static virDomainPtr
 remoteDomainMigrateFinish2 (virConnectPtr dconn,
                             const char *dname,
@@ -3517,6 +3519,7 @@ done:
     return ddom;
 }
 
+
 static int
 remoteListDefinedDomains (virConnectPtr conn, char **const names, int maxnames)
 {
@@ -9770,6 +9773,346 @@ done:
     return rv;
 }
 
+
+static char *
+remoteDomainMigrateBegin3(virDomainPtr domain,
+                          char **cookieout,
+                          int *cookieoutlen,
+                          unsigned long flags,
+                          const char *dname,
+                          unsigned long resource)
+{
+    char *rv = NULL;
+    remote_domain_migrate_begin3_args args;
+    remote_domain_migrate_begin3_ret ret;
+    struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
+
+    memset(&args, 0, sizeof(args));
+    memset(&ret, 0, sizeof(ret));
+
+    make_nonnull_domain (&args.dom, domain);
+    args.flags = flags;
+    args.dname = dname == NULL ? NULL : (char **) &dname;
+    args.resource = resource;
+
+    if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_BEGIN3,
+              (xdrproc_t) xdr_remote_domain_migrate_begin3_args, (char *) &args,
+              (xdrproc_t) xdr_remote_domain_migrate_begin3_ret, (char *) &ret) == -1)
+        goto done;
+
+    if (ret.cookie_out.cookie_out_len > 0) {
+        if (!cookieout || !cookieoutlen) {
+            remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("caller ignores cookieout or cookieoutlen"));
+            goto error;
+        }
+        *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
+        *cookieoutlen = ret.cookie_out.cookie_out_len;
+    }
+
+    rv = ret.xml; /* caller frees */
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+
+error:
+    VIR_FREE(ret.cookie_out.cookie_out_val);
+    goto done;
+}
+
+
+static int
+remoteDomainMigratePrepare3(virConnectPtr dconn,
+                            const char *cookiein,
+                            int cookieinlen,
+                            char **cookieout,
+                            int *cookieoutlen,
+                            const char *uri_in,
+                            char **uri_out,
+                            unsigned long flags,
+                            const char *dname,
+                            unsigned long resource,
+                            const char *dom_xml)
+{
+    int rv = -1;
+    remote_domain_migrate_prepare3_args args;
+    remote_domain_migrate_prepare3_ret ret;
+    struct private_data *priv = dconn->privateData;
+
+    remoteDriverLock(priv);
+
+    memset(&args, 0, sizeof(args));
+    memset(&ret, 0, sizeof(ret));
+
+    args.cookie_in.cookie_in_val = (char *)cookiein;
+    args.cookie_in.cookie_in_len = cookieinlen;
+    args.uri_in = uri_in == NULL ? NULL : (char **) &uri_in;
+    args.flags = flags;
+    args.dname = dname == NULL ? NULL : (char **) &dname;
+    args.resource = resource;
+    args.dom_xml = (char *) dom_xml;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE3,
+              (xdrproc_t) xdr_remote_domain_migrate_prepare3_args, (char *) &args,
+              (xdrproc_t) xdr_remote_domain_migrate_prepare3_ret, (char *) &ret) == -1)
+        goto done;
+
+    if (ret.cookie_out.cookie_out_len > 0) {
+        if (!cookieout || !cookieoutlen) {
+            remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("caller ignores cookieout or cookieoutlen"));
+            goto error;
+        }
+        *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
+        *cookieoutlen = ret.cookie_out.cookie_out_len;
+    }
+    if (ret.uri_out) {
+        if (!uri_out) {
+            remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("caller ignores uri_out"));
+            goto error;
+        }
+        *uri_out = *ret.uri_out; /* Caller frees. */
+    }
+
+    rv = 0;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+error:
+    VIR_FREE(ret.cookie_out.cookie_out_val);
+    if (ret.uri_out)
+        VIR_FREE(*ret.uri_out);
+    goto done;
+}
+
+
+static int
+remoteDomainMigratePrepareTunnel3(virConnectPtr dconn,
+                                  virStreamPtr st,
+                                  const char *cookiein,
+                                  int cookieinlen,
+                                  char **cookieout,
+                                  int *cookieoutlen,
+                                  unsigned long flags,
+                                  const char *dname,
+                                  unsigned long resource,
+                                  const char *dom_xml)
+{
+    struct private_data *priv = dconn->privateData;
+    struct private_stream_data *privst = NULL;
+    int rv = -1;
+    remote_domain_migrate_prepare_tunnel3_args args;
+    remote_domain_migrate_prepare_tunnel3_ret ret;
+
+    remoteDriverLock(priv);
+
+    memset(&args, 0, sizeof(args));
+    memset(&ret, 0, sizeof(ret));
+
+    if (!(privst = remoteStreamOpen(st,
+                                    REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3,
+                                    priv->counter)))
+        goto done;
+
+    st->driver = &remoteStreamDrv;
+    st->privateData = privst;
+
+    args.cookie_in.cookie_in_val = (char *)cookiein;
+    args.cookie_in.cookie_in_len = cookieinlen;
+    args.flags = flags;
+    args.dname = dname == NULL ? NULL : (char **) &dname;
+    args.resource = resource;
+    args.dom_xml = (char *) dom_xml;
+
+    if (call(dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3,
+             (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_args, (char *) &args,
+             (xdrproc_t) xdr_remote_domain_migrate_prepare_tunnel3_ret, (char *) &ret) == -1) {
+        remoteStreamRelease(st);
+        goto done;
+    }
+
+    if (ret.cookie_out.cookie_out_len > 0) {
+        if (!cookieout || !cookieoutlen) {
+            remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("caller ignores cookieout or cookieoutlen"));
+            goto error;
+        }
+        *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
+        *cookieoutlen = ret.cookie_out.cookie_out_len;
+    }
+
+    rv = 0;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+
+error:
+    VIR_FREE(ret.cookie_out.cookie_out_val);
+    goto done;
+}
+
+
+static int
+remoteDomainMigratePerform3(virDomainPtr dom,
+                            const char *cookiein,
+                            int cookieinlen,
+                            char **cookieout,
+                            int *cookieoutlen,
+                            const char *uri,
+                            unsigned long flags,
+                            const char *dname,
+                            unsigned long resource)
+{
+    int rv = -1;
+    remote_domain_migrate_perform3_args args;
+    remote_domain_migrate_perform3_ret ret;
+    struct private_data *priv = dom->conn->privateData;
+
+    remoteDriverLock(priv);
+
+    memset(&args, 0, sizeof(args));
+    memset(&ret, 0, sizeof(ret));
+
+    make_nonnull_domain(&args.dom, dom);
+
+    args.cookie_in.cookie_in_val = (char *)cookiein;
+    args.cookie_in.cookie_in_len = cookieinlen;
+    args.uri = (char *) uri;
+    args.flags = flags;
+    args.dname = dname == NULL ? NULL : (char **) &dname;
+    args.resource = resource;
+
+    if (call (dom->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_PERFORM3,
+              (xdrproc_t) xdr_remote_domain_migrate_perform3_args, (char *) &args,
+              (xdrproc_t) xdr_remote_domain_migrate_perform3_ret, (char *) &ret) == -1)
+        goto done;
+
+    if (ret.cookie_out.cookie_out_len > 0) {
+        if (!cookieout || !cookieoutlen) {
+            remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("caller ignores cookieout or cookieoutlen"));
+            goto error;
+        }
+        *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
+        *cookieoutlen = ret.cookie_out.cookie_out_len;
+    }
+
+    rv = 0;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+
+error:
+    VIR_FREE(ret.cookie_out.cookie_out_val);
+    goto done;
+}
+
+
+static int
+remoteDomainMigrateFinish3(virConnectPtr dconn,
+                           const char *dname,
+                           const char *cookiein,
+                           int cookieinlen,
+                           char **cookieout,
+                           int *cookieoutlen,
+                           const char *uri,
+                           unsigned long flags,
+                           int cancelled,
+                           virDomainPtr *ddom)
+{
+    remote_domain_migrate_finish3_args args;
+    remote_domain_migrate_finish3_ret ret;
+    struct private_data *priv = dconn->privateData;
+    int rv = -1;
+
+    remoteDriverLock(priv);
+
+    *ddom = NULL;
+    memset(&args, 0, sizeof(args));
+    memset(&ret, 0, sizeof(ret));
+
+    args.cookie_in.cookie_in_val = (char *)cookiein;
+    args.cookie_in.cookie_in_len = cookieinlen;
+    args.dname = (char *) dname;
+    args.uri = (char *) uri;
+    args.flags = flags;
+    args.cancelled = cancelled;
+
+    if (call (dconn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_FINISH3,
+              (xdrproc_t) xdr_remote_domain_migrate_finish3_args, (char *) &args,
+              (xdrproc_t) xdr_remote_domain_migrate_finish3_ret, (char *) &ret) == -1)
+        goto done;
+
+    *ddom = get_domain(dconn, ret.ddom);
+
+    if (ret.cookie_out.cookie_out_len > 0) {
+        if (!cookieout || !cookieoutlen) {
+            remoteError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("caller ignores cookieout or cookieoutlen"));
+            goto error;
+        }
+        *cookieout = ret.cookie_out.cookie_out_val; /* Caller frees. */
+        *cookieoutlen = ret.cookie_out.cookie_out_len;
+        ret.cookie_out.cookie_out_val = NULL;
+        ret.cookie_out.cookie_out_len = 0;
+    }
+
+    xdr_free ((xdrproc_t) &xdr_remote_domain_migrate_finish3_ret, (char *) &ret);
+
+    rv = 0;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+
+error:
+    VIR_FREE(ret.cookie_out.cookie_out_val);
+    goto done;
+}
+
+
+static int
+remoteDomainMigrateConfirm3(virDomainPtr domain,
+                            const char *cookiein,
+                            int cookieinlen,
+                            unsigned long flags,
+                            int cancelled)
+{
+    int rv = -1;
+    remote_domain_migrate_confirm3_args args;
+    struct private_data *priv = domain->conn->privateData;
+
+    remoteDriverLock(priv);
+
+    memset(&args, 0, sizeof(args));
+
+    make_nonnull_domain (&args.dom, domain);
+    args.cookie_in.cookie_in_len = cookieinlen;
+    args.cookie_in.cookie_in_val = (char *) cookiein;
+    args.flags = flags;
+    args.cancelled = cancelled;
+
+    if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_MIGRATE_CONFIRM3,
+              (xdrproc_t) xdr_remote_domain_migrate_confirm3_args, (char *) &args,
+              (xdrproc_t) xdr_void, (char *) NULL) == -1)
+        goto done;
+
+    rv = 0;
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
+
 /*----------------------------------------------------------------------*/
 
 static struct remote_thread_call *
@@ -11062,6 +11405,22 @@ remoteDomainEventQueueFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
  * but if they do then virterror_internal.has been set.
  */
 static virDomainPtr
+get_domain (virConnectPtr conn, remote_domain domain)
+{
+    virDomainPtr dom = NULL;
+    if (domain) {
+        dom = virGetDomain (conn, domain->name, BAD_CAST domain->uuid);
+        if (dom) dom->id = domain->id;
+    }
+    return dom;
+}
+
+/* get_nonnull_domain and get_nonnull_network turn an on-wire
+ * (name, uuid) pair into virDomainPtr or virNetworkPtr object.
+ * These can return NULL if underlying memory allocations fail,
+ * but if they do then virterror_internal.has been set.
+ */
+static virDomainPtr
 get_nonnull_domain (virConnectPtr conn, remote_nonnull_domain domain)
 {
     virDomainPtr dom;
@@ -11298,12 +11657,12 @@ static virDriver remote_driver = {
     remoteDomainSnapshotDelete, /* domainSnapshotDelete */
     remoteQemuDomainMonitorCommand, /* qemuDomainMonitorCommand */
     remoteDomainOpenConsole, /* domainOpenConsole */
-    NULL, /* domainMigrateBegin3 */
-    NULL, /* domainMigratePrepare3 */
-    NULL, /* domainMigratePrepareTunnel3 */
-    NULL, /* domainMigratePerform3 */
-    NULL, /* domainMigrateFinish3 */
-    NULL, /* domainMigrateConfirm3 */
+    remoteDomainMigrateBegin3, /* domainMigrateBegin3 */
+    remoteDomainMigratePrepare3, /* domainMigratePrepare3 */
+    remoteDomainMigratePrepareTunnel3, /* domainMigratePrepareTunnel3 */
+    remoteDomainMigratePerform3, /* domainMigratePerform3 */
+    remoteDomainMigrateFinish3, /* domainMigrateFinish3 */
+    remoteDomainMigrateConfirm3, /* domainMigrateConfirm3 */
 };
 
 static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c
index 5604371..21f7e47 100644
--- a/src/remote/remote_protocol.c
+++ b/src/remote/remote_protocol.c
@@ -3902,6 +3902,169 @@ xdr_remote_storage_vol_download_args (XDR *xdrs, remote_storage_vol_download_arg
 }
 
 bool_t
+xdr_remote_domain_migrate_begin3_args (XDR *xdrs, remote_domain_migrate_begin3_args *objp)
+{
+
+         if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->flags))
+                 return FALSE;
+         if (!xdr_remote_string (xdrs, &objp->dname))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->resource))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_migrate_begin3_ret (XDR *xdrs, remote_domain_migrate_begin3_ret *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->cookie_out.cookie_out_val;
+
+         if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->cookie_out.cookie_out_len, REMOTE_MIGRATE_COOKIE_MAX))
+                 return FALSE;
+         if (!xdr_remote_nonnull_string (xdrs, &objp->xml))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_migrate_prepare3_args (XDR *xdrs, remote_domain_migrate_prepare3_args *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->cookie_in.cookie_in_val;
+
+         if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->cookie_in.cookie_in_len, REMOTE_MIGRATE_COOKIE_MAX))
+                 return FALSE;
+         if (!xdr_remote_string (xdrs, &objp->uri_in))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->flags))
+                 return FALSE;
+         if (!xdr_remote_string (xdrs, &objp->dname))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->resource))
+                 return FALSE;
+         if (!xdr_remote_nonnull_string (xdrs, &objp->dom_xml))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_migrate_prepare3_ret (XDR *xdrs, remote_domain_migrate_prepare3_ret *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->cookie_out.cookie_out_val;
+
+         if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->cookie_out.cookie_out_len, REMOTE_MIGRATE_COOKIE_MAX))
+                 return FALSE;
+         if (!xdr_remote_string (xdrs, &objp->uri_out))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_migrate_prepare_tunnel3_args (XDR *xdrs, remote_domain_migrate_prepare_tunnel3_args *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->cookie_in.cookie_in_val;
+
+         if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->cookie_in.cookie_in_len, REMOTE_MIGRATE_COOKIE_MAX))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->flags))
+                 return FALSE;
+         if (!xdr_remote_string (xdrs, &objp->dname))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->resource))
+                 return FALSE;
+         if (!xdr_remote_nonnull_string (xdrs, &objp->dom_xml))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_migrate_prepare_tunnel3_ret (XDR *xdrs, remote_domain_migrate_prepare_tunnel3_ret *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->cookie_out.cookie_out_val;
+
+         if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->cookie_out.cookie_out_len, REMOTE_MIGRATE_COOKIE_MAX))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_migrate_perform3_args (XDR *xdrs, remote_domain_migrate_perform3_args *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->cookie_in.cookie_in_val;
+
+         if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+                 return FALSE;
+         if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->cookie_in.cookie_in_len, REMOTE_MIGRATE_COOKIE_MAX))
+                 return FALSE;
+         if (!xdr_remote_nonnull_string (xdrs, &objp->uri))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->flags))
+                 return FALSE;
+         if (!xdr_remote_string (xdrs, &objp->dname))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->resource))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_migrate_perform3_ret (XDR *xdrs, remote_domain_migrate_perform3_ret *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->cookie_out.cookie_out_val;
+
+         if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->cookie_out.cookie_out_len, REMOTE_MIGRATE_COOKIE_MAX))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_migrate_finish3_args (XDR *xdrs, remote_domain_migrate_finish3_args *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->cookie_in.cookie_in_val;
+
+         if (!xdr_remote_nonnull_string (xdrs, &objp->dname))
+                 return FALSE;
+         if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->cookie_in.cookie_in_len, REMOTE_MIGRATE_COOKIE_MAX))
+                 return FALSE;
+         if (!xdr_remote_nonnull_string (xdrs, &objp->uri))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->flags))
+                 return FALSE;
+         if (!xdr_int (xdrs, &objp->cancelled))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_migrate_finish3_ret (XDR *xdrs, remote_domain_migrate_finish3_ret *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->cookie_out.cookie_out_val;
+
+         if (!xdr_remote_domain (xdrs, &objp->ddom))
+                 return FALSE;
+         if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->cookie_out.cookie_out_len, REMOTE_MIGRATE_COOKIE_MAX))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_migrate_confirm3_args (XDR *xdrs, remote_domain_migrate_confirm3_args *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->cookie_in.cookie_in_val;
+
+         if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+                 return FALSE;
+         if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->cookie_in.cookie_in_len, REMOTE_MIGRATE_COOKIE_MAX))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->flags))
+                 return FALSE;
+         if (!xdr_int (xdrs, &objp->cancelled))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
 xdr_remote_procedure (XDR *xdrs, remote_procedure *objp)
 {
 
diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h
index d9bf151..385d431 100644
--- a/src/remote/remote_protocol.h
+++ b/src/remote/remote_protocol.h
@@ -2200,6 +2200,118 @@ struct remote_storage_vol_download_args {
         u_int flags;
 };
 typedef struct remote_storage_vol_download_args remote_storage_vol_download_args;
+
+struct remote_domain_migrate_begin3_args {
+        remote_nonnull_domain dom;
+        uint64_t flags;
+        remote_string dname;
+        uint64_t resource;
+};
+typedef struct remote_domain_migrate_begin3_args remote_domain_migrate_begin3_args;
+
+struct remote_domain_migrate_begin3_ret {
+        struct {
+                u_int cookie_out_len;
+                char *cookie_out_val;
+        } cookie_out;
+        remote_nonnull_string xml;
+};
+typedef struct remote_domain_migrate_begin3_ret remote_domain_migrate_begin3_ret;
+
+struct remote_domain_migrate_prepare3_args {
+        struct {
+                u_int cookie_in_len;
+                char *cookie_in_val;
+        } cookie_in;
+        remote_string uri_in;
+        uint64_t flags;
+        remote_string dname;
+        uint64_t resource;
+        remote_nonnull_string dom_xml;
+};
+typedef struct remote_domain_migrate_prepare3_args remote_domain_migrate_prepare3_args;
+
+struct remote_domain_migrate_prepare3_ret {
+        struct {
+                u_int cookie_out_len;
+                char *cookie_out_val;
+        } cookie_out;
+        remote_string uri_out;
+};
+typedef struct remote_domain_migrate_prepare3_ret remote_domain_migrate_prepare3_ret;
+
+struct remote_domain_migrate_prepare_tunnel3_args {
+        struct {
+                u_int cookie_in_len;
+                char *cookie_in_val;
+        } cookie_in;
+        uint64_t flags;
+        remote_string dname;
+        uint64_t resource;
+        remote_nonnull_string dom_xml;
+};
+typedef struct remote_domain_migrate_prepare_tunnel3_args remote_domain_migrate_prepare_tunnel3_args;
+
+struct remote_domain_migrate_prepare_tunnel3_ret {
+        struct {
+                u_int cookie_out_len;
+                char *cookie_out_val;
+        } cookie_out;
+};
+typedef struct remote_domain_migrate_prepare_tunnel3_ret remote_domain_migrate_prepare_tunnel3_ret;
+
+struct remote_domain_migrate_perform3_args {
+        remote_nonnull_domain dom;
+        struct {
+                u_int cookie_in_len;
+                char *cookie_in_val;
+        } cookie_in;
+        remote_nonnull_string uri;
+        uint64_t flags;
+        remote_string dname;
+        uint64_t resource;
+};
+typedef struct remote_domain_migrate_perform3_args remote_domain_migrate_perform3_args;
+
+struct remote_domain_migrate_perform3_ret {
+        struct {
+                u_int cookie_out_len;
+                char *cookie_out_val;
+        } cookie_out;
+};
+typedef struct remote_domain_migrate_perform3_ret remote_domain_migrate_perform3_ret;
+
+struct remote_domain_migrate_finish3_args {
+        remote_nonnull_string dname;
+        struct {
+                u_int cookie_in_len;
+                char *cookie_in_val;
+        } cookie_in;
+        remote_nonnull_string uri;
+        uint64_t flags;
+        int cancelled;
+};
+typedef struct remote_domain_migrate_finish3_args remote_domain_migrate_finish3_args;
+
+struct remote_domain_migrate_finish3_ret {
+        remote_domain ddom;
+        struct {
+                u_int cookie_out_len;
+                char *cookie_out_val;
+        } cookie_out;
+};
+typedef struct remote_domain_migrate_finish3_ret remote_domain_migrate_finish3_ret;
+
+struct remote_domain_migrate_confirm3_args {
+        remote_nonnull_domain dom;
+        struct {
+                u_int cookie_in_len;
+                char *cookie_in_val;
+        } cookie_in;
+        uint64_t flags;
+        int cancelled;
+};
+typedef struct remote_domain_migrate_confirm3_args remote_domain_migrate_confirm3_args;
 #define REMOTE_PROGRAM 0x20008086
 #define REMOTE_PROTOCOL_VERSION 1
 
@@ -2413,6 +2525,12 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207,
         REMOTE_PROC_STORAGE_VOL_UPLOAD = 208,
         REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209,
+        REMOTE_PROC_DOMAIN_MIGRATE_BEGIN3 = 210,
+        REMOTE_PROC_DOMAIN_MIGRATE_PREPARE3 = 211,
+        REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3 = 212,
+        REMOTE_PROC_DOMAIN_MIGRATE_PERFORM3 = 213,
+        REMOTE_PROC_DOMAIN_MIGRATE_FINISH3 = 214,
+        REMOTE_PROC_DOMAIN_MIGRATE_CONFIRM3 = 215,
 };
 typedef enum remote_procedure remote_procedure;
 
@@ -2796,6 +2914,17 @@ extern  bool_t xdr_remote_domain_snapshot_delete_args (XDR *, remote_domain_snap
 extern  bool_t xdr_remote_domain_open_console_args (XDR *, remote_domain_open_console_args*);
 extern  bool_t xdr_remote_storage_vol_upload_args (XDR *, remote_storage_vol_upload_args*);
 extern  bool_t xdr_remote_storage_vol_download_args (XDR *, remote_storage_vol_download_args*);
+extern  bool_t xdr_remote_domain_migrate_begin3_args (XDR *, remote_domain_migrate_begin3_args*);
+extern  bool_t xdr_remote_domain_migrate_begin3_ret (XDR *, remote_domain_migrate_begin3_ret*);
+extern  bool_t xdr_remote_domain_migrate_prepare3_args (XDR *, remote_domain_migrate_prepare3_args*);
+extern  bool_t xdr_remote_domain_migrate_prepare3_ret (XDR *, remote_domain_migrate_prepare3_ret*);
+extern  bool_t xdr_remote_domain_migrate_prepare_tunnel3_args (XDR *, remote_domain_migrate_prepare_tunnel3_args*);
+extern  bool_t xdr_remote_domain_migrate_prepare_tunnel3_ret (XDR *, remote_domain_migrate_prepare_tunnel3_ret*);
+extern  bool_t xdr_remote_domain_migrate_perform3_args (XDR *, remote_domain_migrate_perform3_args*);
+extern  bool_t xdr_remote_domain_migrate_perform3_ret (XDR *, remote_domain_migrate_perform3_ret*);
+extern  bool_t xdr_remote_domain_migrate_finish3_args (XDR *, remote_domain_migrate_finish3_args*);
+extern  bool_t xdr_remote_domain_migrate_finish3_ret (XDR *, remote_domain_migrate_finish3_ret*);
+extern  bool_t xdr_remote_domain_migrate_confirm3_args (XDR *, remote_domain_migrate_confirm3_args*);
 extern  bool_t xdr_remote_procedure (XDR *, remote_procedure*);
 extern  bool_t xdr_remote_message_type (XDR *, remote_message_type*);
 extern  bool_t xdr_remote_message_status (XDR *, remote_message_status*);
@@ -3153,6 +3282,17 @@ extern bool_t xdr_remote_domain_snapshot_delete_args ();
 extern bool_t xdr_remote_domain_open_console_args ();
 extern bool_t xdr_remote_storage_vol_upload_args ();
 extern bool_t xdr_remote_storage_vol_download_args ();
+extern bool_t xdr_remote_domain_migrate_begin3_args ();
+extern bool_t xdr_remote_domain_migrate_begin3_ret ();
+extern bool_t xdr_remote_domain_migrate_prepare3_args ();
+extern bool_t xdr_remote_domain_migrate_prepare3_ret ();
+extern bool_t xdr_remote_domain_migrate_prepare_tunnel3_args ();
+extern bool_t xdr_remote_domain_migrate_prepare_tunnel3_ret ();
+extern bool_t xdr_remote_domain_migrate_perform3_args ();
+extern bool_t xdr_remote_domain_migrate_perform3_ret ();
+extern bool_t xdr_remote_domain_migrate_finish3_args ();
+extern bool_t xdr_remote_domain_migrate_finish3_ret ();
+extern bool_t xdr_remote_domain_migrate_confirm3_args ();
 extern bool_t xdr_remote_procedure ();
 extern bool_t xdr_remote_message_type ();
 extern bool_t xdr_remote_message_status ();
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 675eccd..a5d6fb2 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -1940,6 +1940,76 @@ struct remote_storage_vol_download_args {
     unsigned int flags;
 };
 
+struct remote_domain_migrate_begin3_args {
+    remote_nonnull_domain dom;
+    unsigned hyper flags;
+    remote_string dname;
+    unsigned hyper resource;
+};
+
+struct remote_domain_migrate_begin3_ret {
+    opaque cookie_out<REMOTE_MIGRATE_COOKIE_MAX>;
+    remote_nonnull_string xml;
+};
+
+struct remote_domain_migrate_prepare3_args {
+    opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
+    remote_string uri_in;
+    unsigned hyper flags;
+    remote_string dname;
+    unsigned hyper resource;
+    remote_nonnull_string dom_xml;
+};
+
+struct remote_domain_migrate_prepare3_ret {
+    opaque cookie_out<REMOTE_MIGRATE_COOKIE_MAX>;
+    remote_string uri_out;
+};
+
+struct remote_domain_migrate_prepare_tunnel3_args {
+    opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
+    unsigned hyper flags;
+    remote_string dname;
+    unsigned hyper resource;
+    remote_nonnull_string dom_xml;
+};
+
+struct remote_domain_migrate_prepare_tunnel3_ret {
+    opaque cookie_out<REMOTE_MIGRATE_COOKIE_MAX>;
+};
+
+struct remote_domain_migrate_perform3_args {
+    remote_nonnull_domain dom;
+    opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
+    remote_nonnull_string uri;
+    unsigned hyper flags;
+    remote_string dname;
+    unsigned hyper resource;
+};
+
+struct remote_domain_migrate_perform3_ret {
+    opaque cookie_out<REMOTE_MIGRATE_COOKIE_MAX>;
+};
+
+struct remote_domain_migrate_finish3_args {
+    remote_nonnull_string dname;
+    opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
+    remote_nonnull_string uri;
+    unsigned hyper flags;
+    int cancelled;
+};
+
+struct remote_domain_migrate_finish3_ret {
+    remote_domain ddom;
+    opaque cookie_out<REMOTE_MIGRATE_COOKIE_MAX>;
+};
+
+struct remote_domain_migrate_confirm3_args {
+    remote_nonnull_domain dom;
+    opaque cookie_in<REMOTE_MIGRATE_COOKIE_MAX>;
+    unsigned hyper flags;
+    int cancelled;
+};
 
 /*----- Protocol. -----*/
 
@@ -2176,7 +2246,14 @@ enum remote_procedure {
     REMOTE_PROC_DOMAIN_GET_BLKIO_PARAMETERS = 206,
     REMOTE_PROC_DOMAIN_MIGRATE_SET_MAX_SPEED = 207,
     REMOTE_PROC_STORAGE_VOL_UPLOAD = 208,
-    REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209
+    REMOTE_PROC_STORAGE_VOL_DOWNLOAD = 209,
+    REMOTE_PROC_DOMAIN_MIGRATE_BEGIN3 = 210,
+
+    REMOTE_PROC_DOMAIN_MIGRATE_PREPARE3 = 211,
+    REMOTE_PROC_DOMAIN_MIGRATE_PREPARE_TUNNEL3 = 212,
+    REMOTE_PROC_DOMAIN_MIGRATE_PERFORM3 = 213,
+    REMOTE_PROC_DOMAIN_MIGRATE_FINISH3 = 214,
+    REMOTE_PROC_DOMAIN_MIGRATE_CONFIRM3 = 215
 
     /*
      * Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 944553c..0c2317a 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1427,6 +1427,96 @@ struct remote_storage_vol_download_args {
         uint64_t                   length;
         u_int                      flags;
 };
+struct remote_domain_migrate_begin3_args {
+        remote_nonnull_domain      dom;
+        uint64_t                   flags;
+        remote_string              dname;
+        uint64_t                   resource;
+};
+struct remote_domain_migrate_begin3_ret {
+        struct {
+                u_int              cookie_out_len;
+                char *             cookie_out_val;
+        } cookie_out;
+        remote_nonnull_string      xml;
+};
+struct remote_domain_migrate_prepare3_args {
+        struct {
+                u_int              cookie_in_len;
+                char *             cookie_in_val;
+        } cookie_in;
+        remote_string              uri_in;
+        uint64_t                   flags;
+        remote_string              dname;
+        uint64_t                   resource;
+        remote_nonnull_string      dom_xml;
+};
+struct remote_domain_migrate_prepare3_ret {
+        struct {
+                u_int              cookie_out_len;
+                char *             cookie_out_val;
+        } cookie_out;
+        remote_string              uri_out;
+};
+struct remote_domain_migrate_prepare_tunnel3_args {
+        struct {
+                u_int              cookie_in_len;
+                char *             cookie_in_val;
+        } cookie_in;
+        uint64_t                   flags;
+        remote_string              dname;
+        uint64_t                   resource;
+        remote_nonnull_string      dom_xml;
+};
+struct remote_domain_migrate_prepare_tunnel3_ret {
+        struct {
+                u_int              cookie_out_len;
+                char *             cookie_out_val;
+        } cookie_out;
+};
+struct remote_domain_migrate_perform3_args {
+        remote_nonnull_domain      dom;
+        struct {
+                u_int              cookie_in_len;
+                char *             cookie_in_val;
+        } cookie_in;
+        remote_nonnull_string      uri;
+        uint64_t                   flags;
+        remote_string              dname;
+        uint64_t                   resource;
+};
+struct remote_domain_migrate_perform3_ret {
+        struct {
+                u_int              cookie_out_len;
+                char *             cookie_out_val;
+        } cookie_out;
+};
+struct remote_domain_migrate_finish3_args {
+        remote_nonnull_string      dname;
+        struct {
+                u_int              cookie_in_len;
+                char *             cookie_in_val;
+        } cookie_in;
+        remote_nonnull_string      uri;
+        uint64_t                   flags;
+        int                        cancelled;
+};
+struct remote_domain_migrate_finish3_ret {
+        remote_domain              ddom;
+        struct {
+                u_int              cookie_out_len;
+                char *             cookie_out_val;
+        } cookie_out;
+};
+struct remote_domain_migrate_confirm3_args {
+        remote_nonnull_domain      dom;
+        struct {
+                u_int              cookie_in_len;
+                char *             cookie_in_val;
+        } cookie_in;
+        uint64_t                   flags;
+        int                        cancelled;
+};
 struct remote_message_header {
         u_int                      prog;
         u_int                      vers;
-- 
1.7.4.4




More information about the libvir-list mailing list