]> xenbits.xensource.com Git - libvirt.git/commitdiff
storagevol: add nocow to vol xml
authorChunyan Liu <cyliu@suse.com>
Tue, 15 Jul 2014 08:49:46 +0000 (16:49 +0800)
committerJán Tomko <jtomko@redhat.com>
Wed, 16 Jul 2014 11:35:20 +0000 (13:35 +0200)
Add 'nocow' to storage volume xml so that user can have an option
to set NOCOW flag to the newly created volume. It's useful on btrfs
file system to enhance performance.

Btrfs has low performance when hosting VM images, even more when the guest
in those VM are also using btrfs as file system. One way to mitigate this
bad performance is to turn off COW attributes on VM files. Generally, there
are two ways to turn off COW on btrfs: a) by mounting fs with nodatacow,
then all newly created files will be NOCOW. b) per file. Add the NOCOW file
attribute. It could only be done to empty or new files.

This patch tries the second way, according to 'nocow' option, it could set
NOCOW flag per file:
for raw file images, handle 'nocow' in libvirt code; for non-raw file images,
pass 'nocow=on' option to qemu-img, and let qemu-img to handle that (requires
qemu-img version >= 2.1).

Signed-off-by: Chunyan Liu <cyliu@suse.com>
docs/formatstorage.html.in
docs/schemas/storagevol.rng
src/conf/storage_conf.c
src/storage/storage_backend.c
src/util/virstoragefile.h

index 1cd82b4565a99f69be0cb876df13558191e7e340..789701c18c5dd1848151f6580f249fa577cfce88 100644 (file)
             &lt;label&gt;virt_image_t&lt;/label&gt;
           &lt;/permissions&gt;
           &lt;compat&gt;1.1&lt;/compat&gt;
+          &lt;nocow/&gt;
           &lt;features&gt;
             &lt;lazy_refcounts/&gt;
           &lt;/features&gt;
         1.1 is used. If omitted, qemu-img default is used.
         <span class="since">Since 1.1.0</span>
       </dd>
+      <dt><code>nocow</code></dt>
+      <dd>Turn off COW of the newly created volume. So far, this is only valid
+        for a file image in btrfs file system. It will improve performance when
+        the file image is used in VM. To create non-raw file images, it
+        requires QEMU version since 2.1. <span class="since">Since 1.2.7</span>
+      </dd>
       <dt><code>features</code></dt>
       <dd>Format-specific features. Only used for <code>qcow2</code> now.
         Valid sub-elements are:
index 3798476f0354c48bcca4be5bc224c6b937018d29..1b2d4cccad79e3120ce5c18d3c028f620a5f6958 100644 (file)
         <optional>
           <ref name='compat'/>
         </optional>
+        <optional>
+          <element name='nocow'>
+            <empty/>
+          </element>
+        </optional>
         <optional>
           <ref name='fileFormatFeatures'/>
         </optional>
index c79aebd0a4234a83811592e5288ca00f188b1da3..69333f574aaed0c72ec3d2d31b238350e979de6d 100644 (file)
@@ -1299,6 +1299,9 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool,
         virStringFreeList(version);
     }
 
+    if (virXPathNode("./target/nocow", ctxt))
+        ret->target.nocow = true;
+
     if (options->featureFromString && virXPathNode("./target/features", ctxt)) {
         if ((n = virXPathNodeSet("./target/features/*", ctxt, &nodes)) < 0)
             goto error;
index fdcaadad7767900178f79bbe75636c233213c64c..dc835d36bad0832a47690f51a6bc2b449cc36524 100644 (file)
@@ -37,6 +37,9 @@
 #ifdef __linux__
 # include <sys/ioctl.h>
 # include <linux/fs.h>
+# ifndef FS_NOCOW_FL
+#  define FS_NOCOW_FL                     0x00800000 /* Do not cow file */
+# endif
 #endif
 
 #if WITH_SELINUX
@@ -453,6 +456,21 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED,
         goto cleanup;
     }
 
+    if (vol->target.nocow) {
+#ifdef __linux__
+        int attr;
+
+        /* Set NOCOW flag. This is an optimisation for btrfs.
+         * The FS_IOC_SETFLAGS ioctl return value will be ignored since any
+         * failure of this operation should not block the left work.
+         */
+        if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) {
+            attr |= FS_NOCOW_FL;
+            ioctl(fd, FS_IOC_SETFLAGS, &attr);
+        }
+#endif
+    }
+
     if ((ret = createRawFile(fd, vol, inputvol)) < 0)
         /* createRawFile already reported the exact error. */
         ret = -1;
@@ -718,6 +736,7 @@ virStorageBackendCreateQemuImgOpts(char **opts,
                                    bool preallocate,
                                    int format,
                                    const char *compat,
+                                   bool nocow,
                                    virBitmapPtr features)
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -730,6 +749,8 @@ virStorageBackendCreateQemuImgOpts(char **opts,
         virBufferAddLit(&buf, "encryption=on,");
     if (preallocate)
         virBufferAddLit(&buf, "preallocation=metadata,");
+    if (nocow)
+        virBufferAddLit(&buf, "nocow=on,");
 
     if (compat)
         virBufferAsprintf(&buf, "compat=%s,", compat);
@@ -950,6 +971,7 @@ virStorageBackendCreateQemuImgCmd(virConnectPtr conn,
                                                do_encryption, preallocate,
                                                vol->target.format,
                                                compat,
+                                               vol->target.nocow,
                                                vol->target.features) < 0) {
             virCommandFree(cmd);
             return NULL;
index 0ba746ab7dbbf83db13be025c1b85bdd6f012a2d..c840aa06e249a576b1efe2911c3e75749de735e1 100644 (file)
@@ -247,6 +247,7 @@ struct _virStorageSource {
                  * pool-specific enum for storage volumes */
     virBitmapPtr features;
     char *compat;
+    bool nocow;
 
     virStoragePermsPtr perms;
     virStorageTimestampsPtr timestamps;