mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 12:35:17 +00:00
Implement extensible migration APIs in qemu driver
This commit is contained in:
parent
1004d6323a
commit
35461438cb
@ -1095,6 +1095,7 @@ qemuConnectSupportsFeature(virConnectPtr conn, int feature)
|
||||
case VIR_DRV_FEATURE_TYPED_PARAM_STRING:
|
||||
case VIR_DRV_FEATURE_XML_MIGRATABLE:
|
||||
case VIR_DRV_FEATURE_MIGRATION_OFFLINE:
|
||||
case VIR_DRV_FEATURE_MIGRATION_PARAMS:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
@ -10173,6 +10174,43 @@ qemuDomainMigrateBegin3(virDomainPtr domain,
|
||||
cookieout, cookieoutlen, flags);
|
||||
}
|
||||
|
||||
static char *
|
||||
qemuDomainMigrateBegin3Params(virDomainPtr domain,
|
||||
virTypedParameterPtr params,
|
||||
int nparams,
|
||||
char **cookieout,
|
||||
int *cookieoutlen,
|
||||
unsigned int flags)
|
||||
{
|
||||
const char *xmlin = NULL;
|
||||
const char *dname = NULL;
|
||||
virDomainObjPtr vm;
|
||||
|
||||
virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
|
||||
if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
|
||||
return NULL;
|
||||
|
||||
if (virTypedParamsGetString(params, nparams,
|
||||
VIR_MIGRATE_PARAM_DEST_XML,
|
||||
&xmlin) < 0 ||
|
||||
virTypedParamsGetString(params, nparams,
|
||||
VIR_MIGRATE_PARAM_DEST_NAME,
|
||||
&dname) < 0)
|
||||
return NULL;
|
||||
|
||||
if (!(vm = qemuDomObjFromDomain(domain)))
|
||||
return NULL;
|
||||
|
||||
if (virDomainMigrateBegin3ParamsEnsureACL(domain->conn, vm->def) < 0) {
|
||||
virObjectUnlock(vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return qemuMigrationBegin(domain->conn, vm, xmlin, dname,
|
||||
cookieout, cookieoutlen, flags);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuDomainMigratePrepare3(virConnectPtr dconn,
|
||||
const char *cookiein,
|
||||
@ -10219,6 +10257,66 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
qemuDomainMigratePrepare3Params(virConnectPtr dconn,
|
||||
virTypedParameterPtr params,
|
||||
int nparams,
|
||||
const char *cookiein,
|
||||
int cookieinlen,
|
||||
char **cookieout,
|
||||
int *cookieoutlen,
|
||||
char **uri_out,
|
||||
unsigned int flags)
|
||||
{
|
||||
virQEMUDriverPtr driver = dconn->privateData;
|
||||
virDomainDefPtr def = NULL;
|
||||
const char *dom_xml = NULL;
|
||||
const char *dname = NULL;
|
||||
const char *uri_in = NULL;
|
||||
int ret = -1;
|
||||
|
||||
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
|
||||
if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
|
||||
return -1;
|
||||
|
||||
if (virTypedParamsGetString(params, nparams,
|
||||
VIR_MIGRATE_PARAM_DEST_XML,
|
||||
&dom_xml) < 0 ||
|
||||
virTypedParamsGetString(params, nparams,
|
||||
VIR_MIGRATE_PARAM_DEST_NAME,
|
||||
&dname) < 0 ||
|
||||
virTypedParamsGetString(params, nparams,
|
||||
VIR_MIGRATE_PARAM_URI,
|
||||
&uri_in) < 0)
|
||||
return -1;
|
||||
|
||||
if (flags & VIR_MIGRATE_TUNNELLED) {
|
||||
/* this is a logical error; we never should have gotten here with
|
||||
* VIR_MIGRATE_TUNNELLED set
|
||||
*/
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Tunnelled migration requested but invalid "
|
||||
"RPC method called"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(def = qemuMigrationPrepareDef(driver, dom_xml, dname)))
|
||||
goto cleanup;
|
||||
|
||||
if (virDomainMigratePrepare3ParamsEnsureACL(dconn, def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = qemuMigrationPrepareDirect(driver, dconn,
|
||||
cookiein, cookieinlen,
|
||||
cookieout, cookieoutlen,
|
||||
uri_in, uri_out,
|
||||
&def, flags);
|
||||
|
||||
cleanup:
|
||||
virDomainDefFree(def);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuDomainMigratePrepareTunnel3(virConnectPtr dconn,
|
||||
@ -10260,6 +10358,57 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
qemuDomainMigratePrepareTunnel3Params(virConnectPtr dconn,
|
||||
virStreamPtr st,
|
||||
virTypedParameterPtr params,
|
||||
int nparams,
|
||||
const char *cookiein,
|
||||
int cookieinlen,
|
||||
char **cookieout,
|
||||
int *cookieoutlen,
|
||||
unsigned int flags)
|
||||
{
|
||||
virQEMUDriverPtr driver = dconn->privateData;
|
||||
virDomainDefPtr def = NULL;
|
||||
const char *dom_xml = NULL;
|
||||
const char *dname = NULL;
|
||||
int ret = -1;
|
||||
|
||||
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
|
||||
if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
|
||||
return -1;
|
||||
|
||||
if (virTypedParamsGetString(params, nparams,
|
||||
VIR_MIGRATE_PARAM_DEST_XML,
|
||||
&dom_xml) < 0 ||
|
||||
virTypedParamsGetString(params, nparams,
|
||||
VIR_MIGRATE_PARAM_DEST_NAME,
|
||||
&dname) < 0)
|
||||
return -1;
|
||||
|
||||
if (!(flags & VIR_MIGRATE_TUNNELLED)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("PrepareTunnel called but no TUNNELLED flag set"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!(def = qemuMigrationPrepareDef(driver, dom_xml, dname)))
|
||||
goto cleanup;
|
||||
|
||||
if (virDomainMigratePrepareTunnel3ParamsEnsureACL(dconn, def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = qemuMigrationPrepareTunnel(driver, dconn,
|
||||
cookiein, cookieinlen,
|
||||
cookieout, cookieoutlen,
|
||||
st, &def, flags);
|
||||
|
||||
cleanup:
|
||||
virDomainDefFree(def);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuDomainMigratePerform3(virDomainPtr dom,
|
||||
@ -10293,6 +10442,56 @@ qemuDomainMigratePerform3(virDomainPtr dom,
|
||||
flags, dname, resource, true);
|
||||
}
|
||||
|
||||
static int
|
||||
qemuDomainMigratePerform3Params(virDomainPtr dom,
|
||||
const char *dconnuri,
|
||||
virTypedParameterPtr params,
|
||||
int nparams,
|
||||
const char *cookiein,
|
||||
int cookieinlen,
|
||||
char **cookieout,
|
||||
int *cookieoutlen,
|
||||
unsigned int flags)
|
||||
{
|
||||
virQEMUDriverPtr driver = dom->conn->privateData;
|
||||
virDomainObjPtr vm;
|
||||
const char *dom_xml = NULL;
|
||||
const char *dname = NULL;
|
||||
const char *uri = NULL;
|
||||
unsigned long long bandwidth = 0;
|
||||
|
||||
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
|
||||
if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
|
||||
return -1;
|
||||
|
||||
if (virTypedParamsGetString(params, nparams,
|
||||
VIR_MIGRATE_PARAM_DEST_XML,
|
||||
&dom_xml) < 0 ||
|
||||
virTypedParamsGetString(params, nparams,
|
||||
VIR_MIGRATE_PARAM_DEST_NAME,
|
||||
&dname) < 0 ||
|
||||
virTypedParamsGetString(params, nparams,
|
||||
VIR_MIGRATE_PARAM_URI,
|
||||
&uri) < 0 ||
|
||||
virTypedParamsGetULLong(params, nparams,
|
||||
VIR_MIGRATE_PARAM_BANDWIDTH,
|
||||
&bandwidth) < 0)
|
||||
return -1;
|
||||
|
||||
if (!(vm = qemuDomObjFromDomain(dom)))
|
||||
return -1;
|
||||
|
||||
if (virDomainMigratePerform3ParamsEnsureACL(dom->conn, vm->def) < 0) {
|
||||
virObjectUnlock(vm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return qemuMigrationPerform(driver, dom->conn, vm, dom_xml,
|
||||
dconnuri, uri, cookiein, cookieinlen,
|
||||
cookieout, cookieoutlen,
|
||||
flags, dname, bandwidth, true);
|
||||
}
|
||||
|
||||
|
||||
static virDomainPtr
|
||||
qemuDomainMigrateFinish3(virConnectPtr dconn,
|
||||
@ -10308,29 +10507,72 @@ qemuDomainMigrateFinish3(virConnectPtr dconn,
|
||||
{
|
||||
virQEMUDriverPtr driver = dconn->privateData;
|
||||
virDomainObjPtr vm;
|
||||
virDomainPtr dom = NULL;
|
||||
|
||||
virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
|
||||
|
||||
vm = virDomainObjListFindByName(driver->domains, dname);
|
||||
if (!vm) {
|
||||
if (!dname ||
|
||||
!(vm = virDomainObjListFindByName(driver->domains, dname))) {
|
||||
virReportError(VIR_ERR_NO_DOMAIN,
|
||||
_("no domain with matching name '%s'"), dname);
|
||||
goto cleanup;
|
||||
_("no domain with matching name '%s'"),
|
||||
NULLSTR(dname));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (virDomainMigrateFinish3EnsureACL(dconn, vm->def) < 0)
|
||||
goto cleanup;
|
||||
if (virDomainMigrateFinish3EnsureACL(dconn, vm->def) < 0) {
|
||||
virObjectUnlock(vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dom = qemuMigrationFinish(driver, dconn, vm,
|
||||
cookiein, cookieinlen,
|
||||
cookieout, cookieoutlen,
|
||||
flags, cancelled, true);
|
||||
|
||||
cleanup:
|
||||
return dom;
|
||||
return qemuMigrationFinish(driver, dconn, vm,
|
||||
cookiein, cookieinlen,
|
||||
cookieout, cookieoutlen,
|
||||
flags, cancelled, true);
|
||||
}
|
||||
|
||||
static virDomainPtr
|
||||
qemuDomainMigrateFinish3Params(virConnectPtr dconn,
|
||||
virTypedParameterPtr params,
|
||||
int nparams,
|
||||
const char *cookiein,
|
||||
int cookieinlen,
|
||||
char **cookieout,
|
||||
int *cookieoutlen,
|
||||
unsigned int flags,
|
||||
int cancelled)
|
||||
{
|
||||
virQEMUDriverPtr driver = dconn->privateData;
|
||||
virDomainObjPtr vm;
|
||||
const char *dname = NULL;
|
||||
|
||||
virCheckFlags(QEMU_MIGRATION_FLAGS, NULL);
|
||||
if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
|
||||
return NULL;
|
||||
|
||||
if (virTypedParamsGetString(params, nparams,
|
||||
VIR_MIGRATE_PARAM_DEST_NAME,
|
||||
&dname) < 0)
|
||||
return NULL;
|
||||
|
||||
if (!dname ||
|
||||
!(vm = virDomainObjListFindByName(driver->domains, dname))) {
|
||||
virReportError(VIR_ERR_NO_DOMAIN,
|
||||
_("no domain with matching name '%s'"),
|
||||
NULLSTR(dname));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (virDomainMigrateFinish3ParamsEnsureACL(dconn, vm->def) < 0) {
|
||||
virObjectUnlock(vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return qemuMigrationFinish(driver, dconn, vm,
|
||||
cookiein, cookieinlen,
|
||||
cookieout, cookieoutlen,
|
||||
flags, cancelled, true);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuDomainMigrateConfirm3(virDomainPtr domain,
|
||||
const char *cookiein,
|
||||
@ -10354,6 +10596,34 @@ qemuDomainMigrateConfirm3(virDomainPtr domain,
|
||||
flags, cancelled);
|
||||
}
|
||||
|
||||
static int
|
||||
qemuDomainMigrateConfirm3Params(virDomainPtr domain,
|
||||
virTypedParameterPtr params,
|
||||
int nparams,
|
||||
const char *cookiein,
|
||||
int cookieinlen,
|
||||
unsigned int flags,
|
||||
int cancelled)
|
||||
{
|
||||
virDomainObjPtr vm;
|
||||
|
||||
virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
|
||||
|
||||
if (virTypedParamsValidate(params, nparams, QEMU_MIGRATION_PARAMETERS) < 0)
|
||||
return -1;
|
||||
|
||||
if (!(vm = qemuDomObjFromDomain(domain)))
|
||||
return -1;
|
||||
|
||||
if (virDomainMigrateConfirm3ParamsEnsureACL(domain->conn, vm->def) < 0) {
|
||||
virObjectUnlock(vm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return qemuMigrationConfirm(domain->conn, vm, cookiein, cookieinlen,
|
||||
flags, cancelled);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuNodeDeviceGetPciInfo(virNodeDeviceDefPtr def,
|
||||
@ -15776,6 +16046,12 @@ static virDriver qemuDriver = {
|
||||
.nodeGetCPUMap = qemuNodeGetCPUMap, /* 1.0.0 */
|
||||
.domainFSTrim = qemuDomainFSTrim, /* 1.0.1 */
|
||||
.domainOpenChannel = qemuDomainOpenChannel, /* 1.0.2 */
|
||||
.domainMigrateBegin3Params = qemuDomainMigrateBegin3Params, /* 1.1.0 */
|
||||
.domainMigratePrepare3Params = qemuDomainMigratePrepare3Params, /* 1.1.0 */
|
||||
.domainMigratePrepareTunnel3Params = qemuDomainMigratePrepareTunnel3Params, /* 1.1.0 */
|
||||
.domainMigratePerform3Params = qemuDomainMigratePerform3Params, /* 1.1.0 */
|
||||
.domainMigrateFinish3Params = qemuDomainMigrateFinish3Params, /* 1.1.0 */
|
||||
.domainMigrateConfirm3Params = qemuDomainMigrateConfirm3Params, /* 1.1.0 */
|
||||
};
|
||||
|
||||
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include "viruri.h"
|
||||
#include "virhook.h"
|
||||
#include "virstring.h"
|
||||
#include "virtypedparam.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||
|
||||
@ -3564,16 +3565,18 @@ cleanup:
|
||||
* from libvirt.c, but running in source libvirtd context,
|
||||
* instead of client app context & also adding in tunnel
|
||||
* handling */
|
||||
static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
|
||||
virConnectPtr sconn,
|
||||
virConnectPtr dconn,
|
||||
virDomainObjPtr vm,
|
||||
const char *xmlin,
|
||||
const char *dconnuri,
|
||||
const char *uri,
|
||||
unsigned long flags,
|
||||
const char *dname,
|
||||
unsigned long resource)
|
||||
static int
|
||||
doPeer2PeerMigrate3(virQEMUDriverPtr driver,
|
||||
virConnectPtr sconn,
|
||||
virConnectPtr dconn,
|
||||
const char *dconnuri,
|
||||
virDomainObjPtr vm,
|
||||
const char *xmlin,
|
||||
const char *dname,
|
||||
const char *uri,
|
||||
unsigned long long bandwidth,
|
||||
bool useParams,
|
||||
unsigned long flags)
|
||||
{
|
||||
virDomainPtr ddomain = NULL;
|
||||
char *uri_out = NULL;
|
||||
@ -3584,15 +3587,18 @@ static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
|
||||
int cookieoutlen = 0;
|
||||
int ret = -1;
|
||||
virErrorPtr orig_err = NULL;
|
||||
bool cancelled;
|
||||
bool cancelled = true;
|
||||
virStreamPtr st = NULL;
|
||||
unsigned int destflags = flags & ~VIR_MIGRATE_ABORT_ON_ERROR;
|
||||
|
||||
VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, vm=%p, xmlin=%s, "
|
||||
"dconnuri=%s, uri=%s, flags=%lx, dname=%s, resource=%lu",
|
||||
driver, sconn, dconn, vm, NULLSTR(xmlin),
|
||||
NULLSTR(dconnuri), NULLSTR(uri), flags,
|
||||
NULLSTR(dname), resource);
|
||||
virTypedParameterPtr params = NULL;
|
||||
int nparams = 0;
|
||||
int maxparams = 0;
|
||||
|
||||
VIR_DEBUG("driver=%p, sconn=%p, dconn=%p, dconnuri=%s, vm=%p, xmlin=%s, "
|
||||
"dname=%s, uri=%s, bandwidth=%llu, useParams=%d, flags=%lx",
|
||||
driver, sconn, dconn, NULLSTR(dconnuri), vm, NULLSTR(xmlin),
|
||||
NULLSTR(dname), NULLSTR(uri), bandwidth, useParams, flags);
|
||||
|
||||
/* Unlike the virDomainMigrateVersion3 counterpart, we don't need
|
||||
* to worry about auto-setting the VIR_MIGRATE_CHANGE_PROTECTION
|
||||
@ -3604,6 +3610,28 @@ static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
|
||||
if (!dom_xml)
|
||||
goto cleanup;
|
||||
|
||||
if (useParams) {
|
||||
if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
|
||||
VIR_MIGRATE_PARAM_DEST_XML, dom_xml) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (dname &&
|
||||
virTypedParamsAddString(¶ms, &nparams, &maxparams,
|
||||
VIR_MIGRATE_PARAM_DEST_NAME, dname) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (uri &&
|
||||
virTypedParamsAddString(¶ms, &nparams, &maxparams,
|
||||
VIR_MIGRATE_PARAM_URI, uri) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (bandwidth &&
|
||||
virTypedParamsAddULLong(¶ms, &nparams, &maxparams,
|
||||
VIR_MIGRATE_PARAM_BANDWIDTH,
|
||||
bandwidth) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED)
|
||||
flags |= VIR_MIGRATE_PAUSED;
|
||||
|
||||
@ -3617,16 +3645,27 @@ static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
|
||||
goto cleanup;
|
||||
|
||||
qemuDomainObjEnterRemote(vm);
|
||||
ret = dconn->driver->domainMigratePrepareTunnel3
|
||||
(dconn, st, cookiein, cookieinlen,
|
||||
&cookieout, &cookieoutlen,
|
||||
destflags, dname, resource, dom_xml);
|
||||
if (useParams) {
|
||||
ret = dconn->driver->domainMigratePrepareTunnel3Params
|
||||
(dconn, st, params, nparams, cookiein, cookieinlen,
|
||||
&cookieout, &cookieoutlen, destflags);
|
||||
} else {
|
||||
ret = dconn->driver->domainMigratePrepareTunnel3
|
||||
(dconn, st, cookiein, cookieinlen, &cookieout, &cookieoutlen,
|
||||
destflags, dname, bandwidth, dom_xml);
|
||||
}
|
||||
qemuDomainObjExitRemote(vm);
|
||||
} else {
|
||||
qemuDomainObjEnterRemote(vm);
|
||||
ret = dconn->driver->domainMigratePrepare3
|
||||
(dconn, cookiein, cookieinlen, &cookieout, &cookieoutlen,
|
||||
uri, &uri_out, destflags, dname, resource, dom_xml);
|
||||
if (useParams) {
|
||||
ret = dconn->driver->domainMigratePrepare3Params
|
||||
(dconn, params, nparams, cookiein, cookieinlen,
|
||||
&cookieout, &cookieoutlen, &uri_out, destflags);
|
||||
} else {
|
||||
ret = dconn->driver->domainMigratePrepare3
|
||||
(dconn, cookiein, cookieinlen, &cookieout, &cookieoutlen,
|
||||
uri, &uri_out, destflags, dname, bandwidth, dom_xml);
|
||||
}
|
||||
qemuDomainObjExitRemote(vm);
|
||||
}
|
||||
VIR_FREE(dom_xml);
|
||||
@ -3641,11 +3680,15 @@ static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!(flags & VIR_MIGRATE_TUNNELLED) &&
|
||||
(uri_out == NULL)) {
|
||||
if (uri_out) {
|
||||
uri = uri_out;
|
||||
if (useParams &&
|
||||
virTypedParamsReplaceString(¶ms, &nparams,
|
||||
VIR_MIGRATE_PARAM_URI, uri_out) < 0)
|
||||
goto finish;
|
||||
} else if (!uri && !(flags & VIR_MIGRATE_TUNNELLED)) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("domainMigratePrepare3 did not set uri"));
|
||||
cancelled = true;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@ -3654,23 +3697,24 @@ static int doPeer2PeerMigrate3(virQEMUDriverPtr driver,
|
||||
* running, but in paused state until the destination can
|
||||
* confirm migration completion.
|
||||
*/
|
||||
VIR_DEBUG("Perform3 %p uri=%s uri_out=%s", sconn, uri, uri_out);
|
||||
VIR_DEBUG("Perform3 %p uri=%s", sconn, NULLSTR(uri));
|
||||
qemuMigrationJobSetPhase(driver, vm, QEMU_MIGRATION_PHASE_PERFORM3);
|
||||
VIR_FREE(cookiein);
|
||||
cookiein = cookieout;
|
||||
cookieinlen = cookieoutlen;
|
||||
cookieout = NULL;
|
||||
cookieoutlen = 0;
|
||||
if (flags & VIR_MIGRATE_TUNNELLED)
|
||||
if (flags & VIR_MIGRATE_TUNNELLED) {
|
||||
ret = doTunnelMigrate(driver, vm, st,
|
||||
cookiein, cookieinlen,
|
||||
&cookieout, &cookieoutlen,
|
||||
flags, resource, dconn);
|
||||
else
|
||||
ret = doNativeMigrate(driver, vm, uri_out,
|
||||
flags, bandwidth, dconn);
|
||||
} else {
|
||||
ret = doNativeMigrate(driver, vm, uri,
|
||||
cookiein, cookieinlen,
|
||||
&cookieout, &cookieoutlen,
|
||||
flags, resource, dconn);
|
||||
flags, bandwidth, dconn);
|
||||
}
|
||||
|
||||
/* Perform failed. Make sure Finish doesn't overwrite the error */
|
||||
if (ret < 0) {
|
||||
@ -3698,12 +3742,29 @@ finish:
|
||||
cookieinlen = cookieoutlen;
|
||||
cookieout = NULL;
|
||||
cookieoutlen = 0;
|
||||
dname = dname ? dname : vm->def->name;
|
||||
qemuDomainObjEnterRemote(vm);
|
||||
ddomain = dconn->driver->domainMigrateFinish3
|
||||
(dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen,
|
||||
dconnuri, uri_out ? uri_out : uri, destflags, cancelled);
|
||||
qemuDomainObjExitRemote(vm);
|
||||
|
||||
if (useParams) {
|
||||
if (virTypedParamsGetString(params, nparams,
|
||||
VIR_MIGRATE_PARAM_DEST_NAME, NULL) <= 0 &&
|
||||
virTypedParamsReplaceString(¶ms, &nparams,
|
||||
VIR_MIGRATE_PARAM_DEST_NAME,
|
||||
vm->def->name) < 0) {
|
||||
ddomain = NULL;
|
||||
} else {
|
||||
qemuDomainObjEnterRemote(vm);
|
||||
ddomain = dconn->driver->domainMigrateFinish3Params
|
||||
(dconn, params, nparams, cookiein, cookieinlen,
|
||||
&cookieout, &cookieoutlen, destflags, cancelled);
|
||||
qemuDomainObjExitRemote(vm);
|
||||
}
|
||||
} else {
|
||||
dname = dname ? dname : vm->def->name;
|
||||
qemuDomainObjEnterRemote(vm);
|
||||
ddomain = dconn->driver->domainMigrateFinish3
|
||||
(dconn, dname, cookiein, cookieinlen, &cookieout, &cookieoutlen,
|
||||
dconnuri, uri, destflags, cancelled);
|
||||
qemuDomainObjExitRemote(vm);
|
||||
}
|
||||
|
||||
/* If ddomain is NULL, then we were unable to start
|
||||
* the guest on the target, and must restart on the
|
||||
@ -3759,7 +3820,7 @@ finish:
|
||||
VIR_FREE(uri_out);
|
||||
VIR_FREE(cookiein);
|
||||
VIR_FREE(cookieout);
|
||||
|
||||
virTypedParamsFree(params, nparams);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3781,6 +3842,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
|
||||
virErrorPtr orig_err = NULL;
|
||||
bool offline = false;
|
||||
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||
bool useParams;
|
||||
|
||||
VIR_DEBUG("driver=%p, sconn=%p, vm=%p, xmlin=%s, dconnuri=%s, "
|
||||
"uri=%s, flags=%lx, dname=%s, resource=%lu",
|
||||
@ -3815,6 +3877,8 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
|
||||
*/
|
||||
*v3proto = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
|
||||
VIR_DRV_FEATURE_MIGRATION_V3);
|
||||
useParams = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
|
||||
VIR_DRV_FEATURE_MIGRATION_PARAMS);
|
||||
if (flags & VIR_MIGRATE_OFFLINE)
|
||||
offline = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
|
||||
VIR_DRV_FEATURE_MIGRATION_OFFLINE);
|
||||
@ -3826,6 +3890,17 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Only xmlin, dname, uri, and bandwidth parameters can be used with
|
||||
* old-style APIs. */
|
||||
#if 0
|
||||
if (!useParams && /* any new parameter */) {
|
||||
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
||||
_("Migration APIs with extensible parameters are not "
|
||||
"supported but extended parameters were passed"));
|
||||
goto cleanup;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (flags & VIR_MIGRATE_OFFLINE && !offline) {
|
||||
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
||||
_("offline migration is not supported by "
|
||||
@ -3847,12 +3922,13 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
|
||||
* Therefore it is safe to clear the bit here. */
|
||||
flags &= ~VIR_MIGRATE_CHANGE_PROTECTION;
|
||||
|
||||
if (*v3proto)
|
||||
ret = doPeer2PeerMigrate3(driver, sconn, dconn, vm, xmlin,
|
||||
dconnuri, uri, flags, dname, resource);
|
||||
else
|
||||
if (*v3proto) {
|
||||
ret = doPeer2PeerMigrate3(driver, sconn, dconn, dconnuri, vm, xmlin,
|
||||
dname, uri, resource, useParams, flags);
|
||||
} else {
|
||||
ret = doPeer2PeerMigrate2(driver, sconn, dconn, vm,
|
||||
dconnuri, flags, dname, resource);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
orig_err = virSaveLastError();
|
||||
|
@ -41,6 +41,15 @@
|
||||
VIR_MIGRATE_COMPRESSED | \
|
||||
VIR_MIGRATE_ABORT_ON_ERROR)
|
||||
|
||||
/* All supported migration parameters and their types. */
|
||||
# define QEMU_MIGRATION_PARAMETERS \
|
||||
VIR_MIGRATE_PARAM_URI, VIR_TYPED_PARAM_STRING, \
|
||||
VIR_MIGRATE_PARAM_DEST_NAME, VIR_TYPED_PARAM_STRING, \
|
||||
VIR_MIGRATE_PARAM_DEST_XML, VIR_TYPED_PARAM_STRING, \
|
||||
VIR_MIGRATE_PARAM_BANDWIDTH, VIR_TYPED_PARAM_ULLONG, \
|
||||
NULL
|
||||
|
||||
|
||||
enum qemuMigrationJobPhase {
|
||||
QEMU_MIGRATION_PHASE_NONE = 0,
|
||||
QEMU_MIGRATION_PHASE_PERFORM2,
|
||||
|
Loading…
x
Reference in New Issue
Block a user