render / rpms / libvirt

Forked from rpms/libvirt 5 months ago
Clone
Pablo Greco 40546a
From 8b35858852e5c170410d4462fdf2bb19659b8894 Mon Sep 17 00:00:00 2001
Pablo Greco 40546a
Message-Id: <8b35858852e5c170410d4462fdf2bb19659b8894@dist-git>
Pablo Greco 40546a
From: Pavel Hrdina <phrdina@redhat.com>
Pablo Greco 40546a
Date: Mon, 1 Jul 2019 17:08:09 +0200
Pablo Greco 40546a
Subject: [PATCH] vircgroup: introduce virCgroupKillRecursiveCB
Pablo Greco 40546a
MIME-Version: 1.0
Pablo Greco 40546a
Content-Type: text/plain; charset=UTF-8
Pablo Greco 40546a
Content-Transfer-Encoding: 8bit
Pablo Greco 40546a
Pablo Greco 40546a
The rewrite to support cgroup v2 missed this function.  In cgroup v2
Pablo Greco 40546a
we have different files to track tasks.
Pablo Greco 40546a
Pablo Greco 40546a
We would fail to remove cgroup on non-systemd OSes if there is any
Pablo Greco 40546a
extra process assigned to guest cgroup because we would not kill any
Pablo Greco 40546a
process form the guest cgroup.
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Pablo Greco 40546a
(cherry picked from commit b532546823fde032fe827d41735a0d591c3bc0b8)
Pablo Greco 40546a
Pablo Greco 40546a
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1689297
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
Pablo Greco 40546a
Message-Id: <2414a178eb8aba977e7369bba0b37a18cdfec654.1561993100.git.phrdina@redhat.com>
Pablo Greco 40546a
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Pablo Greco 40546a
---
Pablo Greco 40546a
 src/util/vircgroup.c        | 69 ++++++++++++++++++++-----------------
Pablo Greco 40546a
 src/util/vircgroupbackend.h |  7 ++++
Pablo Greco 40546a
 src/util/vircgrouppriv.h    |  8 +++++
Pablo Greco 40546a
 src/util/vircgroupv1.c      | 16 +++++++++
Pablo Greco 40546a
 src/util/vircgroupv2.c      | 16 +++++++++
Pablo Greco 40546a
 5 files changed, 84 insertions(+), 32 deletions(-)
Pablo Greco 40546a
Pablo Greco 40546a
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
Pablo Greco 40546a
index 069f1ae396..736b5043a8 100644
Pablo Greco 40546a
--- a/src/util/vircgroup.c
Pablo Greco 40546a
+++ b/src/util/vircgroup.c
Pablo Greco 40546a
@@ -2431,33 +2431,15 @@ virCgroupRemove(virCgroupPtr group)
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-static int
Pablo Greco 40546a
-virCgroupPathOfAnyController(virCgroupPtr group,
Pablo Greco 40546a
-                             const char *name,
Pablo Greco 40546a
-                             char **keypath)
Pablo Greco 40546a
-{
Pablo Greco 40546a
-    size_t i;
Pablo Greco 40546a
-    int controller;
Pablo Greco 40546a
-
Pablo Greco 40546a
-    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
-        if (group->backends[i]) {
Pablo Greco 40546a
-            controller = group->backends[i]->getAnyController(group);
Pablo Greco 40546a
-            if (controller >= 0)
Pablo Greco 40546a
-                return virCgroupPathOfController(group, controller, name, keypath);
Pablo Greco 40546a
-        }
Pablo Greco 40546a
-    }
Pablo Greco 40546a
-
Pablo Greco 40546a
-    virReportSystemError(ENOSYS, "%s",
Pablo Greco 40546a
-                         _("No controllers are mounted"));
Pablo Greco 40546a
-    return -1;
Pablo Greco 40546a
-}
Pablo Greco 40546a
-
Pablo Greco 40546a
-
Pablo Greco 40546a
 /*
Pablo Greco 40546a
  * Returns 1 if some PIDs are killed, 0 if none are killed, or -1 on error
Pablo Greco 40546a
  */
Pablo Greco 40546a
 static int
