Line data Source code
1 : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2 :
3 : /***
4 : This file is part of systemd.
5 :
6 : Copyright 2013 Lennart Poettering
7 :
8 : systemd is free software; you can redistribute it and/or modify it
9 : under the terms of the GNU Lesser General Public License as published by
10 : the Free Software Foundation; either version 2.1 of the License, or
11 : (at your option) any later version.
12 :
13 : systemd is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : Lesser General Public License for more details.
17 :
18 : You should have received a copy of the GNU Lesser General Public License
19 : along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 : ***/
21 :
22 : #include <errno.h>
23 : #include <unistd.h>
24 :
25 : #include "unit.h"
26 : #include "scope.h"
27 : #include "log.h"
28 : #include "dbus-scope.h"
29 : #include "special.h"
30 : #include "unit-name.h"
31 : #include "load-dropin.h"
32 :
33 : static const UnitActiveState state_translation_table[_SCOPE_STATE_MAX] = {
34 : [SCOPE_DEAD] = UNIT_INACTIVE,
35 : [SCOPE_RUNNING] = UNIT_ACTIVE,
36 : [SCOPE_ABANDONED] = UNIT_ACTIVE,
37 : [SCOPE_STOP_SIGTERM] = UNIT_DEACTIVATING,
38 : [SCOPE_STOP_SIGKILL] = UNIT_DEACTIVATING,
39 : [SCOPE_FAILED] = UNIT_FAILED
40 : };
41 :
42 : static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
43 :
44 0 : static void scope_init(Unit *u) {
45 0 : Scope *s = SCOPE(u);
46 :
47 0 : assert(u);
48 0 : assert(u->load_state == UNIT_STUB);
49 :
50 0 : s->timeout_stop_usec = u->manager->default_timeout_stop_usec;
51 :
52 0 : UNIT(s)->ignore_on_isolate = true;
53 0 : UNIT(s)->ignore_on_snapshot = true;
54 0 : }
55 :
56 0 : static void scope_done(Unit *u) {
57 0 : Scope *s = SCOPE(u);
58 :
59 0 : assert(u);
60 :
61 0 : free(s->controller);
62 :
63 0 : s->timer_event_source = sd_event_source_unref(s->timer_event_source);
64 0 : }
65 :
66 0 : static int scope_arm_timer(Scope *s) {
67 : int r;
68 :
69 0 : assert(s);
70 :
71 0 : if (s->timeout_stop_usec <= 0) {
72 0 : s->timer_event_source = sd_event_source_unref(s->timer_event_source);
73 0 : return 0;
74 : }
75 :
76 0 : if (s->timer_event_source) {
77 0 : r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_stop_usec);
78 0 : if (r < 0)
79 0 : return r;
80 :
81 0 : return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
82 : }
83 :
84 0 : r = sd_event_add_time(
85 0 : UNIT(s)->manager->event,
86 : &s->timer_event_source,
87 : CLOCK_MONOTONIC,
88 0 : now(CLOCK_MONOTONIC) + s->timeout_stop_usec, 0,
89 : scope_dispatch_timer, s);
90 0 : if (r < 0)
91 0 : return r;
92 :
93 0 : (void) sd_event_source_set_description(s->timer_event_source, "scope-timer");
94 :
95 0 : return 0;
96 : }
97 :
98 0 : static void scope_set_state(Scope *s, ScopeState state) {
99 : ScopeState old_state;
100 0 : assert(s);
101 :
102 0 : old_state = s->state;
103 0 : s->state = state;
104 :
105 0 : if (!IN_SET(state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
106 0 : s->timer_event_source = sd_event_source_unref(s->timer_event_source);
107 :
108 0 : if (IN_SET(state, SCOPE_DEAD, SCOPE_FAILED))
109 0 : unit_unwatch_all_pids(UNIT(s));
110 :
111 0 : if (state != old_state)
112 0 : log_debug("%s changed %s -> %s", UNIT(s)->id, scope_state_to_string(old_state), scope_state_to_string(state));
113 :
114 0 : unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
115 0 : }
116 :
117 0 : static int scope_add_default_dependencies(Scope *s) {
118 : int r;
119 :
120 0 : assert(s);
121 :
122 : /* Make sure scopes are unloaded on shutdown */
123 0 : r = unit_add_two_dependencies_by_name(
124 : UNIT(s),
125 : UNIT_BEFORE, UNIT_CONFLICTS,
126 : SPECIAL_SHUTDOWN_TARGET, NULL, true);
127 0 : if (r < 0)
128 0 : return r;
129 :
130 0 : return 0;
131 : }
132 :
133 0 : static int scope_verify(Scope *s) {
134 0 : assert(s);
135 :
136 0 : if (UNIT(s)->load_state != UNIT_LOADED)
137 0 : return 0;
138 :
139 0 : if (set_isempty(UNIT(s)->pids) && UNIT(s)->manager->n_reloading <= 0) {
140 0 : log_unit_error(UNIT(s), "Scope has no PIDs. Refusing.");
141 0 : return -EINVAL;
142 : }
143 :
144 0 : return 0;
145 : }
146 :
147 0 : static int scope_load(Unit *u) {
148 0 : Scope *s = SCOPE(u);
149 : int r;
150 :
151 0 : assert(s);
152 0 : assert(u->load_state == UNIT_STUB);
153 :
154 0 : if (!u->transient && UNIT(s)->manager->n_reloading <= 0)
155 0 : return -ENOENT;
156 :
157 0 : u->load_state = UNIT_LOADED;
158 :
159 0 : r = unit_load_dropin(u);
160 0 : if (r < 0)
161 0 : return r;
162 :
163 0 : r = unit_patch_contexts(u);
164 0 : if (r < 0)
165 0 : return r;
166 :
167 0 : r = unit_add_default_slice(u, &s->cgroup_context);
168 0 : if (r < 0)
169 0 : return r;
170 :
171 0 : if (u->default_dependencies) {
172 0 : r = scope_add_default_dependencies(s);
173 0 : if (r < 0)
174 0 : return r;
175 : }
176 :
177 0 : return scope_verify(s);
178 : }
179 :
180 0 : static int scope_coldplug(Unit *u) {
181 0 : Scope *s = SCOPE(u);
182 : int r;
183 :
184 0 : assert(s);
185 0 : assert(s->state == SCOPE_DEAD);
186 :
187 0 : if (s->deserialized_state != s->state) {
188 :
189 0 : if (IN_SET(s->deserialized_state, SCOPE_STOP_SIGKILL, SCOPE_STOP_SIGTERM)) {
190 0 : r = scope_arm_timer(s);
191 0 : if (r < 0)
192 0 : return r;
193 : }
194 :
195 0 : if (!IN_SET(s->deserialized_state, SCOPE_DEAD, SCOPE_FAILED))
196 0 : unit_watch_all_pids(UNIT(s));
197 :
198 0 : scope_set_state(s, s->deserialized_state);
199 : }
200 :
201 0 : return 0;
202 : }
203 :
204 0 : static void scope_dump(Unit *u, FILE *f, const char *prefix) {
205 0 : Scope *s = SCOPE(u);
206 :
207 0 : assert(s);
208 0 : assert(f);
209 :
210 0 : fprintf(f,
211 : "%sScope State: %s\n"
212 : "%sResult: %s\n",
213 : prefix, scope_state_to_string(s->state),
214 : prefix, scope_result_to_string(s->result));
215 :
216 0 : cgroup_context_dump(&s->cgroup_context, f, prefix);
217 0 : kill_context_dump(&s->kill_context, f, prefix);
218 0 : }
219 :
220 0 : static void scope_enter_dead(Scope *s, ScopeResult f) {
221 0 : assert(s);
222 :
223 0 : if (f != SCOPE_SUCCESS)
224 0 : s->result = f;
225 :
226 0 : scope_set_state(s, s->result != SCOPE_SUCCESS ? SCOPE_FAILED : SCOPE_DEAD);
227 0 : }
228 :
229 0 : static void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) {
230 0 : bool skip_signal = false;
231 : int r;
232 :
233 0 : assert(s);
234 :
235 0 : if (f != SCOPE_SUCCESS)
236 0 : s->result = f;
237 :
238 0 : unit_watch_all_pids(UNIT(s));
239 :
240 : /* If we have a controller set let's ask the controller nicely
241 : * to terminate the scope, instead of us going directly into
242 : * SIGTERM beserk mode */
243 0 : if (state == SCOPE_STOP_SIGTERM)
244 0 : skip_signal = bus_scope_send_request_stop(s) > 0;
245 :
246 0 : if (!skip_signal) {
247 0 : r = unit_kill_context(
248 : UNIT(s),
249 : &s->kill_context,
250 : state != SCOPE_STOP_SIGTERM ? KILL_KILL : KILL_TERMINATE,
251 : -1, -1, false);
252 0 : if (r < 0)
253 0 : goto fail;
254 : } else
255 0 : r = 1;
256 :
257 0 : if (r > 0) {
258 0 : r = scope_arm_timer(s);
259 0 : if (r < 0)
260 0 : goto fail;
261 :
262 0 : scope_set_state(s, state);
263 0 : } else if (state == SCOPE_STOP_SIGTERM)
264 0 : scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_SUCCESS);
265 : else
266 0 : scope_enter_dead(s, SCOPE_SUCCESS);
267 :
268 0 : return;
269 :
270 : fail:
271 0 : log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
272 :
273 0 : scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
274 : }
275 :
276 0 : static int scope_start(Unit *u) {
277 0 : Scope *s = SCOPE(u);
278 : int r;
279 :
280 0 : assert(s);
281 :
282 0 : if (s->state == SCOPE_FAILED)
283 0 : return -EPERM;
284 :
285 : /* We can't fulfill this right now, please try again later */
286 0 : if (s->state == SCOPE_STOP_SIGTERM ||
287 0 : s->state == SCOPE_STOP_SIGKILL)
288 0 : return -EAGAIN;
289 :
290 0 : assert(s->state == SCOPE_DEAD);
291 :
292 0 : if (!u->transient && UNIT(s)->manager->n_reloading <= 0)
293 0 : return -ENOENT;
294 :
295 0 : (void) unit_realize_cgroup(u);
296 0 : (void) unit_reset_cpu_usage(u);
297 :
298 0 : r = unit_attach_pids_to_cgroup(u);
299 0 : if (r < 0) {
300 0 : log_unit_warning_errno(UNIT(s), r, "Failed to add PIDs to scope's control group: %m");
301 0 : scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
302 0 : return r;
303 : }
304 :
305 0 : s->result = SCOPE_SUCCESS;
306 :
307 0 : scope_set_state(s, SCOPE_RUNNING);
308 0 : return 1;
309 : }
310 :
311 0 : static int scope_stop(Unit *u) {
312 0 : Scope *s = SCOPE(u);
313 :
314 0 : assert(s);
315 :
316 0 : if (s->state == SCOPE_STOP_SIGTERM ||
317 0 : s->state == SCOPE_STOP_SIGKILL)
318 0 : return 0;
319 :
320 0 : assert(s->state == SCOPE_RUNNING ||
321 : s->state == SCOPE_ABANDONED);
322 :
323 0 : scope_enter_signal(s, SCOPE_STOP_SIGTERM, SCOPE_SUCCESS);
324 0 : return 1;
325 : }
326 :
327 0 : static void scope_reset_failed(Unit *u) {
328 0 : Scope *s = SCOPE(u);
329 :
330 0 : assert(s);
331 :
332 0 : if (s->state == SCOPE_FAILED)
333 0 : scope_set_state(s, SCOPE_DEAD);
334 :
335 0 : s->result = SCOPE_SUCCESS;
336 0 : }
337 :
338 0 : static int scope_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
339 0 : return unit_kill_common(u, who, signo, -1, -1, error);
340 : }
341 :
342 0 : static int scope_get_timeout(Unit *u, uint64_t *timeout) {
343 0 : Scope *s = SCOPE(u);
344 : int r;
345 :
346 0 : if (!s->timer_event_source)
347 0 : return 0;
348 :
349 0 : r = sd_event_source_get_time(s->timer_event_source, timeout);
350 0 : if (r < 0)
351 0 : return r;
352 :
353 0 : return 1;
354 : }
355 :
356 0 : static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
357 0 : Scope *s = SCOPE(u);
358 :
359 0 : assert(s);
360 0 : assert(f);
361 0 : assert(fds);
362 :
363 0 : unit_serialize_item(u, f, "state", scope_state_to_string(s->state));
364 0 : return 0;
365 : }
366 :
367 0 : static int scope_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
368 0 : Scope *s = SCOPE(u);
369 :
370 0 : assert(u);
371 0 : assert(key);
372 0 : assert(value);
373 0 : assert(fds);
374 :
375 0 : if (streq(key, "state")) {
376 : ScopeState state;
377 :
378 0 : state = scope_state_from_string(value);
379 0 : if (state < 0)
380 0 : log_unit_debug(u, "Failed to parse state value: %s", value);
381 : else
382 0 : s->deserialized_state = state;
383 :
384 : } else
385 0 : log_unit_debug(u, "Unknown serialization key: %s", key);
386 :
387 0 : return 0;
388 : }
389 :
390 0 : static bool scope_check_gc(Unit *u) {
391 0 : assert(u);
392 :
393 : /* Never clean up scopes that still have a process around,
394 : * even if the scope is formally dead. */
395 :
396 0 : if (u->cgroup_path) {
397 : int r;
398 :
399 0 : r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true);
400 0 : if (r <= 0)
401 0 : return true;
402 : }
403 :
404 0 : return false;
405 : }
406 :
407 0 : static void scope_notify_cgroup_empty_event(Unit *u) {
408 0 : Scope *s = SCOPE(u);
409 0 : assert(u);
410 :
411 0 : log_unit_debug(u, "cgroup is empty");
412 :
413 0 : if (IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
414 0 : scope_enter_dead(s, SCOPE_SUCCESS);
415 0 : }
416 :
417 0 : static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
418 :
419 : /* If we get a SIGCHLD event for one of the processes we were
420 : interested in, then we look for others to watch, under the
421 : assumption that we'll sooner or later get a SIGCHLD for
422 : them, as the original process we watched was probably the
423 : parent of them, and they are hence now our children. */
424 :
425 0 : unit_tidy_watch_pids(u, 0, 0);
426 0 : unit_watch_all_pids(u);
427 :
428 : /* If the PID set is empty now, then let's finish this off */
429 0 : if (set_isempty(u->pids))
430 0 : scope_notify_cgroup_empty_event(u);
431 0 : }
432 :
433 0 : static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
434 0 : Scope *s = SCOPE(userdata);
435 :
436 0 : assert(s);
437 0 : assert(s->timer_event_source == source);
438 :
439 0 : switch (s->state) {
440 :
441 : case SCOPE_STOP_SIGTERM:
442 0 : if (s->kill_context.send_sigkill) {
443 0 : log_unit_warning(UNIT(s), "Stopping timed out. Killing.");
444 0 : scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_FAILURE_TIMEOUT);
445 : } else {
446 0 : log_unit_warning(UNIT(s), "Stopping timed out. Skipping SIGKILL.");
447 0 : scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
448 : }
449 :
450 0 : break;
451 :
452 : case SCOPE_STOP_SIGKILL:
453 0 : log_unit_warning(UNIT(s), "Still around after SIGKILL. Ignoring.");
454 0 : scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
455 0 : break;
456 :
457 : default:
458 0 : assert_not_reached("Timeout at wrong time.");
459 : }
460 :
461 0 : return 0;
462 : }
463 :
464 0 : int scope_abandon(Scope *s) {
465 0 : assert(s);
466 :
467 0 : if (!IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED))
468 0 : return -ESTALE;
469 :
470 0 : free(s->controller);
471 0 : s->controller = NULL;
472 :
473 : /* The client is no longer watching the remaining processes,
474 : * so let's step in here, under the assumption that the
475 : * remaining processes will be sooner or later reassigned to
476 : * us as parent. */
477 :
478 0 : unit_tidy_watch_pids(UNIT(s), 0, 0);
479 0 : unit_watch_all_pids(UNIT(s));
480 :
481 : /* If the PID set is empty now, then let's finish this off */
482 0 : if (set_isempty(UNIT(s)->pids))
483 0 : scope_notify_cgroup_empty_event(UNIT(s));
484 : else
485 0 : scope_set_state(s, SCOPE_ABANDONED);
486 :
487 0 : return 0;
488 : }
489 :
490 0 : _pure_ static UnitActiveState scope_active_state(Unit *u) {
491 0 : assert(u);
492 :
493 0 : return state_translation_table[SCOPE(u)->state];
494 : }
495 :
496 0 : _pure_ static const char *scope_sub_state_to_string(Unit *u) {
497 0 : assert(u);
498 :
499 0 : return scope_state_to_string(SCOPE(u)->state);
500 : }
501 :
502 : static const char* const scope_state_table[_SCOPE_STATE_MAX] = {
503 : [SCOPE_DEAD] = "dead",
504 : [SCOPE_RUNNING] = "running",
505 : [SCOPE_ABANDONED] = "abandoned",
506 : [SCOPE_STOP_SIGTERM] = "stop-sigterm",
507 : [SCOPE_STOP_SIGKILL] = "stop-sigkill",
508 : [SCOPE_FAILED] = "failed",
509 : };
510 :
511 16 : DEFINE_STRING_TABLE_LOOKUP(scope_state, ScopeState);
512 :
513 : static const char* const scope_result_table[_SCOPE_RESULT_MAX] = {
514 : [SCOPE_SUCCESS] = "success",
515 : [SCOPE_FAILURE_RESOURCES] = "resources",
516 : [SCOPE_FAILURE_TIMEOUT] = "timeout",
517 : };
518 :
519 10 : DEFINE_STRING_TABLE_LOOKUP(scope_result, ScopeResult);
520 :
521 : const UnitVTable scope_vtable = {
522 : .object_size = sizeof(Scope),
523 : .cgroup_context_offset = offsetof(Scope, cgroup_context),
524 : .kill_context_offset = offsetof(Scope, kill_context),
525 :
526 : .sections =
527 : "Unit\0"
528 : "Scope\0"
529 : "Install\0",
530 : .private_section = "Scope",
531 :
532 : .no_alias = true,
533 : .no_instances = true,
534 :
535 : .init = scope_init,
536 : .load = scope_load,
537 : .done = scope_done,
538 :
539 : .coldplug = scope_coldplug,
540 :
541 : .dump = scope_dump,
542 :
543 : .start = scope_start,
544 : .stop = scope_stop,
545 :
546 : .kill = scope_kill,
547 :
548 : .get_timeout = scope_get_timeout,
549 :
550 : .serialize = scope_serialize,
551 : .deserialize_item = scope_deserialize_item,
552 :
553 : .active_state = scope_active_state,
554 : .sub_state_to_string = scope_sub_state_to_string,
555 :
556 : .check_gc = scope_check_gc,
557 :
558 : .sigchld_event = scope_sigchld_event,
559 :
560 : .reset_failed = scope_reset_failed,
561 :
562 : .notify_cgroup_empty = scope_notify_cgroup_empty_event,
563 :
564 : .bus_interface = "org.freedesktop.systemd1.Scope",
565 : .bus_vtable = bus_scope_vtable,
566 : .bus_set_property = bus_scope_set_property,
567 : .bus_commit_properties = bus_scope_commit_properties,
568 :
569 : .can_transient = true
570 : };
|