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.
This commit is contained in:
Osier Yang 2011-09-02 21:36:58 +08:00
parent ddcd5674aa
commit 6ee52c1b76
10 changed files with 41 additions and 11 deletions

View File

@ -976,7 +976,9 @@
<li> <li>
The optional <code>cache</code> attribute controls the The optional <code>cache</code> attribute controls the
cache mechanism, possible values are "default", "none", 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.
<span class="since">Since 0.6.0</span> <span class="since">Since 0.6.0</span>
</li> </li>
<li> <li>

View File

@ -829,6 +829,7 @@
<value>none</value> <value>none</value>
<value>writeback</value> <value>writeback</value>
<value>writethrough</value> <value>writethrough</value>
<value>directsync</value>
</choice> </choice>
</attribute> </attribute>
</define> </define>

View File

@ -160,7 +160,8 @@ VIR_ENUM_IMPL(virDomainDiskCache, VIR_DOMAIN_DISK_CACHE_LAST,
"default", "default",
"none", "none",
"writethrough", "writethrough",
"writeback") "writeback",
"directsync")
VIR_ENUM_IMPL(virDomainDiskErrorPolicy, VIR_DOMAIN_DISK_ERROR_POLICY_LAST, VIR_ENUM_IMPL(virDomainDiskErrorPolicy, VIR_DOMAIN_DISK_ERROR_POLICY_LAST,
"default", "default",

View File

@ -165,6 +165,7 @@ enum virDomainDiskCache {
VIR_DOMAIN_DISK_CACHE_DISABLE, VIR_DOMAIN_DISK_CACHE_DISABLE,
VIR_DOMAIN_DISK_CACHE_WRITETHRU, VIR_DOMAIN_DISK_CACHE_WRITETHRU,
VIR_DOMAIN_DISK_CACHE_WRITEBACK, VIR_DOMAIN_DISK_CACHE_WRITEBACK,
VIR_DOMAIN_DISK_CACHE_DIRECTSYNC,
VIR_DOMAIN_DISK_CACHE_LAST VIR_DOMAIN_DISK_CACHE_LAST
}; };

View File

@ -125,6 +125,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"sga", "sga",
"virtio-blk-pci.event_idx", "virtio-blk-pci.event_idx",
"virtio-net-pci.event_idx", "virtio-net-pci.event_idx",
"cache-directsync",
); );
struct qemu_feature_flags { struct qemu_feature_flags {
@ -902,8 +903,11 @@ qemuCapsComputeCmdFlags(const char *help,
if (strstr(help, "-drive")) { if (strstr(help, "-drive")) {
qemuCapsSet(flags, QEMU_CAPS_DRIVE); qemuCapsSet(flags, QEMU_CAPS_DRIVE);
if (strstr(help, "cache=") && if (strstr(help, "cache=") &&
!strstr(help, "cache=on|off")) !strstr(help, "cache=on|off")) {
qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_V2); qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_V2);
if (strstr(help, "directsync"))
qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC);
}
if (strstr(help, "format=")) if (strstr(help, "format="))
qemuCapsSet(flags, QEMU_CAPS_DRIVE_FORMAT); qemuCapsSet(flags, QEMU_CAPS_DRIVE_FORMAT);
if (strstr(help, "readonly=")) if (strstr(help, "readonly="))

View File

@ -100,6 +100,7 @@ enum qemuCapsFlags {
QEMU_CAPS_SGA = 62, /* Serial Graphics Adapter */ QEMU_CAPS_SGA = 62, /* Serial Graphics Adapter */
QEMU_CAPS_VIRTIO_BLK_EVENT_IDX = 63, /* virtio-blk-pci.event_idx */ 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_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 */ QEMU_CAPS_LAST, /* this must always be the last item */
}; };

View File

@ -65,13 +65,15 @@ VIR_ENUM_IMPL(qemuDiskCacheV1, VIR_DOMAIN_DISK_CACHE_LAST,
"default", "default",
"off", "off",
"off", /* writethrough not supported, so for safety, disable */ "off", /* writethrough not supported, so for safety, disable */
"on"); /* Old 'on' was equivalent to 'writeback' */ "on", /* Old 'on' was equivalent to 'writeback' */
"off"); /* directsync not supported, for safety, disable */
VIR_ENUM_IMPL(qemuDiskCacheV2, VIR_DOMAIN_DISK_CACHE_LAST, VIR_ENUM_IMPL(qemuDiskCacheV2, VIR_DOMAIN_DISK_CACHE_LAST,
"default", "default",
"none", "none",
"writethrough", "writethrough",
"writeback"); "writeback",
"directsync");
VIR_ENUM_DECL(qemuVideo) VIR_ENUM_DECL(qemuVideo)
@ -1516,10 +1518,21 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
} }
if (disk->cachemode) { if (disk->cachemode) {
const char *mode = const char *mode = NULL;
qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_V2) ?
qemuDiskCacheV2TypeToString(disk->cachemode) : if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_CACHE_V2)) {
qemuDiskCacheV1TypeToString(disk->cachemode); 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); virBufferAsprintf(&opt, ",cache=%s", mode);
} else if (disk->shared && !disk->readonly) { } else if (disk->shared && !disk->readonly) {
@ -5211,6 +5224,8 @@ qemuParseCommandLineDisk(virCapsPtr caps,
def->cachemode = VIR_DOMAIN_DISK_CACHE_WRITEBACK; def->cachemode = VIR_DOMAIN_DISK_CACHE_WRITEBACK;
else if (STREQ(values[i], "writethrough")) else if (STREQ(values[i], "writethrough"))
def->cachemode = VIR_DOMAIN_DISK_CACHE_WRITETHRU; 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") || } else if (STREQ(keywords[i], "werror") ||
STREQ(keywords[i], "rerror")) { STREQ(keywords[i], "rerror")) {
if (STREQ(values[i], "stop")) if (STREQ(values[i], "stop"))

View File

@ -168,6 +168,7 @@ mymain(void)
DO_TEST("disk-drive-cache-v2-wt"); DO_TEST("disk-drive-cache-v2-wt");
DO_TEST("disk-drive-cache-v2-wb"); DO_TEST("disk-drive-cache-v2-wb");
DO_TEST("disk-drive-cache-v2-none"); DO_TEST("disk-drive-cache-v2-none");
DO_TEST("disk-drive-cache-directsync");
DO_TEST("disk-drive-network-nbd"); DO_TEST("disk-drive-network-nbd");
DO_TEST("disk-drive-network-rbd"); DO_TEST("disk-drive-network-rbd");
DO_TEST("disk-drive-network-sheepdog"); DO_TEST("disk-drive-network-sheepdog");

View File

@ -338,6 +338,9 @@ mymain(void)
QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_FORMAT); QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_FORMAT);
DO_TEST("disk-drive-cache-v2-none", false, DO_TEST("disk-drive-cache-v2-none", false,
QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_FORMAT); 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, DO_TEST("disk-drive-network-nbd", false,
QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT); QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_FORMAT);
DO_TEST("disk-drive-network-rbd", false, DO_TEST("disk-drive-network-rbd", false,

View File

@ -1099,7 +1099,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<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<persistent> indicates the changes will affect the next boot of the domain.
I<sourcetype> can indicate the type of source (block|file) I<sourcetype> can indicate the type of source (block|file)
I<cache> can be one of "default", "none", "writethrough" or "writeback". I<cache> can be one of "default", "none", "writethrough", "writeback", or
"directsync".
I<serial> is the serial of disk device. I<shareable> indicates the disk device I<serial> is the serial of disk device. I<shareable> indicates the disk device
is shareable between domains. is shareable between domains.
I<address> is the address of disk device in the form of pci:domain.bus.slot.function, I<address> is the address of disk device in the form of pci:domain.bus.slot.function,