render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
c480ed
From d72932998be48ff4eeb1b9d73d6f5d60560be031 Mon Sep 17 00:00:00 2001
c480ed
Message-Id: <d72932998be48ff4eeb1b9d73d6f5d60560be031@dist-git>
c480ed
From: Pavel Hrdina <phrdina@redhat.com>
c480ed
Date: Mon, 1 Jul 2019 17:06:35 +0200
c480ed
Subject: [PATCH] vircgroup: extract virCgroupV1MakeGroup
c480ed
MIME-Version: 1.0
c480ed
Content-Type: text/plain; charset=UTF-8
c480ed
Content-Transfer-Encoding: 8bit
c480ed
c480ed
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
c480ed
Reviewed-by: Ján Tomko <jtomko@redhat.com>
c480ed
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
c480ed
(cherry picked from commit 152c0f0bf52d4f727e09f388fef5c836c3c94db4)
c480ed
c480ed
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297
c480ed
c480ed
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
c480ed
Message-Id: <b90114ff10174e747131ddc3dfeb4fe177d4bf21.1561993100.git.phrdina@redhat.com>
c480ed
Reviewed-by: Ján Tomko <jtomko@redhat.com>
c480ed
---
c480ed
 src/util/vircgroup.c        | 141 ++----------------------------------
c480ed
 src/util/vircgroupbackend.h |  15 ++++
c480ed
 src/util/vircgrouppriv.h    |  20 +++++
c480ed
 src/util/vircgroupv1.c      | 132 +++++++++++++++++++++++++++++++++
c480ed
 4 files changed, 174 insertions(+), 134 deletions(-)
c480ed
c480ed
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
c480ed
index 438d9b4e70..8f0ea4de9a 100644
c480ed
--- a/src/util/vircgroup.c
c480ed
+++ b/src/util/vircgroup.c
c480ed
@@ -80,14 +80,6 @@ VIR_ENUM_IMPL(virCgroupController, VIR_CGROUP_CONTROLLER_LAST,
c480ed
               "freezer", "blkio", "net_cls", "perf_event",
c480ed
               "name=systemd");
c480ed
 
c480ed
-typedef enum {
c480ed
-    VIR_CGROUP_NONE = 0, /* create subdir under each cgroup if possible. */
c480ed
-    VIR_CGROUP_MEM_HIERACHY = 1 << 0, /* call virCgroupSetMemoryUseHierarchy
c480ed
-                                       * before creating subcgroups and
c480ed
-                                       * attaching tasks
c480ed
-                                       */
c480ed
-} virCgroupFlags;
c480ed
-
c480ed
 
