c1c534
From 996dfd6322782e72583384381ffebf91ef1d3e27 Mon Sep 17 00:00:00 2001
c1c534
Message-Id: <996dfd6322782e72583384381ffebf91ef1d3e27@dist-git>
c1c534
From: Peter Krempa <pkrempa@redhat.com>
c1c534
Date: Thu, 14 Dec 2017 14:31:51 +0100
c1c534
Subject: [PATCH] conf: Add infrastructure for disk source private data XML
c1c534
c1c534
VM drivers may need to store additional private data to the status XML
c1c534
so that it can be restored after libvirtd restart. Since not everything
c1c534
is needed add a callback infrastructure, where VM drivers can add only
c1c534
stuff they need.
c1c534
c1c534
Note that the private data is formatted as a <privateData> sub-element
c1c534
of the <disk> or <backingStore> <source> sub-element. This is done since
c1c534
storing it out of band (in the VM private data) would require a complex
c1c534
matching process to allow to put the data into correct place.
c1c534
c1c534
(cherry picked from commit aed3d038a6565f3b0e916bdb004ca90b302b200d)
c1c534
c1c534
 Conflicts:
c1c534
	tests/qemublocktest.c: This file does not exist downstream yet.
c1c534
c1c534
https://bugzilla.redhat.com/show_bug.cgi?id=1523261
c1c534
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c1c534
---
c1c534
 src/conf/domain_conf.c      | 136 ++++++++++++++++++++++++++++++++++----------
c1c534
 src/conf/domain_conf.h      |  17 +++++-
c1c534
 src/conf/snapshot_conf.c    |  18 +++---
c1c534
 src/network/bridge_driver.c |   2 +-
c1c534
 src/qemu/qemu_domain.c      |   2 +-
c1c534
 tests/virstoragetest.c      |   2 +-
c1c534
 6 files changed, 134 insertions(+), 43 deletions(-)
c1c534
c1c534
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
c1c534
index 2d54037b71..ad9c16a1e0 100644
c1c534
--- a/src/conf/domain_conf.c
c1c534
+++ b/src/conf/domain_conf.c
c1c534
@@ -8550,11 +8550,43 @@ virDomainDiskSourceEncryptionParse(xmlNodePtr node,
c1c534
 }
c1c534
 
c1c534
 
c1c534
+static int
c1c534
+virDomainDiskSourcePrivateDataParse(xmlXPathContextPtr ctxt,
c1c534
+                                    virStorageSourcePtr src,
c1c534
+                                    unsigned int flags,
c1c534
+                                    virDomainXMLOptionPtr xmlopt)
c1c534
+{
c1c534
+    xmlNodePtr saveNode = ctxt->node;
c1c534
+    xmlNodePtr node;
c1c534
+    int ret = -1;
c1c534
+
c1c534
+    if (!(flags & VIR_DOMAIN_DEF_PARSE_STATUS) ||
c1c534
+        !xmlopt || !xmlopt->privateData.storageParse)
c1c534
+        return 0;
c1c534
+
c1c534
+    if (!(node = virXPathNode("./privateData", ctxt)))
c1c534
+        return 0;
c1c534
+
c1c534
+    ctxt->node = node;
c1c534
+
c1c534
+    if (xmlopt->privateData.storageParse(ctxt, src) < 0)
c1c534
+        goto cleanup;
c1c534
+
c1c534
+    ret = 0;
c1c534
+
c1c534
+ cleanup:
c1c534
+    ctxt->node = saveNode;
c1c534
+
c1c534
+    return ret;
c1c534
+}
c1c534
+
c1c534
+
c1c534
 int
