render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
8c03ec
From 205289d2792aacf68ed2cb8563d1860bd36137a0 Mon Sep 17 00:00:00 2001
8c03ec
Message-Id: <205289d2792aacf68ed2cb8563d1860bd36137a0@dist-git>
8c03ec
From: Pavel Hrdina <phrdina@redhat.com>
8c03ec
Date: Fri, 19 Feb 2021 13:33:55 +0100
8c03ec
Subject: [PATCH] vircgroup: use DBus call to systemd for some APIs
8c03ec
MIME-Version: 1.0
8c03ec
Content-Type: text/plain; charset=UTF-8
8c03ec
Content-Transfer-Encoding: 8bit
8c03ec
8c03ec
When running on host with systemd we register VMs with machined.
8c03ec
In this case systemd creates the root VM cgroup for us. This has some
8c03ec
implications where one of them is that systemd owns all files inside
8c03ec
the root VM cgroup and we should not touch them.
8c03ec
8c03ec
If we change any value in file that systemd knows about it will be
8c03ec
changed to what systemd thinks it should be when executing
8c03ec
`systemctl daemon-reload`.
8c03ec
8c03ec
These are the APIs that we need to call using systemd because they set
8c03ec
limits that are proportional to sibling cgroups.
8c03ec
8c03ec
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
8c03ec
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
8c03ec
(cherry picked from commit 9c1693eff427661616ce1bd2795688f87288a412)
8c03ec
8c03ec
Conflicts:
8c03ec
    src/util/vircgroup.c
8c03ec
        - missing upstream g_autofree rewrite
8c03ec
        - missing upstream glib dbus rewrite, hence the ugly macro
8c03ec
          instead of a function
8c03ec
8c03ec
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1798463
8c03ec
8c03ec
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
8c03ec
Message-Id: <5d22d307112333f1da565cb642ea9001a7b8b55b.1613737828.git.phrdina@redhat.com>
8c03ec
Reviewed-by: Ján Tomko <jtomko@redhat.com>
8c03ec
---
8c03ec
 src/util/vircgroup.c     | 11 ++++++++++
8c03ec
 src/util/vircgrouppriv.h | 25 +++++++++++++++++++++++
8c03ec
 src/util/vircgroupv1.c   | 44 +++++++++++++++++++++++++++-------------
8c03ec
 src/util/vircgroupv2.c   | 44 +++++++++++++++++++++++++++-------------
8c03ec
 tests/Makefile.am        |  1 +
8c03ec
 5 files changed, 97 insertions(+), 28 deletions(-)
8c03ec
8c03ec
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
8c03ec
index a45c2e7f2f..10b934291c 100644
8c03ec
--- a/src/util/vircgroup.c
8c03ec
+++ b/src/util/vircgroup.c
8c03ec
@@ -1027,6 +1027,10 @@ virCgroupNewDetectMachine(const char *name,
8c03ec
         }
8c03ec
     }
8c03ec
 
8c03ec
+    (*group)->unitName = virSystemdGetMachineUnitByPID(pid);
8c03ec
+    if (virSystemdHasMachined() == 0 && !(*group)->unitName)
8c03ec
+        return -1;
8c03ec
+
8c03ec
     return 0;
8c03ec
 }
8c03ec
 
8c03ec
@@ -1146,6 +1150,12 @@ virCgroupNewMachineSystemd(const char *name,
8c03ec
         return -1;
8c03ec
     }
8c03ec
 
