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 @@
The optional cache 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.
-Since 0.6.0
+"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).
+
+ Since 0.6.0,
+ "directsync" since 0.9.5,
+ "unsafe" since 0.9.7
+
The optional error_policy 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 @@
writeback
writethrough
directsync
+unsafe
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);
}
if (strstr(help, "format="))