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 known if unsafe
is supported.
* Improved the reliability of qemu cache type detection.
---
Updated patch based on Eric Blake's comments and rebased it to c4111bd0
docs/formatdomain.html.in | 13 +--
docs/schemas/domaincommon.rng |1 +
src/conf/domain_conf.c |3 +-
src/conf/domain_conf.h |1 +
src/qemu/qemu_capabilities.c | 14 ++--
src/qemu/qemu_capabilities.h |2 +
src/qemu/qemu_command.c| 14 +++-
tests/qemuargv2xmltest.c |1 +
tests/qemuhelptest.c |3 ++
.../qemuxml2argv-disk-drive-cache-unsafe.args |5 +++
.../qemuxml2argv-disk-drive-cache-unsafe.xml | 33
tests/qemuxml2argvtest.c |3 ++
tools/virsh.pod|4 +-
13 files changed, 84 insertions(+), 13 deletions(-)
create mode 100644
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.args
create mode 100644
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-cache-unsafe.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0a7abaf..0628d1c 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -996,10 +996,15 @@
li
The optional codecache/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=sinceSince 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 codeerror_policy/code attribute controls
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index d0da41c..be98be0 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -848,6 +848,7 @@
valuewriteback/value
valuewritethrough/value
valuedirectsync/value
+valueunsafe/value
/choice
/attribute
/define
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7463d7c..a918679 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -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,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 371f270..86b4c79 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -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
};
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 850d46e..8e20e3f 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -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);