[libvirt] [PATCH 4/8] Support block I/O throtte in XML
Adam Litke
agl at us.ibm.com
Thu Nov 10 20:19:22 UTC 2011
This looks good to me.
On Thu, Nov 10, 2011 at 04:32:54AM +0800, Lei HH Li wrote:
> Enable block I/O throttle for per-disk in XML.
>
> Signed-off-by: Zhi Yong Wu <wuzhy at linux.vnet.ibm.com>
> Signed-off-by: Lei Li <lilei at linux.vnet.ibm.com>
> ---
> src/conf/domain_conf.c | 101 +++++++++++++++++++++++++++++++++++++++++++++-
> src/conf/domain_conf.h | 12 ++++++
> src/qemu/qemu_command.c | 33 +++++++++++++++
> src/util/xml.h | 2 +
> 4 files changed, 145 insertions(+), 3 deletions(-)
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 58f4d0f..564914e 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -2318,7 +2318,8 @@ static virDomainDiskDefPtr
> virDomainDiskDefParseXML(virCapsPtr caps,
> xmlNodePtr node,
> virBitmapPtr bootMap,
> - unsigned int flags)
> + unsigned int flags,
> + xmlXPathContextPtr ctxt)
> {
> virDomainDiskDefPtr def;
> xmlNodePtr cur, child;
> @@ -2517,6 +2518,62 @@ virDomainDiskDefParseXML(virCapsPtr caps,
> }
> child = child->next;
> }
> + } else if (xmlStrEqual(cur->name, BAD_CAST "iotune")) {
> + if (virXPathULongLong("string(./devices/disk/iotune/total_bytes_sec)",
> + ctxt, &def->blkdeviotune.total_bytes_sec) < 0) {
> + def->blkdeviotune.total_bytes_sec = 0;
> + } else {
> + def->blkdeviotune.mark = 1;
> + }
> +
> + if (virXPathULongLong("string(./devices/disk/iotune/read_bytes_sec)",
> + ctxt, &def->blkdeviotune.read_bytes_sec) < 0) {
> + def->blkdeviotune.read_bytes_sec = 0;
> + } else {
> + def->blkdeviotune.mark = 1;
> + }
> +
> + if (virXPathULongLong("string(./devices/disk/iotune/write_bytes_sec)",
> + ctxt, &def->blkdeviotune.write_bytes_sec) < 0) {
> + def->blkdeviotune.write_bytes_sec = 0;
> + } else {
> + def->blkdeviotune.mark = 1;
> + }
> +
> + if (virXPathULongLong("string(./devices/disk/iotune/total_iops_sec)",
> + ctxt, &def->blkdeviotune.total_iops_sec) < 0) {
> + def->blkdeviotune.total_iops_sec = 0;
> + } else {
> + def->blkdeviotune.mark = 1;
> + }
> +
> + if (virXPathULongLong("string(./devices/disk/iotune/read_iops_sec)",
> + ctxt, &def->blkdeviotune.read_iops_sec) < 0) {
> + def->blkdeviotune.read_iops_sec = 0;
> + } else {
> + def->blkdeviotune.mark = 1;
> + }
> +
> + if (virXPathULongLong("string(./devices/disk/iotune/write_iops_sec)",
> + ctxt, &def->blkdeviotune.write_iops_sec) < 0) {
> + def->blkdeviotune.write_iops_sec = 0;
> + } else {
> + def->blkdeviotune.mark = 1;
> + }
> +
> + if ((def->blkdeviotune.total_bytes_sec && def->blkdeviotune.read_bytes_sec)
> + || (def->blkdeviotune.total_bytes_sec && def->blkdeviotune.write_bytes_sec)) {
> + virDomainReportError(VIR_ERR_XML_ERROR,
> + _("bps and bps_rd/bps_wr cannot be set at the same time"));
> + goto error;
> + }
> +
> + if ((def->blkdeviotune.total_iops_sec && def->blkdeviotune.read_iops_sec)
> + || (def->blkdeviotune.total_iops_sec && def->blkdeviotune.write_iops_sec)) {
> + virDomainReportError(VIR_ERR_XML_ERROR,
> + _("iops and iops_rd/iops_wr cannot be set at the same time"));
> + goto error;
> + }
> } else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
> def->readonly = 1;
> } else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
> @@ -6003,7 +6060,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
> if (xmlStrEqual(node->name, BAD_CAST "disk")) {
> dev->type = VIR_DOMAIN_DEVICE_DISK;
> if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node,
> - NULL, flags)))
> + NULL, flags, NULL)))
> goto error;
> } else if (xmlStrEqual(node->name, BAD_CAST "lease")) {
> dev->type = VIR_DOMAIN_DEVICE_LEASE;
> @@ -7076,7 +7133,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
> virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps,
> nodes[i],
> bootMap,
> - flags);
> + flags,
> + ctxt);
> if (!disk)
> goto error;
>
> @@ -9511,6 +9569,43 @@ virDomainDiskDefFormat(virBufferPtr buf,
> virBufferAsprintf(buf, " <target dev='%s' bus='%s'/>\n",
> def->dst, bus);
>
> + /*disk I/O throttling*/
> + if (def->blkdeviotune.mark) {
> + virBufferAddLit(buf, " <iotune>\n");
> + if (def->blkdeviotune.total_bytes_sec) {
> + virBufferAsprintf(buf, " <total_bytes_sec>%llu</total_bytes_sec>\n",
> + def->blkdeviotune.total_bytes_sec);
> + }
> +
> + if (def->blkdeviotune.read_bytes_sec) {
> + virBufferAsprintf(buf, " <read_bytes_sec>%llu</read_bytes_sec>\n",
> + def->blkdeviotune.read_bytes_sec);
> +
> + }
> +
> + if (def->blkdeviotune.write_bytes_sec) {
> + virBufferAsprintf(buf, " <write_bytes_sec>%llu</write_bytes_sec>\n",
> + def->blkdeviotune.write_bytes_sec);
> + }
> +
> + if (def->blkdeviotune.total_iops_sec) {
> + virBufferAsprintf(buf, " <total_iops_sec>%llu</total_iops_sec>\n",
> + def->blkdeviotune.total_iops_sec);
> + }
> +
> + if (def->blkdeviotune.read_iops_sec) {
> + virBufferAsprintf(buf, " <read_iops_sec>%llu</read_iops_sec>",
> + def->blkdeviotune.read_iops_sec);
> + }
> +
> + if (def->blkdeviotune.write_iops_sec) {
> + virBufferAsprintf(buf, " <write_iops_sec>%llu</write_iops_sec>",
> + def->blkdeviotune.write_iops_sec);
> + }
> +
> + virBufferAddLit(buf, " </iotune>\n");
> + }
> +
> if (def->bootIndex)
> virBufferAsprintf(buf, " <boot order='%d'/>\n", def->bootIndex);
> if (def->readonly)
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index a3cb834..d95e239 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -333,6 +333,18 @@ struct _virDomainDiskDef {
> } auth;
> char *driverName;
> char *driverType;
> +
> + /*disk I/O throttling*/
> + struct {
> + unsigned long long total_bytes_sec;
> + unsigned long long read_bytes_sec;
> + unsigned long long write_bytes_sec;
> + unsigned long long total_iops_sec;
> + unsigned long long read_iops_sec;
> + unsigned long long write_iops_sec;
> + unsigned int mark;
> + } blkdeviotune;
> +
> char *serial;
> int cachemode;
> int error_policy; /* enum virDomainDiskErrorPolicy */
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 11ebb69..3a8575b 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -1715,6 +1715,39 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
> }
> }
>
> + /*block I/O throttling*/
> + if (disk->blkdeviotune.mark) {
> + if (disk->blkdeviotune.total_bytes_sec) {
> + virBufferAsprintf(&opt, ",bps=%llu",
> + disk->blkdeviotune.total_bytes_sec);
> + }
> +
> + if (disk->blkdeviotune.read_bytes_sec) {
> + virBufferAsprintf(&opt, ",bps_rd=%llu",
> + disk->blkdeviotune.read_bytes_sec);
> + }
> +
> + if (disk->blkdeviotune.write_bytes_sec) {
> + virBufferAsprintf(&opt, ",bps_wr=%llu",
> + disk->blkdeviotune.write_bytes_sec);
> + }
> +
> + if (disk->blkdeviotune.total_iops_sec) {
> + virBufferAsprintf(&opt, ",iops=%llu",
> + disk->blkdeviotune.total_iops_sec);
> + }
> +
> + if (disk->blkdeviotune.read_iops_sec) {
> + virBufferAsprintf(&opt, ",iops_rd=%llu",
> + disk->blkdeviotune.read_iops_sec);
> + }
> +
> + if (disk->blkdeviotune.write_iops_sec) {
> + virBufferAsprintf(&opt, ",iops_wr=%llu",
> + disk->blkdeviotune.write_iops_sec);
> + }
> + }
> +
> if (virBufferError(&opt)) {
> virReportOOMError();
> goto error;
> diff --git a/src/util/xml.h b/src/util/xml.h
> index c492063..5742f19 100644
> --- a/src/util/xml.h
> +++ b/src/util/xml.h
> @@ -50,6 +50,8 @@ xmlNodePtr virXPathNode(const char *xpath,
> int virXPathNodeSet(const char *xpath,
> xmlXPathContextPtr ctxt,
> xmlNodePtr **list);
> +int virXMLStringToULongLong (const char *stringval,
> + unsigned long long *value);
> char * virXMLPropString(xmlNodePtr node,
> const char *name);
>
> --
> 1.7.1
>
--
Adam Litke <agl at us.ibm.com>
IBM Linux Technology Center
More information about the libvir-list
mailing list