Add new attribute wrpolicy to <driver> element

This introduces new attribute wrpolicy with only supported
value as immediate. This will be an optional
attribute with no defaults. This helps specify whether
to skip the host page cache.

When wrpolicy is specified, meaning when wrpolicy=immediate
a writeback is explicitly initiated for the dirty pages in
the host page cache as part of the guest file write operation.

Usage:
<filesystem type='mount' accessmode='passthrough'>
  <driver type='path' wrpolicy='immediate'/>
  <source dir='/export/to/guest'/>
  <target dir='mount_tag'/>
</filesystem>

Currently this only works with type='mount' for the QEMU/KVM driver.

Signed-off-by: Deepak C Shetty <deepakcs@linux.vnet.ibm.com>
This commit is contained in:
Deepak C Shetty 2012-01-17 18:14:18 +05:30 committed by Eric Blake
parent 9619d8a62e
commit d9e0d8204b
12 changed files with 75 additions and 11 deletions

View File

@ -1396,7 +1396,7 @@
&lt;target dir='/'/&gt;
&lt;/filesystem&gt;
&lt;filesystem type='mount' accessmode='passthrough'&gt;
&lt;driver type='path'/&gt;
&lt;driver type='path' wrpolicy='immediate'/&gt;
&lt;source dir='/export/to/guest'/&gt;
&lt;target dir='/import/from/host'/&gt;
&lt;readonly/&gt;
@ -1423,7 +1423,12 @@
sub-element <code>driver</code>, with an
attribute <code>type='path'</code>
or <code>type='handle'</code> <span class="since">(since
0.9.7)</span>.
0.9.7)</span>. The driver block has an optional attribute
<code>wrpolicy</code> that further controls interaction with
the host page cache; omitting the attribute gives default behavior,
while the value <code>immediate</code> means that a host writeback
is immediately triggered for all pages touched during a guest file
write operation <span class="since">(since 0.9.10)</span>.
</dd>
<dt><code>type='template'</code></dt>
<dd>

View File

@ -1162,6 +1162,11 @@
<value>handle</value>
</choice>
</attribute>
<optional>
<attribute name="wrpolicy">
<value>immediate</value>
</attribute>
</optional>
<empty/>
</element>
</optional>

View File

