Annotation of /trunk/systemd/patches/systemd-242-cgroup-util-kill-also-threads.patch
Parent Directory | Revision Log
Revision 3368 -
(hide annotations)
(download)
Tue Jul 9 11:20:22 2019 UTC (5 years, 2 months ago) by niro
File size: 3713 byte(s)
Tue Jul 9 11:20:22 2019 UTC (5 years, 2 months ago) by niro
File size: 3713 byte(s)
-added systemd-242 upstream patches
1 | niro | 3368 | From e48fcfef06d81bf08607d3c1657fdc6aa1e9a6ee Mon Sep 17 00:00:00 2001 |
2 | From: Topi Miettinen <toiwoton@gmail.com> | ||
3 | Date: Mon, 20 May 2019 12:20:58 +0300 | ||
4 | Subject: [PATCH] cgroup-util: kill also threads | ||
5 | |||
6 | It's possible for a zombie process to have live threads. These are not listed | ||
7 | in /sys in "cgroup.procs" for cgroupsv2, but they show up in | ||
8 | "cgroup.threads" (cgroupv2) or "tasks" (cgroupv1) nodes. When killing a | ||
9 | cgroup (v2 only) with SIGKILL, let's also kill threads after killing processes, | ||
10 | so the live threads of a zombie get killed too. | ||
11 | |||
12 | Closes #12262. | ||
13 | --- | ||
14 | src/basic/cgroup-util.c | 40 +++++++++++++++++++++++++++++++++++----- | ||
15 | 1 file changed, 35 insertions(+), 5 deletions(-) | ||
16 | |||
17 | diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c | ||
18 | index 156a360885d..60ce9b7d3a6 100644 | ||
19 | --- a/src/basic/cgroup-util.c | ||
20 | +++ b/src/basic/cgroup-util.c | ||
21 | @@ -43,14 +43,14 @@ | ||
22 | #include "unit-name.h" | ||
23 | #include "user-util.h" | ||
24 | |||
25 | -int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) { | ||
26 | +static int cg_enumerate_items(const char *controller, const char *path, FILE **_f, const char *item) { | ||
27 | _cleanup_free_ char *fs = NULL; | ||
28 | FILE *f; | ||
29 | int r; | ||
30 | |||
31 | assert(_f); | ||
32 | |||
33 | - r = cg_get_path(controller, path, "cgroup.procs", &fs); | ||
34 | + r = cg_get_path(controller, path, item, &fs); | ||
35 | if (r < 0) | ||
36 | return r; | ||
37 | |||
38 | @@ -62,6 +62,10 @@ int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | +int cg_enumerate_processes(const char *controller, const char *path, FILE **_f) { | ||
43 | + return cg_enumerate_items(controller, path, _f, "cgroup.procs"); | ||
44 | +} | ||
45 | + | ||
46 | int cg_read_pid(FILE *f, pid_t *_pid) { | ||
47 | unsigned long ul; | ||
48 | |||
49 | @@ -221,14 +225,15 @@ int cg_rmdir(const char *controller, const char *path) { | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | -int cg_kill( | ||
54 | +static int cg_kill_items( | ||
55 | const char *controller, | ||
56 | const char *path, | ||
57 | int sig, | ||
58 | CGroupFlags flags, | ||
59 | Set *s, | ||
60 | cg_kill_log_func_t log_kill, | ||
61 | - void *userdata) { | ||
62 | + void *userdata, | ||
63 | + const char *item) { | ||
64 | |||
65 | _cleanup_set_free_ Set *allocated_set = NULL; | ||
66 | bool done = false; | ||
67 | @@ -259,7 +264,7 @@ int cg_kill( | ||
68 | pid_t pid = 0; | ||
69 | done = true; | ||
70 | |||
71 | - r = cg_enumerate_processes(controller, path, &f); | ||
72 | + r = cg_enumerate_items(controller, path, &f, item); | ||
73 | if (r < 0) { | ||
74 | if (ret >= 0 && r != -ENOENT) | ||
75 | return r; | ||
76 | @@ -322,6 +327,31 @@ int cg_kill( | ||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | +int cg_kill( | ||
81 | + const char *controller, | ||
82 | + const char *path, | ||
83 | + int sig, | ||
84 | + CGroupFlags flags, | ||
85 | + Set *s, | ||
86 | + cg_kill_log_func_t log_kill, | ||
87 | + void *userdata) { | ||
88 | + int r; | ||
89 | + | ||
90 | + r = cg_kill_items(controller, path, sig, flags, s, log_kill, userdata, "cgroup.procs"); | ||
91 | + if (r < 0 || sig != SIGKILL) | ||
92 | + return r; | ||
93 | + | ||
94 | + /* Only in case of killing with SIGKILL and when using cgroupsv2, kill remaining threads manually as | ||
95 | + a workaround for kernel bug. It was fixed in 5.2-rc5 (c03cd7738a83). */ | ||
96 | + r = cg_unified_controller(controller); | ||
97 | + if (r < 0) | ||
98 | + return r; | ||
99 | + if (r == 0) /* doesn't apply to legacy hierarchy */ | ||
100 | + return 0; | ||
101 | + | ||
102 | + return cg_kill_items(controller, path, sig, flags, s, log_kill, userdata, "cgroup.threads"); | ||
103 | +} | ||
104 | + | ||
105 | int cg_kill_recursive( | ||
106 | const char *controller, | ||
107 | const char *path, |