<target dir='/'/>
</filesystem>
<filesystem type='mount' accessmode='passthrough'>
- <driver type='path'/>
+ <driver type='path' wrpolicy='immediate'/>
<source dir='/export/to/guest'/>
<target dir='/import/from/host'/>
<readonly/>
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>
<value>handle</value>
</choice>
</attribute>
+ <optional>
+ <attribute name="wrpolicy">
+ <value>immediate</value>
+ </attribute>
+ </optional>
<empty/>
</element>
</optional>
"mapped",
"squash")
+VIR_ENUM_IMPL(virDomainFSWrpolicy, VIR_DOMAIN_FS_WRPOLICY_LAST,
+ "default",
+ "immediate")
VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST,
"user",
char *source = NULL;
char *target = NULL;
char *accessmode = NULL;
+ char *wrpolicy = NULL;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
def->readonly = 1;
} else if ((fsdriver == NULL) && (xmlStrEqual(cur->name, BAD_CAST "driver"))) {
fsdriver = virXMLPropString(cur, "type");
+ wrpolicy = virXMLPropString(cur, "wrpolicy");
}
}
cur = cur->next;
}
}
+ 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);
VIR_FREE(target);
VIR_FREE(source);
VIR_FREE(accessmode);
+ VIR_FREE(wrpolicy);
return def;
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,
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) {
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;
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)
virDomainFSDefFree;
virDomainFSTypeFromString;
virDomainFSTypeToString;
+virDomainFSWrpolicyTypeFromString;
+virDomainFSWrpolicyTypeToString;
virDomainFindByID;
virDomainFindByName;
virDomainFindByUUID;
/*
* 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
"blk-sg-io",
"drive-copy-on-read",
"cpu-host",
+ "fsdev-writeout",
);
struct qemu_feature_flags {
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);
/*
* 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
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 */
};
{
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",
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);
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;
}
/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
<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>
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,