Pablo Greco 40546a
-virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids)
Pablo Greco 40546a
+virCgroupKillInternal(virCgroupPtr group,
Pablo Greco 40546a
+                      int signum,
Pablo Greco 40546a
+                      virHashTablePtr pids,
Pablo Greco 40546a
+                      int controller,
Pablo Greco 40546a
+                      const char *taskFile)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     int ret = -1;
Pablo Greco 40546a
     bool killedAny = false;
Pablo Greco 40546a
@@ -2467,7 +2449,7 @@ virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids)
Pablo Greco 40546a
     VIR_DEBUG("group=%p path=%s signum=%d pids=%p",
Pablo Greco 40546a
               group, group->path, signum, pids);
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (virCgroupPathOfAnyController(group, "tasks", &keypath) < 0)
Pablo Greco 40546a
+    if (virCgroupPathOfController(group, controller, taskFile, &keypath) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     /* PIDs may be forking as we kill them, so loop
Pablo Greco 40546a
@@ -2553,10 +2535,12 @@ virCgroupPidCopy(const void *name)
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-static int
Pablo Greco 40546a
+int
Pablo Greco 40546a
 virCgroupKillRecursiveInternal(virCgroupPtr group,
Pablo Greco 40546a
                                int signum,
Pablo Greco 40546a
                                virHashTablePtr pids,
Pablo Greco 40546a
+                               int controller,
Pablo Greco 40546a
+                               const char *taskFile,
Pablo Greco 40546a
                                bool dormdir)
Pablo Greco 40546a
 {
Pablo Greco 40546a
     int ret = -1;
Pablo Greco 40546a
@@ -2570,11 +2554,13 @@ virCgroupKillRecursiveInternal(virCgroupPtr group,
Pablo Greco 40546a
     VIR_DEBUG("group=%p path=%s signum=%d pids=%p",
Pablo Greco 40546a
               group, group->path, signum, pids);
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if (virCgroupPathOfAnyController(group, "", &keypath) < 0)
Pablo Greco 40546a
+    if (virCgroupPathOfController(group, controller, "", &keypath) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    if ((rc = virCgroupKillInternal(group, signum, pids)) < 0)
Pablo Greco 40546a
+    if ((rc = virCgroupKillInternal(group, signum, pids,
Pablo Greco 40546a
+                                    controller, taskFile)) < 0) {
Pablo Greco 40546a
         goto cleanup;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
     if (rc == 1)
Pablo Greco 40546a
         killedAny = true;
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -2598,7 +2584,7 @@ virCgroupKillRecursiveInternal(virCgroupPtr group,
Pablo Greco 40546a
             goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
         if ((rc = virCgroupKillRecursiveInternal(subgroup, signum, pids,
Pablo Greco 40546a
-                                                 true)) < 0)
Pablo Greco 40546a
+                                                 controller, taskFile, true)) < 0)
Pablo Greco 40546a
             goto cleanup;
Pablo Greco 40546a
         if (rc == 1)
Pablo Greco 40546a
             killedAny = true;
Pablo Greco 40546a
@@ -2624,8 +2610,10 @@ virCgroupKillRecursiveInternal(virCgroupPtr group,
Pablo Greco 40546a
 int
Pablo Greco 40546a
 virCgroupKillRecursive(virCgroupPtr group, int signum)
Pablo Greco 40546a
 {
Pablo Greco 40546a
-    int ret;
Pablo Greco 40546a
-    VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum);
Pablo Greco 40546a
+    int ret = 0;
Pablo Greco 40546a
+    int rc;
Pablo Greco 40546a
+    size_t i;
Pablo Greco 40546a
+    virCgroupBackendPtr *backends = virCgroupBackendGetAll();
Pablo Greco 40546a
     virHashTablePtr pids = virHashCreateFull(100,
Pablo Greco 40546a
                                              NULL,
Pablo Greco 40546a
                                              virCgroupPidCode,
Pablo Greco 40546a
@@ -2633,10 +2621,27 @@ virCgroupKillRecursive(virCgroupPtr group, int signum)
Pablo Greco 40546a
                                              virCgroupPidCopy,
Pablo Greco 40546a
                                              NULL);
Pablo Greco 40546a
 
Pablo Greco 40546a
-    ret = virCgroupKillRecursiveInternal(group, signum, pids, false);
Pablo Greco 40546a
+    VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum);
Pablo Greco 40546a
 
Pablo Greco 40546a
+    if (!backends) {
Pablo Greco 40546a
+        ret = -1;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
Pablo Greco 40546a
+        if (backends[i]) {
Pablo Greco 40546a
+            rc = backends[i]->killRecursive(group, signum, pids);
Pablo Greco 40546a
+            if (rc < 0) {
Pablo Greco 40546a
+                ret = -1;
Pablo Greco 40546a
+                goto cleanup;
Pablo Greco 40546a
+            }
Pablo Greco 40546a
+            if (rc > 0)
Pablo Greco 40546a
+                ret = rc;
Pablo Greco 40546a
+        }
Pablo Greco 40546a
+    }
Pablo Greco 40546a
+
Pablo Greco 40546a
+ cleanup:
Pablo Greco 40546a
     virHashFree(pids);
Pablo Greco 40546a
-
Pablo Greco 40546a
     return ret;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
diff --git a/src/util/vircgroupbackend.h b/src/util/vircgroupbackend.h
Pablo Greco 40546a
index bc60b44643..a825dc4be7 100644
Pablo Greco 40546a
--- a/src/util/vircgroupbackend.h
Pablo Greco 40546a
+++ b/src/util/vircgroupbackend.h
Pablo Greco 40546a
@@ -24,6 +24,7 @@
Pablo Greco 40546a
 # include "internal.h"
Pablo Greco 40546a
 
Pablo Greco 40546a
 # include "vircgroup.h"
Pablo Greco 40546a
+# include "virhash.h"
Pablo Greco 40546a
 
Pablo Greco 40546a
 # define CGROUP_MAX_VAL 512
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -128,6 +129,11 @@ typedef int
Pablo Greco 40546a
 (*virCgroupHasEmptyTasksCB)(virCgroupPtr cgroup,
Pablo Greco 40546a
                             int controller);
Pablo Greco 40546a
 
Pablo Greco 40546a
+typedef int
Pablo Greco 40546a
+(*virCgroupKillRecursiveCB)(virCgroupPtr group,
Pablo Greco 40546a
+                            int signum,
Pablo Greco 40546a
+                            virHashTablePtr pids);
Pablo Greco 40546a
+
Pablo Greco 40546a
 typedef int
Pablo Greco 40546a
 (*virCgroupBindMountCB)(virCgroupPtr group,
Pablo Greco 40546a
                         const char *oldroot,
Pablo Greco 40546a
@@ -370,6 +376,7 @@ struct _virCgroupBackend {
Pablo Greco 40546a
     virCgroupRemoveCB remove;
Pablo Greco 40546a
     virCgroupAddTaskCB addTask;
Pablo Greco 40546a
     virCgroupHasEmptyTasksCB hasEmptyTasks;
Pablo Greco 40546a
+    virCgroupKillRecursiveCB killRecursive;
Pablo Greco 40546a
     virCgroupBindMountCB bindMount;
Pablo Greco 40546a
     virCgroupSetOwnerCB setOwner;
Pablo Greco 40546a
 
Pablo Greco 40546a
diff --git a/src/util/vircgrouppriv.h b/src/util/vircgrouppriv.h
Pablo Greco 40546a
index 8f24b0891e..6067f5cdc8 100644
Pablo Greco 40546a
--- a/src/util/vircgrouppriv.h
Pablo Greco 40546a
+++ b/src/util/vircgrouppriv.h
Pablo Greco 40546a
@@ -123,4 +123,12 @@ int virCgroupNewDomainPartition(virCgroupPtr partition,
Pablo Greco 40546a
 
Pablo Greco 40546a
 int virCgroupRemoveRecursively(char *grppath);
Pablo Greco 40546a
 
Pablo Greco 40546a
+
Pablo Greco 40546a
+int virCgroupKillRecursiveInternal(virCgroupPtr group,
Pablo Greco 40546a
+                                   int signum,
Pablo Greco 40546a
+                                   virHashTablePtr pids,
Pablo Greco 40546a
+                                   int controller,
Pablo Greco 40546a
+                                   const char *taskFile,
Pablo Greco 40546a
+                                   bool dormdir);
Pablo Greco 40546a
+
Pablo Greco 40546a
 #endif /* __VIR_CGROUP_PRIV_H__ */
Pablo Greco 40546a
diff --git a/src/util/vircgroupv1.c b/src/util/vircgroupv1.c
Pablo Greco 40546a
index 3147084f21..7098dc5644 100644
Pablo Greco 40546a
--- a/src/util/vircgroupv1.c
Pablo Greco 40546a
+++ b/src/util/vircgroupv1.c
Pablo Greco 40546a
@@ -758,6 +758,21 @@ virCgroupV1HasEmptyTasks(virCgroupPtr cgroup,
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
+static int
Pablo Greco 40546a
+virCgroupV1KillRecursive(virCgroupPtr group,
Pablo Greco 40546a
+                         int signum,
Pablo Greco 40546a
+                         virHashTablePtr pids)
Pablo Greco 40546a
+{
Pablo Greco 40546a
+    int controller = virCgroupV1GetAnyController(group);
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (controller < 0)
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return virCgroupKillRecursiveInternal(group, signum, pids, controller,
Pablo Greco 40546a
+                                          "tasks", false);
Pablo Greco 40546a
+}
Pablo Greco 40546a
+
Pablo Greco 40546a
+
Pablo Greco 40546a
 static char *
Pablo Greco 40546a
 virCgroupV1IdentifyRoot(virCgroupPtr group)
Pablo Greco 40546a
 {
Pablo Greco 40546a
@@ -2042,6 +2057,7 @@ virCgroupBackend virCgroupV1Backend = {
Pablo Greco 40546a
     .remove = virCgroupV1Remove,
Pablo Greco 40546a
     .addTask = virCgroupV1AddTask,
Pablo Greco 40546a
     .hasEmptyTasks = virCgroupV1HasEmptyTasks,
Pablo Greco 40546a
+    .killRecursive = virCgroupV1KillRecursive,
Pablo Greco 40546a
     .bindMount = virCgroupV1BindMount,
Pablo Greco 40546a
     .setOwner = virCgroupV1SetOwner,
Pablo Greco 40546a
 
Pablo Greco 40546a
diff --git a/src/util/vircgroupv2.c b/src/util/vircgroupv2.c
Pablo Greco 40546a
index bff2f78d7e..5652fcfffb 100644
Pablo Greco 40546a
--- a/src/util/vircgroupv2.c
Pablo Greco 40546a
+++ b/src/util/vircgroupv2.c
Pablo Greco 40546a
@@ -463,6 +463,21 @@ virCgroupV2HasEmptyTasks(virCgroupPtr cgroup,
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
+static int
Pablo Greco 40546a
+virCgroupV2KillRecursive(virCgroupPtr group,
Pablo Greco 40546a
+                         int signum,
Pablo Greco 40546a
+                         virHashTablePtr pids)
Pablo Greco 40546a
+{
Pablo Greco 40546a
+    int controller = virCgroupV2GetAnyController(group);
Pablo Greco 40546a
+
Pablo Greco 40546a
+    if (controller < 0)
Pablo Greco 40546a
+        return -1;
Pablo Greco 40546a
+
Pablo Greco 40546a
+    return virCgroupKillRecursiveInternal(group, signum, pids, controller,
Pablo Greco 40546a
+                                          "cgroup.threads", false);
Pablo Greco 40546a
+}
Pablo Greco 40546a
+
Pablo Greco 40546a
+
Pablo Greco 40546a
 static int
Pablo Greco 40546a
 virCgroupV2BindMount(virCgroupPtr group,
Pablo Greco 40546a
                      const char *oldroot,
Pablo Greco 40546a
@@ -1559,6 +1574,7 @@ virCgroupBackend virCgroupV2Backend = {
Pablo Greco 40546a
     .remove = virCgroupV2Remove,
Pablo Greco 40546a
     .addTask = virCgroupV2AddTask,
Pablo Greco 40546a
     .hasEmptyTasks = virCgroupV2HasEmptyTasks,
Pablo Greco 40546a
+    .killRecursive = virCgroupV2KillRecursive,
Pablo Greco 40546a
     .bindMount = virCgroupV2BindMount,
Pablo Greco 40546a
     .setOwner = virCgroupV2SetOwner,
Pablo Greco 40546a
 
Pablo Greco 40546a
-- 
Pablo Greco 40546a
2.22.0
Pablo Greco 40546a