]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: domain: Mark if no blockjobs are active in the status XML
authorPeter Krempa <pkrempa@redhat.com>
Tue, 26 Sep 2017 14:37:47 +0000 (16:37 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Fri, 6 Oct 2017 06:47:30 +0000 (08:47 +0200)
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
src/qemu/qemu_domain.h
tests/qemuxml2xmltest.c

index 2bcc9839d1a137a15b068152e0b680fe3bbb9186..f621cf7afc4f5541c28b9b29e9717bbc29dc9616 100644 (file)
@@ -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, "<chardevStdioLogd/>\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:
index f92841ceb9394858c355bcb9885e4c8ab96e0197..c34cd37fc4c3354678398625cf85754e1ec4009e 100644 (file)
@@ -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)       \
index 7d7a5f1e4b0a9982da66d8a2228f8e4e8eb5ef46..14f5b58fe913361db856b992f6a0f89525aae34b 100644 (file)
@@ -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, "<blockjobs active='%s'/>\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))) {