[libvirt] [PATCH 7/8] Add qcow2 features support to snapshots

Ján Tomko jtomko at redhat.com
Thu May 16 11:07:38 UTC 2013


---
 docs/schemas/domainsnapshot.rng                  |  7 +++
 src/conf/snapshot_conf.c                         | 74 ++++++++++++++++++++++++
 src/conf/snapshot_conf.h                         |  2 +
 tests/domainsnapshotxml2xmlin/disk_snapshot.xml  |  5 ++
 tests/domainsnapshotxml2xmlout/disk_snapshot.xml |  4 ++
 5 files changed, 92 insertions(+)

diff --git a/docs/schemas/domainsnapshot.rng b/docs/schemas/domainsnapshot.rng
index 7b46df1..63c8511 100644
--- a/docs/schemas/domainsnapshot.rng
+++ b/docs/schemas/domainsnapshot.rng
@@ -6,6 +6,7 @@
   </start>
 
   <include href='domaincommon.rng'/>
+  <include href='storagefilefeatures.rng'/>
 
   <define name='domainsnapshot'>
     <element name='domainsnapshot'>
@@ -144,6 +145,12 @@
                 <empty/>
               </element>
             </optional>
+            <optional>
+              <ref name='compat'/>
+            </optional>
+            <optional>
+              <ref name='fileFormatFeatures'/>
+            </optional>
           </interleave>
         </group>
       </choice>
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
index 324b07f..97d8848 100644
--- a/src/conf/snapshot_conf.c
+++ b/src/conf/snapshot_conf.c
@@ -82,6 +82,9 @@ virDomainSnapshotDiskDefClear(virDomainSnapshotDiskDefPtr disk)
 {
     VIR_FREE(disk->name);
     VIR_FREE(disk->file);
+    VIR_FREE(disk->compat);
+    virBitmapFree(disk->features);
+    disk->features = NULL;
 }
 
 void virDomainSnapshotDefFree(virDomainSnapshotDefPtr def)
@@ -103,6 +106,38 @@ void virDomainSnapshotDefFree(virDomainSnapshotDefPtr def)
 }
 
 static int
+virDomainSnapshotDiskFeaturesDefParse(virDomainSnapshotDiskDefPtr def,
+                                      xmlNodePtr node)
+{
+    xmlNodePtr cur;
+    int f, n = 0;
+
+    if (!(def->features = virBitmapNew(VIR_STORAGE_FILE_FEATURE_LAST))) {
+        virReportOOMError();
+        return -1;
+    }
+
+    for (cur = node->children; cur; cur = cur->next) {
+        if (cur->type != XML_ELEMENT_NODE)
+            continue;
+
+        f = virStorageFileFeatureTypeFromString((const char*) cur->name);
+
+        if (f < 0) {
+            virReportError(VIR_ERR_XML_ERROR, _("unsupported feature %s"),
+                           (const char*) cur->name);
+            return -1;
+        }
+        ignore_value(virBitmapSetBit(def->features, f));
+        n++;
+
+    }
+    if (n > 0 && !def->compat && VIR_STRDUP(def->compat, "1.1") < 0)
+        return -1;
+    return 0;
+}
+
+static int
 virDomainSnapshotDiskDefParseXML(xmlNodePtr node,
                                  virDomainSnapshotDiskDefPtr def)
 {
@@ -146,6 +181,17 @@ virDomainSnapshotDiskDefParseXML(xmlNodePtr node,
                     goto cleanup;
                 }
                 VIR_FREE(driver);
+            } else if (xmlStrEqual(cur->name, BAD_CAST "compat")) {
+                if (VIR_STRDUP(def->compat, (const char*)cur->content) < 0)
+                    goto cleanup;
+                if (def->compat && strchr(def->compat, ',')) {
+                    virReportError(VIR_ERR_XML_ERROR, "%s",
+                                   _("forbidden characters in 'compat' attribute"));
+                    goto cleanup;
+                }
+            } else if (xmlStrEqual(cur->name, BAD_CAST "features")) {
+                if (virDomainSnapshotDiskFeaturesDefParse(def, cur) < 0)
+                    goto cleanup;
             }
         }
         cur = cur->next;
