]> xenbits.xensource.com Git - libvirt.git/commitdiff
vircgroup: introduce virCgroupKillRecursiveCB
authorPavel Hrdina <phrdina@redhat.com>
Mon, 10 Dec 2018 08:51:14 +0000 (16:51 +0800)
committerPavel Hrdina <phrdina@redhat.com>
Fri, 14 Dec 2018 03:27:18 +0000 (11:27 +0800)
The rewrite to support cgroup v2 missed this function.  In cgroup v2
we have different files to track tasks.

We would fail to remove cgroup on non-systemd OSes if there is any
extra process assigned to guest cgroup because we would not kill any
process form the guest cgroup.

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

index 3b41dfd99d81f0fc6a177a52d811f8b2b1cf0500..7aca8b8a1acf27c912b52aba347f0cc224c1557e 100644 (file)
@@ -2424,33 +2424,15 @@ virCgroupRemove(virCgroupPtr group)
 }
 
 
-static int
-virCgroupPathOfAnyController(virCgroupPtr group,
-                             const char *name,
-                             char **keypath)
-{
-    size_t i;
-    int controller;
-
-    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
-        if (group->backends[i]) {
-            controller = group->backends[i]->getAnyController(group);
-            if (controller >= 0)
-                return virCgroupPathOfController(group, controller, name, keypath);
-        }
-    }
-
-    virReportSystemError(ENOSYS, "%s",
-                         _("No controllers are mounted"));
-    return -1;
-}
-
-
 /*
  * Returns 1 if some PIDs are killed, 0 if none are killed, or -1 on error
  */
 static int
-virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids)
+virCgroupKillInternal(virCgroupPtr group,
+                      int signum,
+                      virHashTablePtr pids,
+                      int controller,
+                      const char *taskFile)
 {
     int ret = -1;
     bool killedAny = false;
@@ -2460,7 +2442,7 @@ virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids)
     VIR_DEBUG("group=%p path=%s signum=%d pids=%p",
               group, group->path, signum, pids);
 
-    if (virCgroupPathOfAnyController(group, "tasks", &keypath) < 0)
+    if (virCgroupPathOfController(group, controller, taskFile, &keypath) < 0)
         return -1;
 
     /* PIDs may be forking as we kill them, so loop
@@ -2546,10 +2528,12 @@ virCgroupPidCopy(const void *name)
 }
 
 
-static int
+int
 virCgroupKillRecursiveInternal(virCgroupPtr group,
                                int signum,
                                virHashTablePtr pids,
+                               int controller,
+                               const char *taskFile,
                                bool dormdir)
 {
     int ret = -1;
@@ -2563,11 +2547,13 @@ virCgroupKillRecursiveInternal(virCgroupPtr group,
     VIR_DEBUG("group=%p path=%s signum=%d pids=%p",
               group, group->path, signum, pids);
 
-    if (virCgroupPathOfAnyController(group, "", &keypath) < 0)
+    if (virCgroupPathOfController(group, controller, "", &keypath) < 0)
         return -1;
 
-    if ((rc = virCgroupKillInternal(group, signum, pids)) < 0)
+    if ((rc = virCgroupKillInternal(group, signum, pids,
+                                    controller, taskFile)) < 0) {
         goto cleanup;
+    }
     if (rc == 1)
         killedAny = true;
 
@@ -2591,7 +2577,7 @@ virCgroupKillRecursiveInternal(virCgroupPtr group,
             goto cleanup;
 
         if ((rc = virCgroupKillRecursiveInternal(subgroup, signum, pids,
-                                                 true)) < 0)
+                                                 controller, taskFile, true)) < 0)
             goto cleanup;
         if (rc == 1)
             killedAny = true;
@@ -2617,8 +2603,10 @@ virCgroupKillRecursiveInternal(virCgroupPtr group,
 int
 virCgroupKillRecursive(virCgroupPtr group, int signum)
 {
-    int ret;
-    VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum);
+    int ret = 0;
+    int rc;
+    size_t i;
+    virCgroupBackendPtr *backends = virCgroupBackendGetAll();
     virHashTablePtr pids = virHashCreateFull(100,
                                              NULL,
                                              virCgroupPidCode,
@@ -2626,10 +2614,27 @@ virCgroupKillRecursive(virCgroupPtr group, int signum)
                                              virCgroupPidCopy,
                                              NULL);
 
-    ret = virCgroupKillRecursiveInternal(group, signum, pids, false);
+    VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum);
 
-    virHashFree(pids);
+    if (!backends) {
+        ret = -1;
+        goto cleanup;
+    }
 
+    for (i = 0; i < VIR_CGROUP_BACKEND_TYPE_LAST; i++) {
+        if (backends[i]) {
+            rc = backends[i]->killRecursive(group, signum, pids);
+            if (rc < 0) {
+                ret = -1;
+                goto cleanup;
+            }
+            if (rc > 0)
+                ret = rc;
+        }
+    }
+
+ cleanup:
+    virHashFree(pids);
     return ret;
 }
 
index bc60b446434869ce682210b057b1173f3b7238b4..a825dc4be7a1344d2527df6bc646438027c8ca47 100644 (file)
@@ -24,6 +24,7 @@
 # include "internal.h"
 
 # include "vircgroup.h"
+# include "virhash.h"
 
 # define CGROUP_MAX_VAL 512
 
@@ -128,6 +129,11 @@ typedef int
 (*virCgroupHasEmptyTasksCB)(virCgroupPtr cgroup,
                             int controller);
 
+typedef int
+(*virCgroupKillRecursiveCB)(virCgroupPtr group,
+                            int signum,
+                            virHashTablePtr pids);
+
 typedef int
 (*virCgroupBindMountCB)(virCgroupPtr group,
                         const char *oldroot,
@@ -370,6 +376,7 @@ struct _virCgroupBackend {
     virCgroupRemoveCB remove;
     virCgroupAddTaskCB addTask;
     virCgroupHasEmptyTasksCB hasEmptyTasks;
+    virCgroupKillRecursiveCB killRecursive;
     virCgroupBindMountCB bindMount;
     virCgroupSetOwnerCB setOwner;
 
index 3bede28bd2c753639858a9eab7aa75f25ee0b26b..b166b26eee452d642ad93f1a2f547723019860b9 100644 (file)
@@ -120,4 +120,12 @@ int virCgroupNewDomainPartition(virCgroupPtr partition,
 
 int virCgroupRemoveRecursively(char *grppath);
 
+
+int virCgroupKillRecursiveInternal(virCgroupPtr group,
+                                   int signum,
+                                   virHashTablePtr pids,
+                                   int controller,
+                                   const char *taskFile,
+                                   bool dormdir);
+
 #endif /* __VIR_CGROUP_PRIV_H__ */
