Support disk caching mode config

This commit is contained in:
Daniel P. Berrange 2009-01-30 17:15:39 +00:00
parent 3cb55cb51f
commit 67e7416119
20 changed files with 315 additions and 23 deletions

View File

@ -1,4 +1,16 @@
Fri Jan 30 16:12:22 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
Fri Jan 30 17:12:22 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
Support <driver cache='none|writeback|writethrough'/> cache
control options
* src/domain_conf.c, src/domain_conf.h: Add supported for
disk caching mode options
* src/qemu_conf.c, src/qemu_conf.h: Detect supported cache
mode options for -drive and use them when launching QEMU
* docs/schemas/domain.rng: Document cache mode options
* tests/qemuxml2argvtest.c: Validate cache mode processing
* tests/qemuxml2argvdata/: Data files for cache mode options
Fri Jan 30 17:12:22 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
Fix crash when using bogus arch type
* src/capabilities.c, src/capabilities.h: Add method to query

View File

@ -426,18 +426,45 @@
-->
<define name='driver'>
<element name='driver'>
<attribute name='name'>
<ref name='genericName'/>
</attribute>
<optional>
<attribute name='type'>
<ref name='genericName'/>
</attribute>
</optional>
<choice>
<group>
<ref name='driverFormat'/>
<optional>
<ref name='driverCache'/>
</optional>
</group>
<group>
<optional>
<ref name='driverFormat'/>
</optional>
<ref name='driverCache'/>
</group>
</choice>
<empty/>
</element>
</define>
<define name='driverFormat'>
<attribute name='name'>
<ref name='genericName'/>
</attribute>
<optional>
<attribute name='type'>
<ref name='genericName'/>
</attribute>
</optional>
</define>
<define name='driverCache'>
<attribute name='cache'>
<choice>
<value>none</value>
<value>writeback</value>
<value>writethrough</value>
</choice>
</attribute>
</define>
<define name='filesystem'>
<element name='filesystem'>
<choice>

View File