@@ -553,6 +599,29 @@ cleanup:
 }
 
 static void
+virDomainSnapshotDiskFeaturesDefFormat(virBufferPtr buf,
+                                       virBitmapPtr features)
+{
+    int i;
+
+    if (virBitmapIsAllClear(features)) {
+        virBufferAddLit(buf, "<features/>\n");
+        return;
+    }
+
+    virBufferAddLit(buf, "<features>\n");
+    for (i = 0; i < VIR_STORAGE_FILE_FEATURE_LAST; i++) {
+        bool b;
+
+        ignore_value(virBitmapGetBit(features, i, &b));
+        if (b)
+            virBufferAsprintf(buf, "  <%s/>\n",
+                              virStorageFileFeatureTypeToString(i));
+    }
+    virBufferAddLit(buf, "</features>\n");
+}
+
+static void
 virDomainSnapshotDiskDefFormat(virBufferPtr buf,
                                virDomainSnapshotDiskDefPtr disk)
 {
@@ -575,6 +644,11 @@ virDomainSnapshotDiskDefFormat(virBufferPtr buf,
         virBufferEscapeString(buf, "<driver type='%s'/>\n",
                               virStorageFileFormatTypeToString(disk->format));
     virBufferEscapeString(buf, "<source file='%s'/>\n", disk->file);
+    virBufferEscapeString(buf, "<compat>%s</compat>\n", disk->compat);
+
+    if (disk->features)
+        virDomainSnapshotDiskFeaturesDefFormat(buf, disk->features);
+
     virBufferAdjustIndent(buf, -6);
     virBufferAddLit(buf, "    </disk>\n");
 }
diff --git a/src/conf/snapshot_conf.h b/src/conf/snapshot_conf.h
index 6d625a7..2be5319 100644
--- a/src/conf/snapshot_conf.h
+++ b/src/conf/snapshot_conf.h
@@ -53,6 +53,8 @@ struct _virDomainSnapshotDiskDef {
     int snapshot; /* enum virDomainSnapshotLocation */
     char *file; /* new source file when snapshot is external */
     int format; /* enum virStorageFileFormat */
+    char *compat;
+    virBitmapPtr features;
 };
 
 /* Stores the complete snapshot metadata */
diff --git a/tests/domainsnapshotxml2xmlin/disk_snapshot.xml b/tests/domainsnapshotxml2xmlin/disk_snapshot.xml
index ee6b46a..79895d7 100644
--- a/tests/domainsnapshotxml2xmlin/disk_snapshot.xml
+++ b/tests/domainsnapshotxml2xmlin/disk_snapshot.xml
@@ -11,6 +11,11 @@
     </disk>
     <disk name='hde' snapshot='external'>
       <source file='/path/to/new'/>
+      <driver type='qcow2'/>
+      <compat>1.1</compat>
+      <features>
+        <lazy_refcounts/>
+      </features>
     </disk>
   </disks>
 </domainsnapshot>
diff --git a/tests/domainsnapshotxml2xmlout/disk_snapshot.xml b/tests/domainsnapshotxml2xmlout/disk_snapshot.xml
index 5f42bf5..4c3f8ad 100644
--- a/tests/domainsnapshotxml2xmlout/disk_snapshot.xml
+++ b/tests/domainsnapshotxml2xmlout/disk_snapshot.xml
@@ -18,6 +18,10 @@
     <disk name='hde' snapshot='external'>
       <driver type='qcow2'/>
       <source file='/path/to/new'/>
+      <compat>1.1</compat>
+      <features>
+        <lazy_refcounts/>
+      </features>
     </disk>
     <disk name='hdf' snapshot='external'>
       <driver type='qcow2'/>
-- 
1.8.1.5




More information about the libvir-list mailing list