From 6ee52c1b764c2660b143ef3b265a5243949191c3 Mon Sep 17 00:00:00 2001 From: Osier Yang Date: Fri, 2 Sep 2011 21:36:58 +0800 Subject: [PATCH] Add directsync cache mode support for disk driver Newer QEMU introduced cache=directsync for -drive, this patchset is to expose it in libvirt layer. * Introduced a new QEMU capability flag ($prefix_CACHE_DIRECTSYNC), As even $prefix_CACHE_V2 is set, we can't known if directsync is supported. --- docs/formatdomain.html.in | 4 +++- docs/schemas/domain.rng | 1 + src/conf/domain_conf.c | 3 ++- src/conf/domain_conf.h | 1 + src/qemu/qemu_capabilities.c | 6 +++++- src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 29 ++++++++++++++++++++++------- tests/qemuargv2xmltest.c | 1 + tests/qemuxml2argvtest.c | 3 +++ tools/virsh.pod | 3 ++- 10 files changed, 41 insertions(+), 11 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index f46771df0f..8fd6ca1f8d 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -976,7 +976,9 @@
  • The optional cache attribute controls the cache mechanism, possible values are "default", "none", - "writethrough" and "writeback". + "writethrough", "writeback", and "directsync". "directsync" + is like "writethrough", but it bypasses the host page + cache. Since 0.6.0
  • diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index dd8c41ae0c..e43b17decb 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -829,6 +829,7 @@ none writeback writethrough + directsync diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 00212db08b..a2de8df18a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -160,7 +160,8 @@ VIR_ENUM_IMPL(virDomainDiskCache, VIR_DOMAIN_DISK_CACHE_LAST, "default", "none", "writethrough", - "writeback") + "writeback", + "directsync") 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 8382d2839f..0abb75e3d1 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -165,6 +165,7 @@ enum virDomainDiskCache { VIR_DOMAIN_DISK_CACHE_DISABLE, VIR_DOMAIN_DISK_CACHE_WRITETHRU, VIR_DOMAIN_DISK_CACHE_WRITEBACK, + VIR_DOMAIN_DISK_CACHE_DIRECTSYNC, VIR_DOMAIN_DISK_CACHE_LAST }; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index f665de4c09..631d683101 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -125,6 +125,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, "sga", "virtio-blk-pci.event_idx", "virtio-net-pci.event_idx", + "cache-directsync", ); struct qemu_feature_flags { @@ -902,8 +903,11 @@ qemuCapsComputeCmdFlags(const char *help, if (strstr(help, "-drive")) { qemuCapsSet(flags, QEMU_CAPS_DRIVE); if (strstr(help, "cache=") && - !strstr(help, "cache=on|off")) + !strstr(help, "cache=on|off")) { qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_V2); + if (strstr(help, "directsync")) + qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC); + } if (strstr(help, "format=")) qemuCapsSet(flags, QEMU_CAPS_DRIVE_FORMAT); if (strstr(help, "readonly=")) diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 13af0b9d7b..c01d438ca8 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -100,6 +100,7 @@ enum qemuCapsFlags { QEMU_CAPS_SGA = 62, /* Serial Graphics Adapter */ QEMU_CAPS_VIRTIO_BLK_EVENT_IDX = 63, /* virtio-blk-pci.event_idx */ QEMU_CAPS_VIRTIO_NET_EVENT_IDX = 64, /* virtio-net-pci.event_idx */ + QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC = 65, /* Is cache=directsync supported? */ QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 44a553bc63..fa52dc0ab9 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -64,14 +64,16 @@ VIR_ENUM_DECL(qemuDiskCacheV2) VIR_ENUM_IMPL(qemuDiskCacheV1, VIR_DOMAIN_DISK_CACHE_LAST, "default", "off", - "off", /* writethrough not supported, so for safety, disable */ - "on"); /* Old 'on' was equivalent to 'writeback' */ + "off", /* writethrough not supported, so for safety, disable */ + "on", /* Old 'on' was equivalent to 'writeback' */ + "off"); /* directsync not supported, for safety, disable */ VIR_ENUM_IMPL(qemuDiskCacheV2, VIR_DOMAIN_DISK_CACHE_LAST, "default", "none", "writethrough", - "writeback"); + "writeback", + "directsync"); VIR_ENUM_DECL(qemuVideo) @@ -1516,10 +1518,21 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk, } if (disk->cachemode) { - const char *mode = - qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_V2) ? - qemuDiskCacheV2TypeToString(disk->cachemode) : - qemuDiskCacheV1TypeToString(disk->cachemode); + const char *mode = NULL; + + if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_V2)) { + mode = qemuDiskCacheV2TypeToString(disk->cachemode); + + if (disk->cachemode == VIR_DOMAIN_DISK_CACHE_DIRECTSYNC && + !qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC)) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("disk cache mode 'directsync' is not " + "supported by this QEMU")); + goto error; + } + } else { + mode = qemuDiskCacheV1TypeToString(disk->cachemode); + } virBufferAsprintf(&opt, ",cache=%s", mode); } else if (disk->shared && !disk->readonly) { @@ -5211,6 +5224,8 @@ qemuParseCommandLineDisk(virCapsPtr caps, def->cachemode = VIR_DOMAIN_DISK_CACHE_WRITEBACK; else if (STREQ(values[i], "writethrough")) def->cachemode = VIR_DOMAIN_DISK_CACHE_WRITETHRU; + else if (STREQ(values[i], "directsync")) + def->cachemode = VIR_DOMAIN_DISK_CACHE_DIRECTSYNC; } else if (STREQ(keywords[i], "werror") || STREQ(keywords[i], "rerror")) { if (STREQ(values[i], "stop")) diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c index c2b6cf2a8b..91f15af6bb 100644 --- a/tests/qemuargv2xmltest.c +++ b/tests/qemuargv2xmltest.c @@ -168,6 +168,7 @@ mymain(void) DO_TEST("disk-drive-cache-v2-wt"); DO_TEST("disk-drive-cache-v2-wb"); DO_TEST("disk-drive-cache-v2-none"); + DO_TEST("disk-drive-cache-directsync"); DO_TEST("disk-drive-network-nbd"); DO_TEST("disk-drive-network-rbd"); DO_TEST("disk-drive-network-sheepdog"); diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 6e8da5e756..b009bf3cb5 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -338,6 +338,9 @@ mymain(void) QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_FORMAT); DO_TEST("disk-drive-cache-v2-none", false, QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_FORMAT); + 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-network-nbd", false, QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT); DO_TEST("disk-drive-network-rbd", false, diff --git a/tools/virsh.pod b/tools/virsh.pod index 772d33247f..2e765725a3 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1099,7 +1099,8 @@ floppy device; consider using B for this usage instead. I can specify the two specific mode I or I. I indicates the changes will affect the next boot of the domain. I can indicate the type of source (block|file) -I can be one of "default", "none", "writethrough" or "writeback". +I can be one of "default", "none", "writethrough", "writeback", or +"directsync". I is the serial of disk device. I indicates the disk device is shareable between domains. I
    is the address of disk device in the form of pci:domain.bus.slot.function, -- GitLab