c480ed
From a6c731357b9c74e5cc298f04267312ad3bb635fa Mon Sep 17 00:00:00 2001
c480ed
Message-Id: <a6c731357b9c74e5cc298f04267312ad3bb635fa@dist-git>
c480ed
From: Pavel Hrdina <phrdina@redhat.com>
c480ed
Date: Tue, 2 Jul 2019 15:13:26 +0200
c480ed
Subject: [PATCH] util: vircgroupv1: add support for BFQ blkio files
c480ed
MIME-Version: 1.0
c480ed
Content-Type: text/plain; charset=UTF-8
c480ed
Content-Transfer-Encoding: 8bit
c480ed
c480ed
In kernel 4.12 there was introduced new BFQ scheduler and in kernel
c480ed
5.0 the old CFQ scheduler was removed.  This has an implication on
c480ed
the cgroups file names.
c480ed
c480ed
If the CFQ controller is enabled we use these two files:
c480ed
c480ed
    blkio.weight
c480ed
    blkio.weight_device
c480ed
c480ed
The new BFQ controller expose only one file with different name:
c480ed
c480ed
    blkio.bfq.weight
c480ed
c480ed
The reason is that BFQ controller doesn't support per-device weight.
c480ed
c480ed
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
c480ed
Reviewed-by: Ján Tomko <jtomko@redhat.com>
c480ed
(cherry picked from commit 035ebe9390a630964f391816f05c9cc7792212ad)
c480ed
c480ed
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1658890
c480ed
c480ed
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
c480ed
Message-Id: <b66aa3f8ec343e90f9ccd2e458707051c65b4d0d.1562073117.git.phrdina@redhat.com>
c480ed
Reviewed-by: Ján Tomko <jtomko@redhat.com>
c480ed
---
c480ed
 src/util/vircgroupv1.c | 114 ++++++++++++++++++++++++++++++++---------
c480ed
 1 file changed, 90 insertions(+), 24 deletions(-)
c480ed
c480ed
diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
c480ed
index e51db6ee1f..a7d6c92e4c 100644
c480ed
--- a/src/util/vircgroupv1.c
c480ed
+++ b/src/util/vircgroupv1.c
c480ed
@@ -949,10 +949,33 @@ static int
c480ed
 virCgroupV1SetBlkioWeight(virCgroupPtr group,
c480ed
                           unsigned int weight)
c480ed
 {
c480ed
-    return virCgroupSetValueU64(group,
c480ed
-                                VIR_CGROUP_CONTROLLER_BLKIO,
c480ed
-                                "blkio.weight",
c480ed
-                                weight);
c480ed
+    VIR_AUTOFREE(char *) path = NULL;
c480ed
+    VIR_AUTOFREE(char *) value = NULL;
c480ed
+
c480ed
+    if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
c480ed
+                                    "blkio.bfq.weight", &path) < 0) {
c480ed
+        return -1;
c480ed
+    }
c480ed
+
c480ed
+    if (!virFileExists(path)) {
c480ed
+        VIR_FREE(path);
c480ed
+
c480ed
+        if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
c480ed
+                                        "blkio.weight", &path) < 0) {
c480ed
+            return -1;
c480ed
+        }
c480ed
+    }
c480ed
+
c480ed
+    if (!virFileExists(path)) {
c480ed
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
c480ed
+                       _("blkio device weight is valid only for bfq or cfq scheduler"));
c480ed
+        return -1;
c480ed
+    }
c480ed
+
c480ed
+    if (virAsprintf(&value, "%u", weight) < 0)
c480ed
+        return -1;
c480ed
+
c480ed
+    return virCgroupSetValueRaw(path, value);
c480ed
 }
c480ed
 
c480ed
 
c480ed
@@ -960,14 +983,40 @@ static int
c480ed
 virCgroupV1GetBlkioWeight(virCgroupPtr group,
c480ed
                           unsigned int *weight)
