]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cgroup: optionally check number of tasks before cgroup.kill
authorLuca Boccassi <luca.boccassi@gmail.com>
Thu, 28 May 2026 18:15:33 +0000 (19:15 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Thu, 28 May 2026 19:55:01 +0000 (20:55 +0100)
This of course cannot be atomic, but for informational purposes it
should be good enough

src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/core/unit.c

index 6a40ede29ed661f127fe8f8ab47175382f7771f2..aac0f035ebafdb2f3a3f51be66dde663fe955846 100644 (file)
@@ -406,8 +406,9 @@ int cg_kill_recursive(
         return ret;
 }
 
-int cg_kill_kernel_sigkill(const char *path) {
+int cg_kill_kernel_sigkill(const char *path, uint64_t *ret_n_pids_killed) {
         _cleanup_free_ char *killfile = NULL;
+        uint64_t n_pids = UINT64_MAX;
         int r;
 
         /* Kills the cgroup at `path` directly by writing to its cgroup.kill file.  This sends SIGKILL to all
@@ -422,10 +423,22 @@ int cg_kill_kernel_sigkill(const char *path) {
         if (r < 0)
                 return r;
 
+        if (ret_n_pids_killed) {
+                /* This is not and cannot be atomic so there is a chance the counter might not be accurate
+                 * if a process starts/stops between this read and the next write, but this is used for
+                 * informational purposes so that's ok. */
+                r = cg_get_attribute_as_uint64(path, "pids.current", &n_pids);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to read pids.current from cgroup '%s', ignoring: %m", path);
+        }
+
         r = write_string_file(killfile, "1", WRITE_STRING_FILE_DISABLE_BUFFER);
         if (r < 0)
                 return log_debug_errno(r, "Failed to write to cgroup.kill for cgroup '%s': %m", path);
 
+        if (ret_n_pids_killed)
+                *ret_n_pids_killed = n_pids;
+
         return 0;
 }
 
index 7cf0f779b8b95475bcc4c75e50485a81904e2242..2c438167f10eb05f7b66a7941211be23084570ad 100644 (file)
@@ -142,7 +142,7 @@ int cg_read_subgroup(DIR *d, char **ret);
 typedef int (*cg_kill_log_func_t)(const PidRef *pid, int sig, void *userdata);
 
 int cg_kill(const char *path, int sig, CGroupFlags flags, Set *killed_pids, cg_kill_log_func_t log_kill, void *userdata);
-int cg_kill_kernel_sigkill(const char *path);
+int cg_kill_kernel_sigkill(const char *path, uint64_t *ret_n_pids_killed);
 int cg_kill_recursive(const char *path, int sig, CGroupFlags flags, Set *killed_pids, cg_kill_log_func_t log_kill, void *userdata);
 
 int cg_split_spec(const char *spec, char **ret_controller, char **ret_path);
index d66f813a9a3de407898afe193b7e0fbc142bdbd5..b5a3951c969639baa52a4da9529b8bdfeee85743 100644 (file)
@@ -4158,7 +4158,7 @@ int unit_kill(
                         }
 
                         if (signo == SIGKILL) {
-                                r = cg_kill_kernel_sigkill(p);
+                                r = cg_kill_kernel_sigkill(p, /* ret_n_pids_killed= */ NULL);
                                 if (r >= 0) {
                                         killed = true;
                                         log_unit_info(u, "Killed unit cgroup '%s' with SIGKILL on client request.", p);