]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Add unsafe cache mode support for disk driver
authorOskari Saarenmaa <os@ohmu.fi>
Thu, 22 Sep 2011 19:33:47 +0000 (22:33 +0300)
committerEric Blake <eblake@redhat.com>
Fri, 23 Sep 2011 14:29:57 +0000 (08:29 -0600)
QEMU 0.13 introduced cache=unsafe for -drive, this patch exposes
it in the libvirt layer.

  * Introduced a new QEMU capability flag ($prefix_CACHE_UNSAFE),
    as even if $prefix_CACHE_V2 is set, we can't know if unsafe
    is supported.

  * Improved the reliability of qemu cache type detection.

13 files changed:
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
src/qemu/qemu_command.c
tests/qemuargv2xmltest.c
tests/qemuhelptest.c
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c
tools/virsh.pod

index 0a7abafac4203786c9cc9e043186149065182d5b..3087d016e3a9c7ad000f04869a4cdc4002c0ce30 100644 (file)
           <li>
             The optional <code>cache</code> attribute controls the
             cache mechanism, possible values are "default", "none",
-            "writethrough", "writeback", and "directsync". "directsync"
-            is like "writethrough", but it bypasses the host page
-            cache.
-            <span class="since">Since 0.6.0</span>
+            "writethrough", "writeback", "directsync" (like
+            "writethrough", but it bypasses the host page cache) and
+            "unsafe" (host may cache all disk io, and sync requests from
+            guest are ignored).
+            <span class="since">
+              Since 0.6.0,
+              "directsync" since 0.9.5,
+              "unsafe" since 0.9.7
+            </span>
           </li>
           <li>
             The optional <code>error_policy</code> attribute controls
index d0da41c5837b1293f750b6043dff320e6c2e1d30..be98be03d67d78f2038be9d3d410a762daadba5e 100644 (file)
         <value>writeback</value>
         <value>writethrough</value>
         <value>directsync</value>
+        <value>unsafe</value>
       </choice>
     </attribute>
   </define>
index 7463d7c3c2d2fc9c746512332e906b50623e33cb..a91867915af0be0bc5c569bf9b568ae40736bfdc 100644 (file)
@@ -164,7 +164,8 @@ VIR_ENUM_IMPL(virDomainDiskCache, VIR_DOMAIN_DISK_CACHE_LAST,
               "none",
               "writethrough",
               "writeback",
-              "directsync")
+              "directsync",
+              "unsafe")
 
 VIR_ENUM_IMPL(virDomainDiskErrorPolicy, VIR_DOMAIN_DISK_ERROR_POLICY_LAST,
               "default",
index 371f2701f9b71abf007b287b2ad98a965e1df629..86b4c799f7fb22a8097c1c98bcb1cd2e2d9ab5eb 100644 (file)
@@ -192,6 +192,7 @@ enum  virDomainDiskCache {
     VIR_DOMAIN_DISK_CACHE_WRITETHRU,
     VIR_DOMAIN_DISK_CACHE_WRITEBACK,
     VIR_DOMAIN_DISK_CACHE_DIRECTSYNC,
+    VIR_DOMAIN_DISK_CACHE_UNSAFE,
 
     VIR_DOMAIN_DISK_CACHE_LAST
 };
index 850d46e7665e094aae42e105f9a35e36bea9ec2e..8e20e3f32c5a8b4e28e6879a3f1c8b3f8da46332 100644 (file)
@@ -137,6 +137,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
               "usb-redir",
               "usb-hub",
               "no-shutdown",
+
+              "cache-unsafe", /* 75 */
     );
 
 struct qemu_feature_flags {
@@ -912,12 +914,16 @@ qemuCapsComputeCmdFlags(const char *help,
     else if (strstr(help, "-domid"))
         qemuCapsSet(flags, QEMU_CAPS_DOMID);
     if (strstr(help, "-drive")) {
+        const char *cache = strstr(help, "cache=");
+
         qemuCapsSet(flags, QEMU_CAPS_DRIVE);
-        if (strstr(help, "cache=") &&
-            !strstr(help, "cache=on|off")) {
-            qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_V2);
-            if (strstr(help, "directsync"))
+        if (cache && (p = strchr(cache, ']'))) {
+            if (memmem(cache, p - cache, "on|off", sizeof("on|off") - 1) == NULL)
+                qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_V2);
+            if (memmem(cache, p - cache, "directsync", sizeof("directsync") - 1))
                 qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC);
+            if (memmem(cache, p - cache, "unsafe", sizeof("unsafe") - 1))
+                qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_UNSAFE);
         }
         if (strstr(help, "format="))
             qemuCapsSet(flags, QEMU_CAPS_DRIVE_FORMAT);