@ -266,6 +266,9 @@ VIR_ENUM_IMPL(virDomainFSAccessMode, VIR_DOMAIN_FS_ACCESSMODE_LAST,
"mapped",
"squash")
VIR_ENUM_IMPL(virDomainFSWrpolicy, VIR_DOMAIN_FS_WRPOLICY_LAST,
"default",
"immediate")
VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST,
"user",
@ -3460,6 +3463,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
char *source = NULL;
char *target = NULL;
char *accessmode = NULL;
char *wrpolicy = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@ -3509,6 +3513,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
def->readonly = 1;
} else if ((fsdriver == NULL) && (xmlStrEqual(cur->name, BAD_CAST "driver"))) {
fsdriver = virXMLPropString(cur, "type");
wrpolicy = virXMLPropString(cur, "wrpolicy");
}
}
cur = cur->next;
@ -3522,6 +3527,16 @@ virDomainFSDefParseXML(xmlNodePtr node,
}
}
if (wrpolicy) {
if ((def->wrpolicy = virDomainFSWrpolicyTypeFromString(wrpolicy)) <= 0) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown filesystem write policy '%s'"), wrpolicy);
goto error;
}
} else {
def->wrpolicy = VIR_DOMAIN_FS_WRPOLICY_DEFAULT;
}
if (source == NULL) {
virDomainReportError(VIR_ERR_NO_SOURCE,
target ? "%s" : NULL, target);
@ -3548,6 +3563,7 @@ cleanup:
VIR_FREE(target);
VIR_FREE(source);
VIR_FREE(accessmode);
VIR_FREE(wrpolicy);
return def;
@ -10166,6 +10182,7 @@ virDomainFSDefFormat(virBufferPtr buf,
const char *type = virDomainFSTypeToString(def->type);
const char *accessmode = virDomainFSAccessModeTypeToString(def->accessmode);
const char *fsdriver = virDomainFSDriverTypeTypeToString(def->fsdriver);
const char *wrpolicy = virDomainFSWrpolicyTypeToString(def->wrpolicy);
if (!type) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@ -10185,7 +10202,14 @@ virDomainFSDefFormat(virBufferPtr buf,
type, accessmode);
if (def->fsdriver) {
virBufferAsprintf(buf, " <driver type='%s'/>\n", fsdriver);
virBufferAsprintf(buf, " <driver type='%s'", fsdriver);
/* Don't generate anything if wrpolicy is set to default */
if (def->wrpolicy) {
virBufferAsprintf(buf, " wrpolicy='%s'", wrpolicy);
}
virBufferAddLit(buf, "/>\n");
}
if (def->src) {

View File

@ -491,12 +491,21 @@ enum virDomainFSAccessMode {
VIR_DOMAIN_FS_ACCESSMODE_LAST
};
/* Filesystem Write policy */
enum virDomainFSWrpolicy {
VIR_DOMAIN_FS_WRPOLICY_DEFAULT = 0,
VIR_DOMAIN_FS_WRPOLICY_IMMEDIATE,
VIR_DOMAIN_FS_WRPOLICY_LAST
};
typedef struct _virDomainFSDef virDomainFSDef;
typedef virDomainFSDef *virDomainFSDefPtr;
struct _virDomainFSDef {
int type;
int fsdriver;
int accessmode;
int wrpolicy; /* enum virDomainFSWrpolicy */
char *src;
char *dst;
unsigned int readonly : 1;
@ -1985,6 +1994,7 @@ VIR_ENUM_DECL(virDomainControllerModelUSB)
VIR_ENUM_DECL(virDomainFS)
VIR_ENUM_DECL(virDomainFSDriverType)
VIR_ENUM_DECL(virDomainFSAccessMode)
VIR_ENUM_DECL(virDomainFSWrpolicy)
VIR_ENUM_DECL(virDomainNet)
VIR_ENUM_DECL(virDomainNetBackend)
VIR_ENUM_DECL(virDomainNetVirtioTxMode)

View File

@ -316,6 +316,8 @@ virDomainDiskTypeToString;
virDomainFSDefFree;
virDomainFSTypeFromString;
virDomainFSTypeToString;
virDomainFSWrpolicyTypeFromString;
virDomainFSWrpolicyTypeToString;
virDomainFindByID;
virDomainFindByName;
virDomainFindByUUID;

View File

@ -1,7 +1,7 @@
/*
* qemu_capabilities.c: QEMU capabilities generation
*
* Copyright (C) 2006-2011 Red Hat, Inc.
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@ -149,6 +149,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"blk-sg-io",
"drive-copy-on-read",
"cpu-host",
"fsdev-writeout",
);
struct qemu_feature_flags {
@ -1090,6 +1091,8 @@ qemuCapsComputeCmdFlags(const char *help,
qemuCapsSet(flags, QEMU_CAPS_FSDEV);
if (strstr(fsdev, "readonly"))
qemuCapsSet(flags, QEMU_CAPS_FSDEV_READONLY);
if (strstr(fsdev, "writeout"))
qemuCapsSet(flags, QEMU_CAPS_FSDEV_WRITEOUT);
}
if (strstr(help, "-smbios type"))
qemuCapsSet(flags, QEMU_CAPS_SMBIOS_TYPE);

View File

@ -1,7 +1,7 @@
/*
* qemu_capabilities.h: QEMU capabilities generation
*
* Copyright (C) 2006-2011 Red Hat, Inc.
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@ -122,6 +122,7 @@ enum qemuCapsFlags {
QEMU_CAPS_VIRTIO_BLK_SG_IO = 81, /* support for SG_IO commands, reportedly added in 0.11 */
QEMU_CAPS_DRIVE_COPY_ON_READ = 82, /* -drive copy-on-read */
QEMU_CAPS_CPU_HOST = 83, /* support for -cpu host */
QEMU_CAPS_FSDEV_WRITEOUT = 84, /* -fsdev writeout supported */
QEMU_CAPS_LAST, /* this must always be the last item */
};

View File

@ -2138,6 +2138,7 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs,
{
virBuffer opt = VIR_BUFFER_INITIALIZER;
const char *driver = qemuDomainFSDriverTypeToString(fs->fsdriver);
const char *wrpolicy = virDomainFSWrpolicyTypeToString(fs->wrpolicy);
if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@ -2170,6 +2171,17 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs,
goto error;
}
}
if (fs->wrpolicy) {
if (qemuCapsGet(qemuCaps, QEMU_CAPS_FSDEV_WRITEOUT)) {
virBufferAsprintf(&opt, ",writeout=%s", wrpolicy);
} else {
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("filesystem writeout not supported"));
goto error;
}
}
virBufferAsprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
virBufferAsprintf(&opt, ",path=%s", fs->src);

View File

@ -666,7 +666,8 @@ mymain(void)
QEMU_CAPS_FSDEV_READONLY,
QEMU_CAPS_VIRTIO_BLK_SCSI,
QEMU_CAPS_VIRTIO_BLK_SG_IO,
QEMU_CAPS_CPU_HOST);
QEMU_CAPS_CPU_HOST,
QEMU_CAPS_FSDEV_WRITEOUT);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

View File

@ -4,10 +4,10 @@ unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \
/dev/HostVG/QEMUGuest1 -fsdev local,security_model=passthrough,id=fsdev-fs0,\
path=/export/to/guest -device virtio-9p-pci,id=fs0,fsdev=fsdev-fs0,\
mount_tag=/import/from/host,bus=pci.0,addr=0x3 \
-fsdev local,security_model=mapped,id=fsdev-fs1,\
-fsdev local,security_model=mapped,writeout=immediate,id=fsdev-fs1,\
path=/export/to/guest2 -device virtio-9p-pci,id=fs1,fsdev=fsdev-fs1,\
mount_tag=/import/from/host2,bus=pci.0,addr=0x4 \
-fsdev handle,id=fsdev-fs2,\
-fsdev handle,writeout=immediate,id=fsdev-fs2,\
path=/export/to/guest3 -device virtio-9p-pci,id=fs2,fsdev=fsdev-fs2,\
mount_tag=/import/from/host3,bus=pci.0,addr=0x5 \
-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6

View File

@ -25,12 +25,12 @@
<target dir='/import/from/host'/>
</filesystem>
<filesystem accessmode='mapped'>
<driver type='path'/>
<driver type='path' wrpolicy='immediate'/>
<source dir='/export/to/guest2'/>
<target dir='/import/from/host2'/>
</filesystem>
<filesystem>
<driver type='handle'/>
<driver type='handle' wrpolicy='immediate'/>
<source dir='/export/to/guest3'/>
<target dir='/import/from/host3'/>
</filesystem>

View File

@ -651,7 +651,8 @@ mymain(void)
DO_TEST("sound-device", false,
QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_HDA_DUPLEX);
DO_TEST("fs9p", false,
QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_FSDEV);
QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_FSDEV,
QEMU_CAPS_FSDEV_WRITEOUT);
DO_TEST("hostdev-usb-address", false, NONE);
DO_TEST("hostdev-usb-address-device", false,