This is an automated email from the ASF dual-hosted git repository.

bmahler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git


The following commit(s) were added to refs/heads/master by this push:
     new 756b7d7ff [cgroups2] Introduced API to kill the processes inside of 
cgroup subtree.
756b7d7ff is described below

commit 756b7d7ff9465cdf5758584e864a5b0444b14e16
Author: Devin Leamy <[email protected]>
AuthorDate: Fri Apr 5 17:14:28 2024 -0400

    [cgroups2] Introduced API to kill the processes inside of cgroup subtree.
    
    Introduces
    ```
            cgroups2::kill(cgroup)
    ```
    which will recursively kill all of the cgroups in a subtree.
    
    We additionally update `cgroups::destroy` to use `cgroups::kill` such that
    it now completely destroys a cgroup (i.e. all directories processes).
    
    This closes #550
---
 src/linux/cgroups2.cpp                     | 38 ++++++++++++++++++++++++++----
 src/linux/cgroups2.hpp                     |  9 +++++--
 src/tests/containerizer/cgroups2_tests.cpp |  6 -----
 3 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/src/linux/cgroups2.cpp b/src/linux/cgroups2.cpp
index 8b401a178..b5e4babe9 100644
--- a/src/linux/cgroups2.cpp
+++ b/src/linux/cgroups2.cpp
@@ -360,16 +360,46 @@ Try<Nothing> create(const string& cgroup, bool recursive)
 }
 
 
+Try<Nothing> kill(const std::string& cgroup)
+{
+  if (!cgroups2::exists(cgroup)) {
+    return Error("Cgroup does not exist");
+  }
+
+  return cgroups2::write(cgroup, cgroups2::control::KILL, "1");
+}
+
+
 Try<Nothing> destroy(const string& cgroup)
 {
   if (!cgroups2::exists(cgroup)) {
     return Error("Cgroup '" + cgroup + "' does not exist");
   }
 
-  const string path = cgroups2::path(cgroup);
-  Try<Nothing> rmdir = os::rmdir(path, false);
-  if (rmdir.isError()) {
-    return Error("Failed to remove directory '" + path + "': " + 
rmdir.error());
+  // To destroy a subtree of cgroups we first kill all of the processes inside
+  // of the cgroup and then remove all of the cgroup directories, removing
+  // the most deeply nested directories first.
+  Try<Nothing> kill = cgroups2::kill(cgroup);
+  if (kill.isError()) {
+    return Error("Failed to kill processes in cgroup");
+  }
+
+  Try<set<string>> cgroups = cgroups2::get(cgroup);
+  if (cgroups.isError()) {
+    return Error("Failed to get nested cgroups: " + cgroups.error());
+  }
+
+  vector<string> sorted(cgroups->begin(), cgroups->end());
+  sorted.push_back(cgroup);
+  std::sort(sorted.rbegin(), sorted.rend());
+
+  foreach (const string& cgroup, sorted) {
+    const string& path = cgroups2::path(cgroup);
+    Try<Nothing> rmdir = os::rmdir(path, false);
+    if (rmdir.isError()) {
+      return Error(
+          "Failed to remove directory '" + path + "': " + rmdir.error());
+    }
   }
 
   return Nothing();
diff --git a/src/linux/cgroups2.hpp b/src/linux/cgroups2.hpp
index 3a31ca0da..e4f482405 100644
--- a/src/linux/cgroups2.hpp
+++ b/src/linux/cgroups2.hpp
@@ -69,8 +69,13 @@ Try<std::set<std::string>> get(const std::string& cgroup = 
ROOT_CGROUP);
 Try<Nothing> create(const std::string& cgroup, bool recursive = false);
 
 
-// Destroy a cgroup. If the cgroup does not exist or cannot be destroyed,
-// e.g. because it contains processes, an error is returned.
+// Recursively kill all of the processes inside of a cgroup and all child
+// cgroups with SIGKILL.
+Try<Nothing> kill(const std::string& cgroup);
+
+
+// Recursively destroy a cgroup and all nested cgroups. Processes inside of
+// destroyed cgroups are killed with SIGKILL.
 Try<Nothing> destroy(const std::string& cgroup);
 
 
diff --git a/src/tests/containerizer/cgroups2_tests.cpp 
b/src/tests/containerizer/cgroups2_tests.cpp
index cddf2e428..5c0a3e7b2 100644
--- a/src/tests/containerizer/cgroups2_tests.cpp
+++ b/src/tests/containerizer/cgroups2_tests.cpp
@@ -360,12 +360,6 @@ TEST_F(Cgroups2Test, ROOT_CGROUPS2_GetCgroups)
         path::join(TEST_CGROUP, "test1/b/c")
       }),
       cgroups2::get(path::join(TEST_CGROUP, "test1/b")));
-
-  // Destroy the cgroups in reverse order so the most deeply-nested cgroups
-  // are removed first.
-  for (int i = cgroups.size() - 1; i >= 0; --i) {
-    ASSERT_SOME(cgroups2::destroy(cgroups[i]));
-  }
 }
 
 

Reply via email to