Simplify the doTunnelMigrate() method by pulling out the code
which opens/closes the virConnectPtr object into a parent
method
* qemu/qemu_driver.c: Add doPeer2PeerMigrate which then calls
doTunnelMigrate with dconn & dom_xml
---
docs/libvirt-api.xml | 8 ++++-
docs/libvirt-refs.xml | 18 +++++++++++
src/qemu/qemu_driver.c | 78 +++++++++++++++++++++++++++++++----------------
3 files changed, 75 insertions(+), 29 deletions(-)
diff --git a/docs/libvirt-api.xml b/docs/libvirt-api.xml
index 88dc246..a32c397 100644
--- a/docs/libvirt-api.xml
+++ b/docs/libvirt-api.xml
@@ -47,6 +47,7 @@
<exports symbol='VIR_MIGRATE_LIVE' type='enum'/>
<exports symbol='VIR_DOMAIN_EVENT_STOPPED_DESTROYED'
type='enum'/>
<exports symbol='VIR_DOMAIN_EVENT_DEFINED_ADDED'
type='enum'/>
+ <exports symbol='VIR_VCPU_BLOCKED' type='enum'/>
<exports symbol='VIR_SECRET_USAGE_TYPE_NONE' type='enum'/>
<exports symbol='VIR_DOMAIN_EVENT_STARTED_MIGRATED'
type='enum'/>
<exports symbol='VIR_STREAM_EVENT_HANGUP' type='enum'/>
@@ -82,7 +83,7 @@
<exports symbol='VIR_STREAM_EVENT_WRITABLE' type='enum'/>
<exports symbol='VIR_DOMAIN_SCHED_FIELD_DOUBLE' type='enum'/>
<exports symbol='VIR_DOMAIN_SCHED_FIELD_LLONG' type='enum'/>
- <exports symbol='VIR_VCPU_BLOCKED' type='enum'/>
+ <exports symbol='VIR_MIGRATE_TUNNELLED' type='enum'/>
<exports symbol='VIR_DOMAIN_SCHED_FIELD_BOOLEAN'
type='enum'/>
<exports symbol='VIR_DOMAIN_XML_INACTIVE' type='enum'/>
<exports symbol='VIR_STORAGE_VOL_BLOCK' type='enum'/>
@@ -718,7 +719,8 @@
<enum name='VIR_FROM_XML' file='virterror' value='5'
type='virErrorDomain' info='Error in the XML code'/>
<enum name='VIR_MEMORY_PHYSICAL' file='libvirt' value='2'
type='virDomainMemoryFlags' info=' addresses are physical addresses'/>
<enum name='VIR_MEMORY_VIRTUAL' file='libvirt' value='1'
type='virDomainMemoryFlags' info='addresses are virtual addresses'/>
- <enum name='VIR_MIGRATE_LIVE' file='libvirt' value='1'
type='virDomainMigrateFlags' info=' live migration'/>
+ <enum name='VIR_MIGRATE_LIVE' file='libvirt' value='1'
type='virDomainMigrateFlags' info='live migration'/>
+ <enum name='VIR_MIGRATE_TUNNELLED' file='libvirt'
value='2' type='virDomainMigrateFlags' info=' tunnelled
migration'/>
<enum name='VIR_SECRET_USAGE_TYPE_NONE' file='libvirt'
value='0' type='virSecretUsageType'/>
<enum name='VIR_SECRET_USAGE_TYPE_VOLUME' file='libvirt'
value='1' type='virSecretUsageType' info=' Expect more owner types
later...'/>
<enum name='VIR_STORAGE_POOL_BUILDING' file='libvirt'
value='1' type='virStoragePoolState' info='Initializing pool, not
available'/>
@@ -1596,6 +1598,8 @@ host given by dconn (a connection to the destination host).
Flags may be one of more of the following:
VIR_MIGRATE_LIVE Attempt a live migration.
+ VIR_MIGRATE_TUNNELLED Attempt to do a migration tunnelled through the
+ libvirt RPC mechanism
If a hypervisor supports renaming domains during migration,
then you may set the dname parameter to the new name (otherwise
diff --git a/docs/libvirt-refs.xml b/docs/libvirt-refs.xml
index 08034e4..0352e77 100644
--- a/docs/libvirt-refs.xml
+++ b/docs/libvirt-refs.xml
@@ -154,6 +154,7 @@
<reference name='VIR_MEMORY_PHYSICAL'
href='html/libvirt-libvirt.html#VIR_MEMORY_PHYSICAL'/>
<reference name='VIR_MEMORY_VIRTUAL'
href='html/libvirt-libvirt.html#VIR_MEMORY_VIRTUAL'/>
<reference name='VIR_MIGRATE_LIVE'
href='html/libvirt-libvirt.html#VIR_MIGRATE_LIVE'/>
+ <reference name='VIR_MIGRATE_TUNNELLED'
href='html/libvirt-libvirt.html#VIR_MIGRATE_TUNNELLED'/>
<reference name='VIR_NODEINFO_MAXCPUS'
href='html/libvirt-libvirt.html#VIR_NODEINFO_MAXCPUS'/>
<reference name='VIR_SECRET_USAGE_TYPE_NONE'
href='html/libvirt-libvirt.html#VIR_SECRET_USAGE_TYPE_NONE'/>
<reference name='VIR_SECRET_USAGE_TYPE_VOLUME'
href='html/libvirt-libvirt.html#VIR_SECRET_USAGE_TYPE_VOLUME'/>
@@ -659,6 +660,7 @@
<ref name='VIR_MEMORY_PHYSICAL'/>
<ref name='VIR_MEMORY_VIRTUAL'/>
<ref name='VIR_MIGRATE_LIVE'/>
+ <ref name='VIR_MIGRATE_TUNNELLED'/>
<ref name='VIR_NODEINFO_MAXCPUS'/>
<ref name='VIR_SECRET_USAGE_TYPE_NONE'/>
<ref name='VIR_SECRET_USAGE_TYPE_VOLUME'/>
@@ -1596,6 +1598,7 @@
<ref name='VIR_MEMORY_PHYSICAL'/>
<ref name='VIR_MEMORY_VIRTUAL'/>
<ref name='VIR_MIGRATE_LIVE'/>
+ <ref name='VIR_MIGRATE_TUNNELLED'/>
<ref name='VIR_NODEINFO_MAXCPUS'/>
<ref name='VIR_SECRET_USAGE_TYPE_NONE'/>
<ref name='VIR_SECRET_USAGE_TYPE_VOLUME'/>
@@ -2654,6 +2657,9 @@
<ref name='virNetworkGetUUIDString'/>
<ref name='virSecretGetUUIDString'/>
</word>
+ <word name='RPC'>
+ <ref name='virDomainMigrate'/>
+ </word>
<word name='Re-attach'>
<ref name='virNodeDeviceReAttach'/>
</word>
@@ -2912,6 +2918,9 @@
<word name='VIR_MIGRATE_LIVE'>
<ref name='virDomainMigrate'/>
</word>
+ <word name='VIR_MIGRATE_TUNNELLED'>
+ <ref name='virDomainMigrate'/>
+ </word>
<word name='VIR_SECRET_USAGE_TYPE_VOLUME'>
<ref name='virSecretGetUsageID'/>
</word>
@@ -5604,6 +5613,9 @@
<word name='means'>
<ref name='virDomainPinVcpu'/>
</word>
+ <word name='mechanism'>
+ <ref name='virDomainMigrate'/>
+ </word>
<word name='mem'>
<ref name='_virNodeInfo'/>
</word>
@@ -7381,6 +7393,9 @@
<ref name='virStoragePoolRef'/>
<ref name='virStorageVolRef'/>
</word>
+ <word name='through'>
+ <ref name='virDomainMigrate'/>
+ </word>
<word name='time'>
<ref name='_virDomainInfo'/>
<ref name='_virVcpuInfo'/>
@@ -7443,6 +7458,9 @@
<word name='trying'>
<ref name='virConnectOpen'/>
</word>
+ <word name='tunnelled'>
+ <ref name='virDomainMigrate'/>
+ </word>
<word name='turn'>
<ref name='virConnectOpen'/>
</word>
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 561b0c8..fe5a376 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6467,7 +6467,9 @@ cleanup:
static int doTunnelMigrate(virDomainPtr dom,
+ virConnectPtr dconn,
virDomainObjPtr vm,
+ const char *dom_xml,
const char *uri,
unsigned long flags,
const char *dname,
@@ -6477,13 +6479,11 @@ static int doTunnelMigrate(virDomainPtr dom,
int client_sock, qemu_sock;
struct sockaddr_un sa_qemu, sa_client;
socklen_t addrlen;
- virConnectPtr dconn;
virDomainPtr ddomain;
int retval = -1;
ssize_t bytes;
char buffer[65536];
virStreamPtr st;
- char *dom_xml = NULL;
char *unixfile = NULL;
int internalret;
unsigned int qemuCmdFlags;
@@ -6494,35 +6494,15 @@ static int doTunnelMigrate(virDomainPtr dom,
* destination side is completely setup before we touch the source
*/
- dconn = virConnectOpen(uri);
- if (dconn == NULL) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- _("Failed to connect to remote libvirt URI %s"),
uri);
- return -1;
- }
- if (!VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
- VIR_DRV_FEATURE_MIGRATION_V2)) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s",
- _("Destination libvirt does not support required migration
protocol 2"));
- goto close_dconn;
- }
-
st = virStreamNew(dconn, 0);
if (st == NULL)
/* virStreamNew only fails on OOM, and it reports the error itself */
- goto close_dconn;
-
- dom_xml = virDomainDefFormat(dom->conn, vm->def, VIR_DOMAIN_XML_SECURE);
- if (!dom_xml) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
- "%s", _("failed to get domain xml"));
- goto close_stream;
- }
+ goto cleanup;
internalret = dconn->driver->domainMigratePrepareTunnel(dconn, st,
flags, dname,
resource, dom_xml);
- VIR_FREE(dom_xml);
+
if (internalret < 0)
/* domainMigratePrepareTunnel sets the error for us */
goto close_stream;
@@ -6663,13 +6643,57 @@ close_stream:
/* don't call virStreamFree(), because that resets any pending errors */
virUnrefStream(st);
-close_dconn:
+cleanup:
+ return retval;
+}
+
+
+static int doPeer2PeerMigrate(virDomainPtr dom,
+ virDomainObjPtr vm,
+ const char *uri,
+ unsigned long flags,
+ const char *dname,
+ unsigned long resource)
+{
+ int ret = -1;
+ virConnectPtr dconn = NULL;
+ char *dom_xml;
+
+ /* the order of operations is important here; we make sure the
+ * destination side is completely setup before we touch the source
+ */
+
+ dconn = virConnectOpen(uri);
+ if (dconn == NULL) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ _("Failed to connect to remote libvirt URI %s"),
uri);
+ return -1;
+ }
+ if (!VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
+ VIR_DRV_FEATURE_MIGRATION_V2)) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
"%s",
+ _("Destination libvirt does not support required migration
protocol 2"));
+ goto cleanup;
+ }
+
+ dom_xml = virDomainDefFormat(dom->conn, vm->def, VIR_DOMAIN_XML_SECURE);
+ if (!dom_xml) {
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+ "%s", _("failed to get domain xml"));
+ goto cleanup;
+ }
+
+ ret = doTunnelMigrate(dom, dconn, vm, dom_xml, uri, flags, dname, resource);
+
+cleanup:
+ VIR_FREE(dom_xml);
/* don't call virConnectClose(), because that resets any pending errors */
virUnrefConnect(dconn);
- return retval;
+ return ret;
}
+
/* Perform is the second step, and it runs on the source host. */
static int
qemudDomainMigratePerform (virDomainPtr dom,
@@ -6717,7 +6741,7 @@ qemudDomainMigratePerform (virDomainPtr dom,
}
if ((flags & VIR_MIGRATE_TUNNELLED)) {
- if (doTunnelMigrate(dom, vm, uri, flags, dname, resource) < 0)
+ if (doPeer2PeerMigrate(dom, vm, uri, flags, dname, resource) < 0)
/* doTunnelMigrate already set the error, so just get out */
goto cleanup;
} else {
--
1.6.2.5