This patch introduces new xml elements under <blkiotune>, we use these new elements to setup the throttle blkio cgroup for domain. The new blkiotune node looks like this: <blkiotune> <device> <path>/path/to/block</path> <weight>1000</weight> <read_iops_sec>10000</read_iops_sec> <write_iops_sec>10000</write_iops_sec> <read_bytes_sec>1000000</read_bytes_sec> <write_bytes_sec>1000000</write_bytes_sec> </device> </blkiotune> Signed-off-by: Guan Qiang <hzguanqiang@xxxxxxxxxxxxxxxx> Signed-off-by: Gao feng <gaofeng@xxxxxxxxxxxxxx> --- docs/schemas/domaincommon.rng | 28 ++++++++++++-- src/conf/domain_conf.c | 85 +++++++++++++++++++++++++++++++++++++------ src/conf/domain_conf.h | 4 ++ 3 files changed, 103 insertions(+), 14 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 38c6801..bc8ed5d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -621,9 +621,31 @@ <element name="path"> <ref name="absFilePath"/> </element> - <element name="weight"> - <ref name="weight"/> - </element> + <optional> + <element name="weight"> + <ref name="weight"/> + </element> + </optional> + <optional> + <element name="read_iops_sec"> + <data type='unsignedInt'/> + </element> + </optional> + <optional> + <element name="write_iops_sec"> + <data type='unsignedInt'/> + </element> + </optional> + <optional> + <element name="read_bytes_sec"> + <data type='unsignedLong'/> + </element> + </optional> + <optional> + <element name="write_bytes_sec"> + <data type='unsignedLong'/> + </element> + </optional> </interleave> </element> </zeroOrMore> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 26242b6..c4d51b4 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -899,15 +899,19 @@ virBlkioDeviceArrayClear(virBlkioDevicePtr devices, * <device> * <path>/fully/qualified/device/path</path> * <weight>weight</weight> + * <read_bytes_sec>bps</read_bytes_sec> + * <write_bytes_sec>bps</write_bytes_sec> + * <read_iops_sec>iops</read_iops_sec> + * <write_iops_sec>iops</write_iops_sec> * </device> * - * and fills a virBlkioDeviceTune struct. + * and fills a virBlkioDevicePtr struct. */ static int virDomainBlkioDeviceParseXML(xmlNodePtr root, virBlkioDevicePtr dev) { - char *c; + char *c = NULL; xmlNodePtr node; node = root->children; @@ -921,9 +925,43 @@ virDomainBlkioDeviceParseXML(xmlNodePtr root, virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("could not parse weight %s"), c); - VIR_FREE(c); - VIR_FREE(dev->path); - return -1; + goto error; + } + VIR_FREE(c); + } else if (xmlStrEqual(node->name, BAD_CAST "read_bytes_sec")) { + c = (char *)xmlNodeGetContent(node); + if (virStrToLong_ull(c, NULL, 10, &dev->rbps) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("could not parse read bytes sec %s"), + c); + goto error; + } + VIR_FREE(c); + } else if (xmlStrEqual(node->name, BAD_CAST "write_bytes_sec")) { + c = (char *)xmlNodeGetContent(node); + if (virStrToLong_ull(c, NULL, 10, &dev->wbps) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("could not parse write bytes sec %s"), + c); + goto error; + } + VIR_FREE(c); + } else if (xmlStrEqual(node->name, BAD_CAST "read_iops_sec")) { + c = (char *)xmlNodeGetContent(node); + if (virStrToLong_ui(c, NULL, 10, &dev->riops) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("could not parse read iops sec %s"), + c); + goto error; + } + VIR_FREE(c); + } else if (xmlStrEqual(node->name, BAD_CAST "write_iops_sec")) { + c = (char *)xmlNodeGetContent(node); + if (virStrToLong_ui(c, NULL, 10, &dev->wiops) < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("could not parse write iops sec %s"), + c); + goto error; } VIR_FREE(c); } @@ -937,6 +975,11 @@ virDomainBlkioDeviceParseXML(xmlNodePtr root, } return 0; + +error: + VIR_FREE(c); + VIR_FREE(dev->path); + return -1; } @@ -11105,7 +11148,7 @@ virDomainDefParseXML(xmlDocPtr xml, if (STREQ(def->blkio.devices[j].path, def->blkio.devices[i].path)) { virReportError(VIR_ERR_XML_ERROR, - _("duplicate device weight path '%s'"), + _("duplicate blkio device path '%s'"), def->blkio.devices[i].path); goto error; } @@ -16614,7 +16657,11 @@ virDomainDefFormatInternal(virDomainDefPtr def, blkio = true; } else { for (n = 0; n < def->blkio.ndevices; n++) { - if (def->blkio.devices[n].weight) { + if (def->blkio.devices[n].weight || + def->blkio.devices[n].riops || + def->blkio.devices[n].wiops || + def->blkio.devices[n].rbps || + def->blkio.devices[n].wbps) { blkio = true; break; } @@ -16629,13 +16676,29 @@ virDomainDefFormatInternal(virDomainDefPtr def, def->blkio.weight); for (n = 0; n < def->blkio.ndevices; n++) { - if (def->blkio.devices[n].weight == 0) + virBlkioDevicePtr dev = &def->blkio.devices[n]; + + if (!dev->weight && !dev->riops && !dev->wiops && + !dev->rbps && !dev->wbps) continue; virBufferAddLit(buf, " <device>\n"); virBufferEscapeString(buf, " <path>%s</path>\n", - def->blkio.devices[n].path); - virBufferAsprintf(buf, " <weight>%u</weight>\n", - def->blkio.devices[n].weight); + dev->path); + if (dev->weight) + virBufferAsprintf(buf, " <weight>%u</weight>\n", + dev->weight); + if (dev->riops) + virBufferAsprintf(buf, " <read_iops_sec>%u</read_iops_sec>\n", + dev->riops); + if (dev->wiops) + virBufferAsprintf(buf, " <write_iops_sec>%u</write_iops_sec>\n", + dev->wiops); + if (dev->rbps) + virBufferAsprintf(buf, " <read_bytes_sec>%llu</read_bytes_sec>\n", + dev->rbps); + if (dev->wbps) + virBufferAsprintf(buf, " <write_bytes_sec>%llu</write_bytes_sec>\n", + dev->wbps); virBufferAddLit(buf, " </device>\n"); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index b410fd0..5631ccd 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1865,6 +1865,10 @@ typedef virBlkioDevice *virBlkioDevicePtr; struct _virBlkioDevice { char *path; unsigned int weight; + unsigned int riops; + unsigned int wiops; + unsigned long long rbps; + unsigned long long wbps; }; enum virDomainRNGModel { -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list