8c03ec
+    (*group)->unitName = virSystemdGetMachineUnitByPID(pidleader);
8c03ec
+    if (!(*group)->unitName) {
8c03ec
+        virCgroupFree(group);
8c03ec
+        return -1;
8c03ec
+    }
8c03ec
+
8c03ec
     if (virCgroupAddProcess(*group, pidleader) < 0) {
8c03ec
         virErrorPtr saved;
8c03ec
 
8c03ec
@@ -3553,6 +3563,7 @@ virCgroupFree(virCgroupPtr *group)
8c03ec
 
8c03ec
     VIR_FREE((*group)->unified.mountPoint);
8c03ec
     VIR_FREE((*group)->unified.placement);
8c03ec
+    VIR_FREE((*group)->unitName);
8c03ec
 
8c03ec
     VIR_FREE((*group)->path);
8c03ec
     VIR_FREE(*group);
8c03ec
diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h
8c03ec
index f2a80aeb82..b4a9e0b379 100644
8c03ec
--- a/src/util/vircgrouppriv.h
8c03ec
+++ b/src/util/vircgrouppriv.h
8c03ec
@@ -27,6 +27,7 @@
8c03ec
 
8c03ec
 #include "vircgroup.h"
8c03ec
 #include "vircgroupbackend.h"
8c03ec
+#include "virdbus.h"
8c03ec
 
8c03ec
 struct _virCgroupV1Controller {
8c03ec
     int type;
8c03ec
@@ -66,8 +67,32 @@ struct _virCgroup {
8c03ec
 
8c03ec
     virCgroupV1Controller legacy[VIR_CGROUP_CONTROLLER_LAST];
8c03ec
     virCgroupV2Controller unified;
8c03ec
+
8c03ec
+    char *unitName;
8c03ec
 };
8c03ec
 
8c03ec
+#define virCgroupSetValueDBus(unitName, key, ...) \
8c03ec
+    ({ \
8c03ec
+        int __ret = -1; \
8c03ec
+        do { \
8c03ec
+            DBusConnection *__conn; \
8c03ec
+            if (!(__conn = virDBusGetSystemBus())) \
8c03ec
+                break; \
8c03ec
+            __ret = virDBusCallMethod(__conn, NULL, NULL, \
8c03ec
+                                      "org.freedesktop.systemd1", \
8c03ec
+                                      "/org/freedesktop/systemd1", \
8c03ec
+                                      "org.freedesktop.systemd1.Manager", \
8c03ec
+                                      "SetUnitProperties", \
8c03ec
+                                      "sba(sv)", \
8c03ec
+                                      unitName, \
8c03ec
+                                      true, \
8c03ec
+                                      1, \
8c03ec
+                                      key, \
8c03ec
+                                      __VA_ARGS__); \
8c03ec
+        } while (0); \
8c03ec
+        __ret; \
8c03ec
+    })
8c03ec
+
8c03ec
 int virCgroupSetValueRaw(const char *path,
8c03ec
                          const char *value);
8c03ec
 
8c03ec
diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
8c03ec
index c35088a3c4..7ec8f3a316 100644
8c03ec
--- a/src/util/vircgroupv1.c
8c03ec
+++ b/src/util/vircgroupv1.c
8c03ec
@@ -931,7 +931,6 @@ virCgroupV1SetBlkioWeight(virCgroupPtr group,
8c03ec
                           unsigned int weight)
8c03ec
 {
8c03ec
     g_autofree char *path = NULL;
8c03ec
-    g_autofree char *value = NULL;
8c03ec
 
8c03ec
     if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
8c03ec
                                     "blkio.bfq.weight", &path) < 0) {
8c03ec
@@ -953,9 +952,14 @@ virCgroupV1SetBlkioWeight(virCgroupPtr group,
8c03ec
         return -1;
8c03ec
     }
8c03ec
 
8c03ec
-    value = g_strdup_printf("%u", weight);
8c03ec
+    if (group->unitName) {
8c03ec
+        return virCgroupSetValueDBus(group->unitName, "BlockIOWeight",
8c03ec
+                                     "t", (unsigned long long) weight);
8c03ec
+    } else {
8c03ec
+        g_autofree char *value = g_strdup_printf("%u", weight);
8c03ec
 
8c03ec
-    return virCgroupSetValueRaw(path, value);
8c03ec
+        return virCgroupSetValueRaw(path, value);
8c03ec
+    }
8c03ec
 }
8c03ec
 
8c03ec
 
8c03ec
@@ -1188,15 +1192,8 @@ virCgroupV1SetBlkioDeviceWeight(virCgroupPtr group,
8c03ec
                                 const char *devPath,
8c03ec
                                 unsigned int weight)
8c03ec
 {
8c03ec
-    g_autofree char *str = NULL;
8c03ec
-    g_autofree char *blkstr = NULL;
8c03ec
     g_autofree char *path = NULL;
8c03ec
 
8c03ec
-    if (!(blkstr = virCgroupGetBlockDevString(devPath)))
8c03ec
-        return -1;
8c03ec
-
8c03ec
-    str = g_strdup_printf("%s%d", blkstr, weight);
8c03ec
-
8c03ec
     if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
8c03ec
                                     "blkio.weight_device", &path) < 0) {
8c03ec
         return -1;
8c03ec
@@ -1208,7 +1205,21 @@ virCgroupV1SetBlkioDeviceWeight(virCgroupPtr group,
8c03ec
         return -1;
8c03ec
     }
8c03ec
 
8c03ec
-    return virCgroupSetValueRaw(path, str);
8c03ec
+    if (group->unitName) {
8c03ec
+        return virCgroupSetValueDBus(group->unitName, "BlockIODeviceWeight",
8c03ec
+                                     "a(st)",
8c03ec
+                                     1, path, (unsigned long long) weight);
8c03ec
+    } else {
8c03ec
+        g_autofree char *str = NULL;
8c03ec
+        g_autofree char *blkstr = NULL;
8c03ec
+
8c03ec
+        if (!(blkstr = virCgroupGetBlockDevString(devPath)))
8c03ec
+            return -1;
8c03ec
+
8c03ec
+        str = g_strdup_printf("%s%d", blkstr, weight);
8c03ec
+
8c03ec
+        return virCgroupSetValueRaw(path, str);
8c03ec
+    }
8c03ec
 }