@ -1,7 +1,7 @@
/*
* domain_conf.c: domain XML processing
*
* Copyright (C) 2006-2008 Red Hat, Inc.
* Copyright (C) 2006-2009 Red Hat, Inc.
* Copyright (C) 2006-2008 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@ -91,6 +91,12 @@ VIR_ENUM_IMPL(virDomainDiskBus, VIR_DOMAIN_DISK_BUS_LAST,
"usb",
"uml")
VIR_ENUM_IMPL(virDomainDiskCache, VIR_DOMAIN_DISK_CACHE_LAST,
"default",
"none",
"writethrough",
"writeback");
VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST,
"mount",
"block",
@ -568,6 +574,7 @@ virDomainDiskDefParseXML(virConnectPtr conn,
char *source = NULL;
char *target = NULL;
char *bus = NULL;
char *cachetag = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError(conn);
@ -617,6 +624,7 @@ virDomainDiskDefParseXML(virConnectPtr conn,
(xmlStrEqual(cur->name, BAD_CAST "driver"))) {
driverName = virXMLPropString(cur, "name");
driverType = virXMLPropString(cur, "type");
cachetag = virXMLPropString(cur, "cache");
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
def->readonly = 1;
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
@ -713,6 +721,13 @@ virDomainDiskDefParseXML(virConnectPtr conn,
goto error;
}
if (cachetag &&
(def->cachemode = virDomainDiskCacheTypeFromString(cachetag)) < 0) {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("unknown disk cache mode '%s'"), cachetag);
goto error;
}
def->src = source;
source = NULL;
def->dst = target;
@ -730,6 +745,7 @@ cleanup:
VIR_FREE(device);
VIR_FREE(driverType);
VIR_FREE(driverName);
VIR_FREE(cachetag);
return def;
@ -2756,6 +2772,7 @@ virDomainDiskDefFormat(virConnectPtr conn,
const char *type = virDomainDiskTypeToString(def->type);
const char *device = virDomainDiskDeviceTypeToString(def->device);
const char *bus = virDomainDiskBusTypeToString(def->bus);
const char *cachemode = virDomainDiskCacheTypeToString(def->cachemode);
if (!type) {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
@ -2772,20 +2789,23 @@ virDomainDiskDefFormat(virConnectPtr conn,
_("unexpected disk bus %d"), def->bus);
return -1;
}
if (!cachemode) {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("unexpected disk cache mode %d"), def->cachemode);
return -1;
}
virBufferVSprintf(buf,
" <disk type='%s' device='%s'>\n",
type, device);
if (def->driverName) {
virBufferVSprintf(buf, " <driver name='%s'", def->driverName);
if (def->driverType)
virBufferVSprintf(buf,
" <driver name='%s' type='%s'/>\n",
def->driverName, def->driverType);
else
virBufferVSprintf(buf,
" <driver name='%s'/>\n",
def->driverName);
virBufferVSprintf(buf, " type='%s'", def->driverType);
if (def->cachemode)
virBufferVSprintf(buf, " cache='%s'", cachemode);
virBufferVSprintf(buf, "/>\n");
}
if (def->src) {

View File

@ -81,6 +81,15 @@ enum virDomainDiskBus {
VIR_DOMAIN_DISK_BUS_LAST
};
enum virDomainDiskCache {
VIR_DOMAIN_DISK_CACHE_DEFAULT,
VIR_DOMAIN_DISK_CACHE_DISABLE,
VIR_DOMAIN_DISK_CACHE_WRITETHRU,
VIR_DOMAIN_DISK_CACHE_WRITEBACK,
VIR_DOMAIN_DISK_CACHE_LAST
};
/* Stores the virtual disk configuration */
typedef struct _virDomainDiskDef virDomainDiskDef;
typedef virDomainDiskDef *virDomainDiskDefPtr;
@ -92,6 +101,7 @@ struct _virDomainDiskDef {
char *dst;
char *driverName;
char *driverType;
int cachemode;
unsigned int readonly : 1;
unsigned int shared : 1;
int slotnum; /* pci slot number for unattach */
@ -615,6 +625,7 @@ VIR_ENUM_DECL(virDomainLifecycle)
VIR_ENUM_DECL(virDomainDisk)
VIR_ENUM_DECL(virDomainDiskDevice)
VIR_ENUM_DECL(virDomainDiskBus)
VIR_ENUM_DECL(virDomainDiskCache)
VIR_ENUM_DECL(virDomainFS)
VIR_ENUM_DECL(virDomainNet)
VIR_ENUM_DECL(virDomainChr)

View File

@ -1,7 +1,7 @@
/*
* config.c: VM configuration management
*
* Copyright (C) 2006, 2007, 2008 Red Hat, Inc.
* Copyright (C) 2006, 2007, 2008, 2009 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@ -61,6 +61,22 @@ VIR_ENUM_IMPL(virDomainDiskQEMUBus, VIR_DOMAIN_DISK_BUS_LAST,
"uml")
VIR_ENUM_DECL(qemuDiskCacheV1)
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' */
VIR_ENUM_IMPL(qemuDiskCacheV2, VIR_DOMAIN_DISK_CACHE_LAST,
"default",
"none",
"writethrough",
"writeback");
#define qemudLog(level, msg...) fprintf(stderr, msg)
int qemudLoadDriverConfig(struct qemud_driver *driver,
@ -398,8 +414,11 @@ int qemudExtractVersionInfo(const char *qemu,
flags |= QEMUD_CMD_FLAG_UUID;
if (strstr(help, "-domid"))
flags |= QEMUD_CMD_FLAG_DOMID;
if (strstr(help, "-drive"))
if (strstr(help, "-drive")) {
flags |= QEMUD_CMD_FLAG_DRIVE;
if (strstr(help, "cache=writethrough|writeback|none"))
flags |= QEMUD_CMD_FLAG_DRIVE_CACHE_V2;
}
if (strstr(help, "boot=on"))
flags |= QEMUD_CMD_FLAG_DRIVE_BOOT;
if (version >= 9000)
@ -591,6 +610,7 @@ qemudNetworkIfaceConnect(virConnectPtr conn,
return NULL;
}
static int qemudBuildCommandLineChrDevStr(virDomainChrDefPtr dev,
char *buf,
int buflen)
@ -1015,11 +1035,20 @@ int qemudBuildCommandLine(virConnectPtr conn,
if (bootable &&
disk->device == VIR_DOMAIN_DISK_DEVICE_DISK)
virBufferAddLit(&opt, ",boot=on");
if (disk->shared && !disk->readonly)
virBufferAddLit(&opt, ",cache=off");
if (disk->driverType)
virBufferVSprintf(&opt, ",fmt=%s", disk->driverType);
if (disk->cachemode) {
const char *mode =
(qemuCmdFlags & QEMUD_CMD_FLAG_DRIVE_CACHE_V2) ?
qemuDiskCacheV2TypeToString(disk->cachemode) :
qemuDiskCacheV1TypeToString(disk->cachemode);
virBufferVSprintf(&opt, ",cache=%s", mode);
} else if (disk->shared && !disk->readonly) {
virBufferAddLit(&opt, ",cache=off");
}
if (virBufferError(&opt)) {
virReportOOMError(conn);
goto error;
@ -1585,4 +1614,3 @@ cleanup:
VIR_FREE(xml);
return ret;
}

View File

@ -1,7 +1,7 @@
/*
* config.h: VM configuration management
*
* Copyright (C) 2006, 2007 Red Hat, Inc.
* Copyright (C) 2006, 2007, 2009 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@ -53,6 +53,7 @@ enum qemud_cmd_flags {
* since it had a design bug blocking the entire monitor console */
QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP = (1 << 10), /* New migration syntax after merge to QEMU with TCP transport */
QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC = (1 << 11), /* New migration syntax after merge to QEMU with EXEC transport */
QEMUD_CMD_FLAG_DRIVE_CACHE_V2 = (1 << 12), /* Is the cache= flag wanting new v2 values */
};
/* Main driver state */

View File

@ -0,0 +1 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor pty -pidfile /nowhere/QEMUGuest1.pid -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,fmt=qcow2,cache=off -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,fmt=raw -net none -serial none -parallel none -usb

View File

@ -0,0 +1,29 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219200</memory>
<currentMemory>219200</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='none'/>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
</disk>
<disk type='block' device='cdrom'>
<driver name='qemu' type='raw'/>
<source dev='/dev/HostVG/QEMUGuest2'/>
<target dev='hdc' bus='ide'/>
<readonly/>
</disk>
</devices>
</domain>

View File

@ -0,0 +1 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor pty -pidfile /nowhere/QEMUGuest1.pid -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,fmt=qcow2,cache=on -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,fmt=raw -net none -serial none -parallel none -usb

View File

@ -0,0 +1,29 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219200</memory>
<currentMemory>219200</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='writeback'/>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
</disk>
<disk type='block' device='cdrom'>
<driver name='qemu' type='raw'/>
<source dev='/dev/HostVG/QEMUGuest2'/>
<target dev='hdc' bus='ide'/>
<readonly/>
</disk>
</devices>
</domain>

View File

@ -0,0 +1 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor pty -pidfile /nowhere/QEMUGuest1.pid -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,fmt=qcow2,cache=off -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,fmt=raw -net none -serial none -parallel none -usb

View File

@ -0,0 +1,29 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219200</memory>
<currentMemory>219200</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='writethrough'/>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
</disk>
<disk type='block' device='cdrom'>
<driver name='qemu' type='raw'/>
<source dev='/dev/HostVG/QEMUGuest2'/>
<target dev='hdc' bus='ide'/>
<readonly/>
</disk>
</devices>
</domain>

View File

@ -0,0 +1 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor pty -pidfile /nowhere/QEMUGuest1.pid -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,fmt=qcow2,cache=none -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,fmt=raw -net none -serial none -parallel none -usb

View File

@ -0,0 +1,29 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219200</memory>
<currentMemory>219200</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='none'/>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
</disk>
<disk type='block' device='cdrom'>
<driver name='qemu' type='raw'/>
<source dev='/dev/HostVG/QEMUGuest2'/>
<target dev='hdc' bus='ide'/>
<readonly/>
</disk>
</devices>
</domain>

View File

@ -0,0 +1 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor pty -pidfile /nowhere/QEMUGuest1.pid -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,fmt=qcow2,cache=writeback -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,fmt=raw -net none -serial none -parallel none -usb

View File

@ -0,0 +1,29 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219200</memory>
<currentMemory>219200</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='writeback'/>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
</disk>
<disk type='block' device='cdrom'>
<driver name='qemu' type='raw'/>
<source dev='/dev/HostVG/QEMUGuest2'/>
<target dev='hdc' bus='ide'/>
<readonly/>
</disk>
</devices>
</domain>

View File

@ -0,0 +1 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor pty -pidfile /nowhere/QEMUGuest1.pid -no-acpi -boot c -drive file=/dev/HostVG/QEMUGuest1,if=ide,index=0,fmt=qcow2,cache=writethrough -drive file=/dev/HostVG/QEMUGuest2,if=ide,media=cdrom,index=2,fmt=raw -net none -serial none -parallel none -usb

View File

@ -0,0 +1,29 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219200</memory>
<currentMemory>219200</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='writethrough'/>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
</disk>
<disk type='block' device='cdrom'>
<driver name='qemu' type='raw'/>
<source dev='/dev/HostVG/QEMUGuest2'/>
<target dev='hdc' bus='ide'/>
<readonly/>
</disk>
</devices>
</domain>

View File

@ -201,6 +201,16 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_DRIVE_BOOT);
DO_TEST("disk-drive-fmt-qcow", QEMUD_CMD_FLAG_DRIVE |
QEMUD_CMD_FLAG_DRIVE_BOOT);
DO_TEST("disk-drive-shared", QEMUD_CMD_FLAG_DRIVE);
DO_TEST("disk-drive-cache-v1-wt", QEMUD_CMD_FLAG_DRIVE);
DO_TEST("disk-drive-cache-v1-wb", QEMUD_CMD_FLAG_DRIVE);
DO_TEST("disk-drive-cache-v1-none", QEMUD_CMD_FLAG_DRIVE);
DO_TEST("disk-drive-cache-v2-wt", QEMUD_CMD_FLAG_DRIVE |
QEMUD_CMD_FLAG_DRIVE_CACHE_V2);
DO_TEST("disk-drive-cache-v2-wb", QEMUD_CMD_FLAG_DRIVE |
QEMUD_CMD_FLAG_DRIVE_CACHE_V2);
DO_TEST("disk-drive-cache-v2-none", QEMUD_CMD_FLAG_DRIVE |
QEMUD_CMD_FLAG_DRIVE_CACHE_V2);
DO_TEST("disk-usb", 0);
DO_TEST("graphics-vnc", 0);
DO_TEST("graphics-sdl", 0);

View File

@ -98,6 +98,9 @@ mymain(int argc, char **argv)
DO_TEST("disk-xenvbd");
DO_TEST("disk-usb");
DO_TEST("disk-drive-fmt-qcow");
DO_TEST("disk-drive-cache-v1-wt");
DO_TEST("disk-drive-cache-v1-wb");
DO_TEST("disk-drive-cache-v1-none");
DO_TEST("graphics-vnc");
DO_TEST("graphics-sdl");
DO_TEST("graphics-sdl-fullscreen");