[libvirt] [PATCHv1 4/5] conf: add format features to target XML

Ján Tomko jtomko at redhat.com
Thu Jan 10 12:28:58 UTC 2013


The format is:

<volume>
  <name>q4</name>
  <source>
  </source>
  <capacity unit='MiB'>128</capacity>
  <target>
    <path>/var/lib/libvirt/images/q4</path>
    <format type='qcow3'/>
    <features>
        <compatible>
            <lazy_refcounts/>
        </compatible>
    </features>
  </target>
</volume>
---
 src/conf/storage_conf.c          |   90 ++++++++++++++++++++++++++++++++++++++
 src/conf/storage_conf.h          |    3 +
 src/libvirt_private.syms         |    2 +
 src/storage/storage_backend_fs.c |    7 +++
 4 files changed, 102 insertions(+), 0 deletions(-)

diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 7a39998..f13daa1 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -293,10 +293,15 @@ virStorageVolDefFree(virStorageVolDefPtr def) {
     }
     VIR_FREE(def->source.extents);
 
+    virBitmapFree(def->target.features.compatible);
+    virBitmapFree(def->target.features.incompatible);
     VIR_FREE(def->target.path);
     VIR_FREE(def->target.perms.label);
     VIR_FREE(def->target.timestamps);
     virStorageEncryptionFree(def->target.encryption);
+
+    virBitmapFree(def->backingStore.features.compatible);
+    virBitmapFree(def->backingStore.features.incompatible);
     VIR_FREE(def->backingStore.path);
     VIR_FREE(def->backingStore.perms.label);
     VIR_FREE(def->backingStore.timestamps);
@@ -1105,6 +1110,60 @@ virStorageSize(const char *unit,
     return 0;
 }
 
+static int
+virStorageVolDefParseTargetFeatures(virStorageVolTargetPtr target,
+                                    xmlNodePtr start_node)
+{
+    int value, ret = -1;
+    xmlNodePtr cur, node;
+
+    target->features.compatible = virBitmapNew(VIR_STORAGE_FILE_QCOW3_COMP_LAST);
+    target->features.incompatible = virBitmapNew(VIR_STORAGE_FILE_QCOW3_INCOMP_LAST);
+
+    if (!target->features.compatible || !target->features.incompatible) {
+        virReportOOMError();
+        goto error;
+    }
+
+    for (cur = start_node->children; cur; cur = cur->next) {
+        if (cur->type != XML_ELEMENT_NODE)
+            continue;
+
+        if (xmlStrEqual(cur->name, BAD_CAST "compatible")) {
+            for (node = cur->children->next; node; node = node->next) {
+                if (node->type != XML_ELEMENT_NODE)
+                    continue;
+                value = virStorageFileQcow3CompTypeFromString(
+                            (const char*) node->name);
+
+                if (value < 0) {
+                    virReportError(VIR_ERR_XML_ERROR,
+                                   _("unexpected feature %s"),
+                                   node->name);
+                    goto error;
+                }
+                if (virBitmapSetBit(target->features.compatible, value) < 0)
+                    goto error;
+            }
+        } else {
+            value = virStorageFileQcow3IncompTypeFromString(
+                        (const char*) cur->name);
+            if (value < 0) {
+                virReportError(VIR_ERR_XML_ERROR,
+                               _("unexpected feature %s"),
+                               cur->name);
+                goto error;
+            }
+            if (virBitmapSetBit(target->features.incompatible, value) < 0)
+                goto error;
+        }
+    }
+
+    ret = 0;
+error:
+    return ret;
+}
+
 static virStorageVolDefPtr
 virStorageVolDefParseXML(virStoragePoolDefPtr pool,
                          xmlXPathContextPtr ctxt) {
@@ -1211,6 +1270,13 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool,
                                 DEFAULT_VOL_PERM_MODE) < 0)
         goto cleanup;
 
+    if (pool->type == VIR_STORAGE_POOL_DIR &&
+        ret->target.format == VIR_STORAGE_FILE_QCOW3 &&
+        (node = virXPathNode("./target/features", ctxt)) != NULL) {
+        if (virStorageVolDefParseTargetFeatures(&(ret->target), node) < 0)
+            goto cleanup;
+    }
+
     return ret;
 
  cleanup:
@@ -1294,6 +1360,9 @@ virStorageVolTargetDefFormat(virStorageVolOptionsPtr options,
                              virBufferPtr buf,
                              virStorageVolTargetPtr def,
                              const char *type) {
+    bool tmp;
+    int i;
+
     virBufferAsprintf(buf, "  <%s>\n", type);
 
     if (def->path)
@@ -1341,6 +1410,27 @@ virStorageVolTargetDefFormat(virStorageVolOptionsPtr options,
         virBufferAdjustIndent(buf, -4);
     }
 
+    if (def->features.compatible || def->features.incompatible) {
+        virBufferAddLit(buf, "    <features>\n");
+        for (i = 0; i < VIR_STORAGE_FILE_QCOW3_INCOMP_LAST; i++) {
+            if (virBitmapGetBit(def->features.incompatible, i, &tmp) == 0
+                && tmp) {
+                virBufferAsprintf(buf, "        <%s/>\n",
+                                  virStorageFileQcow3IncompTypeToString(i));
+            }
+        }
+        virBufferAddLit(buf, "        <compatible>\n");
+        for (i = 0; i < VIR_STORAGE_FILE_QCOW3_COMP_LAST; i++) {
+            if (virBitmapGetBit(def->features.compatible, i, &tmp) == 0
+                && tmp) {
+                virBufferAsprintf(buf, "            <%s/>\n",
+                                  virStorageFileQcow3CompTypeToString(i));
+            }
+        }
+        virBufferAddLit(buf, "        </compatible>\n");
+        virBufferAddLit(buf, "    </features>\n");
+    }
+
     virBufferAsprintf(buf, "  </%s>\n", type);
 
     return 0;
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index ad16eca..fa60252 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -28,6 +28,7 @@
 # include "virutil.h"
 # include "storage_encryption_conf.h"
 # include "virthread.h"
+# include "virstoragefile.h"
 
 # include <libxml/tree.h>
 
@@ -93,6 +94,8 @@ struct _virStorageVolTarget {
     int type; /* only used by disk backend for partition type */
     /* Currently used only in virStorageVolDef.target, not in .backingstore. */
     virStorageEncryptionPtr encryption;
+    /* Currently used only by Qcow3 */
+    virStorageFileFeatures features;
 };
 
 
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d079cc9..699cec6 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1177,6 +1177,8 @@ virStorageFileIsSharedFS;
 virStorageFileIsSharedFSType;
 virStorageFileProbeFormat;
 virStorageFileProbeFormatFromFD;
+virStorageFileQcow3CompTypeToString;
+virStorageFileQcow3IncompTypeToString;
 virStorageFileResize;
 
 # sysinfo.h
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 2205371..33ef129 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -136,6 +136,7 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
         switch (target->format) {
         case VIR_STORAGE_FILE_QCOW:
         case VIR_STORAGE_FILE_QCOW2:
+        case VIR_STORAGE_FILE_QCOW3:
             (*encryption)->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
             break;
         default:
@@ -149,6 +150,12 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
          */
     }
 
+    if (target->format == VIR_STORAGE_FILE_QCOW3) {
+        target->features = meta->features;
+        meta->features.compatible = NULL;
+        meta->features.incompatible = NULL;
+    }
+
     virStorageFileFreeMetadata(meta);
 
     return ret;
-- 
1.7.8.6




More information about the libvir-list mailing list