c480ed
 /**
c480ed
  * virCgroupGetDevicePermsString:
c480ed
@@ -446,7 +438,7 @@ virCgroupGetBlockDevString(const char *path)
c480ed
 }
c480ed
 
c480ed
 
c480ed
-static int
c480ed
+int
c480ed
 virCgroupSetValueStr(virCgroupPtr group,
c480ed
                      int controller,
c480ed
                      const char *key,
c480ed
@@ -476,7 +468,7 @@ virCgroupSetValueStr(virCgroupPtr group,
c480ed
 }
c480ed
 
c480ed
 
c480ed
-static int
c480ed
+int
c480ed
 virCgroupGetValueStr(virCgroupPtr group,
c480ed
                      int controller,
c480ed
                      const char *key,
c480ed
@@ -537,7 +529,7 @@ virCgroupGetValueForBlkDev(virCgroupPtr group,
c480ed
 }
c480ed
 
c480ed
 
c480ed
-static int
c480ed
+int
c480ed
 virCgroupSetValueU64(virCgroupPtr group,
c480ed
                      int controller,
c480ed
                      const char *key,
c480ed
@@ -589,7 +581,7 @@ virCgroupGetValueI64(virCgroupPtr group,
c480ed
 }
c480ed
 
c480ed
 
c480ed
-static int
c480ed
+int
c480ed
 virCgroupGetValueU64(virCgroupPtr group,
c480ed
                      int controller,
c480ed
                      const char *key,
c480ed
@@ -611,137 +603,18 @@ virCgroupGetValueU64(virCgroupPtr group,
c480ed
 }
c480ed
 
c480ed
 
c480ed
-static int
c480ed
-virCgroupCpuSetInherit(virCgroupPtr parent, virCgroupPtr group)
c480ed
-{
c480ed
-    size_t i;
c480ed
-    const char *inherit_values[] = {
c480ed
-        "cpuset.cpus",
c480ed
-        "cpuset.mems",
c480ed
-        "cpuset.memory_migrate",
c480ed
-    };
c480ed
-
c480ed
-    VIR_DEBUG("Setting up inheritance %s -> %s", parent->path, group->path);
c480ed
-    for (i = 0; i < ARRAY_CARDINALITY(inherit_values); i++) {
c480ed
-        VIR_AUTOFREE(char *) value = NULL;
c480ed
-
c480ed
-        if (virCgroupGetValueStr(parent,
c480ed
-                                 VIR_CGROUP_CONTROLLER_CPUSET,
c480ed
-                                 inherit_values[i],
c480ed
-                                 &value) < 0)
c480ed
-            return -1;
c480ed
-
c480ed
-        VIR_DEBUG("Inherit %s = %s", inherit_values[i], value);
c480ed
-
c480ed
-        if (virCgroupSetValueStr(group,
c480ed
-                                 VIR_CGROUP_CONTROLLER_CPUSET,
c480ed
-                                 inherit_values[i],
c480ed
-                                 value) < 0)
c480ed
-            return -1;
c480ed
-    }
c480ed
-
c480ed
-    return 0;
c480ed
-}
c480ed
-
c480ed
-
c480ed
-static int
c480ed
-virCgroupSetMemoryUseHierarchy(virCgroupPtr group)
c480ed
-{
c480ed
-    unsigned long long value;
c480ed
-    const char *filename = "memory.use_hierarchy";
c480ed
-
c480ed
-    if (virCgroupGetValueU64(group,
c480ed
-                             VIR_CGROUP_CONTROLLER_MEMORY,
c480ed
-                             filename, &value) < 0)
c480ed
-        return -1;
c480ed
-
c480ed
-    /* Setting twice causes error, so if already enabled, skip setting */
c480ed
-    if (value == 1)
c480ed
-        return 0;
c480ed
-
c480ed
-    VIR_DEBUG("Setting up %s/%s", group->path, filename);
c480ed
-    if (virCgroupSetValueU64(group,
c480ed
-                             VIR_CGROUP_CONTROLLER_MEMORY,
c480ed
-                             filename, 1) < 0)
c480ed
-        return -1;
c480ed
-
c480ed
-    return 0;
c480ed
-}
c480ed
-
c480ed
-
c480ed
 static int
c480ed
 virCgroupMakeGroup(virCgroupPtr parent,
c480ed
                    virCgroupPtr group,
c480ed
                    bool create,
c480ed
                    unsigned int flags)