index ab1a2870a3ed0fcd96bb90a5e881859bd71b5722..45378be34ba940a0b15564235d53beac7670b5d4 100644 (file)
@@ -757,6 +757,21 @@ virCgroupV1HasEmptyTasks(virCgroupPtr cgroup,
 }
 
 
+static int
+virCgroupV1KillRecursive(virCgroupPtr group,
+                         int signum,
+                         virHashTablePtr pids)
+{
+    int controller = virCgroupV1GetAnyController(group);
+
+    if (controller < 0)
+        return -1;
+
+    return virCgroupKillRecursiveInternal(group, signum, pids, controller,
+                                          "tasks", false);
+}
+
+
 static char *
 virCgroupV1IdentifyRoot(virCgroupPtr group)
 {
@@ -2041,6 +2056,7 @@ virCgroupBackend virCgroupV1Backend = {
     .remove = virCgroupV1Remove,
     .addTask = virCgroupV1AddTask,
     .hasEmptyTasks = virCgroupV1HasEmptyTasks,
+    .killRecursive = virCgroupV1KillRecursive,
     .bindMount = virCgroupV1BindMount,
     .setOwner = virCgroupV1SetOwner,
 
index 85aa62bd4cba2145333684cf569f0d99a0139716..dc2b2a65bcbb4987b52ce82df98a0f0e6ec7b0b5 100644 (file)
@@ -462,6 +462,21 @@ virCgroupV2HasEmptyTasks(virCgroupPtr cgroup,
 }
 
 
+static int
+virCgroupV2KillRecursive(virCgroupPtr group,
+                         int signum,
+                         virHashTablePtr pids)
+{
+    int controller = virCgroupV2GetAnyController(group);
+
+    if (controller < 0)
+        return -1;
+
+    return virCgroupKillRecursiveInternal(group, signum, pids, controller,
+                                          "cgroup.threads", false);
+}
+
+
 static int
 virCgroupV2BindMount(virCgroupPtr group,
                      const char *oldroot,
@@ -1558,6 +1573,7 @@ virCgroupBackend virCgroupV2Backend = {
     .remove = virCgroupV2Remove,
     .addTask = virCgroupV2AddTask,
     .hasEmptyTasks = virCgroupV2HasEmptyTasks,
+    .killRecursive = virCgroupV2KillRecursive,
     .bindMount = virCgroupV2BindMount,
     .setOwner = virCgroupV2SetOwner,