]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
conf: restrict external snapshots to backing store formats
authorEric Blake <eblake@redhat.com>
Mon, 14 Apr 2014 22:54:14 +0000 (16:54 -0600)
committerJiri Denemark <jdenemar@redhat.com>
Tue, 15 Apr 2014 11:57:15 +0000 (13:57 +0200)
Domain snapshots should only permit an external snapshot into
a storage format that permits a backing chain, since the new
snapshot file necessarily must be backed by the existing file.
The C code for the qemu driver is a little bit stricter in
currently enforcing only qcow2 or qed, but at the XML parser
level, including virt-xml-validate, it is fairly easy to
enforce that a user can't request a 'raw' external snapshot.

* docs/schemas/storagecommon.rng (storageFormat): Split out...
(storageFormatBacking): ...new sublist.
* docs/schemas/domainsnapshot.rng (disksnapshotdriver): Use new
type.
* src/util/virstoragefile.h (virStorageFileFormat): Rearrange for
easier code management.
* src/util/virstoragefile.c (virStorageFileFormat, fileTypeInfo):
Likewise.
* src/conf/snapshot_conf.c (virDomainSnapshotDiskDefParseXML): Use
new marker to limit selection of formats.

Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
docs/schemas/domainsnapshot.rng
docs/schemas/storagecommon.rng
src/conf/snapshot_conf.c
src/util/virstoragefile.c
src/util/virstoragefile.h

index 824a18616a250b7ccbb39f1bb349aadd421801d2..644da90f9c33a2c66be2d95c1b645cd2234c35c6 100644 (file)
       <element name='driver'>
         <optional>
           <attribute name='type'>
-            <ref name='storageFormat'/>
+            <ref name='storageFormatBacking'/>
           </attribute>
         </optional>
         <empty/>
index 37b43c64dd373ffa281bb31b769b7750c1af3fc0..1015e8d33427b098751c5c0920e0f5b0ac98bec0 100644 (file)
     </element>
   </define>
 
+  <!-- split the list of known storage formats into two, those where
+       we know how to follow backing chains, and all others -->
+  <define name='storageFormatBacking'>
+    <choice>
+      <value>cow</value>
+      <value>qcow</value>
+      <value>qcow2</value>
+      <value>qed</value>
+      <value>vmdk</value>
+    </choice>
+  </define>
   <define name='storageFormat'>
     <choice>
       <value>raw</value>
       <value>dir</value>
       <value>bochs</value>
       <value>cloop</value>
-      <value>cow</value>
       <value>dmg</value>
       <value>iso</value>
-      <value>qcow</value>
-      <value>qcow2</value>
-      <value>qed</value>
-      <value>vmdk</value>
       <value>vpc</value>
+      <value>vdi</value>
       <value>fat</value>
       <value>vhd</value>
-      <value>vdi</value>
+      <ref name='storageFormatBacking'/>
     </choice>
   </define>
 
