[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