From 3b431929a220abd835b7fc8f5e3c66879280499b Mon Sep 17 00:00:00 2001 From: Gao feng Date: Wed, 11 Dec 2013 16:29:50 +0800 Subject: [PATCH] blkio: Setting throttle blkio cgroup for domain This patch introduces virCgroupSetBlkioDeviceReadIops, virCgroupSetBlkioDeviceWriteIops, virCgroupSetBlkioDeviceReadBps and virCgroupSetBlkioDeviceWriteBps, we can use these interfaces to set up throttle blkio cgroup for domain. This patch also adds the new throttle blkio cgroup elements to the test xml. Signed-off-by: Guan Qiang Signed-off-by: Gao feng --- src/libvirt_private.syms | 4 + src/lxc/lxc_cgroup.c | 27 ++- src/qemu/qemu_cgroup.c | 27 ++- src/util/vircgroup.c | 224 +++++++++++++++++- src/util/vircgroup.h | 16 ++ .../qemuxml2argv-blkiotune-device.xml | 8 + 6 files changed, 295 insertions(+), 11 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 91d130495e..3ede3d5ebc 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1035,7 +1035,11 @@ virCgroupNewVcpu; virCgroupPathOfController; virCgroupRemove; virCgroupRemoveRecursively; +virCgroupSetBlkioDeviceReadBps; +virCgroupSetBlkioDeviceReadIops; virCgroupSetBlkioDeviceWeight; +virCgroupSetBlkioDeviceWriteBps; +virCgroupSetBlkioDeviceWriteIops; virCgroupSetBlkioWeight; virCgroupSetCpuCfsPeriod; virCgroupSetCpuCfsQuota; diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index 310a4760e6..cc0d5e8d08 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -113,9 +113,30 @@ static int virLXCCgroupSetupBlkioTune(virDomainDefPtr def, if (def->blkio.ndevices) { for (i = 0; i < def->blkio.ndevices; i++) { virBlkioDevicePtr dev = &def->blkio.devices[i]; - if (!dev->weight) - continue; - if (virCgroupSetBlkioDeviceWeight(cgroup, dev->path, dev->weight) < 0) + + if (dev->weight && + (virCgroupSetBlkioDeviceWeight(cgroup, dev->path, + dev->weight) < 0)) + return -1; + + if (dev->riops && + (virCgroupSetBlkioDeviceReadIops(cgroup, dev->path, + dev->riops) < 0)) + return -1; + + if (dev->wiops && + (virCgroupSetBlkioDeviceWriteIops(cgroup, dev->path, + dev->wiops) < 0)) + return -1; + + if (dev->rbps && + (virCgroupSetBlkioDeviceReadBps(cgroup, dev->path, + dev->rbps) < 0)) + return -1; + + if (dev->wbps && + (virCgroupSetBlkioDeviceWriteBps(cgroup, dev->path, + dev->wbps) < 0)) return -1; } } diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index a18955e779..1cc929c5ec 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -400,10 +400,29 @@ qemuSetupBlkioCgroup(virDomainObjPtr vm) if (vm->def->blkio.ndevices) { for (i = 0; i < vm->def->blkio.ndevices; i++) { virBlkioDevicePtr dev = &vm->def->blkio.devices[i]; - if (!dev->weight) - continue; - if (virCgroupSetBlkioDeviceWeight(priv->cgroup, dev->path, - dev->weight) < 0) + if (dev->weight && + (virCgroupSetBlkioDeviceWeight(priv->cgroup, dev->path, + dev->weight) < 0)) + return -1; + + if (dev->riops && + (virCgroupSetBlkioDeviceReadIops(priv->cgroup, dev->path, + dev->riops) < 0)) + return -1; + + if (dev->wiops && + (virCgroupSetBlkioDeviceWriteIops(priv->cgroup, dev->path, + dev->wiops) < 0)) + return -1; + + if (dev->rbps && + (virCgroupSetBlkioDeviceReadBps(priv->cgroup, dev->path, + dev->rbps) < 0)) + return -1; + + if (dev->wbps && + (virCgroupSetBlkioDeviceWriteBps(priv->cgroup, dev->path, + dev->wbps) < 0)) return -1; } } diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 43eb64920e..a6d60c54b5 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -1824,12 +1824,189 @@ virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight) return ret; } +/** + * virCgroupSetBlkioDeviceReadIops: + * @group: The cgroup to change block io setting for + * @path: The path of device + * @riops: The new device read iops throttle, or 0 to clear + * + * Returns: 0 on success, -1 on error + */ +int +virCgroupSetBlkioDeviceReadIops(virCgroupPtr group, + const char *path, + unsigned int riops) +{ + char *str; + struct stat sb; + int ret; + + if (stat(path, &sb) < 0) { + virReportSystemError(errno, + _("Path '%s' is not accessible"), + path); + return -1; + } + + if (!S_ISBLK(sb.st_mode)) { + virReportSystemError(EINVAL, + _("Path '%s' must be a block device"), + path); + return -1; + } + + if (virAsprintf(&str, "%d:%d %u", major(sb.st_rdev), + minor(sb.st_rdev), riops) < 0) + return -1; + + ret = virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.read_iops_device", + str); + + VIR_FREE(str); + return ret; +} + /** - * virCgroupSetBlkioDeviceWeight: + * virCgroupSetBlkioDeviceWriteIops: + * @group: The cgroup to change block io setting for + * @path: The path of device + * @wiops: The new device write iops throttle, or 0 to clear + * + * Returns: 0 on success, -1 on error + */ +int +virCgroupSetBlkioDeviceWriteIops(virCgroupPtr group, + const char *path, + unsigned int wiops) +{ + char *str; + struct stat sb; + int ret; + + if (stat(path, &sb) < 0) { + virReportSystemError(errno, + _("Path '%s' is not accessible"), + path); + return -1; + } + + if (!S_ISBLK(sb.st_mode)) { + virReportSystemError(EINVAL, + _("Path '%s' must be a block device"), + path); + return -1; + } + + if (virAsprintf(&str, "%d:%d %u", major(sb.st_rdev), + minor(sb.st_rdev), wiops) < 0) + return -1; + + ret = virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.write_iops_device", + str); + + VIR_FREE(str); + return ret; +} + + +/** + * virCgroupSetBlkioDeviceReadBps: + * @group: The cgroup to change block io setting for + * @path: The path of device + * @rbps: The new device read bps throttle, or 0 to clear + * + * Returns: 0 on success, -1 on error + */ +int +virCgroupSetBlkioDeviceReadBps(virCgroupPtr group, + const char *path, + unsigned long long rbps) +{ + char *str; + struct stat sb; + int ret; + + if (stat(path, &sb) < 0) { + virReportSystemError(errno, + _("Path '%s' is not accessible"), + path); + return -1; + } + + if (!S_ISBLK(sb.st_mode)) { + virReportSystemError(EINVAL, + _("Path '%s' must be a block device"), + path); + return -1; + } + + if (virAsprintf(&str, "%d:%d %llu", major(sb.st_rdev), + minor(sb.st_rdev), rbps) < 0) + return -1; + + ret = virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.read_bps_device", + str); + + VIR_FREE(str); + return ret; +} + +/** + * virCgroupSetBlkioDeviceWriteBps: + * @group: The cgroup to change block io setting for + * @path: The path of device + * @wbps: The new device write bps throttle, or 0 to clear * - * @group: The cgroup to change io device weight device for - * @path: The device with a weight to alter + * Returns: 0 on success, -1 on error + */ +int +virCgroupSetBlkioDeviceWriteBps(virCgroupPtr group, + const char *path, + unsigned long long wbps) +{ + char *str; + struct stat sb; + int ret; + + if (stat(path, &sb) < 0) { + virReportSystemError(errno, + _("Path '%s' is not accessible"), + path); + return -1; + } + + if (!S_ISBLK(sb.st_mode)) { + virReportSystemError(EINVAL, + _("Path '%s' must be a block device"), + path); + return -1; + } + + if (virAsprintf(&str, "%d:%d %llu", major(sb.st_rdev), + minor(sb.st_rdev), wbps) < 0) + return -1; + + ret = virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_BLKIO, + "blkio.throttle.write_bps_device", + str); + + VIR_FREE(str); + return ret; +} + + +/** + * virCgroupSetBlkioDeviceWeight: + * @group: The cgroup to change block io setting for + * @path: The path of device * @weight: The new device weight (100-1000), * (10-1000) after kernel 2.6.39, or 0 to clear * @@ -1874,7 +2051,6 @@ virCgroupSetBlkioDeviceWeight(virCgroupPtr group, } - /** * virCgroupSetMemory: * @@ -3312,6 +3488,46 @@ virCgroupSetBlkioDeviceWeight(virCgroupPtr group ATTRIBUTE_UNUSED, return -1; } +int +virCgroupSetBlkioDeviceReadIops(virCgroupPtr group ATTRIBUTE_UNUSED, + const char *path ATTRIBUTE_UNUSED, + unsigned int riops ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Control groups not supported on this platform")); + return -1; +} + +int +virCgroupSetBlkioDeviceWriteIops(virCgroupPtr group ATTRIBUTE_UNUSED, + const char *path ATTRIBUTE_UNUSED, + unsigned int wiops ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Control groups not supported on this platform")); + return -1; +} + +int +virCgroupSetBlkioDeviceReadBps(virCgroupPtr group ATTRIBUTE_UNUSED, + const char *path ATTRIBUTE_UNUSED, + unsigned long long rbps ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Control groups not supported on this platform")); + return -1; +} + +int +virCgroupSetBlkioDeviceWriteBps(virCgroupPtr group ATTRIBUTE_UNUSED, + const char *path ATTRIBUTE_UNUSED, + unsigned long long wbps ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, "%s", + _("Control groups not supported on this platform")); + return -1; +} + int virCgroupSetMemory(virCgroupPtr group ATTRIBUTE_UNUSED, diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h index 835eb30689..a70eb18aad 100644 --- a/src/util/vircgroup.h +++ b/src/util/vircgroup.h @@ -126,6 +126,22 @@ int virCgroupSetBlkioDeviceWeight(virCgroupPtr group, const char *path, unsigned int weight); +int virCgroupSetBlkioDeviceReadIops(virCgroupPtr group, + const char *path, + unsigned int riops); + +int virCgroupSetBlkioDeviceWriteIops(virCgroupPtr group, + const char *path, + unsigned int wiops); + +int virCgroupSetBlkioDeviceReadBps(virCgroupPtr group, + const char *path, + unsigned long long rbps); + +int virCgroupSetBlkioDeviceWriteBps(virCgroupPtr group, + const char *path, + unsigned long long wbps); + int virCgroupSetMemory(virCgroupPtr group, unsigned long long kb); int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml index 743cf2958f..bfb5b03782 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml @@ -8,10 +8,18 @@ /dev/sda 400 + 10000 + 10000 + 10000 + 10000 /dev/sdb 900 + 20000 + 20000 + 20000 + 20000 1 -- 2.39.5