index 74d3ab24226fbb088e15e5752a58d372ddb4ffdb..ae3de90ac947fecc6b2a946d41adafd536abb798 100644 (file)
@@ -112,6 +112,8 @@ enum qemuCapsFlags {
     QEMU_CAPS_USB_HUB           = 73, /* -device usb-hub */
     QEMU_CAPS_NO_SHUTDOWN       = 74, /* usable -no-shutdown */
 
+    QEMU_CAPS_DRIVE_CACHE_UNSAFE = 75, /* Is cache=unsafe supported? */
+
     QEMU_CAPS_LAST,                   /* this must always be the last item */
 };
 
index 0adc56a5f94f75480559c6267a6c0e0879765d16..9174a5f4efd79aa082877a6501ea23cd77e29696 100644 (file)
@@ -66,14 +66,16 @@ VIR_ENUM_IMPL(qemuDiskCacheV1, VIR_DOMAIN_DISK_CACHE_LAST,
               "off",
               "off",  /* writethrough not supported, so for safety, disable */
               "on",   /* Old 'on' was equivalent to 'writeback' */
-              "off"); /* directsync not supported, for safety, disable */
+              "off",  /* directsync not supported, for safety, disable */
+              "off"); /* unsafe not supported, for safety, disable */
 
 VIR_ENUM_IMPL(qemuDiskCacheV2, VIR_DOMAIN_DISK_CACHE_LAST,
               "default",
               "none",
               "writethrough",
               "writeback",
-              "directsync");
+              "directsync",
+              "unsafe");
 
 VIR_ENUM_DECL(qemuVideo)
 
@@ -1622,6 +1624,12 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
                                 _("disk cache mode 'directsync' is not "
                                   "supported by this QEMU"));
                 goto error;
