]>
Commit | Line | Data |
---|---|---|
86d92a68 JR |
1 | From ecedd90fcdf647f9a7b56b4934b65e30b2979b04 Mon Sep 17 00:00:00 2001 |
2 | From: Lennart Poettering <lennart@poettering.net> | |
3 | Date: Fri, 13 Apr 2012 21:24:47 +0000 | |
4 | Subject: service: place control command in subcgroup control/ | |
5 | ||
6 | Previously, we were brutally and onconditionally killing all processes | |
7 | in a service's cgroup before starting the service anew, in order to | |
8 | ensure that StartPre lines cannot be misused to spawn long-running | |
9 | processes. | |
10 | ||
11 | On logind-less systems this has the effect that restarting sshd | |
12 | necessarily calls all active ssh sessions, which is usually not | |
13 | desirable. | |
14 | ||
15 | With this patch control processes for a service are placed in a | |
16 | sub-cgroup called "control/". When starting a service anew we simply | |
17 | kill this cgroup, but not the main cgroup, in order to avoid killing any | |
18 | long-running non-control processes from previous runs. | |
19 | ||
20 | https://bugzilla.redhat.com/show_bug.cgi?id=805942 | |
21 | --- | |
22 | diff --git a/src/cgroup.c b/src/cgroup.c | |
23 | index ef9b02f..7a5f673 100644 | |
24 | --- a/src/cgroup.c | |
25 | +++ b/src/cgroup.c | |
26 | @@ -108,26 +108,43 @@ void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root) { | |
27 | cgroup_bonding_trim(b, delete_root); | |
28 | } | |
29 | ||
30 | -int cgroup_bonding_install(CGroupBonding *b, pid_t pid) { | |
31 | + | |
32 | +int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *cgroup_suffix) { | |
33 | + char *p = NULL; | |
34 | + const char *path; | |
35 | int r; | |
36 | ||
37 | assert(b); | |
38 | assert(pid >= 0); | |
39 | ||
40 | - if ((r = cg_create_and_attach(b->controller, b->path, pid)) < 0) | |
41 | + if (cgroup_suffix) { | |
42 | + p = join(b->path, "/", cgroup_suffix, NULL); | |
43 | + if (!p) | |
44 | + return -ENOMEM; | |
45 | + | |
46 | + path = p; | |
47 | + } else | |
48 | + path = b->path; | |
49 | + | |
50 | + r = cg_create_and_attach(b->controller, path, pid); | |
51 | + free(p); | |
52 | + | |
53 | + if (r < 0) | |
54 | return r; | |
55 | ||
56 | b->realized = true; | |
57 | return 0; | |
58 | } | |
59 | ||
60 | -int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid) { | |
61 | +int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid, const char *cgroup_suffix) { | |
62 | CGroupBonding *b; | |
63 | int r; | |
64 | ||
65 | - LIST_FOREACH(by_unit, b, first) | |
66 | - if ((r = cgroup_bonding_install(b, pid)) < 0 && b->essential) | |
67 | + LIST_FOREACH(by_unit, b, first) { | |
68 | + r = cgroup_bonding_install(b, pid, cgroup_suffix); | |
69 | + if (r < 0 && b->essential) | |
70 | return r; | |
71 | + } | |
72 | ||
73 | return 0; | |
74 | } | |
75 | @@ -176,7 +193,11 @@ int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t | |
76 | return 0; | |
77 | } | |
78 | ||
79 | -int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s) { | |
80 | +int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s, const char *cgroup_suffix) { | |
81 | + char *p = NULL; | |
82 | + const char *path; | |
83 | + int r; | |
84 | + | |
85 | assert(b); | |
86 | assert(sig >= 0); | |
87 | ||
88 | @@ -184,10 +205,22 @@ int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s) { | |
89 | if (!b->ours) | |
90 | return 0; | |
91 | ||
92 | - return cg_kill_recursive(b->controller, b->path, sig, sigcont, true, false, s); | |
93 | + if (cgroup_suffix) { | |
94 | + p = join(b->path, "/", cgroup_suffix, NULL); | |
95 | + if (!p) | |
96 | + return -ENOMEM; | |
97 | + | |
98 | + path = p; | |
99 | + } else | |
100 | + path = b->path; | |
101 | + | |
102 | + r = cg_kill_recursive(b->controller, path, sig, sigcont, true, false, s); | |
103 | + free(p); | |
104 | + | |
105 | + return r; | |
106 | } | |
107 | ||
108 | -int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s) { | |
109 | +int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s, const char *cgroup_suffix) { | |
110 | CGroupBonding *b; | |
111 | Set *allocated_set = NULL; | |
112 | int ret = -EAGAIN, r; | |
113 | @@ -200,7 +233,8 @@ int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s | |
114 | return -ENOMEM; | |
115 | ||
116 | LIST_FOREACH(by_unit, b, first) { | |
117 | - if ((r = cgroup_bonding_kill(b, sig, sigcont, s)) < 0) { | |
118 | + r = cgroup_bonding_kill(b, sig, sigcont, s, cgroup_suffix); | |
119 | + if (r < 0) { | |
120 | if (r == -EAGAIN || r == -ESRCH) | |
121 | continue; | |
122 | ||
123 | diff --git a/src/cgroup.h b/src/cgroup.h | |
124 | index de248fb..95f09e0 100644 | |
125 | --- a/src/cgroup.h | |
126 | +++ b/src/cgroup.h | |
127 | @@ -56,8 +56,8 @@ int cgroup_bonding_realize_list(CGroupBonding *first); | |
128 | void cgroup_bonding_free(CGroupBonding *b, bool trim); | |
129 | void cgroup_bonding_free_list(CGroupBonding *first, bool trim); | |
130 | ||
131 | -int cgroup_bonding_install(CGroupBonding *b, pid_t pid); | |
132 | -int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid); | |
133 | +int cgroup_bonding_install(CGroupBonding *b, pid_t pid, const char *suffix); | |
134 | +int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid, const char *suffix); | |
135 | ||
136 | int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); | |
137 | int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid); | |
138 | @@ -65,8 +65,8 @@ int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t ui | |
139 | int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky); | |
140 | int cgroup_bonding_set_task_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid, int sticky); | |
141 | ||
142 | -int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s); | |
143 | -int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s); | |
144 | +int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s, const char *suffix); | |
145 | +int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s, const char *suffix); | |
146 | ||
147 | void cgroup_bonding_trim(CGroupBonding *first, bool delete_root); | |
148 | void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root); | |
149 | diff --git a/src/execute.c b/src/execute.c | |
150 | index 271c57f..c59f7e2 100644 | |
151 | --- a/src/execute.c | |
152 | +++ b/src/execute.c | |
153 | @@ -962,6 +962,7 @@ int exec_spawn(ExecCommand *command, | |
154 | bool confirm_spawn, | |
155 | CGroupBonding *cgroup_bondings, | |
156 | CGroupAttribute *cgroup_attributes, | |
157 | + const char *cgroup_suffix, | |
158 | pid_t *ret) { | |
159 | ||
160 | pid_t pid; | |
161 | @@ -1154,7 +1155,7 @@ int exec_spawn(ExecCommand *command, | |
162 | } | |
163 | ||
164 | if (cgroup_bondings) { | |
165 | - err = cgroup_bonding_install_list(cgroup_bondings, 0); | |
166 | + err = cgroup_bonding_install_list(cgroup_bondings, 0, cgroup_suffix); | |
167 | if (err < 0) { | |
168 | r = EXIT_CGROUP; | |
169 | goto fail_child; | |
170 | @@ -1505,7 +1506,7 @@ int exec_spawn(ExecCommand *command, | |
171 | * sure that when we kill the cgroup the process will be | |
172 | * killed too). */ | |
173 | if (cgroup_bondings) | |
174 | - cgroup_bonding_install_list(cgroup_bondings, pid); | |
175 | + cgroup_bonding_install_list(cgroup_bondings, pid, cgroup_suffix); | |
176 | ||
177 | log_debug("Forked %s as %lu", command->path, (unsigned long) pid); | |
178 | ||
179 | diff --git a/src/execute.h b/src/execute.h | |
180 | index fc4c71e..428bb7c 100644 | |
181 | --- a/src/execute.h | |
182 | +++ b/src/execute.h | |
183 | @@ -192,6 +192,7 @@ int exec_spawn(ExecCommand *command, | |
184 | bool confirm_spawn, | |
185 | struct CGroupBonding *cgroup_bondings, | |
186 | struct CGroupAttribute *cgroup_attributes, | |
187 | + const char *cgroup_suffix, | |
188 | pid_t *ret); | |
189 | ||
190 | void exec_command_done(ExecCommand *c); | |
191 | diff --git a/src/mount.c b/src/mount.c | |
192 | index 6c768a3..760ffcd 100644 | |
193 | --- a/src/mount.c | |
194 | +++ b/src/mount.c | |
195 | @@ -805,6 +805,7 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { | |
196 | UNIT(m)->manager->confirm_spawn, | |
197 | UNIT(m)->cgroup_bondings, | |
198 | UNIT(m)->cgroup_attributes, | |
199 | + NULL, | |
200 | &pid)) < 0) | |
201 | goto fail; | |
202 | ||
203 | @@ -875,7 +876,8 @@ static void mount_enter_signal(Mount *m, MountState state, MountResult f) { | |
204 | if ((r = set_put(pid_set, LONG_TO_PTR(m->control_pid))) < 0) | |
205 | goto fail; | |
206 | ||
207 | - if ((r = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, sig, true, pid_set)) < 0) { | |
208 | + r = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, sig, true, pid_set, NULL); | |
209 | + if (r < 0) { | |
210 | if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) | |
211 | log_warning("Failed to kill control group: %s", strerror(-r)); | |
212 | } else if (r > 0) | |
213 | @@ -1833,7 +1835,8 @@ static int mount_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError | |
214 | goto finish; | |
215 | } | |
216 | ||
217 | - if ((q = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, signo, false, pid_set)) < 0) | |
218 | + q = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, signo, false, pid_set, NULL); | |
219 | + if (q < 0) | |
220 | if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) | |
221 | r = q; | |
222 | } | |
223 | diff --git a/src/service.c b/src/service.c | |
224 | index 1c04ed3..59dd712 100644 | |
225 | --- a/src/service.c | |
226 | +++ b/src/service.c | |
227 | @@ -1686,6 +1686,7 @@ static int service_spawn( | |
228 | bool apply_chroot, | |
229 | bool apply_tty_stdin, | |
230 | bool set_notify_socket, | |
231 | + bool is_control, | |
232 | pid_t *_pid) { | |
233 | ||
234 | pid_t pid; | |
235 | @@ -1767,6 +1768,7 @@ static int service_spawn( | |
236 | UNIT(s)->manager->confirm_spawn, | |
237 | UNIT(s)->cgroup_bondings, | |
238 | UNIT(s)->cgroup_attributes, | |
239 | + is_control ? "control" : NULL, | |
240 | &pid); | |
241 | ||
242 | if (r < 0) | |
243 | @@ -1886,15 +1888,17 @@ static void service_enter_stop_post(Service *s, ServiceResult f) { | |
244 | if ((s->control_command = s->exec_command[SERVICE_EXEC_STOP_POST])) { | |
245 | s->control_command_id = SERVICE_EXEC_STOP_POST; | |
246 | ||
247 | - if ((r = service_spawn(s, | |
248 | - s->control_command, | |
249 | - true, | |
250 | - false, | |
251 | - !s->permissions_start_only, | |
252 | - !s->root_directory_start_only, | |
253 | - true, | |
254 | - false, | |
255 | - &s->control_pid)) < 0) | |
256 | + r = service_spawn(s, | |
257 | + s->control_command, | |
258 | + true, | |
259 | + false, | |
260 | + !s->permissions_start_only, | |
261 | + !s->root_directory_start_only, | |
262 | + true, | |
263 | + false, | |
264 | + true, | |
265 | + &s->control_pid); | |
266 | + if (r < 0) | |
267 | goto fail; | |
268 | ||
269 | ||
270 | @@ -1952,7 +1956,8 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f | |
271 | if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) | |
272 | goto fail; | |
273 | ||
274 | - if ((r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set)) < 0) { | |
275 | + r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set, NULL); | |
276 | + if (r < 0) { | |
277 | if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) | |
278 | log_warning("Failed to kill control group: %s", strerror(-r)); | |
279 | } else if (r > 0) | |
280 | @@ -2001,15 +2006,17 @@ static void service_enter_stop(Service *s, ServiceResult f) { | |
281 | if ((s->control_command = s->exec_command[SERVICE_EXEC_STOP])) { | |
282 | s->control_command_id = SERVICE_EXEC_STOP; | |
283 | ||
284 | - if ((r = service_spawn(s, | |
285 | - s->control_command, | |
286 | - true, | |
287 | - false, | |
288 | - !s->permissions_start_only, | |
289 | - !s->root_directory_start_only, | |
290 | - false, | |
291 | - false, | |
292 | - &s->control_pid)) < 0) | |
293 | + r = service_spawn(s, | |
294 | + s->control_command, | |
295 | + true, | |
296 | + false, | |
297 | + !s->permissions_start_only, | |
298 | + !s->root_directory_start_only, | |
299 | + false, | |
300 | + false, | |
301 | + true, | |
302 | + &s->control_pid); | |
303 | + if (r < 0) | |
304 | goto fail; | |
305 | ||
306 | service_set_state(s, SERVICE_STOP); | |
307 | @@ -2054,15 +2061,17 @@ static void service_enter_start_post(Service *s) { | |
308 | if ((s->control_command = s->exec_command[SERVICE_EXEC_START_POST])) { | |
309 | s->control_command_id = SERVICE_EXEC_START_POST; | |
310 | ||
311 | - if ((r = service_spawn(s, | |
312 | - s->control_command, | |
313 | - true, | |
314 | - false, | |
315 | - !s->permissions_start_only, | |
316 | - !s->root_directory_start_only, | |
317 | - false, | |
318 | - false, | |
319 | - &s->control_pid)) < 0) | |
320 | + r = service_spawn(s, | |
321 | + s->control_command, | |
322 | + true, | |
323 | + false, | |
324 | + !s->permissions_start_only, | |
325 | + !s->root_directory_start_only, | |
326 | + false, | |
327 | + false, | |
328 | + true, | |
329 | + &s->control_pid); | |
330 | + if (r < 0) | |
331 | goto fail; | |
332 | ||
333 | service_set_state(s, SERVICE_START_POST); | |
334 | @@ -2094,7 +2103,7 @@ static void service_enter_start(Service *s) { | |
335 | /* We want to ensure that nobody leaks processes from | |
336 | * START_PRE here, so let's go on a killing spree, People | |
337 | * should not spawn long running processes from START_PRE. */ | |
338 | - cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, NULL); | |
339 | + cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, NULL, "control"); | |
340 | ||
341 | if (s->type == SERVICE_FORKING) { | |
342 | s->control_command_id = SERVICE_EXEC_START; | |
343 | @@ -2108,15 +2117,17 @@ static void service_enter_start(Service *s) { | |
344 | c = s->main_command = s->exec_command[SERVICE_EXEC_START]; | |
345 | } | |
346 | ||
347 | - if ((r = service_spawn(s, | |
348 | - c, | |
349 | - s->type == SERVICE_FORKING || s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY, | |
350 | - true, | |
351 | - true, | |
352 | - true, | |
353 | - true, | |
354 | - s->notify_access != NOTIFY_NONE, | |
355 | - &pid)) < 0) | |
356 | + r = service_spawn(s, | |
357 | + c, | |
358 | + s->type == SERVICE_FORKING || s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY, | |
359 | + true, | |
360 | + true, | |
361 | + true, | |
362 | + true, | |
363 | + s->notify_access != NOTIFY_NONE, | |
364 | + false, | |
365 | + &pid); | |
366 | + if (r < 0) | |
367 | goto fail; | |
368 | ||
369 | if (s->type == SERVICE_SIMPLE) { | |
370 | @@ -2168,19 +2179,21 @@ static void service_enter_start_pre(Service *s) { | |
371 | ||
372 | /* Before we start anything, let's clear up what might | |
373 | * be left from previous runs. */ | |
374 | - cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, NULL); | |
375 | + cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, SIGKILL, true, NULL, "control"); | |
376 | ||
377 | s->control_command_id = SERVICE_EXEC_START_PRE; | |
378 | ||
379 | - if ((r = service_spawn(s, | |
380 | - s->control_command, | |
381 | - true, | |
382 | - false, | |
383 | - !s->permissions_start_only, | |
384 | - !s->root_directory_start_only, | |
385 | - true, | |
386 | - false, | |
387 | - &s->control_pid)) < 0) | |
388 | + r = service_spawn(s, | |
389 | + s->control_command, | |
390 | + true, | |
391 | + false, | |
392 | + !s->permissions_start_only, | |
393 | + !s->root_directory_start_only, | |
394 | + true, | |
395 | + false, | |
396 | + true, | |
397 | + &s->control_pid); | |
398 | + if (r < 0) | |
399 | goto fail; | |
400 | ||
401 | service_set_state(s, SERVICE_START_PRE); | |
402 | @@ -2236,15 +2249,17 @@ static void service_enter_reload(Service *s) { | |
403 | if ((s->control_command = s->exec_command[SERVICE_EXEC_RELOAD])) { | |
404 | s->control_command_id = SERVICE_EXEC_RELOAD; | |
405 | ||
406 | - if ((r = service_spawn(s, | |
407 | - s->control_command, | |
408 | - true, | |
409 | - false, | |
410 | - !s->permissions_start_only, | |
411 | - !s->root_directory_start_only, | |
412 | - false, | |
413 | - false, | |
414 | - &s->control_pid)) < 0) | |
415 | + r = service_spawn(s, | |
416 | + s->control_command, | |
417 | + true, | |
418 | + false, | |
419 | + !s->permissions_start_only, | |
420 | + !s->root_directory_start_only, | |
421 | + false, | |
422 | + false, | |
423 | + true, | |
424 | + &s->control_pid); | |
425 | + if (r < 0) | |
426 | goto fail; | |
427 | ||
428 | service_set_state(s, SERVICE_RELOAD); | |
429 | @@ -2271,16 +2286,18 @@ static void service_run_next_control(Service *s) { | |
430 | s->control_command = s->control_command->command_next; | |
431 | service_unwatch_control_pid(s); | |
432 | ||
433 | - if ((r = service_spawn(s, | |
434 | - s->control_command, | |
435 | - true, | |
436 | - false, | |
437 | - !s->permissions_start_only, | |
438 | - !s->root_directory_start_only, | |
439 | - s->control_command_id == SERVICE_EXEC_START_PRE || | |
440 | - s->control_command_id == SERVICE_EXEC_STOP_POST, | |
441 | - false, | |
442 | - &s->control_pid)) < 0) | |
443 | + r = service_spawn(s, | |
444 | + s->control_command, | |
445 | + true, | |
446 | + false, | |
447 | + !s->permissions_start_only, | |
448 | + !s->root_directory_start_only, | |
449 | + s->control_command_id == SERVICE_EXEC_START_PRE || | |
450 | + s->control_command_id == SERVICE_EXEC_STOP_POST, | |
451 | + false, | |
452 | + true, | |
453 | + &s->control_pid); | |
454 | + if (r < 0) | |
455 | goto fail; | |
456 | ||
457 | return; | |
458 | @@ -2313,15 +2330,17 @@ static void service_run_next_main(Service *s) { | |
459 | s->main_command = s->main_command->command_next; | |
460 | service_unwatch_main_pid(s); | |
461 | ||
462 | - if ((r = service_spawn(s, | |
463 | - s->main_command, | |
464 | - false, | |
465 | - true, | |
466 | - true, | |
467 | - true, | |
468 | - true, | |
469 | - s->notify_access != NOTIFY_NONE, | |
470 | - &pid)) < 0) | |
471 | + r = service_spawn(s, | |
472 | + s->main_command, | |
473 | + false, | |
474 | + true, | |
475 | + true, | |
476 | + true, | |
477 | + true, | |
478 | + s->notify_access != NOTIFY_NONE, | |
479 | + false, | |
480 | + &pid); | |
481 | + if (r < 0) | |
482 | goto fail; | |
483 | ||
484 | service_set_main_pid(s, pid); | |
485 | @@ -3647,8 +3666,8 @@ static int service_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusErro | |
486 | r = q; | |
487 | goto finish; | |
488 | } | |
489 | - | |
490 | - if ((q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set)) < 0) | |
491 | + q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set, NULL); | |
492 | + if (q < 0) | |
493 | if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) | |
494 | r = q; | |
495 | } | |
496 | diff --git a/src/socket.c b/src/socket.c | |
497 | index 37a0236..a439717 100644 | |
498 | --- a/src/socket.c | |
499 | +++ b/src/socket.c | |
500 | @@ -1150,6 +1150,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) { | |
501 | UNIT(s)->manager->confirm_spawn, | |
502 | UNIT(s)->cgroup_bondings, | |
503 | UNIT(s)->cgroup_attributes, | |
504 | + NULL, | |
505 | &pid); | |
506 | ||
507 | strv_free(argv); | |
508 | @@ -1240,7 +1241,8 @@ static void socket_enter_signal(Socket *s, SocketState state, SocketResult f) { | |
509 | if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) | |
510 | goto fail; | |
511 | ||
512 | - if ((r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set)) < 0) { | |
513 | + r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set, NULL); | |
514 | + if (r < 0) { | |
515 | if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) | |
516 | log_warning("Failed to kill control group: %s", strerror(-r)); | |
517 | } else if (r > 0) | |
518 | @@ -2127,7 +2129,8 @@ static int socket_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError | |
519 | goto finish; | |
520 | } | |
521 | ||
522 | - if ((q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set)) < 0) | |
523 | + q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set, NULL); | |
524 | + if (q < 0) | |
525 | if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) | |
526 | r = q; | |
527 | } | |
528 | diff --git a/src/swap.c b/src/swap.c | |
529 | index 6331864..363852d 100644 | |
530 | --- a/src/swap.c | |
531 | +++ b/src/swap.c | |
532 | @@ -621,6 +621,7 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) { | |
533 | UNIT(s)->manager->confirm_spawn, | |
534 | UNIT(s)->cgroup_bondings, | |
535 | UNIT(s)->cgroup_attributes, | |
536 | + NULL, | |
537 | &pid)) < 0) | |
538 | goto fail; | |
539 | ||
540 | @@ -690,7 +691,8 @@ static void swap_enter_signal(Swap *s, SwapState state, SwapResult f) { | |
541 | if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) | |
542 | goto fail; | |
543 | ||
544 | - if ((r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set)) < 0) { | |
545 | + r = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, sig, true, pid_set, NULL); | |
546 | + if (r < 0) { | |
547 | if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) | |
548 | log_warning("Failed to kill control group: %s", strerror(-r)); | |
549 | } else if (r > 0) | |
550 | @@ -1321,7 +1323,8 @@ static int swap_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError * | |
551 | goto finish; | |
552 | } | |
553 | ||
554 | - if ((q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set)) < 0) | |
555 | + q = cgroup_bonding_kill_list(UNIT(s)->cgroup_bondings, signo, false, pid_set, NULL); | |
556 | + if (q < 0) | |
557 | if (q != -EAGAIN && q != -ESRCH && q != -ENOENT) | |
558 | r = q; | |
559 | } | |
560 | -- | |
561 | cgit v0.9.0.2-2-gbebe |