c1c534
 virDomainDiskSourceParse(xmlNodePtr node,
c1c534
                          xmlXPathContextPtr ctxt,
c1c534
                          virStorageSourcePtr src,
c1c534
-                         unsigned int flags)
c1c534
+                         unsigned int flags,
c1c534
+                         virDomainXMLOptionPtr xmlopt)
c1c534
 {
c1c534
     int ret = -1;
c1c534
     xmlNodePtr saveNode = ctxt->node;
c1c534
@@ -8593,6 +8625,9 @@ virDomainDiskSourceParse(xmlNodePtr node,
c1c534
     if (virDomainDiskSourceEncryptionParse(node, &src->encryption) < 0)
c1c534
         goto cleanup;
c1c534
 
c1c534
+    if (virDomainDiskSourcePrivateDataParse(ctxt, src, flags, xmlopt) < 0)
c1c534
+        goto cleanup;
c1c534
+
c1c534
     /* People sometimes pass a bogus '' source path when they mean to omit the
c1c534
      * source element completely (e.g. CDROM without media). This is just a
c1c534
      * little compatibility check to help those broken apps */
c1c534
@@ -8610,7 +8645,8 @@ virDomainDiskSourceParse(xmlNodePtr node,
c1c534
 static int
c1c534
 virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt,
c1c534
                                virStorageSourcePtr src,
c1c534
-                               unsigned int flags)
c1c534
+                               unsigned int flags,
c1c534
+                               virDomainXMLOptionPtr xmlopt)
c1c534
 {
c1c534
     virStorageSourcePtr backingStore = NULL;
c1c534
     xmlNodePtr save_ctxt = ctxt->node;
c1c534
@@ -8668,8 +8704,8 @@ virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt,
c1c534
         goto cleanup;
c1c534
     }
c1c534
 
c1c534
-    if (virDomainDiskSourceParse(source, ctxt, backingStore, flags) < 0 ||
c1c534
-        virDomainDiskBackingStoreParse(ctxt, backingStore, flags) < 0)
c1c534
+    if (virDomainDiskSourceParse(source, ctxt, backingStore, flags, xmlopt) < 0 ||
c1c534
+        virDomainDiskBackingStoreParse(ctxt, backingStore, flags, xmlopt) < 0)
c1c534
         goto cleanup;
c1c534
 
c1c534
     VIR_STEAL_PTR(src->backingStore, backingStore);
c1c534
@@ -8771,7 +8807,8 @@ static int
c1c534
 virDomainDiskDefMirrorParse(virDomainDiskDefPtr def,
c1c534
                             xmlNodePtr cur,
c1c534
                             xmlXPathContextPtr ctxt,
c1c534
-                            unsigned int flags)
c1c534
+                            unsigned int flags,
c1c534
+                            virDomainXMLOptionPtr xmlopt)
c1c534
 {
c1c534
     xmlNodePtr mirrorNode;
c1c534
     char *mirrorFormat = NULL;
c1c534
@@ -8809,7 +8846,8 @@ virDomainDiskDefMirrorParse(virDomainDiskDefPtr def,
c1c534
             goto cleanup;
c1c534
         }
c1c534
 
c1c534
-        if (virDomainDiskSourceParse(mirrorNode, ctxt, def->mirror, flags) < 0)
c1c534
+        if (virDomainDiskSourceParse(mirrorNode, ctxt, def->mirror,
c1c534
+                                     flags, xmlopt) < 0)
c1c534
             goto cleanup;
c1c534
     } else {
c1c534
         /* For back-compat reasons, we handle a file name
c1c534
@@ -9235,7 +9273,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
c1c534
         if (!source && virXMLNodeNameEqual(cur, "source")) {
c1c534
             sourceNode = cur;
c1c534
 
c1c534
-            if (virDomainDiskSourceParse(cur, ctxt, def->src, flags) < 0)
c1c534
+            if (virDomainDiskSourceParse(cur, ctxt, def->src, flags, xmlopt) < 0)
c1c534
                 goto error;
c1c534
 
c1c534
             /* If we've already found an <auth> as a child of <disk> and
c1c534
@@ -9316,7 +9354,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
c1c534
         } else if (!def->mirror &&
c1c534
                    virXMLNodeNameEqual(cur, "mirror") &&
c1c534
                    !(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE)) {
c1c534
-            if (virDomainDiskDefMirrorParse(def, cur, ctxt, flags) < 0)
c1c534
+            if (virDomainDiskDefMirrorParse(def, cur, ctxt, flags, xmlopt) < 0)
c1c534
                 goto error;
c1c534
         } else if (!authdef &&
c1c534
                    virXMLNodeNameEqual(cur, "auth")) {
c1c534
@@ -9587,7 +9625,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
c1c534
     product = NULL;
c1c534
 
c1c534
     if (!(flags & VIR_DOMAIN_DEF_PARSE_DISK_SOURCE)) {
c1c534
-        if (virDomainDiskBackingStoreParse(ctxt, def->src, flags) < 0)
c1c534
+        if (virDomainDiskBackingStoreParse(ctxt, def->src, flags, xmlopt) < 0)
c1c534
             goto error;
c1c534
     }
c1c534
 
c1c534
@@ -22349,12 +22387,43 @@ virDomainDiskSourceFormatNetwork(virBufferPtr attrBuf,
c1c534
 }
c1c534
 
c1c534
 
c1c534
+static int
c1c534
+virDomainDiskSourceFormatPrivateData(virBufferPtr buf,
c1c534
+                                     virStorageSourcePtr src,
c1c534
+                                     unsigned int flags,
c1c534
+                                     virDomainXMLOptionPtr xmlopt)
c1c534
+{
c1c534
+    virBuffer childBuf = VIR_BUFFER_INITIALIZER;
c1c534
+    int ret = -1;
c1c534
+
c1c534
+    if (!(flags & VIR_DOMAIN_DEF_FORMAT_STATUS) ||
c1c534
+        !xmlopt || !xmlopt->privateData.storageFormat)
c1c534
+        return 0;
c1c534
+
c1c534
+    virBufferSetChildIndent(&childBuf, buf);
c1c534
+
c1c534
+    if (xmlopt->privateData.storageFormat(src, &childBuf) < 0)
c1c534
+        goto cleanup;
c1c534
+
c1c534
+    if (virXMLFormatElement(buf, "privateData", NULL, &childBuf) < 0)
c1c534
+        goto cleanup;
c1c534
+
c1c534
+    ret = 0;
c1c534
+
c1c534
+ cleanup:
c1c534
+    virBufferFreeAndReset(&childBuf);
c1c534
+
c1c534
+    return ret;
c1c534
+}
c1c534
+
c1c534
+
c1c534
 static int
c1c534
 virDomainDiskSourceFormatInternal(virBufferPtr buf,
c1c534
                                   virStorageSourcePtr src,
c1c534
                                   int policy,
c1c534
                                   unsigned int flags,
c1c534
-                                  bool skipSeclabels)
c1c534
+                                  bool skipSeclabels,
c1c534
+                                  virDomainXMLOptionPtr xmlopt)
c1c534
 {
c1c534
     const char *startupPolicy = NULL;
c1c534
     virBuffer attrBuf = VIR_BUFFER_INITIALIZER;
c1c534
@@ -22436,6 +22505,9 @@ virDomainDiskSourceFormatInternal(virBufferPtr buf,
c1c534
             virStorageEncryptionFormat(&childBuf, src->encryption) < 0)
c1c534
             return -1;
c1c534
 
c1c534
+        if (virDomainDiskSourceFormatPrivateData(&childBuf, src, flags, xmlopt) < 0)
c1c534
+            return -1;
c1c534
+
c1c534
         if (virXMLFormatElement(buf, "source", &attrBuf, &childBuf) < 0)
c1c534
             goto error;
c1c534
     }
c1c534
@@ -22453,15 +22525,18 @@ int
c1c534
 virDomainDiskSourceFormat(virBufferPtr buf,
c1c534
                           virStorageSourcePtr src,
c1c534
                           int policy,
c1c534
-                          unsigned int flags)
c1c534
+                          unsigned int flags,
c1c534
+                          virDomainXMLOptionPtr xmlopt)
c1c534
 {
c1c534
-    return virDomainDiskSourceFormatInternal(buf, src, policy, flags, false);
c1c534
+    return virDomainDiskSourceFormatInternal(buf, src, policy, flags, false, xmlopt);
c1c534
 }
c1c534
 
c1c534
 
c1c534
 static int
c1c534
 virDomainDiskBackingStoreFormat(virBufferPtr buf,
c1c534
-                                virStorageSourcePtr backingStore)
c1c534
+                                virStorageSourcePtr backingStore,
c1c534
+                                virDomainXMLOptionPtr xmlopt,
c1c534
+                                unsigned int flags)
c1c534
 {
c1c534
     const char *format;
c1c534
 
c1c534
@@ -22490,9 +22565,9 @@ virDomainDiskBackingStoreFormat(virBufferPtr buf,
c1c534
 
c1c534
     virBufferAsprintf(buf, "<format type='%s'/>\n", format);
c1c534
     /* We currently don't output seclabels for backing chain element */
c1c534
-    if (virDomainDiskSourceFormatInternal(buf, backingStore, 0, 0, true) < 0 ||
c1c534
-        virDomainDiskBackingStoreFormat(buf,
c1c534
-                                        backingStore->backingStore) < 0)
c1c534
+    if (virDomainDiskSourceFormatInternal(buf, backingStore, 0, flags, true, xmlopt) < 0 ||
c1c534
+        virDomainDiskBackingStoreFormat(buf, backingStore->backingStore,
c1c534
+                                        xmlopt, flags) < 0)
c1c534
         return -1;
c1c534
 
c1c534
     virBufferAdjustIndent(buf, -2);
c1c534
@@ -22510,7 +22585,8 @@ virDomainDiskBackingStoreFormat(virBufferPtr buf,
c1c534
 static int
c1c534
 virDomainDiskDefFormat(virBufferPtr buf,
c1c534
                        virDomainDiskDefPtr def,
c1c534
-                       unsigned int flags)
c1c534
+                       unsigned int flags,
c1c534
+                       virDomainXMLOptionPtr xmlopt)
c1c534
 {
c1c534
     const char *type = virStorageTypeToString(def->src->type);
c1c534
     const char *device = virDomainDiskDeviceTypeToString(def->device);
c1c534
@@ -22623,13 +22699,14 @@ virDomainDiskDefFormat(virBufferPtr buf,
c1c534
     }
c1c534
 
c1c534
     if (virDomainDiskSourceFormat(buf, def->src, def->startupPolicy,
c1c534
-                                  flags) < 0)
c1c534
+                                  flags, xmlopt) < 0)
c1c534
         return -1;