8c03ec
 
8c03ec
 
8c03ec
@@ -1849,9 +1860,14 @@ static int
8c03ec
 virCgroupV1SetCpuShares(virCgroupPtr group,
8c03ec
                         unsigned long long shares)
8c03ec
 {
8c03ec
-    return virCgroupSetValueU64(group,
8c03ec
-                                VIR_CGROUP_CONTROLLER_CPU,
8c03ec
-                                "cpu.shares", shares);
8c03ec
+    if (group->unitName) {
8c03ec
+        return virCgroupSetValueDBus(group->unitName, "CPUShares",
8c03ec
+                                     "t", shares);
8c03ec
+    } else {
8c03ec
+        return virCgroupSetValueU64(group,
8c03ec
+                                    VIR_CGROUP_CONTROLLER_CPU,
8c03ec
+                                    "cpu.shares", shares);
8c03ec
+    }
8c03ec
 }
8c03ec
 
8c03ec
 
8c03ec
diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
8c03ec
index 4682a6a920..8fe4894a9e 100644
8c03ec
--- a/src/util/vircgroupv2.c
8c03ec
+++ b/src/util/vircgroupv2.c
8c03ec
@@ -606,7 +606,6 @@ virCgroupV2SetBlkioWeight(virCgroupPtr group,
8c03ec
                           unsigned int weight)
8c03ec
 {
8c03ec
     g_autofree char *path = NULL;
8c03ec
-    g_autofree char *value = NULL;
8c03ec
     const char *format = "%u";
8c03ec
 
8c03ec
     if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
8c03ec
@@ -630,9 +629,14 @@ virCgroupV2SetBlkioWeight(virCgroupPtr group,
8c03ec
         return -1;
8c03ec
     }
8c03ec
 
8c03ec
-    value = g_strdup_printf(format, weight);
8c03ec
+    if (group->unitName) {
8c03ec
+        return virCgroupSetValueDBus(group->unitName, "IOWeight",
8c03ec
+                                     "t", (unsigned long long) weight);
8c03ec
+    } else {
8c03ec
+        g_autofree char *value = g_strdup_printf(format, weight);
8c03ec
 
8c03ec
-    return virCgroupSetValueRaw(path, value);
8c03ec
+        return virCgroupSetValueRaw(path, value);
8c03ec
+    }
8c03ec
 }
