qemu: Store supported migration capabilities in a bitmap

Each time we need to check whether a given migration capability is
supported by QEMU, we call query-migrate-capabilities QMP command and
lookup the capability in the returned list. Asking for the list of
supported capabilities once when we connect to QEMU and storing the
result in a bitmap is much better and we don't need to enter a monitor
just to check whether a migration capability is supported.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
Jiri Denemark 2017-10-17 21:39:41 +02:00
parent 19bade7ad9
commit 765d9b1245
3 changed files with 78 additions and 12 deletions

View File

@ -1806,6 +1806,9 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePtr priv)
priv->reconnectBlockjobs = VIR_TRISTATE_BOOL_ABSENT; priv->reconnectBlockjobs = VIR_TRISTATE_BOOL_ABSENT;
priv->allowReboot = VIR_TRISTATE_BOOL_ABSENT; priv->allowReboot = VIR_TRISTATE_BOOL_ABSENT;
virBitmapFree(priv->migrationCaps);
priv->migrationCaps = NULL;
} }
@ -10242,3 +10245,68 @@ qemuDomainCheckCCWS390AddressSupport(const virDomainDef *def,
} }
return true; return true;
} }
int
qemuDomainCheckMigrationCapabilities(virQEMUDriverPtr driver,
virDomainObjPtr vm,
qemuDomainAsyncJob asyncJob)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
char **caps = NULL;
char **capStr;
int ret = -1;
int rc;
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
return -1;
rc = qemuMonitorGetMigrationCapabilities(priv->mon, &caps);
if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
goto cleanup;
if (!caps) {
ret = 0;
goto cleanup;
}
priv->migrationCaps = virBitmapNew(QEMU_MONITOR_MIGRATION_CAPS_LAST);
if (!priv->migrationCaps)
goto cleanup;
for (capStr = caps; *capStr; capStr++) {
int cap = qemuMonitorMigrationCapsTypeFromString(*capStr);
if (cap < 0) {
VIR_DEBUG("Unknown migration capability: '%s'", *capStr);
} else {
ignore_value(virBitmapSetBit(priv->migrationCaps, cap));
VIR_DEBUG("Found migration capability: '%s'", *capStr);
}
}
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT)) {
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
goto cleanup;
rc = qemuMonitorSetMigrationCapability(priv->mon,
QEMU_MONITOR_MIGRATION_CAPS_EVENTS,
true);
if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup;
if (rc < 0) {
virResetLastError();
VIR_DEBUG("Cannot enable migration events; clearing capability");
virQEMUCapsClear(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
}
}
ret = 0;
cleanup:
virStringListFree(caps);
return ret;
}

View File

@ -324,6 +324,10 @@ struct _qemuDomainObjPrivate {
/* Tracks blockjob state for vm. Valid only while reconnecting to qemu. */ /* Tracks blockjob state for vm. Valid only while reconnecting to qemu. */
virTristateBool reconnectBlockjobs; virTristateBool reconnectBlockjobs;
/* Migration capabilities. Rechecked on reconnect, not to be saved in
* private XML. */
virBitmapPtr migrationCaps;
}; };
# define QEMU_DOMAIN_PRIVATE(vm) \ # define QEMU_DOMAIN_PRIVATE(vm) \
@ -1000,4 +1004,9 @@ bool qemuDomainCheckCCWS390AddressSupport(const virDomainDef *def,
virQEMUCapsPtr qemuCaps, virQEMUCapsPtr qemuCaps,
const char *devicename); const char *devicename);
int
qemuDomainCheckMigrationCapabilities(virQEMUDriverPtr driver,
virDomainObjPtr vm,
qemuDomainAsyncJob asyncJob);
#endif /* __QEMU_DOMAIN_H__ */ #endif /* __QEMU_DOMAIN_H__ */

View File

@ -1816,18 +1816,7 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob,
if (qemuProcessInitMonitor(driver, vm, asyncJob) < 0) if (qemuProcessInitMonitor(driver, vm, asyncJob) < 0)
return -1; return -1;
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0) if (qemuDomainCheckMigrationCapabilities(driver, vm, asyncJob) < 0)
return -1;
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT) &&
qemuMonitorSetMigrationCapability(priv->mon,
QEMU_MONITOR_MIGRATION_CAPS_EVENTS,
true) < 0) {
VIR_DEBUG("Cannot enable migration events; clearing capability");
virQEMUCapsClear(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
}
if (qemuDomainObjExitMonitor(driver, vm) < 0)
return -1; return -1;
return 0; return 0;