[libvirt] [PATCH 5/8] blkio: Setting throttle blkio cgroup for domain

Gao feng gaofeng at cn.fujitsu.com
Wed Dec 11 08:29:50 UTC 2013


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 <hzguanqiang at corp.netease.com>
Signed-off-by: Gao feng <gaofeng at cn.fujitsu.com>
---
 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 d8f8f7e..a535bf3 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1031,7 +1031,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 310a476..cc0d5e8 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 a18955e..1cc929c 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 43eb649..a6d60c5 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 835eb30..a70eb18 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 743cf29..bfb5b03 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml
@@ -8,10 +8,18 @@
     <device>
       <path>/dev/sda</path>
       <weight>400</weight>
+      <read_iops_sec>10000</read_iops_sec>
+      <write_iops_sec>10000</write_iops_sec>
+      <read_bytes_sec>10000</read_bytes_sec>
+      <write_bytes_sec>10000</write_bytes_sec>
     </device>
     <device>
       <path>/dev/sdb</path>
       <weight>900</weight>
+      <read_iops_sec>20000</read_iops_sec>
+      <write_iops_sec>20000</write_iops_sec>
+      <read_bytes_sec>20000</read_bytes_sec>
+      <write_bytes_sec>20000</write_bytes_sec>
     </device>
   </blkiotune>
   <vcpu placement='static'>1</vcpu>
-- 
1.8.3.1




More information about the libvir-list mailing list