c1c534
 
c1c534
     /* Don't format backingStore to inactive XMLs until the code for
c1c534
      * persistent storage of backing chains is ready. */
c1c534
     if (!(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE) &&
c1c534
-        virDomainDiskBackingStoreFormat(buf, def->src->backingStore) < 0)
c1c534
+        virDomainDiskBackingStoreFormat(buf, def->src->backingStore,
c1c534
+                                        xmlopt, flags) < 0)
c1c534
         return -1;
c1c534
 
c1c534
     virBufferEscapeString(buf, "<backenddomain name='%s'/>\n", def->domain_name);
c1c534
@@ -22666,7 +22743,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
c1c534
         virBufferAddLit(buf, ">\n");
c1c534
         virBufferAdjustIndent(buf, 2);
c1c534
         virBufferEscapeString(buf, "<format type='%s'/>\n", formatStr);
c1c534
-        if (virDomainDiskSourceFormat(buf, def->mirror, 0, 0) < 0)
c1c534
+        if (virDomainDiskSourceFormat(buf, def->mirror, 0, 0, xmlopt) < 0)
c1c534
             return -1;
c1c534
         virBufferAdjustIndent(buf, -2);
c1c534
         virBufferAddLit(buf, "</mirror>\n");
c1c534
@@ -25897,7 +25974,8 @@ int
c1c534
 virDomainDefFormatInternal(virDomainDefPtr def,
c1c534
                            virCapsPtr caps,
c1c534
                            unsigned int flags,
c1c534
-                           virBufferPtr buf)
c1c534
+                           virBufferPtr buf,
c1c534
+                           virDomainXMLOptionPtr xmlopt)
c1c534
 {
c1c534
     unsigned char *uuid;
c1c534
     char uuidstr[VIR_UUID_STRING_BUFLEN];
c1c534
@@ -25952,10 +26030,10 @@ virDomainDefFormatInternal(virDomainDefPtr def,
c1c534
          * but no leading indentation before the starting element.
c1c534
          * Thankfully, libxml maps what looks like globals into
c1c534
          * thread-local uses, so we are thread-safe.  */
c1c534
-        xmlIndentTreeOutput = 1;
c1c534
-        xmlbuf = xmlBufferCreate();
c1c534
-        if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata,
c1c534
-                        virBufferGetIndent(buf, false) / 2, 1) < 0) {
c1c534
+            xmlIndentTreeOutput = 1;
c1c534
+            xmlbuf = xmlBufferCreate();
c1c534
+            if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata,
c1c534
+                            virBufferGetIndent(buf, false) / 2, 1) < 0) {
c1c534
             xmlBufferFree(xmlbuf);
c1c534
             xmlIndentTreeOutput = oldIndentTreeOutput;
c1c534
             goto error;
c1c534
@@ -26528,7 +26606,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
c1c534
                           def->emulator);
