]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
vircgroup: use DBus call to systemd for some APIs
authorPavel Hrdina <phrdina@redhat.com>
Fri, 5 Feb 2021 15:17:35 +0000 (16:17 +0100)
committerPavel Hrdina <phrdina@redhat.com>
Wed, 10 Feb 2021 12:37:12 +0000 (13:37 +0100)
When running on host with systemd we register VMs with machined.
In this case systemd creates the root VM cgroup for us. This has some
implications where one of them is that systemd owns all files inside
the root VM cgroup and we should not touch them.

If we change any value in file that systemd knows about it will be
changed to what systemd thinks it should be when executing
`systemctl daemon-reload`.

These are the APIs that we need to call using systemd because they set
limits that are proportional to sibling cgroups.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
src/util/vircgroup.c
src/util/vircgrouppriv.h
src/util/vircgroupv1.c
src/util/vircgroupv2.c

index b5c74e94de3307fc7912db521a79d1215fb7abab..7a0e14eb731f8dde0c23897ac8d8d7da8f07f7cb 100644 (file)
@@ -41,6 +41,7 @@
 #include "virerror.h"
 #include "virlog.h"
 #include "virfile.h"
+#include "virgdbus.h"
 #include "virhash.h"
 #include "virstring.h"
 #include "virsystemd.h"
@@ -484,6 +485,37 @@ virCgroupGetBlockDevString(const char *path)
 }
 
 
+int
+virCgroupSetValueDBus(const char *unitName,
+                      const char *key,
+                      GVariant *value)
+{
+    GDBusConnection *conn;
+    g_autoptr(GVariant) message = NULL;
+    GVariantBuilder builder;
+    GVariant *props = NULL;
+
+    g_variant_builder_init(&builder, G_VARIANT_TYPE("a(sv)"));
+    g_variant_builder_add(&builder, "(sv)", key, value);
+    props = g_variant_builder_end(&builder);
+
+    message = g_variant_new("(sb@a(sv))", unitName, true, props);
+
+    if (!(conn = virGDBusGetSystemBus()))
+        return -1;
+
+    return virGDBusCallMethod(conn,
+                              NULL,
+                              NULL,
+                              NULL,
+                              "org.freedesktop.systemd1",
+                              "/org/freedesktop/systemd1",
+                              "org.freedesktop.systemd1.Manager",
+                              "SetUnitProperties",
+                              message);
+}
+
+
 int
 virCgroupSetValueRaw(const char *path,
                      const char *value)
@@ -1129,6 +1161,10 @@ virCgroupNewDetectMachine(const char *name,
         }
     }
 
+    newGroup->unitName = virSystemdGetMachineUnitByPID(pid);
+    if (virSystemdHasMachined() == 0 && !newGroup->unitName)
+        return -1;
+
     *group = g_steal_pointer(&newGroup);
     return 0;
 }
@@ -1229,6 +1265,10 @@ virCgroupNewMachineSystemd(const char *name,
     if (virCgroupEnableMissingControllers(path, controllers, &newGroup) < 0)
         return -1;
 
+    newGroup->unitName = virSystemdGetMachineUnitByPID(pidleader);
+    if (!newGroup->unitName)
+        return -1;
+
     if (virCgroupAddProcess(newGroup, pidleader) < 0) {
         virErrorPtr saved;
 
@@ -3588,6 +3628,7 @@ virCgroupFree(virCgroupPtr group)
 
     g_free(group->unified.mountPoint);
     g_free(group->unified.placement);
+    g_free(group->unitName);
 
     g_free(group);
 }
index 85ba5393e02b828d52a3c5f93a80272da195126b..f88d00814db58e09776687387c500d01b9be58e7 100644 (file)
@@ -64,8 +64,14 @@ struct _virCgroup {
 
     virCgroupV1Controller legacy[VIR_CGROUP_CONTROLLER_LAST];
     virCgroupV2Controller unified;
+
+    char *unitName;
 };
 
+int virCgroupSetValueDBus(const char *unitName,
+                          const char *key,
+                          GVariant *value);
+
 int virCgroupSetValueRaw(const char *path,
                          const char *value);
 
index 2b4d625c358335344724e3c20c41f39362626a77..edb2c23bbcf6a30ef9c84fec6ee7ea23e312ec43 100644 (file)
@@ -946,7 +946,6 @@ virCgroupV1SetBlkioWeight(virCgroupPtr group,
                           unsigned int weight)
 {
     g_autofree char *path = NULL;
-    g_autofree char *value = NULL;
 
     if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
                                     "blkio.bfq.weight", &path) < 0) {
@@ -968,9 +967,15 @@ virCgroupV1SetBlkioWeight(virCgroupPtr group,
         return -1;
     }
 
-    value = g_strdup_printf("%u", weight);
+    if (group->unitName) {
+        GVariant *value = g_variant_new("t", weight);
+
+        return virCgroupSetValueDBus(group->unitName, "BlockIOWeight", value);
+    } else {
+        g_autofree char *value = g_strdup_printf("%u", weight);
 
-    return virCgroupSetValueRaw(path, value);
+        return virCgroupSetValueRaw(path, value);
+    }
 }
 
 