index 070e50d0b2d8dc2ef064730c70ebc74079f3d7a6..b0e4700b67242bf91fa7a9b6088581eba405b5aa 100644 (file)
@@ -158,9 +158,12 @@ virDomainSnapshotDiskDefParseXML(xmlNodePtr node,
             char *driver = virXMLPropString(cur, "type");
             if (driver) {
                 def->src.format = virStorageFileFormatTypeFromString(driver);
-                if (def->src.format <= 0) {
+                if (def->src.format < VIR_STORAGE_FILE_BACKING) {
                     virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                                   _("unknown disk snapshot driver '%s'"),
+                                   def->src.format <= 0
+                                   ? _("unknown disk snapshot driver '%s'")
+                                   : _("disk format '%s' lacks backing file "
+                                       "support"),
                                    driver);
                     VIR_FREE(driver);
                     goto cleanup;
index 94dddbc62268571cba8995da362159bc270b817d..ea80c1d88bdd517a2a22e9a885c2cef59e80f97b 100644 (file)
@@ -59,9 +59,12 @@ VIR_ENUM_IMPL(virStorageFileFormat,
               VIR_STORAGE_FILE_LAST,
               "none",
               "raw", "dir", "bochs",
-              "cloop", "cow", "dmg", "iso",
-              "qcow", "qcow2", "qed", "vmdk", "vpc",
-              "fat", "vhd", "vdi")
+              "cloop", "dmg", "iso",
+              "vpc", "vdi",
+              /* Not direct file formats, but used for various drivers */
+              "fat", "vhd",
+              /* Formats with backing file below here */
+              "cow", "qcow", "qcow2", "qed", "vmdk")
 
 VIR_ENUM_IMPL(virStorageFileFeature,
               VIR_STORAGE_FILE_FEATURE_LAST,
@@ -198,11 +201,6 @@ static struct FileTypeInfo const fileTypeInfo[] = {
         LV_LITTLE_ENDIAN, -1, {0},
         -1, 0, 0, -1, NULL, NULL
     },
-    [VIR_STORAGE_FILE_COW] = {
-        0, "OOOM", NULL,
-        LV_BIG_ENDIAN, 4, {2},
-        4+4+1024+4, 8, 1, -1, cowGetBackingStore, NULL
-    },
     [VIR_STORAGE_FILE_DMG] = {
         /* XXX QEMU says there's no magic for dmg,
          * /usr/share/misc/magic lists double magic (both offsets
@@ -216,6 +214,29 @@ static struct FileTypeInfo const fileTypeInfo[] = {
         LV_LITTLE_ENDIAN, -2, {0},
         -1, 0, 0, -1, NULL, NULL
     },
+    [VIR_STORAGE_FILE_VPC] = {
+        0, "conectix", NULL,
+        LV_BIG_ENDIAN, 12, {0x10000},
+        8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL, NULL
+    },
+    /* TODO: add getBackingStore function */
+    [VIR_STORAGE_FILE_VDI] = {
+        64, "\x7f\x10\xda\xbe", ".vdi",
+        LV_LITTLE_ENDIAN, 68, {0x00010001},
+        64 + 5 * 4 + 256 + 7 * 4, 8, 1, -1, NULL, NULL},
+
+    /* Not direct file formats, but used for various drivers */
+    [VIR_STORAGE_FILE_FAT] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
+                               -1, {0}, 0, 0, 0, 0, NULL, NULL },
+    [VIR_STORAGE_FILE_VHD] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
+                               -1, {0}, 0, 0, 0, 0, NULL, NULL },
+
+    /* All formats with a backing store probe below here */
+    [VIR_STORAGE_FILE_COW] = {
+        0, "OOOM", NULL,
+        LV_BIG_ENDIAN, 4, {2},
+        4+4+1024+4, 8, 1, -1, cowGetBackingStore, NULL
+    },
     [VIR_STORAGE_FILE_QCOW] = {
         0, "QFI", NULL,
         LV_BIG_ENDIAN, 4, {1},
@@ -238,22 +259,6 @@ static struct FileTypeInfo const fileTypeInfo[] = {
         LV_LITTLE_ENDIAN, 4, {1, 2},
         4+4+4, 8, 512, -1, vmdk4GetBackingStore, NULL
     },
-    [VIR_STORAGE_FILE_VPC] = {
-        0, "conectix", NULL,
-        LV_BIG_ENDIAN, 12, {0x10000},
-        8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL, NULL
-    },
-    /* TODO: add getBackingStore function */
-    [VIR_STORAGE_FILE_VDI] = {
-        64, "\x7f\x10\xda\xbe", ".vdi",
-        LV_LITTLE_ENDIAN, 68, {0x00010001},
-        64 + 5 * 4 + 256 + 7 * 4, 8, 1, -1, NULL, NULL},
-
-    /* Not direct file formats, but used for various drivers */
-    [VIR_STORAGE_FILE_FAT] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
-                               -1, {0}, 0, 0, 0, 0, NULL, NULL },
-    [VIR_STORAGE_FILE_VHD] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
-                               -1, {0}, 0, 0, 0, 0, NULL, NULL },
 };
 verify(ARRAY_CARDINALITY(fileTypeInfo) == VIR_STORAGE_FILE_LAST);
 
index 55ea890e4feddb09a6ae842d43700665cea0e7e5..1b8b14f31c552c182484bed617f9e0b07e633f01 100644 (file)
@@ -64,17 +64,24 @@ enum virStorageFileFormat {
     VIR_STORAGE_FILE_DIR,
     VIR_STORAGE_FILE_BOCHS,
     VIR_STORAGE_FILE_CLOOP,
-    VIR_STORAGE_FILE_COW,
     VIR_STORAGE_FILE_DMG,
     VIR_STORAGE_FILE_ISO,
+    VIR_STORAGE_FILE_VPC,
+    VIR_STORAGE_FILE_VDI,
+
+    /* Not direct file formats, but used for various drivers */
+    VIR_STORAGE_FILE_FAT,
+    VIR_STORAGE_FILE_VHD,
+
+    /* Not a format, but a marker: all formats below this point have
+     * libvirt support for following a backing chain */
+    VIR_STORAGE_FILE_BACKING,
+
+    VIR_STORAGE_FILE_COW = VIR_STORAGE_FILE_BACKING,
     VIR_STORAGE_FILE_QCOW,
     VIR_STORAGE_FILE_QCOW2,
     VIR_STORAGE_FILE_QED,
     VIR_STORAGE_FILE_VMDK,
-    VIR_STORAGE_FILE_VPC,
-    VIR_STORAGE_FILE_FAT,
-    VIR_STORAGE_FILE_VHD,
-    VIR_STORAGE_FILE_VDI,
 
     VIR_STORAGE_FILE_LAST,
 };