8c03ec
 
8c03ec
 
8c03ec
@@ -817,13 +821,6 @@ virCgroupV2SetBlkioDeviceWeight(virCgroupPtr group,
8c03ec
                                 unsigned int weight)
8c03ec
 {
8c03ec
     g_autofree char *path = NULL;
8c03ec
-    g_autofree char *str = NULL;
8c03ec
-    g_autofree char *blkstr = NULL;
8c03ec
-
8c03ec
-    if (!(blkstr = virCgroupGetBlockDevString(devPath)))
8c03ec
-        return -1;
8c03ec
-
8c03ec
-    str = g_strdup_printf("%s%d", blkstr, weight);
8c03ec
 
8c03ec
     if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
8c03ec
                                     "io.weight", &path) < 0) {
8c03ec
@@ -836,7 +833,21 @@ virCgroupV2SetBlkioDeviceWeight(virCgroupPtr group,
8c03ec
         return -1;
8c03ec
     }
8c03ec
 
8c03ec
-    return virCgroupSetValueRaw(path, str);
8c03ec
+    if (group->unitName) {
8c03ec
+        return virCgroupSetValueDBus(group->unitName, "IODeviceWeight",
8c03ec
+                                     "a(st)",
8c03ec
+                                     1, path, (unsigned long long) weight);
8c03ec
+    } else {
8c03ec
+        g_autofree char *str = NULL;
8c03ec
+        g_autofree char *blkstr = NULL;
8c03ec
+
8c03ec
+        if (!(blkstr = virCgroupGetBlockDevString(devPath)))
8c03ec
+            return -1;
8c03ec
+
8c03ec
+        str = g_strdup_printf("%s%d", blkstr, weight);
8c03ec
+
8c03ec
+        return virCgroupSetValueRaw(path, str);
8c03ec
+    }
8c03ec
 }
8c03ec
 
8c03ec
 
8c03ec
@@ -1455,9 +1466,14 @@ static int
8c03ec
 virCgroupV2SetCpuShares(virCgroupPtr group,
8c03ec
                         unsigned long long shares)
8c03ec
 {
8c03ec
-    return virCgroupSetValueU64(group,
8c03ec
-                                VIR_CGROUP_CONTROLLER_CPU,
8c03ec
-                                "cpu.weight", shares);
8c03ec
+    if (group->unitName) {
8c03ec
+        return virCgroupSetValueDBus(group->unitName, "CPUWeight",
8c03ec
+                                     "t", shares);
8c03ec
+    } else {
8c03ec
+        return virCgroupSetValueU64(group,
8c03ec
+                                    VIR_CGROUP_CONTROLLER_CPU,
8c03ec
+                                    "cpu.weight", shares);
8c03ec
+    }
8c03ec
 }
8c03ec
 
8c03ec
 
8c03ec
diff --git a/tests/Makefile.am b/tests/Makefile.am
8c03ec
index f957c7d1ba..b030d0e8f6 100644
8c03ec
--- a/tests/Makefile.am
8c03ec
+++ b/tests/Makefile.am
8c03ec
@@ -1188,6 +1188,7 @@ libvirportallocatormock_la_LIBADD = $(MOCKLIBS_LIBS)
8c03ec
 
8c03ec
 vircgrouptest_SOURCES = \
8c03ec
 	vircgrouptest.c testutils.h testutils.c
8c03ec
+vircgrouptest_CFLAGS = $(DBUS_CFLAGS) $(AM_CFLAGS)
8c03ec
 vircgrouptest_LDADD = $(LDADDS)
8c03ec
 
8c03ec
 libvircgroupmock_la_SOURCES = \
8c03ec
-- 
8c03ec
2.30.0
8c03ec