mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-20 07:59:00 +00:00
qemu: Add support for sending capabilities in migration cookie
Some migration capabilities may be enabled automatically, but only if both sides of migration support them. Thus we need to be able transfer the list of supported migration capabilities in migration cookie. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
0cd77cd18b
commit
40ced93b01
@ -1917,6 +1917,7 @@ qemuMigrationSrcBeginPhase(virQEMUDriverPtr driver,
|
||||
goto cleanup;
|
||||
|
||||
if (qemuMigrationBakeCookie(mig, driver, vm,
|
||||
QEMU_MIGRATION_SOURCE,
|
||||
cookieout, cookieoutlen,
|
||||
cookieFlags) < 0)
|
||||
goto cleanup;
|
||||
@ -2429,8 +2430,9 @@ qemuMigrationDstPrepareAny(virQEMUDriverPtr driver,
|
||||
goto stopjob;
|
||||
|
||||
done:
|
||||
if (qemuMigrationBakeCookie(mig, driver, vm, cookieout,
|
||||
cookieoutlen, cookieFlags) < 0) {
|
||||
if (qemuMigrationBakeCookie(mig, driver, vm,
|
||||
QEMU_MIGRATION_DESTINATION,
|
||||
cookieout, cookieoutlen, cookieFlags) < 0) {
|
||||
/* We could tear down the whole guest here, but
|
||||
* cookie data is (so far) non-critical, so that
|
||||
* seems a little harsh. We'll just warn for now.
|
||||
@ -3523,8 +3525,9 @@ qemuMigrationSrcRun(virQEMUDriverPtr driver,
|
||||
QEMU_MIGRATION_COOKIE_STATS;
|
||||
|
||||
if (qemuMigrationCookieAddPersistent(mig, &persistDef) < 0 ||
|
||||
qemuMigrationBakeCookie(mig, driver, vm, cookieout,
|
||||
cookieoutlen, cookieFlags) < 0) {
|
||||
qemuMigrationBakeCookie(mig, driver, vm,
|
||||
QEMU_MIGRATION_SOURCE,
|
||||
cookieout, cookieoutlen, cookieFlags) < 0) {
|
||||
VIR_WARN("Unable to encode migration cookie");
|
||||
}
|
||||
|
||||
@ -5019,7 +5022,9 @@ qemuMigrationDstFinish(virQEMUDriverPtr driver,
|
||||
priv->job.completed->status = QEMU_DOMAIN_JOB_STATUS_COMPLETED;
|
||||
}
|
||||
|
||||
if (qemuMigrationBakeCookie(mig, driver, vm, cookieout, cookieoutlen,
|
||||
if (qemuMigrationBakeCookie(mig, driver, vm,
|
||||
QEMU_MIGRATION_DESTINATION,
|
||||
cookieout, cookieoutlen,
|
||||
QEMU_MIGRATION_COOKIE_STATS) < 0)
|
||||
VIR_WARN("Unable to encode migration cookie");
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include "qemu_domain.h"
|
||||
#include "qemu_migration_cookie.h"
|
||||
#include "qemu_migration_params.h"
|
||||
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||
@ -50,7 +51,8 @@ VIR_ENUM_IMPL(qemuMigrationCookieFlag,
|
||||
"memory-hotplug",
|
||||
"cpu-hotplug",
|
||||
"cpu",
|
||||
"allowReboot");
|
||||
"allowReboot",
|
||||
"capabilities");
|
||||
|
||||
|
||||
static void
|
||||
@ -94,6 +96,18 @@ qemuMigrationCookieNBDFree(qemuMigrationCookieNBDPtr nbd)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
qemuMigrationCookieCapsFree(qemuMigrationCookieCapsPtr caps)
|
||||
{
|
||||
if (!caps)
|
||||
return;
|
||||
|
||||
virBitmapFree(caps->supported);
|
||||
virBitmapFree(caps->automatic);
|
||||
VIR_FREE(caps);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
qemuMigrationCookieFree(qemuMigrationCookiePtr mig)
|
||||
{
|
||||
@ -112,6 +126,7 @@ qemuMigrationCookieFree(qemuMigrationCookiePtr mig)
|
||||
VIR_FREE(mig->lockDriver);
|
||||
VIR_FREE(mig->jobInfo);
|
||||
virCPUDefFree(mig->cpu);
|
||||
qemuMigrationCookieCapsFree(mig->caps);
|
||||
VIR_FREE(mig);
|
||||
}
|
||||
|
||||
@ -550,6 +565,33 @@ qemuMigrationCookieAddAllowReboot(qemuMigrationCookiePtr mig,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuMigrationCookieAddCaps(qemuMigrationCookiePtr mig,
|
||||
virDomainObjPtr vm,
|
||||
qemuMigrationParty party)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
|
||||
qemuMigrationCookieCapsFree(mig->caps);
|
||||
if (VIR_ALLOC(mig->caps) < 0)
|
||||
return -1;
|
||||
|
||||
if (priv->migrationCaps)
|
||||
mig->caps->supported = virBitmapNewCopy(priv->migrationCaps);
|
||||
else
|
||||
mig->caps->supported = virBitmapNew(0);
|
||||
|
||||
mig->caps->automatic = qemuMigrationParamsGetAlwaysOnCaps(party);
|
||||
|
||||
if (!mig->caps->supported || !mig->caps->automatic)
|
||||
return -1;
|
||||
|
||||
mig->flags |= QEMU_MIGRATION_COOKIE_CAPS;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
qemuMigrationCookieGraphicsXMLFormat(virBufferPtr buf,
|
||||
qemuMigrationCookieGraphicsPtr grap)
|
||||
@ -710,6 +752,33 @@ qemuMigrationCookieStatisticsXMLFormat(virBufferPtr buf,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
qemuMigrationCookieCapsXMLFormat(virBufferPtr buf,
|
||||
qemuMigrationCookieCapsPtr caps)
|
||||
{
|
||||
qemuMigrationCapability cap;
|
||||
|
||||
virBufferAddLit(buf, "<capabilities>\n");
|
||||
virBufferAdjustIndent(buf, 2);
|
||||
|
||||
for (cap = 0; cap < QEMU_MIGRATION_CAP_LAST; cap++) {
|
||||
bool supported = false;
|
||||
bool automatic = false;
|
||||
|
||||
ignore_value(virBitmapGetBit(caps->supported, cap, &supported));
|
||||
ignore_value(virBitmapGetBit(caps->automatic, cap, &automatic));
|
||||
if (supported) {
|
||||
virBufferAsprintf(buf, "<cap name='%s' auto='%s'/>\n",
|
||||
qemuMigrationCapabilityTypeToString(cap),
|
||||
automatic ? "yes" : "no");
|
||||
}
|
||||
}
|
||||
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
virBufferAddLit(buf, "</capabilities>\n");
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver,
|
||||
virBufferPtr buf,
|
||||
@ -793,6 +862,9 @@ qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver,
|
||||
if (mig->flags & QEMU_MIGRATION_COOKIE_ALLOW_REBOOT)
|
||||
qemuDomainObjPrivateXMLFormatAllowReboot(buf, mig->allowReboot);
|
||||
|
||||
if (mig->flags & QEMU_MIGRATION_COOKIE_CAPS)
|
||||
qemuMigrationCookieCapsXMLFormat(buf, mig->caps);
|
||||
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
virBufferAddLit(buf, "</qemu-migration>\n");
|
||||
return 0;
|
||||
@ -1067,6 +1139,59 @@ qemuMigrationCookieStatisticsXMLParse(xmlXPathContextPtr ctxt)
|
||||
}
|
||||
|
||||
|
||||
static qemuMigrationCookieCapsPtr
|
||||
qemuMigrationCookieCapsXMLParse(xmlXPathContextPtr ctxt)
|
||||
{
|
||||
qemuMigrationCookieCapsPtr caps = NULL;
|
||||
xmlNodePtr *nodes = NULL;
|
||||
qemuMigrationCookieCapsPtr ret = NULL;
|
||||
char *name = NULL;
|
||||
char *automatic = NULL;
|
||||
int cap;
|
||||
size_t i;
|
||||
int n;
|
||||
|
||||
if (VIR_ALLOC(caps) < 0)
|
||||
return NULL;
|
||||
|
||||
if (!(caps->supported = virBitmapNew(QEMU_MIGRATION_CAP_LAST)) ||
|
||||
!(caps->automatic = virBitmapNew(QEMU_MIGRATION_CAP_LAST)))
|
||||
goto cleanup;
|
||||
|
||||
if ((n = virXPathNodeSet("./capabilities[1]/cap", ctxt, &nodes)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (!(name = virXMLPropString(nodes[i], "name"))) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("missing migration capability name"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((cap = qemuMigrationCapabilityTypeFromString(name)) < 0)
|
||||
VIR_DEBUG("unknown migration capability '%s'", name);
|
||||
else
|
||||
ignore_value(virBitmapSetBit(caps->supported, cap));
|
||||
|
||||
if ((automatic = virXMLPropString(nodes[i], "auto")) &&
|
||||
STREQ(automatic, "yes"))
|
||||
ignore_value(virBitmapSetBit(caps->automatic, cap));
|
||||
|
||||
VIR_FREE(name);
|
||||
VIR_FREE(automatic);
|
||||
}
|
||||
|
||||
VIR_STEAL_PTR(ret, caps);
|
||||
|
||||
cleanup:
|
||||
qemuMigrationCookieCapsFree(caps);
|
||||
VIR_FREE(nodes);
|
||||
VIR_FREE(name);
|
||||
VIR_FREE(automatic);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
|
||||
virQEMUDriverPtr driver,
|
||||
@ -1246,6 +1371,10 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
|
||||
qemuDomainObjPrivateXMLParseAllowReboot(ctxt, &mig->allowReboot) < 0)
|
||||
goto error;
|
||||
|
||||
if (flags & QEMU_MIGRATION_COOKIE_CAPS &&
|
||||
!(mig->caps = qemuMigrationCookieCapsXMLParse(ctxt)))
|
||||
goto error;
|
||||
|
||||
virObjectUnref(caps);
|
||||
return 0;
|
||||
|
||||
@ -1286,6 +1415,7 @@ int
|
||||
qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
|
||||
virQEMUDriverPtr driver,
|
||||
virDomainObjPtr dom,
|
||||
qemuMigrationParty party,
|
||||
char **cookieout,
|
||||
int *cookieoutlen,
|
||||
unsigned int flags)
|
||||
@ -1329,6 +1459,10 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
|
||||
if (flags & QEMU_MIGRATION_COOKIE_ALLOW_REBOOT)
|
||||
qemuMigrationCookieAddAllowReboot(mig, dom);
|
||||
|
||||
if (flags & QEMU_MIGRATION_COOKIE_CAPS &&
|
||||
qemuMigrationCookieAddCaps(mig, dom, party) < 0)
|
||||
return -1;
|
||||
|
||||
if (!(*cookieout = qemuMigrationCookieXMLFormatStr(driver, mig)))
|
||||
return -1;
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
#ifndef __QEMU_MIGRATION_COOKIE_H__
|
||||
# define __QEMU_MIGRATION_COOKIE_H__
|
||||
|
||||
# include "qemu_migration_params.h"
|
||||
|
||||
typedef enum {
|
||||
QEMU_MIGRATION_COOKIE_FLAG_GRAPHICS,
|
||||
QEMU_MIGRATION_COOKIE_FLAG_LOCKSTATE,
|
||||
@ -30,6 +32,7 @@ typedef enum {
|
||||
QEMU_MIGRATION_COOKIE_FLAG_CPU_HOTPLUG,
|
||||
QEMU_MIGRATION_COOKIE_FLAG_CPU,
|
||||
QEMU_MIGRATION_COOKIE_FLAG_ALLOW_REBOOT,
|
||||
QEMU_MIGRATION_COOKIE_FLAG_CAPS,
|
||||
|
||||
QEMU_MIGRATION_COOKIE_FLAG_LAST
|
||||
} qemuMigrationCookieFlags;
|
||||
@ -47,6 +50,7 @@ typedef enum {
|
||||
QEMU_MIGRATION_COOKIE_CPU_HOTPLUG = (1 << QEMU_MIGRATION_COOKIE_FLAG_CPU_HOTPLUG),
|
||||
QEMU_MIGRATION_COOKIE_CPU = (1 << QEMU_MIGRATION_COOKIE_FLAG_CPU),
|
||||
QEMU_MIGRATION_COOKIE_ALLOW_REBOOT = (1 << QEMU_MIGRATION_COOKIE_FLAG_ALLOW_REBOOT),
|
||||
QEMU_MIGRATION_COOKIE_CAPS = (1 << QEMU_MIGRATION_COOKIE_FLAG_CAPS),
|
||||
} qemuMigrationCookieFeatures;
|
||||
|
||||
typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics;
|
||||
@ -92,6 +96,13 @@ struct _qemuMigrationCookieNBD {
|
||||
} *disks;
|
||||
};
|
||||
|
||||
typedef struct _qemuMigrationCookieCaps qemuMigrationCookieCaps;
|
||||
typedef qemuMigrationCookieCaps *qemuMigrationCookieCapsPtr;
|
||||
struct _qemuMigrationCookieCaps {
|
||||
virBitmapPtr supported;
|
||||
virBitmapPtr automatic;
|
||||
};
|
||||
|
||||
typedef struct _qemuMigrationCookie qemuMigrationCookie;
|
||||
typedef qemuMigrationCookie *qemuMigrationCookiePtr;
|
||||
struct _qemuMigrationCookie {
|
||||
@ -132,6 +143,9 @@ struct _qemuMigrationCookie {
|
||||
|
||||
/* If flags & QEMU_MIGRATION_COOKIE_ALLOW_REBOOT */
|
||||
virTristateBool allowReboot;
|
||||
|
||||
/* If flags & QEMU_MIGRATION_COOKIE_CAPS */
|
||||
qemuMigrationCookieCapsPtr caps;
|
||||
};
|
||||
|
||||
|
||||
@ -139,6 +153,7 @@ int
|
||||
qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
|
||||
virQEMUDriverPtr driver,
|
||||
virDomainObjPtr dom,
|
||||
qemuMigrationParty party,
|
||||
char **cookieout,
|
||||
int *cookieoutlen,
|
||||
unsigned int flags);
|
||||
|
@ -153,6 +153,26 @@ static const qemuMigrationParamType qemuMigrationParamTypes[] = {
|
||||
verify(ARRAY_CARDINALITY(qemuMigrationParamTypes) == QEMU_MIGRATION_PARAM_LAST);
|
||||
|
||||
|
||||
virBitmapPtr
|
||||
qemuMigrationParamsGetAlwaysOnCaps(qemuMigrationParty party)
|
||||
{
|
||||
virBitmapPtr caps = NULL;
|
||||
size_t i;
|
||||
|
||||
if (!(caps = virBitmapNew(QEMU_MIGRATION_CAP_LAST)))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < ARRAY_CARDINALITY(qemuMigrationParamsAlwaysOn); i++) {
|
||||
if (!(qemuMigrationParamsAlwaysOn[i].party & party))
|
||||
continue;
|
||||
|
||||
ignore_value(virBitmapSetBit(caps, qemuMigrationParamsAlwaysOn[i].cap));
|
||||
}
|
||||
|
||||
return caps;
|
||||
}
|
||||
|
||||
|
||||
static qemuMigrationParamsPtr
|
||||
qemuMigrationParamsNew(void)
|
||||
{
|
||||
|
@ -65,6 +65,9 @@ typedef enum {
|
||||
} qemuMigrationParty;
|
||||
|
||||
|
||||
virBitmapPtr
|
||||
qemuMigrationParamsGetAlwaysOnCaps(qemuMigrationParty party);
|
||||
|
||||
qemuMigrationParamsPtr
|
||||
qemuMigrationParamsFromFlags(virTypedParameterPtr params,
|
||||
int nparams,
|
||||
|
Loading…
x
Reference in New Issue
Block a user