c480ed
 {
c480ed
-    unsigned long long tmp;
c480ed
-    int ret;
c480ed
-    ret = virCgroupGetValueU64(group,
c480ed
-                               VIR_CGROUP_CONTROLLER_BLKIO,
c480ed
-                               "blkio.weight", &tmp);
c480ed
-    if (ret == 0)
c480ed
-        *weight = tmp;
c480ed
-    return ret;
c480ed
+    VIR_AUTOFREE(char *) path = NULL;
c480ed
+    VIR_AUTOFREE(char *) value = NULL;
c480ed
+
c480ed
+    if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
c480ed
+                                    "blkio.bfq.weight", &path) < 0) {
c480ed
+        return -1;
c480ed
+    }
c480ed
+
c480ed
+    if (!virFileExists(path)) {
c480ed
+        VIR_FREE(path);
c480ed
+
c480ed
+        if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
c480ed
+                                        "blkio.weight", &path) < 0) {
c480ed
+            return -1;
c480ed
+        }
c480ed
+    }
c480ed
+
c480ed
+    if (!virFileExists(path)) {
c480ed
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
c480ed
+                       _("blkio device weight is valid only for bfq or cfq scheduler"));
c480ed
+        return -1;
c480ed
+    }
c480ed
+
c480ed
+    if (virCgroupGetValueRaw(path, &value) < 0)
c480ed
+        return -1;
c480ed
+
c480ed
+    if (virStrToLong_ui(value, NULL, 10, weight) < 0) {
c480ed
+        virReportError(VIR_ERR_INTERNAL_ERROR,
c480ed
+                       _("Unable to parse '%s' as an integer"),
c480ed
+                       value);
c480ed
+        return -1;
c480ed
+    }
c480ed
+
c480ed
+    return 0;
c480ed
 }
c480ed
 
c480ed
 
c480ed
@@ -1156,41 +1205,58 @@ virCgroupV1GetBlkioIoDeviceServiced(virCgroupPtr group,
c480ed
 
c480ed
 static int
c480ed
 virCgroupV1SetBlkioDeviceWeight(virCgroupPtr group,
c480ed
-                                const char *path,
c480ed
+                                const char *devPath,
c480ed
                                 unsigned int weight)
c480ed
 {
c480ed
     VIR_AUTOFREE(char *) str = NULL;
c480ed
     VIR_AUTOFREE(char *) blkstr = NULL;
c480ed
+    VIR_AUTOFREE(char *) path = NULL;
c480ed
 
c480ed
-    if (!(blkstr = virCgroupGetBlockDevString(path)))
c480ed
+    if (!(blkstr = virCgroupGetBlockDevString(devPath)))
c480ed
         return -1;
c480ed
 
c480ed
     if (virAsprintf(&str, "%s%d", blkstr, weight) < 0)
c480ed
         return -1;
c480ed
 
c480ed
-    return virCgroupSetValueStr(group,
c480ed
-                                VIR_CGROUP_CONTROLLER_BLKIO,
c480ed
-                                "blkio.weight_device",
c480ed
-                                str);
c480ed
+    if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
c480ed
+                                    "blkio.weight_device", &path) < 0) {
c480ed
+        return -1;
c480ed
+    }
c480ed
+
c480ed
+    if (!virFileExists(path)) {
c480ed
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
c480ed
+                       _("blkio device weight is valid only for cfq scheduler"));
c480ed
+        return -1;
c480ed
+    }
c480ed
+
c480ed
+    return virCgroupSetValueRaw(path, str);
c480ed
 }
c480ed
 
c480ed
 
c480ed
 static int
c480ed
 virCgroupV1GetBlkioDeviceWeight(virCgroupPtr group,
c480ed
-                                const char *path,
c480ed
+                                const char *devPath,
c480ed
                                 unsigned int *weight)
c480ed
 {
c480ed
     VIR_AUTOFREE(char *) str = NULL;
c480ed
     VIR_AUTOFREE(char *) value = NULL;
c480ed
+    VIR_AUTOFREE(char *) path = NULL;
c480ed
 
c480ed
-    if (virCgroupGetValueStr(group,
c480ed
-                             VIR_CGROUP_CONTROLLER_BLKIO,
c480ed
-                             "blkio.weight_device",
c480ed
-                             &value) < 0) {
c480ed
+    if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
c480ed
+                                    "blkio.weight_device", &path) < 0) {
c480ed
         return -1;
c480ed
     }
c480ed
 
c480ed
-    if (virCgroupGetValueForBlkDev(value, path, &str) < 0)
c480ed
+    if (!virFileExists(path)) {
c480ed
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
c480ed
+                       _("blkio device weight is valid only for cfq scheduler"));
c480ed
+        return -1;
c480ed
+    }
c480ed
+
c480ed
+    if (virCgroupGetValueRaw(path, &value) < 0)
c480ed
+        return -1;
c480ed
+
c480ed
+    if (virCgroupGetValueForBlkDev(value, devPath, &str) < 0)
c480ed
         return -1;
c480ed
 
c480ed
     if (!str) {
c480ed
-- 
c480ed
2.22.0
c480ed