From d9e0d8204b239f95449c8ab9f43b75b92ca39556 Mon Sep 17 00:00:00 2001 From: Deepak C Shetty Date: Tue, 17 Jan 2012 18:14:18 +0530 Subject: [PATCH] Add new attribute wrpolicy to 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: Currently this only works with type='mount' for the QEMU/KVM driver. Signed-off-by: Deepak C Shetty --- docs/formatdomain.html.in | 9 +++++-- docs/schemas/domaincommon.rng | 5 ++++ src/conf/domain_conf.c | 26 ++++++++++++++++++- src/conf/domain_conf.h | 10 +++++++ src/libvirt_private.syms | 2 ++ src/qemu/qemu_capabilities.c | 5 +++- src/qemu/qemu_capabilities.h | 3 ++- src/qemu/qemu_command.c | 12 +++++++++ tests/qemuhelptest.c | 3 ++- tests/qemuxml2argvdata/qemuxml2argv-fs9p.args | 4 +-- tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml | 4 +-- tests/qemuxml2argvtest.c | 3 ++- 12 files changed, 75 insertions(+), 11 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 6bb5721a74..de9b480ac2 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1396,7 +1396,7 @@ <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/> @@ -1423,7 +1423,12 @@ sub-element driver, with an attribute type='path' or type='handle' (since - 0.9.7). + 0.9.7). The driver block has an optional attribute + wrpolicy that further controls interaction with + the host page cache; omitting the attribute gives default behavior, + while the value immediate means that a host writeback + is immediately triggered for all pages touched during a guest file + write operation (since 0.9.10).
type='template'
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 27b9a1f046..2041dfbbc2 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1162,6 +1162,11 @@ handle + + + immediate + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 96a4669fc3..f97014eef4 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -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, " \n", fsdriver); + virBufferAsprintf(buf, " wrpolicy) { + virBufferAsprintf(buf, " wrpolicy='%s'", wrpolicy); + } + + virBufferAddLit(buf, "/>\n"); } if (def->src) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index f3c45be07c..b121f9c17e 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -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) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index faab0e252a..df8e4b0eec 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -316,6 +316,8 @@ virDomainDiskTypeToString; virDomainFSDefFree; virDomainFSTypeFromString; virDomainFSTypeToString; +virDomainFSWrpolicyTypeFromString; +virDomainFSWrpolicyTypeToString; virDomainFindByID; virDomainFindByName; virDomainFindByUUID; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index e9ae44d325..0a1c9aa384 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -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); diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index d69f854a2d..1d4d10e59d 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -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 */ }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index eccbe01638..3bbe9cf639 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -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); diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c index 164707df56..8802271d39 100644 --- a/tests/qemuhelptest.c +++ b/tests/qemuhelptest.c @@ -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; } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fs9p.args b/tests/qemuxml2argvdata/qemuxml2argv-fs9p.args index 857981052f..f244114f04 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-fs9p.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-fs9p.args @@ -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 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml b/tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml index 07d7e8abe3..e31db4879c 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-fs9p.xml @@ -25,12 +25,12 @@ - + - + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index d1834f59d3..5cec86bed4 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -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,