+            } else if (disk->cachemode == VIR_DOMAIN_DISK_CACHE_UNSAFE &&
+                !qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_UNSAFE)) {
+                qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                _("disk cache mode 'unsafe' is not "
+                                  "supported by this QEMU"));
+                goto error;
             }
         } else {
             mode = qemuDiskCacheV1TypeToString(disk->cachemode);
@@ -5536,6 +5544,8 @@ qemuParseCommandLineDisk(virCapsPtr caps,
                 def->cachemode = VIR_DOMAIN_DISK_CACHE_WRITETHRU;
             else if (STREQ(values[i], "directsync"))
                 def->cachemode = VIR_DOMAIN_DISK_CACHE_DIRECTSYNC;
+            else if (STREQ(values[i], "unsafe"))
+                def->cachemode = VIR_DOMAIN_DISK_CACHE_UNSAFE;
         } else if (STREQ(keywords[i], "werror") ||
                    STREQ(keywords[i], "rerror")) {
             if (STREQ(values[i], "stop"))
index 91f15af6bb08e2f700dc32140c28d68266e31dc6..6a79630865fd01191babcb4a4e0494b02dca45ec 100644 (file)
@@ -169,6 +169,7 @@ mymain(void)
     DO_TEST("disk-drive-cache-v2-wb");
     DO_TEST("disk-drive-cache-v2-none");
     DO_TEST("disk-drive-cache-directsync");
+    DO_TEST("disk-drive-cache-unsafe");
     DO_TEST("disk-drive-network-nbd");
     DO_TEST("disk-drive-network-rbd");
     DO_TEST("disk-drive-network-sheepdog");
index 933d5563046bce82e30e5dcc06741d8b988b270a..0ff8236582de6b476ac711a08423f9d83d13be76 100644 (file)
@@ -165,6 +165,7 @@ mymain(void)
             QEMU_CAPS_MIGRATE_QEMU_TCP,
             QEMU_CAPS_MIGRATE_QEMU_EXEC,
             QEMU_CAPS_DRIVE_CACHE_V2,
+            QEMU_CAPS_DRIVE_CACHE_UNSAFE,
             QEMU_CAPS_KVM,
             QEMU_CAPS_DRIVE_FORMAT,
             QEMU_CAPS_DRIVE_SERIAL,
@@ -408,6 +409,7 @@ mymain(void)
             QEMU_CAPS_MIGRATE_QEMU_TCP,
             QEMU_CAPS_MIGRATE_QEMU_EXEC,
             QEMU_CAPS_DRIVE_CACHE_V2,
+            QEMU_CAPS_DRIVE_CACHE_UNSAFE,
             QEMU_CAPS_KVM,
             QEMU_CAPS_DRIVE_FORMAT,
             QEMU_CAPS_DRIVE_SERIAL,
@@ -460,6 +462,7 @@ mymain(void)
             QEMU_CAPS_MIGRATE_QEMU_TCP,
             QEMU_CAPS_MIGRATE_QEMU_EXEC,
             QEMU_CAPS_DRIVE_CACHE_V2,
+            QEMU_CAPS_DRIVE_CACHE_UNSAFE,
             QEMU_CAPS_KVM,
             QEMU_CAPS_DRIVE_FORMAT,
             QEMU_CAPS_DRIVE_SERIAL,
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.args
new file mode 100644 (file)
index 0000000..f8ddcd8
--- /dev/null
@@ -0,0 +1,5 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
+pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,bus=0,unit=0,\
+format=qcow2,cache=unsafe -drive file=/dev/HostVG/QEMUGuest2,if=ide,\
+media=cdrom,bus=1,unit=0,format=raw -net none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.xml
new file mode 100644 (file)
index 0000000..37185f6
--- /dev/null
@@ -0,0 +1,33 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219136</memory>
+  <currentMemory>219136</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <driver name='qemu' type='qcow2' cache='unsafe'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' unit='0'/>
+    </disk>
+    <disk type='block' device='cdrom'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest2'/>
+      <target dev='hdc' bus='ide'/>
+      <readonly/>
+      <address type='drive' controller='0' bus='1' unit='0'/>
+    </disk>
+    <controller type='ide' index='0'/>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
index 1dc6a017597dc4f466d62af14274d3b2af289a94..9e174b378f39c09d421c6b9ae56a3ea0e3082209 100644 (file)
@@ -341,6 +341,9 @@ mymain(void)
     DO_TEST("disk-drive-cache-directsync", false,
             QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_CACHE_V2,
             QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC, QEMU_CAPS_DRIVE_FORMAT);
+    DO_TEST("disk-drive-cache-unsafe", false,
+            QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_CACHE_V2,
+            QEMU_CAPS_DRIVE_CACHE_UNSAFE, QEMU_CAPS_DRIVE_FORMAT);
     DO_TEST("disk-drive-network-nbd", false,
             QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
     DO_TEST("disk-drive-network-rbd", false,
index 086fe93c8c2941e97be2e6eda33848ef9786105e..43ed1eae0d9826ffbde505e7841ff8987264a869 100644 (file)
@@ -1195,8 +1195,8 @@ floppy device; consider using B<update-device> for this usage instead.
 I<mode> can specify the two specific mode I<readonly> or I<shareable>.
 I<persistent> indicates the changes will affect the next boot of the domain.
 I<sourcetype> can indicate the type of source (block|file)
-I<cache> can be one of "default", "none", "writethrough", "writeback", or
-"directsync".
+I<cache> can be one of "default", "none", "writethrough", "writeback",
+"directsync" or "unsafe".
 I<serial> is the serial of disk device. I<shareable> indicates the disk device
 is shareable between domains.
 I<address> is the address of disk device in the form of pci:domain.bus.slot.function,