c480ed
 {
c480ed
-    size_t i;
c480ed
-
c480ed
-    VIR_DEBUG("Make group %s", group->path);
c480ed
-    for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
c480ed
-        VIR_AUTOFREE(char *) path = NULL;
c480ed
-
c480ed
-        /* We must never mkdir() in systemd's hierarchy */
c480ed
-        if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) {
c480ed
-            VIR_DEBUG("Not creating systemd controller group");
c480ed
-            continue;
c480ed
-        }
c480ed
-
c480ed
-        /* Skip over controllers that aren't mounted */
c480ed
-        if (!group->controllers[i].mountPoint) {
c480ed
-            VIR_DEBUG("Skipping unmounted controller %s",
c480ed
-                      virCgroupControllerTypeToString(i));
c480ed
-            continue;
c480ed
-        }
c480ed
-
c480ed
-        if (virCgroupPathOfController(group, i, "", &path) < 0)
c480ed
-            goto error;
c480ed
-
c480ed
-        VIR_DEBUG("Make controller %s", path);
c480ed
-        if (!virFileExists(path)) {
c480ed
-            if (!create ||
c480ed
-                mkdir(path, 0755) < 0) {
c480ed
-                if (errno == EEXIST)
c480ed
-                    continue;
c480ed
-                /* With a kernel that doesn't support multi-level directory
c480ed
-                 * for blkio controller, libvirt will fail and disable all
c480ed
-                 * other controllers even though they are available. So
c480ed
-                 * treat blkio as unmounted if mkdir fails. */
c480ed
-                if (i == VIR_CGROUP_CONTROLLER_BLKIO) {
c480ed
-                    VIR_DEBUG("Ignoring mkdir failure with blkio controller. Kernel probably too old");
c480ed
-                    VIR_FREE(group->controllers[i].mountPoint);
c480ed
-                    continue;
c480ed
-                } else {
c480ed
-                    virReportSystemError(errno,
c480ed
-                                         _("Failed to create controller %s for group"),
c480ed
-                                         virCgroupControllerTypeToString(i));
c480ed
-                    goto error;
c480ed
-                }
c480ed
-            }
c480ed
-            if (i == VIR_CGROUP_CONTROLLER_CPUSET &&
c480ed
-                group->controllers[i].mountPoint != NULL &&
c480ed
-                virCgroupCpuSetInherit(parent, group) < 0) {
c480ed
-                goto error;
c480ed
-            }
c480ed
-            /*
c480ed
-             * Note that virCgroupSetMemoryUseHierarchy should always be
c480ed
-             * called prior to creating subcgroups and attaching tasks.
c480ed
-             */
c480ed
-            if ((flags & VIR_CGROUP_MEM_HIERACHY) &&
c480ed
-                i == VIR_CGROUP_CONTROLLER_MEMORY &&
c480ed
-                group->controllers[i].mountPoint != NULL &&
c480ed
-                virCgroupSetMemoryUseHierarchy(group) < 0) {
c480ed
-                goto error;
c480ed
-            }
c480ed
-        }
c480ed
+    if (group->backend->makeGroup(parent, group, create, flags) < 0) {
c480ed
+        virCgroupRemove(group);
c480ed
+        return -1;
c480ed
     }
c480ed
 
c480ed
-    VIR_DEBUG("Done making controllers for group");
c480ed
     return 0;
c480ed
-
c480ed
- error:
c480ed
-    virCgroupRemove(group);
c480ed
-    return -1;
c480ed
 }
c480ed
 
c480ed
 
c480ed
diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h
c480ed
index 916227ba6a..b2848c2076 100644
c480ed
--- a/src/util/vircgroupbackend.h
c480ed
+++ b/src/util/vircgroupbackend.h
c480ed
@@ -27,6 +27,14 @@
c480ed
 
c480ed
 # define CGROUP_MAX_VAL 512
c480ed
 
c480ed
+typedef enum {
c480ed
+    VIR_CGROUP_NONE = 0, /* create subdir under each cgroup if possible. */
c480ed
+    VIR_CGROUP_MEM_HIERACHY = 1 << 0, /* call virCgroupSetMemoryUseHierarchy
c480ed
+                                       * before creating subcgroups and
c480ed
+                                       * attaching tasks
c480ed
+                                       */
c480ed
+} virCgroupBackendFlags;
c480ed
+
c480ed
 typedef enum {
c480ed
     VIR_CGROUP_BACKEND_TYPE_V1 = 0,
c480ed
     VIR_CGROUP_BACKEND_TYPE_LAST,
c480ed
@@ -86,6 +94,12 @@ typedef int
c480ed
                                const char *key,
c480ed
                                char **path);
c480ed
 
c480ed
+typedef int
c480ed
+(*virCgroupMakeGroupCB)(virCgroupPtr parent,
c480ed
+                        virCgroupPtr group,
c480ed
+                        bool create,
c480ed
+                        unsigned int flags);
c480ed
+
c480ed
 struct _virCgroupBackend {
c480ed
     virCgroupBackendType type;
c480ed
 
c480ed
@@ -102,6 +116,7 @@ struct _virCgroupBackend {
c480ed
     virCgroupHasControllerCB hasController;
c480ed
     virCgroupGetAnyControllerCB getAnyController;
c480ed
     virCgroupPathOfControllerCB pathOfController;
c480ed
+    virCgroupMakeGroupCB makeGroup;
c480ed
 };
c480ed
 typedef struct _virCgroupBackend virCgroupBackend;
c480ed
 typedef virCgroupBackend *virCgroupBackendPtr;
c480ed
diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h
c480ed
index e7f4a1f0fc..2e731458d5 100644
c480ed
--- a/src/util/vircgrouppriv.h
c480ed
+++ b/src/util/vircgrouppriv.h
c480ed
@@ -53,6 +53,26 @@ struct _virCgroup {
c480ed
     virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST];
c480ed
 };
