From 802fd24506f98a4b57e3119d2b1c1387de5385e6 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Tue, 26 Sep 2017 16:37:47 +0200 Subject: [PATCH] qemu: domain: Mark if no blockjobs are active in the status XML Note when no blockjobs are running in the status XML so that we know that the backing chain will not change until we reconnect. --- src/qemu/qemu_domain.c | 38 +++++++++++++++++++++++++++++++++++ src/qemu/qemu_domain.h | 3 +++ tests/qemuxml2xmltest.c | 44 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 2bcc9839d1..f621cf7afc 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1759,6 +1759,8 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePtr priv) /* clear previously used namespaces */ virBitmapFree(priv->namespaces); priv->namespaces = NULL; + + priv->reconnectBlockjobs = VIR_TRISTATE_BOOL_ABSENT; } @@ -1854,6 +1856,20 @@ qemuDomainObjPrivateXMLFormatAutomaticPlacement(virBufferPtr buf, } +static int +qemuDomainObjPrivateXMLFormatBlockjobs(virBufferPtr buf, + virDomainObjPtr vm) +{ + virBuffer attrBuf = VIR_BUFFER_INITIALIZER; + bool bj = qemuDomainHasBlockjob(vm, false); + + virBufferAsprintf(&attrBuf, " active='%s'", + virTristateBoolTypeToString(virTristateBoolFromBool(bj))); + + return virXMLFormatElement(buf, "blockjobs", &attrBuf, NULL); +} + + static int qemuDomainObjPrivateXMLFormat(virBufferPtr buf, virDomainObjPtr vm) @@ -1976,6 +1992,9 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf, if (priv->chardevStdioLogd) virBufferAddLit(buf, "\n"); + if (qemuDomainObjPrivateXMLFormatBlockjobs(buf, vm) < 0) + return -1; + return 0; } @@ -2067,6 +2086,22 @@ qemuDomainObjPrivateXMLParseAutomaticPlacement(xmlXPathContextPtr ctxt, } +static int +qemuDomainObjPrivateXMLParseBlockjobs(qemuDomainObjPrivatePtr priv, + xmlXPathContextPtr ctxt) +{ + char *active; + int tmp; + + if ((active = virXPathString("string(./blockjobs/@active)", ctxt)) && + (tmp = virTristateBoolTypeFromString(active)) > 0) + priv->reconnectBlockjobs = tmp; + + VIR_FREE(active); + return 0; +} + + static int qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, virDomainObjPtr vm, @@ -2282,6 +2317,9 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, priv->chardevStdioLogd = virXPathBoolean("boolean(./chardevStdioLogd)", ctxt) == 1; + if (qemuDomainObjPrivateXMLParseBlockjobs(priv, ctxt) < 0) + goto error; + return 0; error: diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index f92841ceb9..c34cd37fc4 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -320,6 +320,9 @@ struct _qemuDomainObjPrivate { /* If true virtlogd is used as stdio handler for character devices. */ bool chardevStdioLogd; + + /* Tracks blockjob state for vm. Valid only while reconnecting to qemu. */ + virTristateBool reconnectBlockjobs; }; # define QEMU_DOMAIN_PRIVATE(vm) \ diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 7d7a5f1e4b..14f5b58fe9 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -34,6 +34,7 @@ struct testInfo { char *outInactiveName; virBitmapPtr activeVcpus; + bool blockjobs; virQEMUCapsPtr qemuCaps; }; @@ -43,11 +44,22 @@ qemuXML2XMLActivePreFormatCallback(virDomainDefPtr def, const void *opaque) { struct testInfo *info = (struct testInfo *) opaque; + size_t i; /* store vCPU bitmap so that the status XML can be created faithfully */ if (!info->activeVcpus) info->activeVcpus = virDomainDefGetOnlineVcpumap(def); + info->blockjobs = false; + + /* remember whether we have mirror jobs */ + for (i = 0; i < def->ndisks; i++) { + if (def->disks[i]->mirror) { + info->blockjobs = true; + break; + } + } + return 0; } @@ -124,6 +136,15 @@ testGetStatuXMLPrefixVcpus(virBufferPtr buf, } +static void +testGetStatusXMLAddBlockjobs(virBufferPtr buf, + const struct testInfo *data) +{ + virBufferAsprintf(buf, "\n", + virTristateBoolTypeToString(virTristateBoolFromBool(data->blockjobs))); +} + + static char * testGetStatusXMLPrefix(const struct testInfo *data) { @@ -136,12 +157,31 @@ testGetStatusXMLPrefix(const struct testInfo *data) virBufferAddStr(&buf, testStatusXMLPrefixBodyStatic); + testGetStatusXMLAddBlockjobs(&buf, data); + virBufferAdjustIndent(&buf, -2); return virBufferContentAndReset(&buf); } +static int +testProcessStatusXML(virDomainObjPtr vm) +{ + size_t i; + + /* fix the private 'blockjob' flag for disks */ + for (i = 0; i < vm->def->ndisks; i++) { + virDomainDiskDefPtr disk = vm->def->disks[i]; + qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk); + + diskPriv->blockjob = !!disk->mirror; + } + + return 0; +} + + static int testCompareStatusXMLToXMLFiles(const void *opaque) { @@ -200,6 +240,10 @@ testCompareStatusXMLToXMLFiles(const void *opaque) goto cleanup; } + /* process the definition if necessary */ + if (testProcessStatusXML(obj) < 0) + goto cleanup; + /* format it back */ if (!(actual = virDomainObjFormat(driver.xmlopt, obj, NULL, VIR_DOMAIN_DEF_FORMAT_SECURE))) { -- GitLab