提交 f887334d 编写于 作者: O Oskari Saarenmaa 提交者: Eric Blake

Add unsafe cache mode support for disk driver

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.
上级 cb610092
...@@ -996,10 +996,15 @@ ...@@ -996,10 +996,15 @@
<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", "writeback", and "directsync". "directsync" "writethrough", "writeback", "directsync" (like
is like "writethrough", but it bypasses the host page "writethrough", but it bypasses the host page cache) and
cache. "unsafe" (host may cache all disk io, and sync requests from
<span class="since">Since 0.6.0</span> guest are ignored).
<span class="since">
Since 0.6.0,
"directsync" since 0.9.5,
"unsafe" since 0.9.7
</span>
</li> </li>
<li> <li>
The optional <code>error_policy</code> attribute controls The optional <code>error_policy</code> attribute controls
......
...@@ -848,6 +848,7 @@ ...@@ -848,6 +848,7 @@
<value>writeback</value> <value>writeback</value>
<value>writethrough</value> <value>writethrough</value>
<value>directsync</value> <value>directsync</value>
<value>unsafe</value>
</choice> </choice>
</attribute> </attribute>
</define> </define>
......
...@@ -164,7 +164,8 @@ VIR_ENUM_IMPL(virDomainDiskCache, VIR_DOMAIN_DISK_CACHE_LAST, ...@@ -164,7 +164,8 @@ VIR_ENUM_IMPL(virDomainDiskCache, VIR_DOMAIN_DISK_CACHE_LAST,
"none", "none",
"writethrough", "writethrough",
"writeback", "writeback",
"directsync") "directsync",
"unsafe")
VIR_ENUM_IMPL(virDomainDiskErrorPolicy, VIR_DOMAIN_DISK_ERROR_POLICY_LAST, VIR_ENUM_IMPL(virDomainDiskErrorPolicy, VIR_DOMAIN_DISK_ERROR_POLICY_LAST,
"default", "default",
......
...@@ -192,6 +192,7 @@ enum virDomainDiskCache { ...@@ -192,6 +192,7 @@ enum virDomainDiskCache {
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_DIRECTSYNC,
VIR_DOMAIN_DISK_CACHE_UNSAFE,
VIR_DOMAIN_DISK_CACHE_LAST VIR_DOMAIN_DISK_CACHE_LAST
}; };
......
...@@ -137,6 +137,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST, ...@@ -137,6 +137,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"usb-redir", "usb-redir",
"usb-hub", "usb-hub",
"no-shutdown", "no-shutdown",
"cache-unsafe", /* 75 */
); );
struct qemu_feature_flags { struct qemu_feature_flags {
...@@ -912,12 +914,16 @@ qemuCapsComputeCmdFlags(const char *help, ...@@ -912,12 +914,16 @@ qemuCapsComputeCmdFlags(const char *help,
else if (strstr(help, "-domid")) else if (strstr(help, "-domid"))
qemuCapsSet(flags, QEMU_CAPS_DOMID); qemuCapsSet(flags, QEMU_CAPS_DOMID);
if (strstr(help, "-drive")) { if (strstr(help, "-drive")) {
const char *cache = strstr(help, "cache=");
qemuCapsSet(flags, QEMU_CAPS_DRIVE); qemuCapsSet(flags, QEMU_CAPS_DRIVE);
if (strstr(help, "cache=") && if (cache && (p = strchr(cache, ']'))) {
!strstr(help, "cache=on|off")) { if (memmem(cache, p - cache, "on|off", sizeof("on|off") - 1) == NULL)
qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_V2); qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_V2);
if (strstr(help, "directsync")) if (memmem(cache, p - cache, "directsync", sizeof("directsync") - 1))
qemuCapsSet(flags, QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC); 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=")) if (strstr(help, "format="))
qemuCapsSet(flags, QEMU_CAPS_DRIVE_FORMAT); qemuCapsSet(flags, QEMU_CAPS_DRIVE_FORMAT);
......
...@@ -112,6 +112,8 @@ enum qemuCapsFlags { ...@@ -112,6 +112,8 @@ enum qemuCapsFlags {
QEMU_CAPS_USB_HUB = 73, /* -device usb-hub */ QEMU_CAPS_USB_HUB = 73, /* -device usb-hub */
QEMU_CAPS_NO_SHUTDOWN = 74, /* usable -no-shutdown */ 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 */ QEMU_CAPS_LAST, /* this must always be the last item */
}; };
......
...@@ -66,14 +66,16 @@ VIR_ENUM_IMPL(qemuDiskCacheV1, VIR_DOMAIN_DISK_CACHE_LAST, ...@@ -66,14 +66,16 @@ VIR_ENUM_IMPL(qemuDiskCacheV1, VIR_DOMAIN_DISK_CACHE_LAST,
"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 */ "off", /* directsync not supported, for safety, disable */
"off"); /* unsafe 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"); "directsync",
"unsafe");
VIR_ENUM_DECL(qemuVideo) VIR_ENUM_DECL(qemuVideo)
...@@ -1622,6 +1624,12 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk, ...@@ -1622,6 +1624,12 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
_("disk cache mode 'directsync' is not " _("disk cache mode 'directsync' is not "
"supported by this QEMU")); "supported by this QEMU"));
goto error; 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 { } else {
mode = qemuDiskCacheV1TypeToString(disk->cachemode); mode = qemuDiskCacheV1TypeToString(disk->cachemode);
...@@ -5536,6 +5544,8 @@ qemuParseCommandLineDisk(virCapsPtr caps, ...@@ -5536,6 +5544,8 @@ qemuParseCommandLineDisk(virCapsPtr caps,
def->cachemode = VIR_DOMAIN_DISK_CACHE_WRITETHRU; def->cachemode = VIR_DOMAIN_DISK_CACHE_WRITETHRU;
else if (STREQ(values[i], "directsync")) else if (STREQ(values[i], "directsync"))
def->cachemode = VIR_DOMAIN_DISK_CACHE_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") || } else if (STREQ(keywords[i], "werror") ||
STREQ(keywords[i], "rerror")) { STREQ(keywords[i], "rerror")) {
if (STREQ(values[i], "stop")) if (STREQ(values[i], "stop"))
......
...@@ -169,6 +169,7 @@ mymain(void) ...@@ -169,6 +169,7 @@ mymain(void)
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-cache-directsync");
DO_TEST("disk-drive-cache-unsafe");
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");
......
...@@ -165,6 +165,7 @@ mymain(void) ...@@ -165,6 +165,7 @@ mymain(void)
QEMU_CAPS_MIGRATE_QEMU_TCP, QEMU_CAPS_MIGRATE_QEMU_TCP,
QEMU_CAPS_MIGRATE_QEMU_EXEC, QEMU_CAPS_MIGRATE_QEMU_EXEC,
QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_CACHE_V2,
QEMU_CAPS_DRIVE_CACHE_UNSAFE,
QEMU_CAPS_KVM, QEMU_CAPS_KVM,
QEMU_CAPS_DRIVE_FORMAT, QEMU_CAPS_DRIVE_FORMAT,
QEMU_CAPS_DRIVE_SERIAL, QEMU_CAPS_DRIVE_SERIAL,
...@@ -408,6 +409,7 @@ mymain(void) ...@@ -408,6 +409,7 @@ mymain(void)
QEMU_CAPS_MIGRATE_QEMU_TCP, QEMU_CAPS_MIGRATE_QEMU_TCP,
QEMU_CAPS_MIGRATE_QEMU_EXEC, QEMU_CAPS_MIGRATE_QEMU_EXEC,
QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_CACHE_V2,
QEMU_CAPS_DRIVE_CACHE_UNSAFE,
QEMU_CAPS_KVM, QEMU_CAPS_KVM,
QEMU_CAPS_DRIVE_FORMAT, QEMU_CAPS_DRIVE_FORMAT,
QEMU_CAPS_DRIVE_SERIAL, QEMU_CAPS_DRIVE_SERIAL,
...@@ -460,6 +462,7 @@ mymain(void) ...@@ -460,6 +462,7 @@ mymain(void)
QEMU_CAPS_MIGRATE_QEMU_TCP, QEMU_CAPS_MIGRATE_QEMU_TCP,
QEMU_CAPS_MIGRATE_QEMU_EXEC, QEMU_CAPS_MIGRATE_QEMU_EXEC,
QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_CACHE_V2,
QEMU_CAPS_DRIVE_CACHE_UNSAFE,
QEMU_CAPS_KVM, QEMU_CAPS_KVM,
QEMU_CAPS_DRIVE_FORMAT, QEMU_CAPS_DRIVE_FORMAT,
QEMU_CAPS_DRIVE_SERIAL, QEMU_CAPS_DRIVE_SERIAL,
......
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
<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>
...@@ -341,6 +341,9 @@ mymain(void) ...@@ -341,6 +341,9 @@ mymain(void)
DO_TEST("disk-drive-cache-directsync", false, DO_TEST("disk-drive-cache-directsync", false,
QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_CACHE_V2,
QEMU_CAPS_DRIVE_CACHE_DIRECTSYNC, QEMU_CAPS_DRIVE_FORMAT); 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, 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,
......
...@@ -1195,8 +1195,8 @@ floppy device; consider using B<update-device> for this usage instead. ...@@ -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<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", "writeback", or I<cache> can be one of "default", "none", "writethrough", "writeback",
"directsync". "directsync" or "unsafe".
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,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册