c480ed
 
c480ed
+int virCgroupSetValueStr(virCgroupPtr group,
c480ed
+                         int controller,
c480ed
+                         const char *key,
c480ed
+                         const char *value);
c480ed
+
c480ed
+int virCgroupGetValueStr(virCgroupPtr group,
c480ed
+                         int controller,
c480ed
+                         const char *key,
c480ed
+                         char **value);
c480ed
+
c480ed
+int virCgroupSetValueU64(virCgroupPtr group,
c480ed
+                         int controller,
c480ed
+                         const char *key,
c480ed
+                         unsigned long long int value);
c480ed
+
c480ed
+int virCgroupGetValueU64(virCgroupPtr group,
c480ed
+                         int controller,
c480ed
+                         const char *key,
c480ed
+                         unsigned long long int *value);
c480ed
+
c480ed
 int virCgroupPartitionEscape(char **path);
c480ed
 
c480ed
 int virCgroupNewPartition(const char *path,
c480ed
diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
c480ed
index a6302d71b1..653e848a83 100644
c480ed
--- a/src/util/vircgroupv1.c
c480ed
+++ b/src/util/vircgroupv1.c
c480ed
@@ -537,6 +537,137 @@ virCgroupV1PathOfController(virCgroupPtr group,
c480ed
 }
c480ed
 
c480ed
 
c480ed
+static int
c480ed
+virCgroupV1CpuSetInherit(virCgroupPtr parent,
c480ed
+                         virCgroupPtr group)
c480ed
+{
c480ed
+    size_t i;
c480ed
+    const char *inherit_values[] = {
c480ed
+        "cpuset.cpus",
c480ed
+        "cpuset.mems",
c480ed
+        "cpuset.memory_migrate",
c480ed
+    };
c480ed
+
c480ed
+    VIR_DEBUG("Setting up inheritance %s -> %s", parent->path, group->path);
c480ed
+    for (i = 0; i < ARRAY_CARDINALITY(inherit_values); i++) {
c480ed
+        VIR_AUTOFREE(char *) value = NULL;
c480ed
+
c480ed
+        if (virCgroupGetValueStr(parent,
c480ed
+                                 VIR_CGROUP_CONTROLLER_CPUSET,
c480ed
+                                 inherit_values[i],
c480ed
+                                 &value) < 0)
c480ed
+            return -1;
c480ed
+
c480ed
+        VIR_DEBUG("Inherit %s = %s", inherit_values[i], value);
c480ed
+
c480ed
+        if (virCgroupSetValueStr(group,
c480ed
+                                 VIR_CGROUP_CONTROLLER_CPUSET,
c480ed
+                                 inherit_values[i],
c480ed
+                                 value) < 0)
c480ed
+            return -1;
c480ed
+    }
c480ed
+
c480ed
+    return 0;
c480ed
+}
c480ed
+
c480ed
+
c480ed
+static int
c480ed
+virCgroupV1SetMemoryUseHierarchy(virCgroupPtr group)
c480ed
+{
c480ed
+    unsigned long long value;
c480ed
+    const char *filename = "memory.use_hierarchy";
c480ed
+
c480ed
+    if (virCgroupGetValueU64(group,
c480ed
+                             VIR_CGROUP_CONTROLLER_MEMORY,
c480ed
+                             filename, &value) < 0)
c480ed
+        return -1;
c480ed
+
c480ed
+    /* Setting twice causes error, so if already enabled, skip setting */
c480ed
+    if (value == 1)
c480ed
+        return 0;
c480ed
+
c480ed
+    VIR_DEBUG("Setting up %s/%s", group->path, filename);
c480ed
+    if (virCgroupSetValueU64(group,
c480ed
+                             VIR_CGROUP_CONTROLLER_MEMORY,
c480ed
+                             filename, 1) < 0)
c480ed
+        return -1;
c480ed
+
c480ed
+    return 0;
c480ed
+}
c480ed
+
c480ed
+
c480ed
+static int
c480ed
+virCgroupV1MakeGroup(virCgroupPtr parent,
c480ed
+                     virCgroupPtr group,
c480ed
+                     bool create,
c480ed
+                     unsigned int flags)
c480ed
+{
c480ed
+    size_t i;
c480ed
+
c480ed
+    VIR_DEBUG("Make group %s", group->path);
c480ed
+    for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) {
c480ed
+        VIR_AUTOFREE(char *) path = NULL;
c480ed
+
c480ed
+        /* We must never mkdir() in systemd's hierarchy */
c480ed
+        if (i == VIR_CGROUP_CONTROLLER_SYSTEMD) {
c480ed
+            VIR_DEBUG("Not creating systemd controller group");
c480ed
+            continue;
c480ed
+        }
c480ed
+
c480ed
+        /* Skip over controllers that aren't mounted */
c480ed
+        if (!group->controllers[i].mountPoint) {
c480ed
+            VIR_DEBUG("Skipping unmounted controller %s",
c480ed
+                      virCgroupV1ControllerTypeToString(i));
c480ed
+            continue;
c480ed
+        }
c480ed
+
c480ed
+        if (virCgroupV1PathOfController(group, i, "", &path) < 0)
c480ed
+            return -1;
c480ed
+
c480ed
+        VIR_DEBUG("Make controller %s", path);
c480ed
+        if (!virFileExists(path)) {
c480ed
+            if (!create ||
c480ed
+                mkdir(path, 0755) < 0) {
c480ed
+                if (errno == EEXIST)
c480ed
+                    continue;
c480ed
+                /* With a kernel that doesn't support multi-level directory
c480ed
+                 * for blkio controller, libvirt will fail and disable all
c480ed
+                 * other controllers even though they are available. So
c480ed
+                 * treat blkio as unmounted if mkdir fails. */
c480ed
+                if (i == VIR_CGROUP_CONTROLLER_BLKIO) {
c480ed
+                    VIR_DEBUG("Ignoring mkdir failure with blkio controller. Kernel probably too old");
c480ed
+                    VIR_FREE(group->controllers[i].mountPoint);
c480ed
+                    continue;
c480ed
+                } else {
c480ed
+                    virReportSystemError(errno,
c480ed
+                                         _("Failed to create v1 controller %s for group"),
c480ed
+                                         virCgroupV1ControllerTypeToString(i));
c480ed
+                    return -1;
c480ed
+                }
c480ed
+            }
c480ed
+            if (i == VIR_CGROUP_CONTROLLER_CPUSET &&
c480ed
+                group->controllers[i].mountPoint != NULL &&
c480ed
+                virCgroupV1CpuSetInherit(parent, group) < 0) {
c480ed
+                return -1;
c480ed
+            }
c480ed
+            /*
c480ed
+             * Note that virCgroupV1SetMemoryUseHierarchy should always be
c480ed
+             * called prior to creating subcgroups and attaching tasks.
c480ed
+             */
c480ed
+            if ((flags & VIR_CGROUP_MEM_HIERACHY) &&
c480ed
+                i == VIR_CGROUP_CONTROLLER_MEMORY &&
c480ed
+                group->controllers[i].mountPoint != NULL &&
c480ed
+                virCgroupV1SetMemoryUseHierarchy(group) < 0) {
c480ed
+                return -1;
c480ed
+            }
c480ed
+        }
c480ed
+    }
c480ed
+
c480ed
+    VIR_DEBUG("Done making controllers for group");
c480ed
+    return 0;
c480ed
+}
c480ed
+
c480ed
+
c480ed
 virCgroupBackend virCgroupV1Backend = {
c480ed
     .type = VIR_CGROUP_BACKEND_TYPE_V1,
c480ed
 
c480ed
@@ -552,6 +683,7 @@ virCgroupBackend virCgroupV1Backend = {
c480ed
     .hasController = virCgroupV1HasController,
c480ed
     .getAnyController = virCgroupV1GetAnyController,
c480ed
     .pathOfController = virCgroupV1PathOfController,
c480ed
+    .makeGroup = virCgroupV1MakeGroup,
c480ed
 };
c480ed
 
c480ed
 
c480ed
-- 
c480ed
2.22.0
c480ed