mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-30 09:53:10 +00:00
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:
parent
9619d8a62e
commit
d9e0d8204b
@ -1396,7 +1396,7 @@
|
|||||||
<target dir='/'/>
|
<target dir='/'/>
|
||||||
</filesystem>
|
</filesystem>
|
||||||
<filesystem type='mount' accessmode='passthrough'>
|
<filesystem type='mount' accessmode='passthrough'>
|
||||||
<driver type='path'/>
|
<driver type='path' wrpolicy='immediate'/>
|
||||||
<source dir='/export/to/guest'/>
|
<source dir='/export/to/guest'/>
|
||||||
<target dir='/import/from/host'/>
|
<target dir='/import/from/host'/>
|
||||||
<readonly/>
|
<readonly/>
|
||||||
@ -1423,7 +1423,12 @@
|
|||||||
sub-element <code>driver</code>, with an
|
sub-element <code>driver</code>, with an
|
||||||
attribute <code>type='path'</code>
|
attribute <code>type='path'</code>
|
||||||
or <code>type='handle'</code> <span class="since">(since
|
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>
|
</dd>
|
||||||
<dt><code>type='template'</code></dt>
|
<dt><code>type='template'</code></dt>
|
||||||
<dd>
|
<dd>
|
||||||
|
@ -1162,6 +1162,11 @@
|
|||||||
<value>handle</value>
|
<value>handle</value>
|
||||||
</choice>
|
</choice>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
<optional>
|
||||||
|
<attribute name="wrpolicy">
|
||||||
|
<value>immediate</value>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
<empty/>
|
<empty/>
|
||||||
</element>
|
</element>
|
||||||
</optional>
|
</optional>
|
||||||
|
@ -266,6 +266,9 @@ VIR_ENUM_IMPL(virDomainFSAccessMode, VIR_DOMAIN_FS_ACCESSMODE_LAST,
|
|||||||
"mapped",
|
"mapped",
|
||||||
"squash")
|
"squash")
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(virDomainFSWrpolicy, VIR_DOMAIN_FS_WRPOLICY_LAST,
|
||||||
|
"default",
|
||||||
|
"immediate")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST,
|
VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST,
|
||||||
"user",
|
"user",
|
||||||
@ -3460,6 +3463,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
|
|||||||
char *source = NULL;
|
char *source = NULL;
|
||||||
char *target = NULL;
|
char *target = NULL;
|
||||||
char *accessmode = NULL;
|
char *accessmode = NULL;
|
||||||
|
char *wrpolicy = NULL;
|
||||||
|
|
||||||
if (VIR_ALLOC(def) < 0) {
|
if (VIR_ALLOC(def) < 0) {
|
||||||
virReportOOMError();
|
virReportOOMError();
|
||||||
@ -3509,6 +3513,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
|
|||||||
def->readonly = 1;
|
def->readonly = 1;
|
||||||
} else if ((fsdriver == NULL) && (xmlStrEqual(cur->name, BAD_CAST "driver"))) {
|
} else if ((fsdriver == NULL) && (xmlStrEqual(cur->name, BAD_CAST "driver"))) {
|
||||||
fsdriver = virXMLPropString(cur, "type");
|
fsdriver = virXMLPropString(cur, "type");
|
||||||
|
wrpolicy = virXMLPropString(cur, "wrpolicy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
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) {
|
if (source == NULL) {
|
||||||
virDomainReportError(VIR_ERR_NO_SOURCE,
|
virDomainReportError(VIR_ERR_NO_SOURCE,
|
||||||
target ? "%s" : NULL, target);
|
target ? "%s" : NULL, target);
|
||||||
@ -3548,6 +3563,7 @@ cleanup:
|
|||||||
VIR_FREE(target);
|
VIR_FREE(target);
|
||||||
VIR_FREE(source);
|
VIR_FREE(source);
|
||||||
VIR_FREE(accessmode);
|
VIR_FREE(accessmode);
|
||||||
|
VIR_FREE(wrpolicy);
|
||||||
|
|
||||||
return def;
|
return def;
|
||||||
|
|
||||||
@ -10166,6 +10182,7 @@ virDomainFSDefFormat(virBufferPtr buf,
|
|||||||
const char *type = virDomainFSTypeToString(def->type);
|
const char *type = virDomainFSTypeToString(def->type);
|
||||||
const char *accessmode = virDomainFSAccessModeTypeToString(def->accessmode);
|
const char *accessmode = virDomainFSAccessModeTypeToString(def->accessmode);
|
||||||
const char *fsdriver = virDomainFSDriverTypeTypeToString(def->fsdriver);
|
const char *fsdriver = virDomainFSDriverTypeTypeToString(def->fsdriver);
|
||||||
|
const char *wrpolicy = virDomainFSWrpolicyTypeToString(def->wrpolicy);
|
||||||
|
|
||||||
if (!type) {
|
if (!type) {
|
||||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
@ -10185,7 +10202,14 @@ virDomainFSDefFormat(virBufferPtr buf,
|
|||||||
type, accessmode);
|
type, accessmode);
|
||||||
|
|
||||||
if (def->fsdriver) {
|
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) {
|
if (def->src) {
|
||||||
|
@ -491,12 +491,21 @@ enum virDomainFSAccessMode {
|
|||||||
VIR_DOMAIN_FS_ACCESSMODE_LAST
|
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 struct _virDomainFSDef virDomainFSDef;
|
||||||
typedef virDomainFSDef *virDomainFSDefPtr;
|
typedef virDomainFSDef *virDomainFSDefPtr;
|
||||||
struct _virDomainFSDef {
|
struct _virDomainFSDef {
|
||||||
int type;
|
int type;
|
||||||
int fsdriver;
|
int fsdriver;
|
||||||
int accessmode;
|
int accessmode;
|
||||||
|
int wrpolicy; /* enum virDomainFSWrpolicy */
|
||||||
char *src;
|
char *src;
|
||||||
char *dst;
|
char *dst;
|
||||||
unsigned int readonly : 1;
|
unsigned int readonly : 1;
|
||||||
@ -1985,6 +1994,7 @@ VIR_ENUM_DECL(virDomainControllerModelUSB)
|
|||||||
VIR_ENUM_DECL(virDomainFS)
|
VIR_ENUM_DECL(virDomainFS)
|
||||||
VIR_ENUM_DECL(virDomainFSDriverType)
|
VIR_ENUM_DECL(virDomainFSDriverType)
|
||||||
VIR_ENUM_DECL(virDomainFSAccessMode)
|
VIR_ENUM_DECL(virDomainFSAccessMode)
|
||||||
|
VIR_ENUM_DECL(virDomainFSWrpolicy)
|
||||||
VIR_ENUM_DECL(virDomainNet)
|
VIR_ENUM_DECL(virDomainNet)
|
||||||
VIR_ENUM_DECL(virDomainNetBackend)
|
VIR_ENUM_DECL(virDomainNetBackend)
|
||||||
VIR_ENUM_DECL(virDomainNetVirtioTxMode)
|
VIR_ENUM_DECL(virDomainNetVirtioTxMode)
|
||||||
|
@ -316,6 +316,8 @@ virDomainDiskTypeToString;
|
|||||||
virDomainFSDefFree;
|
virDomainFSDefFree;
|
||||||
virDomainFSTypeFromString;
|
virDomainFSTypeFromString;
|
||||||
virDomainFSTypeToString;
|
virDomainFSTypeToString;
|
||||||
|
virDomainFSWrpolicyTypeFromString;
|
||||||
|
virDomainFSWrpolicyTypeToString;
|
||||||
virDomainFindByID;
|
virDomainFindByID;
|
||||||
virDomainFindByName;
|
virDomainFindByName;
|
||||||
virDomainFindByUUID;
|
virDomainFindByUUID;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* qemu_capabilities.c: QEMU capabilities generation
|
* 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
|
* Copyright (C) 2006 Daniel P. Berrange
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* 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",
|
"blk-sg-io",
|
||||||
"drive-copy-on-read",
|
"drive-copy-on-read",
|
||||||
"cpu-host",
|
"cpu-host",
|
||||||
|
"fsdev-writeout",
|
||||||
);
|
);
|
||||||
|
|
||||||
struct qemu_feature_flags {
|
struct qemu_feature_flags {
|
||||||
@ -1090,6 +1091,8 @@ qemuCapsComputeCmdFlags(const char *help,
|
|||||||
qemuCapsSet(flags, QEMU_CAPS_FSDEV);
|
qemuCapsSet(flags, QEMU_CAPS_FSDEV);
|
||||||
if (strstr(fsdev, "readonly"))
|
if (strstr(fsdev, "readonly"))
|
||||||
qemuCapsSet(flags, QEMU_CAPS_FSDEV_READONLY);
|
qemuCapsSet(flags, QEMU_CAPS_FSDEV_READONLY);
|
||||||
|
if (strstr(fsdev, "writeout"))
|
||||||
|
qemuCapsSet(flags, QEMU_CAPS_FSDEV_WRITEOUT);
|
||||||
}
|
}
|
||||||
if (strstr(help, "-smbios type"))
|
if (strstr(help, "-smbios type"))
|
||||||
qemuCapsSet(flags, QEMU_CAPS_SMBIOS_TYPE);
|
qemuCapsSet(flags, QEMU_CAPS_SMBIOS_TYPE);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* qemu_capabilities.h: QEMU capabilities generation
|
* 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
|
* Copyright (C) 2006 Daniel P. Berrange
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* 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_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_DRIVE_COPY_ON_READ = 82, /* -drive copy-on-read */
|
||||||
QEMU_CAPS_CPU_HOST = 83, /* support for -cpu host */
|
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 */
|
QEMU_CAPS_LAST, /* this must always be the last item */
|
||||||
};
|
};
|
||||||
|
@ -2138,6 +2138,7 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs,
|
|||||||
{
|
{
|
||||||
virBuffer opt = VIR_BUFFER_INITIALIZER;
|
virBuffer opt = VIR_BUFFER_INITIALIZER;
|
||||||
const char *driver = qemuDomainFSDriverTypeToString(fs->fsdriver);
|
const char *driver = qemuDomainFSDriverTypeToString(fs->fsdriver);
|
||||||
|
const char *wrpolicy = virDomainFSWrpolicyTypeToString(fs->wrpolicy);
|
||||||
|
|
||||||
if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
|
if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) {
|
||||||
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
@ -2170,6 +2171,17 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs,
|
|||||||
goto error;
|
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, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias);
|
||||||
virBufferAsprintf(&opt, ",path=%s", fs->src);
|
virBufferAsprintf(&opt, ",path=%s", fs->src);
|
||||||
|
|
||||||
|
@ -666,7 +666,8 @@ mymain(void)
|
|||||||
QEMU_CAPS_FSDEV_READONLY,
|
QEMU_CAPS_FSDEV_READONLY,
|
||||||
QEMU_CAPS_VIRTIO_BLK_SCSI,
|
QEMU_CAPS_VIRTIO_BLK_SCSI,
|
||||||
QEMU_CAPS_VIRTIO_BLK_SG_IO,
|
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;
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -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,\
|
/dev/HostVG/QEMUGuest1 -fsdev local,security_model=passthrough,id=fsdev-fs0,\
|
||||||
path=/export/to/guest -device virtio-9p-pci,id=fs0,fsdev=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 \
|
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,\
|
path=/export/to/guest2 -device virtio-9p-pci,id=fs1,fsdev=fsdev-fs1,\
|
||||||
mount_tag=/import/from/host2,bus=pci.0,addr=0x4 \
|
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,\
|
path=/export/to/guest3 -device virtio-9p-pci,id=fs2,fsdev=fsdev-fs2,\
|
||||||
mount_tag=/import/from/host3,bus=pci.0,addr=0x5 \
|
mount_tag=/import/from/host3,bus=pci.0,addr=0x5 \
|
||||||
-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6
|
-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6
|
||||||
|
@ -25,12 +25,12 @@
|
|||||||
<target dir='/import/from/host'/>
|
<target dir='/import/from/host'/>
|
||||||
</filesystem>
|
</filesystem>
|
||||||
<filesystem accessmode='mapped'>
|
<filesystem accessmode='mapped'>
|
||||||
<driver type='path'/>
|
<driver type='path' wrpolicy='immediate'/>
|
||||||
<source dir='/export/to/guest2'/>
|
<source dir='/export/to/guest2'/>
|
||||||
<target dir='/import/from/host2'/>
|
<target dir='/import/from/host2'/>
|
||||||
</filesystem>
|
</filesystem>
|
||||||
<filesystem>
|
<filesystem>
|
||||||
<driver type='handle'/>
|
<driver type='handle' wrpolicy='immediate'/>
|
||||||
<source dir='/export/to/guest3'/>
|
<source dir='/export/to/guest3'/>
|
||||||
<target dir='/import/from/host3'/>
|
<target dir='/import/from/host3'/>
|
||||||
</filesystem>
|
</filesystem>
|
||||||
|
@ -651,7 +651,8 @@ mymain(void)
|
|||||||
DO_TEST("sound-device", false,
|
DO_TEST("sound-device", false,
|
||||||
QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_HDA_DUPLEX);
|
QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_HDA_DUPLEX);
|
||||||
DO_TEST("fs9p", false,
|
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", false, NONE);
|
||||||
DO_TEST("hostdev-usb-address-device", false,
|
DO_TEST("hostdev-usb-address-device", false,
|
||||||
|
Loading…
Reference in New Issue
Block a user