@@ -1203,15 +1208,8 @@ virCgroupV1SetBlkioDeviceWeight(virCgroupPtr group,
                                 const char *devPath,
                                 unsigned int weight)
 {
-    g_autofree char *str = NULL;
-    g_autofree char *blkstr = NULL;
     g_autofree char *path = NULL;
 
-    if (!(blkstr = virCgroupGetBlockDevString(devPath)))
-        return -1;
-
-    str = g_strdup_printf("%s%d", blkstr, weight);
-
     if (virCgroupV1PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
                                     "blkio.weight_device", &path) < 0) {
         return -1;
@@ -1223,7 +1221,23 @@ virCgroupV1SetBlkioDeviceWeight(virCgroupPtr group,
         return -1;
     }
 
-    return virCgroupSetValueRaw(path, str);
+    if (group->unitName) {
+        GVariant *value = NULL;
+
+        value = g_variant_new_parsed("[(%s, uint64 %u)]", path, weight);
+
+        return virCgroupSetValueDBus(group->unitName, "BlockIODeviceWeight", value);
+    } else {
+        g_autofree char *str = NULL;
+        g_autofree char *blkstr = NULL;
+
+        if (!(blkstr = virCgroupGetBlockDevString(devPath)))
+            return -1;
+
+        str = g_strdup_printf("%s%d", blkstr, weight);
+
+        return virCgroupSetValueRaw(path, str);
+    }
 }
 
 
@@ -1862,9 +1876,15 @@ static int
 virCgroupV1SetCpuShares(virCgroupPtr group,
                         unsigned long long shares)
 {
-    return virCgroupSetValueU64(group,
-                                VIR_CGROUP_CONTROLLER_CPU,
-                                "cpu.shares", shares);
+    if (group->unitName) {
+        GVariant *value = g_variant_new("t", shares);
+
+        return virCgroupSetValueDBus(group->unitName, "CPUShares", value);
+    } else {
+        return virCgroupSetValueU64(group,
+                                    VIR_CGROUP_CONTROLLER_CPU,
+                                    "cpu.shares", shares);
+    }
 }
 
 
index 49acd27714f82b9e19e1da064d2f2809905206fa..a61c633a1f9d279010653c4a2ee843a7bc0f1a89 100644 (file)
@@ -609,7 +609,6 @@ virCgroupV2SetBlkioWeight(virCgroupPtr group,
                           unsigned int weight)
 {
     g_autofree char *path = NULL;
-    g_autofree char *value = NULL;
     const char *format = "%u";
 
     if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
@@ -633,9 +632,15 @@ virCgroupV2SetBlkioWeight(virCgroupPtr group,
         return -1;
     }
 
-    value = g_strdup_printf(format, weight);
+    if (group->unitName) {
+        GVariant *value = g_variant_new("t", weight);
+
+        return virCgroupSetValueDBus(group->unitName, "IOWeight", value);
+    } else {
+        g_autofree char *value = g_strdup_printf(format, weight);
 
-    return virCgroupSetValueRaw(path, value);
+        return virCgroupSetValueRaw(path, value);
+    }
 }
 
 
@@ -820,13 +825,6 @@ virCgroupV2SetBlkioDeviceWeight(virCgroupPtr group,
                                 unsigned int weight)
 {
     g_autofree char *path = NULL;
-    g_autofree char *str = NULL;
-    g_autofree char *blkstr = NULL;
-
-    if (!(blkstr = virCgroupGetBlockDevString(devPath)))
-        return -1;
-
-    str = g_strdup_printf("%s%d", blkstr, weight);
 
     if (virCgroupV2PathOfController(group, VIR_CGROUP_CONTROLLER_BLKIO,
                                     "io.weight", &path) < 0) {
@@ -839,7 +837,23 @@ virCgroupV2SetBlkioDeviceWeight(virCgroupPtr group,
         return -1;
     }
 
-    return virCgroupSetValueRaw(path, str);
+    if (group->unitName) {
+        GVariant *value = NULL;
+
+        value = g_variant_new_parsed("[(%s, uint64 %u)]", path, weight);
+
+        return virCgroupSetValueDBus(group->unitName, "IODeviceWeight", value);
+    } else {
+        g_autofree char *str = NULL;
+        g_autofree char *blkstr = NULL;
+
+        if (!(blkstr = virCgroupGetBlockDevString(devPath)))
+            return -1;
+
+        str = g_strdup_printf("%s%d", blkstr, weight);
+
+        return virCgroupSetValueRaw(path, str);
+    }
 }
 
 
@@ -1458,9 +1472,15 @@ static int
 virCgroupV2SetCpuShares(virCgroupPtr group,
                         unsigned long long shares)
 {
-    return virCgroupSetValueU64(group,
-                                VIR_CGROUP_CONTROLLER_CPU,
-                                "cpu.weight", shares);
+    if (group->unitName) {
+        GVariant *value = g_variant_new("t", shares);
+
+        return virCgroupSetValueDBus(group->unitName, "CPUWeight", value);
+    } else {
+        return virCgroupSetValueU64(group,
+                                    VIR_CGROUP_CONTROLLER_CPU,
+                                    "cpu.weight", shares);
+    }
 }