1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
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.
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.
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/>.
28 #include "load-fragment.h"
30 #include "dbus-scope.h"
32 #include "unit-name.h"
33 #include "load-dropin.h"
35 static const UnitActiveState state_translation_table[_SCOPE_STATE_MAX] = {
36 [SCOPE_DEAD] = UNIT_INACTIVE,
37 [SCOPE_RUNNING] = UNIT_ACTIVE,
38 [SCOPE_ABANDONED] = UNIT_ACTIVE,
39 [SCOPE_STOP_SIGTERM] = UNIT_DEACTIVATING,
40 [SCOPE_STOP_SIGKILL] = UNIT_DEACTIVATING,
41 [SCOPE_FAILED] = UNIT_FAILED
44 static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
46 static void scope_init(Unit *u) {
50 assert(u->load_state == UNIT_STUB);
52 s->timeout_stop_usec = u->manager->default_timeout_stop_usec;
54 cgroup_context_init(&s->cgroup_context);
55 kill_context_init(&s->kill_context);
57 UNIT(s)->ignore_on_isolate = true;
58 UNIT(s)->ignore_on_snapshot = true;
61 static void scope_done(Unit *u) {
66 cgroup_context_done(&s->cgroup_context);
70 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
73 static int scope_arm_timer(Scope *s) {
78 if (s->timeout_stop_usec <= 0) {
79 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
83 if (s->timer_event_source) {
84 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_stop_usec);
88 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
91 return sd_event_add_monotonic(UNIT(s)->manager->event, now(CLOCK_MONOTONIC) + s->timeout_stop_usec, 0, scope_dispatch_timer, s, &s->timer_event_source);
94 static void scope_set_state(Scope *s, ScopeState state) {
101 if (!IN_SET(state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
102 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
104 if (IN_SET(state, SCOPE_DEAD, SCOPE_FAILED))
105 unit_unwatch_all_pids(UNIT(s));
107 if (state != old_state)
108 log_debug("%s changed %s -> %s", UNIT(s)->id, scope_state_to_string(old_state), scope_state_to_string(state));
110 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
113 static int scope_add_default_dependencies(Scope *s) {
118 /* Make sure scopes are unloaded on shutdown */
119 r = unit_add_two_dependencies_by_name(
121 UNIT_BEFORE, UNIT_CONFLICTS,
122 SPECIAL_SHUTDOWN_TARGET, NULL, true);
129 static int scope_verify(Scope *s) {
132 if (UNIT(s)->load_state != UNIT_LOADED)
135 if (set_isempty(UNIT(s)->pids) && UNIT(s)->manager->n_reloading <= 0) {
136 log_error_unit(UNIT(s)->id, "Scope %s has no PIDs. Refusing.", UNIT(s)->id);
143 static int scope_load(Unit *u) {
148 assert(u->load_state == UNIT_STUB);
150 if (!u->transient && UNIT(s)->manager->n_reloading <= 0)
153 u->load_state = UNIT_LOADED;
155 r = unit_load_dropin(u);
159 r = unit_add_default_slice(u);
163 if (u->default_dependencies) {
164 r = scope_add_default_dependencies(s);
169 return scope_verify(s);
172 static int scope_coldplug(Unit *u) {
177 assert(s->state == SCOPE_DEAD);
179 if (s->deserialized_state != s->state) {
181 if (IN_SET(s->deserialized_state, SCOPE_STOP_SIGKILL, SCOPE_STOP_SIGTERM)) {
182 r = scope_arm_timer(s);
187 if (!IN_SET(s->deserialized_state, SCOPE_DEAD, SCOPE_FAILED))
188 unit_watch_all_pids(UNIT(s));
190 scope_set_state(s, s->deserialized_state);
196 static void scope_dump(Unit *u, FILE *f, const char *prefix) {
203 "%sScope State: %s\n"
205 prefix, scope_state_to_string(s->state),
206 prefix, scope_result_to_string(s->result));
208 cgroup_context_dump(&s->cgroup_context, f, prefix);
209 kill_context_dump(&s->kill_context, f, prefix);
212 static void scope_enter_dead(Scope *s, ScopeResult f) {
215 if (f != SCOPE_SUCCESS)
218 scope_set_state(s, s->result != SCOPE_SUCCESS ? SCOPE_FAILED : SCOPE_DEAD);
221 static void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) {
222 bool skip_signal = false;
227 if (f != SCOPE_SUCCESS)
230 unit_watch_all_pids(UNIT(s));
232 /* If we have a controller set let's ask the controller nicely
233 * to terminate the scope, instead of us going directly into
234 * SIGTERM beserk mode */
235 if (state == SCOPE_STOP_SIGTERM)
236 skip_signal = bus_scope_send_request_stop(s) > 0;
239 r = unit_kill_context(
242 state != SCOPE_STOP_SIGTERM,
250 r = scope_arm_timer(s);
254 scope_set_state(s, state);
255 } else if (state == SCOPE_STOP_SIGTERM)
256 scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_SUCCESS);
258 scope_enter_dead(s, SCOPE_SUCCESS);
263 log_warning_unit(UNIT(s)->id,
264 "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
266 scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
269 static int scope_start(Unit *u) {
275 if (s->state == SCOPE_FAILED)
278 if (s->state == SCOPE_STOP_SIGTERM ||
279 s->state == SCOPE_STOP_SIGKILL)
282 assert(s->state == SCOPE_DEAD);
284 if (!u->transient && UNIT(s)->manager->n_reloading <= 0)
287 r = unit_realize_cgroup(u);
289 log_error("Failed to realize cgroup: %s", strerror(-r));
293 r = cg_attach_many_everywhere(u->manager->cgroup_supported, u->cgroup_path, UNIT(s)->pids);
297 s->result = SCOPE_SUCCESS;
299 scope_set_state(s, SCOPE_RUNNING);
303 static int scope_stop(Unit *u) {
308 if (s->state == SCOPE_STOP_SIGTERM ||
309 s->state == SCOPE_STOP_SIGKILL)
312 assert(s->state == SCOPE_RUNNING ||
313 s->state == SCOPE_ABANDONED);
315 scope_enter_signal(s, SCOPE_STOP_SIGTERM, SCOPE_SUCCESS);
319 static void scope_reset_failed(Unit *u) {
324 if (s->state == SCOPE_FAILED)
325 scope_set_state(s, SCOPE_DEAD);
327 s->result = SCOPE_SUCCESS;
330 static int scope_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
331 return unit_kill_common(u, who, signo, -1, -1, error);
334 static int scope_get_timeout(Unit *u, uint64_t *timeout) {
338 if (!s->timer_event_source)
341 r = sd_event_source_get_time(s->timer_event_source, timeout);
348 static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
355 unit_serialize_item(u, f, "state", scope_state_to_string(s->state));
359 static int scope_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
367 if (streq(key, "state")) {
370 state = scope_state_from_string(value);
372 log_debug("Failed to parse state value %s", value);
374 s->deserialized_state = state;
377 log_debug("Unknown serialization key '%s'", key);
382 static bool scope_check_gc(Unit *u) {
388 /* Never clean up scopes that still have a process around,
389 * even if the scope is formally dead. */
391 if (u->cgroup_path) {
392 r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true);
400 static void scope_notify_cgroup_empty_event(Unit *u) {
404 log_debug_unit(u->id, "%s: cgroup is empty", u->id);
406 if (IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
407 scope_enter_dead(s, SCOPE_SUCCESS);
410 static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
412 /* If we get a SIGCHLD event for one of the processes we were
413 interested in, then we look for others to watch, under the
414 assumption that we'll sooner or later get a SIGCHLD for
415 them, as the original process we watched was probably the
416 parent of them, and they are hence now our children. */
418 unit_tidy_watch_pids(u, 0, 0);
419 unit_watch_all_pids(u);
421 /* If the PID set is empty now, then let's finish this off */
422 if (set_isempty(u->pids))
423 scope_notify_cgroup_empty_event(u);
426 static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
427 Scope *s = SCOPE(userdata);
430 assert(s->timer_event_source == source);
434 case SCOPE_STOP_SIGTERM:
435 if (s->kill_context.send_sigkill) {
436 log_warning_unit(UNIT(s)->id, "%s stopping timed out. Killing.", UNIT(s)->id);
437 scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_FAILURE_TIMEOUT);
439 log_warning_unit(UNIT(s)->id, "%s stopping timed out. Skipping SIGKILL.", UNIT(s)->id);
440 scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
445 case SCOPE_STOP_SIGKILL:
446 log_warning_unit(UNIT(s)->id, "%s still around after SIGKILL. Ignoring.", UNIT(s)->id);
447 scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
451 assert_not_reached("Timeout at wrong time.");
457 int scope_abandon(Scope *s) {
460 if (!IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED))
464 s->controller = NULL;
466 /* The client is no longer watching the remaining processes,
467 * so let's step in here, under the assumption that the
468 * remaining processes will be sooner or later reassigned to
471 unit_tidy_watch_pids(UNIT(s), 0, 0);
472 unit_watch_all_pids(UNIT(s));
474 /* If the PID set is empty now, then let's finish this off */
475 if (set_isempty(UNIT(s)->pids))
476 scope_notify_cgroup_empty_event(UNIT(s));
478 scope_set_state(s, SCOPE_ABANDONED);
483 _pure_ static UnitActiveState scope_active_state(Unit *u) {
486 return state_translation_table[SCOPE(u)->state];
489 _pure_ static const char *scope_sub_state_to_string(Unit *u) {
492 return scope_state_to_string(SCOPE(u)->state);
495 static const char* const scope_state_table[_SCOPE_STATE_MAX] = {
496 [SCOPE_DEAD] = "dead",
497 [SCOPE_RUNNING] = "running",
498 [SCOPE_ABANDONED] = "abandoned",
499 [SCOPE_STOP_SIGTERM] = "stop-sigterm",
500 [SCOPE_STOP_SIGKILL] = "stop-sigkill",
501 [SCOPE_FAILED] = "failed",
504 DEFINE_STRING_TABLE_LOOKUP(scope_state, ScopeState);
506 static const char* const scope_result_table[_SCOPE_RESULT_MAX] = {
507 [SCOPE_SUCCESS] = "success",
508 [SCOPE_FAILURE_RESOURCES] = "resources",
509 [SCOPE_FAILURE_TIMEOUT] = "timeout",
512 DEFINE_STRING_TABLE_LOOKUP(scope_result, ScopeResult);
514 const UnitVTable scope_vtable = {
515 .object_size = sizeof(Scope),
516 .cgroup_context_offset = offsetof(Scope, cgroup_context),
517 .kill_context_offset = offsetof(Scope, kill_context),
523 .private_section = "Scope",
526 .no_instances = true,
532 .coldplug = scope_coldplug,
536 .start = scope_start,
541 .get_timeout = scope_get_timeout,
543 .serialize = scope_serialize,
544 .deserialize_item = scope_deserialize_item,
546 .active_state = scope_active_state,
547 .sub_state_to_string = scope_sub_state_to_string,
549 .check_gc = scope_check_gc,
551 .sigchld_event = scope_sigchld_event,
553 .reset_failed = scope_reset_failed,
555 .notify_cgroup_empty = scope_notify_cgroup_empty_event,
557 .bus_interface = "org.freedesktop.systemd1.Scope",
558 .bus_vtable = bus_scope_vtable,
559 .bus_set_property = bus_scope_set_property,
560 .bus_commit_properties = bus_scope_commit_properties,
562 .can_transient = true