qemu_driver: add check for qemu capabilities requirements

query-dirty-rate command is used for virsh domstats by default, but this
is available only on qemu >=5.2.0.

By this commit, qemu domain stats will check capabilities requirements before issuing actual query.

Signed-off-by: Hiroki Narukawa <hnarukaw@yahoo-corp.jp>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Hiroki Narukawa 2021-10-15 18:49:19 +09:00 committed by Michal Privoznik
parent f29d7c3e69
commit fd56272203

View File

@ -18710,13 +18710,30 @@ static struct qemuDomainGetStatsWorker qemuDomainGetStatsWorkers[] = {
static int static int
qemuDomainGetStatsCheckSupport(unsigned int *stats, qemuDomainGetStatsCheckSupport(unsigned int *stats,
bool enforce) bool enforce,
virDomainObj *vm)
{ {
qemuDomainObjPrivate *priv = vm->privateData;
unsigned int supportedstats = 0; unsigned int supportedstats = 0;
size_t i; size_t i;
for (i = 0; qemuDomainGetStatsWorkers[i].func; i++) for (i = 0; qemuDomainGetStatsWorkers[i].func; i++) {
supportedstats |= qemuDomainGetStatsWorkers[i].stats; bool supportedByQemu = true;
virQEMUCapsFlags *requiredCaps = qemuDomainGetStatsWorkers[i].requiredCaps;
while (requiredCaps && *requiredCaps != QEMU_CAPS_LAST) {
if (!virQEMUCapsGet(priv->qemuCaps, *requiredCaps)) {
supportedByQemu = false;
break;
}
requiredCaps++;
}
if (supportedByQemu) {
supportedstats |= qemuDomainGetStatsWorkers[i].stats;
}
}
if (*stats == 0) { if (*stats == 0) {
*stats = supportedstats; *stats = supportedstats;
@ -18726,7 +18743,7 @@ qemuDomainGetStatsCheckSupport(unsigned int *stats,
if (enforce && if (enforce &&
*stats & ~supportedstats) { *stats & ~supportedstats) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
_("Stats types bits 0x%x are not supported by this daemon"), _("Stats types bits 0x%x are not supported by this daemon or QEMU"),
*stats & ~supportedstats); *stats & ~supportedstats);
return -1; return -1;
} }
@ -18801,7 +18818,6 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
int nstats = 0; int nstats = 0;
size_t i; size_t i;
int ret = -1; int ret = -1;
unsigned int privflags = 0;
unsigned int domflags = 0; unsigned int domflags = 0;
unsigned int lflags = flags & (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE | unsigned int lflags = flags & (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE |
VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT | VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT |
@ -18817,9 +18833,6 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
if (virConnectGetAllDomainStatsEnsureACL(conn) < 0) if (virConnectGetAllDomainStatsEnsureACL(conn) < 0)
return -1; return -1;
if (qemuDomainGetStatsCheckSupport(&stats, enforce) < 0)
return -1;
if (ndoms) { if (ndoms) {
if (virDomainObjListConvert(driver->domains, conn, doms, ndoms, &vms, if (virDomainObjListConvert(driver->domains, conn, doms, ndoms, &vms,
&nvms, virConnectGetAllDomainStatsCheckACL, &nvms, virConnectGetAllDomainStatsCheckACL,
@ -18834,16 +18847,24 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
tmpstats = g_new0(virDomainStatsRecordPtr, nvms + 1); tmpstats = g_new0(virDomainStatsRecordPtr, nvms + 1);
if (qemuDomainGetStatsNeedMonitor(stats))
privflags |= QEMU_DOMAIN_STATS_HAVE_JOB;
for (i = 0; i < nvms; i++) { for (i = 0; i < nvms; i++) {
virDomainStatsRecordPtr tmp = NULL; virDomainStatsRecordPtr tmp = NULL;
unsigned int privflags = 0;
unsigned int requestedStats = stats;
domflags = 0; domflags = 0;
vm = vms[i]; vm = vms[i];
virObjectLock(vm); virObjectLock(vm);
if (qemuDomainGetStatsCheckSupport(&requestedStats, enforce, vm) < 0) {
virObjectUnlock(vm);
goto cleanup;
}
if (qemuDomainGetStatsNeedMonitor(requestedStats))
privflags |= QEMU_DOMAIN_STATS_HAVE_JOB;
if (HAVE_JOB(privflags)) { if (HAVE_JOB(privflags)) {
int rv; int rv;
@ -18859,7 +18880,7 @@ qemuConnectGetAllDomainStats(virConnectPtr conn,
if (flags & VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING) if (flags & VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING)
domflags |= QEMU_DOMAIN_STATS_BACKING; domflags |= QEMU_DOMAIN_STATS_BACKING;
if (qemuDomainGetStats(conn, vm, stats, &tmp, domflags) < 0) { if (qemuDomainGetStats(conn, vm, requestedStats, &tmp, domflags) < 0) {
if (HAVE_JOB(domflags) && vm) if (HAVE_JOB(domflags) && vm)
qemuDomainObjEndJob(driver, vm); qemuDomainObjEndJob(driver, vm);