c1c534
 
c1c534
     for (n = 0; n < def->ndisks; n++)
c1c534
-        if (virDomainDiskDefFormat(buf, def->disks[n], flags) < 0)
c1c534
+        if (virDomainDiskDefFormat(buf, def->disks[n], flags, xmlopt) < 0)
c1c534
             goto error;
c1c534
 
c1c534
     for (n = 0; n < def->ncontrollers; n++)
c1c534
@@ -26715,7 +26793,7 @@ virDomainDefFormat(virDomainDefPtr def, virCapsPtr caps, unsigned int flags)
c1c534
     virBuffer buf = VIR_BUFFER_INITIALIZER;
c1c534
 
c1c534
     virCheckFlags(VIR_DOMAIN_DEF_FORMAT_COMMON_FLAGS, NULL);
c1c534
-    if (virDomainDefFormatInternal(def, caps, flags, &buf) < 0)
c1c534
+    if (virDomainDefFormatInternal(def, caps, flags, &buf, NULL) < 0)
c1c534
         return NULL;
c1c534
 
c1c534
     return virBufferContentAndReset(&buf;;
c1c534
@@ -26750,7 +26828,7 @@ virDomainObjFormat(virDomainXMLOptionPtr xmlopt,
c1c534
         xmlopt->privateData.format(&buf, obj) < 0)
c1c534
         goto error;
c1c534
 
c1c534
-    if (virDomainDefFormatInternal(obj->def, caps, flags, &buf) < 0)
c1c534
+    if (virDomainDefFormatInternal(obj->def, caps, flags, &buf, xmlopt) < 0)
c1c534
         goto error;
c1c534
 
c1c534
     virBufferAdjustIndent(&buf, -2);
c1c534
@@ -27704,7 +27782,7 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
c1c534
 
c1c534
     switch ((virDomainDeviceType) src->type) {
c1c534
     case VIR_DOMAIN_DEVICE_DISK:
c1c534
-        rc = virDomainDiskDefFormat(&buf, src->data.disk, flags);
c1c534
+        rc = virDomainDiskDefFormat(&buf, src->data.disk, flags, xmlopt);
c1c534
         break;
c1c534
     case VIR_DOMAIN_DEVICE_LEASE:
c1c534
         rc = virDomainLeaseDefFormat(&buf, src->data.lease);
c1c534
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
c1c534
index 698d3280fe..5e67c9a9c1 100644
c1c534
--- a/src/conf/domain_conf.h
c1c534
+++ b/src/conf/domain_conf.h
c1c534
@@ -2626,6 +2626,12 @@ typedef int (*virDomainXMLPrivateDataParseFunc)(xmlXPathContextPtr,
c1c534
                                                 virDomainObjPtr,
c1c534
                                                 virDomainDefParserConfigPtr);
c1c534
 
c1c534
+typedef int (*virDomainXMLPrivateDataStorageSourceParseFunc)(xmlXPathContextPtr ctxt,
c1c534
+                                                             virStorageSourcePtr src);
c1c534
+typedef int (*virDomainXMLPrivateDataStorageSourceFormatFunc)(virStorageSourcePtr src,
c1c534
+                                                              virBufferPtr buf);
c1c534
+
c1c534
+
c1c534
 typedef struct _virDomainXMLPrivateDataCallbacks virDomainXMLPrivateDataCallbacks;
c1c534
 typedef virDomainXMLPrivateDataCallbacks *virDomainXMLPrivateDataCallbacksPtr;
c1c534
 struct _virDomainXMLPrivateDataCallbacks {
c1c534
@@ -2639,6 +2645,8 @@ struct _virDomainXMLPrivateDataCallbacks {
c1c534
     virDomainXMLPrivateDataNewFunc    chrSourceNew;
c1c534
     virDomainXMLPrivateDataFormatFunc format;
c1c534
     virDomainXMLPrivateDataParseFunc  parse;
c1c534
+    virDomainXMLPrivateDataStorageSourceParseFunc storageParse;
c1c534
+    virDomainXMLPrivateDataStorageSourceFormatFunc storageFormat;
c1c534
 };
c1c534
 
c1c534
 typedef bool (*virDomainABIStabilityDomain)(const virDomainDef *src,
c1c534
@@ -2963,12 +2971,14 @@ char *virDomainObjFormat(virDomainXMLOptionPtr xmlopt,
c1c534
 int virDomainDefFormatInternal(virDomainDefPtr def,
c1c534
                                virCapsPtr caps,
c1c534
                                unsigned int flags,
c1c534
-                               virBufferPtr buf);
c1c534
+                               virBufferPtr buf,
c1c534
+                               virDomainXMLOptionPtr xmlopt);
c1c534
 
c1c534
 int virDomainDiskSourceFormat(virBufferPtr buf,
c1c534
                               virStorageSourcePtr src,
c1c534
                               int policy,
c1c534
-                              unsigned int flags);
c1c534
+                              unsigned int flags,
c1c534
+                              virDomainXMLOptionPtr xmlopt);
c1c534
 
c1c534
 int virDomainNetDefFormat(virBufferPtr buf,
c1c534
                           virDomainNetDefPtr def,
c1c534
@@ -3017,7 +3027,8 @@ virDomainDiskRemoveByName(virDomainDefPtr def, const char *name);
c1c534
 int virDomainDiskSourceParse(xmlNodePtr node,
c1c534
                              xmlXPathContextPtr ctxt,
c1c534
                              virStorageSourcePtr src,
c1c534
-                             unsigned int flags);
c1c534
+                             unsigned int flags,
c1c534
+                             virDomainXMLOptionPtr xmlopt);
c1c534
 
c1c534
 int virDomainNetFindIdx(virDomainDefPtr def, virDomainNetDefPtr net);
c1c534
 virDomainNetDefPtr virDomainNetFind(virDomainDefPtr def, const char *device);
c1c534
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
c1c534
index f0e852c92b..d7b086242b 100644
c1c534
--- a/src/conf/snapshot_conf.c
c1c534
+++ b/src/conf/snapshot_conf.c
c1c534
@@ -110,7 +110,8 @@ static int
c1c534
 virDomainSnapshotDiskDefParseXML(xmlNodePtr node,
c1c534
                                  xmlXPathContextPtr ctxt,
c1c534
                                  virDomainSnapshotDiskDefPtr def,
c1c534
-                                 unsigned int flags)
c1c534
+                                 unsigned int flags,
c1c534
+                                 virDomainXMLOptionPtr xmlopt)
c1c534
 {
c1c534
     int ret = -1;
c1c534
     char *snapshot = NULL;
c1c534
@@ -155,7 +156,7 @@ virDomainSnapshotDiskDefParseXML(xmlNodePtr node,
c1c534
     }
c1c534
 
c1c534
     if ((cur = virXPathNode("./source", ctxt)) &&
c1c534
-        virDomainDiskSourceParse(cur, ctxt, def->src, flags) < 0)
c1c534
+        virDomainDiskSourceParse(cur, ctxt, def->src, flags, xmlopt) < 0)
c1c534
         goto cleanup;
c1c534
 
c1c534
     if ((driver = virXPathString("string(./driver/@type)", ctxt))) {
c1c534
@@ -348,8 +349,8 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
c1c534
             goto cleanup;
c1c534
         def->ndisks = n;
c1c534
         for (i = 0; i < def->ndisks; i++) {
c1c534
-            if (virDomainSnapshotDiskDefParseXML(nodes[i], ctxt,
c1c534
-                                                 &def->disks[i], flags) < 0)
c1c534
+            if (virDomainSnapshotDiskDefParseXML(nodes[i], ctxt, &def->disks[i],
c1c534
+                                                 flags, xmlopt) < 0)
c1c534
                 goto cleanup;
c1c534
         }
c1c534
         VIR_FREE(nodes);
c1c534
@@ -663,7 +664,8 @@ virDomainSnapshotAlignDisks(virDomainSnapshotDefPtr def,
c1c534
 
c1c534
 static void
c1c534
 virDomainSnapshotDiskDefFormat(virBufferPtr buf,
c1c534
-                               virDomainSnapshotDiskDefPtr disk)
c1c534
+                               virDomainSnapshotDiskDefPtr disk,
c1c534
+                               virDomainXMLOptionPtr xmlopt)
c1c534
 {
c1c534
     int type = disk->src->type;
c1c534
 
c1c534
@@ -686,7 +688,7 @@ virDomainSnapshotDiskDefFormat(virBufferPtr buf,
c1c534
     if (disk->src->format > 0)
c1c534
         virBufferEscapeString(buf, "<driver type='%s'/>\n",
c1c534
                               virStorageFileFormatTypeToString(disk->src->format));
c1c534
-    virDomainDiskSourceFormat(buf, disk->src, 0, 0);
c1c534
+    virDomainDiskSourceFormat(buf, disk->src, 0, 0, xmlopt);
c1c534
 
c1c534
     virBufferAdjustIndent(buf, -2);
c1c534
     virBufferAddLit(buf, "</disk>\n");
c1c534
@@ -740,13 +742,13 @@ virDomainSnapshotDefFormat(const char *domain_uuid,
c1c534
         virBufferAddLit(&buf, "<disks>\n");
c1c534
         virBufferAdjustIndent(&buf, 2);
c1c534
         for (i = 0; i < def->ndisks; i++)
c1c534
-            virDomainSnapshotDiskDefFormat(&buf, &def->disks[i]);
c1c534
+            virDomainSnapshotDiskDefFormat(&buf, &def->disks[i], xmlopt);
c1c534
         virBufferAdjustIndent(&buf, -2);
c1c534
         virBufferAddLit(&buf, "</disks>\n");
c1c534
     }
c1c534
 
c1c534
     if (def->dom) {
c1c534
-        if (virDomainDefFormatInternal(def->dom, caps, flags, &buf) < 0)
c1c534
+        if (virDomainDefFormatInternal(def->dom, caps, flags, &buf, xmlopt) < 0)
c1c534
             goto error;
c1c534
     } else if (domain_uuid) {
c1c534
         virBufferAddLit(&buf, "<domain>\n");
c1c534
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
c1c534
index fcaa66df91..334da7a85d 100644
c1c534
--- a/src/network/bridge_driver.c
c1c534
+++ b/src/network/bridge_driver.c
c1c534
@@ -233,7 +233,7 @@ networkRunHook(virNetworkObjPtr obj,
c1c534
             goto cleanup;
c1c534
         if (virNetworkDefFormatBuf(&buf, def, 0) < 0)
c1c534
             goto cleanup;
c1c534
-        if (dom && virDomainDefFormatInternal(dom, NULL, 0, &buf) < 0)
c1c534
+        if (dom && virDomainDefFormatInternal(dom, NULL, 0, &buf, NULL) < 0)
c1c534
             goto cleanup;
c1c534
 
c1c534
         virBufferAdjustIndent(&buf, -2);
c1c534
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
c1c534
index 9dd9db049b..625bcb20d5 100644
c1c534
--- a/src/qemu/qemu_domain.c
c1c534
+++ b/src/qemu/qemu_domain.c
c1c534
@@ -5245,7 +5245,7 @@ qemuDomainDefFormatBufInternal(virQEMUDriverPtr driver,
c1c534
  format:
c1c534
     ret = virDomainDefFormatInternal(def, caps,
c1c534
                                      virDomainDefFormatConvertXMLFlags(flags),
c1c534
-                                     buf);
c1c534
+                                     buf, driver->xmlopt);
c1c534
 
c1c534
  cleanup:
c1c534
     virDomainDefFree(copy);
c1c534
diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c
c1c534
index e1d8751728..bdd0829c21 100644
c1c534
--- a/tests/virstoragetest.c
c1c534
+++ b/tests/virstoragetest.c
c1c534
@@ -693,7 +693,7 @@ testBackingParse(const void *args)
c1c534
         goto cleanup;
c1c534
     }
c1c534
 
c1c534
-    if (virDomainDiskSourceFormat(&buf, src, 0, 0) < 0 ||
c1c534
+    if (virDomainDiskSourceFormat(&buf, src, 0, 0, NULL) < 0 ||
c1c534
         !(xml = virBufferContentAndReset(&buf))) {
c1c534
         fprintf(stderr, "failed to format disk source xml\n");
c1c534
         goto cleanup;
c1c534
-- 
c1c534
2.15.1
c1c534