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/>.
25 #include "dbus-scope.h"
26 #include "load-dropin.h"
29 #include "string-util.h"
31 #include "unit-name.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 UNIT(s
)->ignore_on_isolate
= true;
55 UNIT(s
)->ignore_on_snapshot
= true;
58 static void scope_done(Unit
*u
) {
65 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
68 static int scope_arm_timer(Scope
*s
) {
73 if (s
->timeout_stop_usec
<= 0) {
74 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
78 if (s
->timer_event_source
) {
79 r
= sd_event_source_set_time(s
->timer_event_source
, now(CLOCK_MONOTONIC
) + s
->timeout_stop_usec
);
83 return sd_event_source_set_enabled(s
->timer_event_source
, SD_EVENT_ONESHOT
);
86 r
= sd_event_add_time(
87 UNIT(s
)->manager
->event
,
88 &s
->timer_event_source
,
90 now(CLOCK_MONOTONIC
) + s
->timeout_stop_usec
, 0,
91 scope_dispatch_timer
, s
);
95 (void) sd_event_source_set_description(s
->timer_event_source
, "scope-timer");
100 static void scope_set_state(Scope
*s
, ScopeState state
) {
101 ScopeState old_state
;
104 old_state
= s
->state
;
107 if (!IN_SET(state
, SCOPE_STOP_SIGTERM
, SCOPE_STOP_SIGKILL
))
108 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
110 if (IN_SET(state
, SCOPE_DEAD
, SCOPE_FAILED
))
111 unit_unwatch_all_pids(UNIT(s
));
113 if (state
!= old_state
)
114 log_debug("%s changed %s -> %s", UNIT(s
)->id
, scope_state_to_string(old_state
), scope_state_to_string(state
));
116 unit_notify(UNIT(s
), state_translation_table
[old_state
], state_translation_table
[state
], true);
119 static int scope_add_default_dependencies(Scope
*s
) {
124 /* Make sure scopes are unloaded on shutdown */
125 r
= unit_add_two_dependencies_by_name(
127 UNIT_BEFORE
, UNIT_CONFLICTS
,
128 SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
135 static int scope_verify(Scope
*s
) {
138 if (UNIT(s
)->load_state
!= UNIT_LOADED
)
141 if (set_isempty(UNIT(s
)->pids
) &&
142 !manager_is_reloading_or_reexecuting(UNIT(s
)->manager
) &&
143 !unit_has_name(UNIT(s
), SPECIAL_INIT_SCOPE
)) {
144 log_unit_error(UNIT(s
), "Scope has no PIDs. Refusing.");
151 static int scope_load(Unit
*u
) {
156 assert(u
->load_state
== UNIT_STUB
);
158 if (!u
->transient
&& !manager_is_reloading_or_reexecuting(u
->manager
))
161 u
->load_state
= UNIT_LOADED
;
163 r
= unit_load_dropin(u
);
167 r
= unit_patch_contexts(u
);
171 r
= unit_set_default_slice(u
);
175 if (u
->default_dependencies
) {
176 r
= scope_add_default_dependencies(s
);
181 return scope_verify(s
);
184 static int scope_coldplug(Unit
*u
) {
189 assert(s
->state
== SCOPE_DEAD
);
191 if (s
->deserialized_state
!= s
->state
) {
193 if (IN_SET(s
->deserialized_state
, SCOPE_STOP_SIGKILL
, SCOPE_STOP_SIGTERM
)) {
194 r
= scope_arm_timer(s
);
199 if (!IN_SET(s
->deserialized_state
, SCOPE_DEAD
, SCOPE_FAILED
))
200 unit_watch_all_pids(UNIT(s
));
202 scope_set_state(s
, s
->deserialized_state
);
208 static void scope_dump(Unit
*u
, FILE *f
, const char *prefix
) {
215 "%sScope State: %s\n"
217 prefix
, scope_state_to_string(s
->state
),
218 prefix
, scope_result_to_string(s
->result
));
220 cgroup_context_dump(&s
->cgroup_context
, f
, prefix
);
221 kill_context_dump(&s
->kill_context
, f
, prefix
);
224 static void scope_enter_dead(Scope
*s
, ScopeResult f
) {
227 if (f
!= SCOPE_SUCCESS
)
230 scope_set_state(s
, s
->result
!= SCOPE_SUCCESS
? SCOPE_FAILED
: SCOPE_DEAD
);
233 static void scope_enter_signal(Scope
*s
, ScopeState state
, ScopeResult f
) {
234 bool skip_signal
= false;
239 if (f
!= SCOPE_SUCCESS
)
242 unit_watch_all_pids(UNIT(s
));
244 /* If we have a controller set let's ask the controller nicely
245 * to terminate the scope, instead of us going directly into
246 * SIGTERM beserk mode */
247 if (state
== SCOPE_STOP_SIGTERM
)
248 skip_signal
= bus_scope_send_request_stop(s
) > 0;
251 r
= unit_kill_context(
254 state
!= SCOPE_STOP_SIGTERM
? KILL_KILL
: KILL_TERMINATE
,
262 r
= scope_arm_timer(s
);
266 scope_set_state(s
, state
);
267 } else if (state
== SCOPE_STOP_SIGTERM
)
268 scope_enter_signal(s
, SCOPE_STOP_SIGKILL
, SCOPE_SUCCESS
);
270 scope_enter_dead(s
, SCOPE_SUCCESS
);
275 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
277 scope_enter_dead(s
, SCOPE_FAILURE_RESOURCES
);
280 static int scope_start(Unit
*u
) {
286 if (unit_has_name(u
, SPECIAL_INIT_SCOPE
))
289 if (s
->state
== SCOPE_FAILED
)
292 /* We can't fulfill this right now, please try again later */
293 if (s
->state
== SCOPE_STOP_SIGTERM
||
294 s
->state
== SCOPE_STOP_SIGKILL
)
297 assert(s
->state
== SCOPE_DEAD
);
299 if (!u
->transient
&& !manager_is_reloading_or_reexecuting(u
->manager
))
302 (void) unit_realize_cgroup(u
);
303 (void) unit_reset_cpu_usage(u
);
305 r
= unit_attach_pids_to_cgroup(u
);
307 log_unit_warning_errno(UNIT(s
), r
, "Failed to add PIDs to scope's control group: %m");
308 scope_enter_dead(s
, SCOPE_FAILURE_RESOURCES
);
312 s
->result
= SCOPE_SUCCESS
;
314 scope_set_state(s
, SCOPE_RUNNING
);
318 static int scope_stop(Unit
*u
) {
323 if (s
->state
== SCOPE_STOP_SIGTERM
||
324 s
->state
== SCOPE_STOP_SIGKILL
)
327 assert(s
->state
== SCOPE_RUNNING
||
328 s
->state
== SCOPE_ABANDONED
);
330 scope_enter_signal(s
, SCOPE_STOP_SIGTERM
, SCOPE_SUCCESS
);
334 static void scope_reset_failed(Unit
*u
) {
339 if (s
->state
== SCOPE_FAILED
)
340 scope_set_state(s
, SCOPE_DEAD
);
342 s
->result
= SCOPE_SUCCESS
;
345 static int scope_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
346 return unit_kill_common(u
, who
, signo
, -1, -1, error
);
349 static int scope_get_timeout(Unit
*u
, uint64_t *timeout
) {
353 if (!s
->timer_event_source
)
356 r
= sd_event_source_get_time(s
->timer_event_source
, timeout
);
363 static int scope_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
370 unit_serialize_item(u
, f
, "state", scope_state_to_string(s
->state
));
374 static int scope_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
382 if (streq(key
, "state")) {
385 state
= scope_state_from_string(value
);
387 log_unit_debug(u
, "Failed to parse state value: %s", value
);
389 s
->deserialized_state
= state
;
392 log_unit_debug(u
, "Unknown serialization key: %s", key
);
397 static bool scope_check_gc(Unit
*u
) {
400 /* Never clean up scopes that still have a process around,
401 * even if the scope is formally dead. */
403 if (u
->cgroup_path
) {
406 r
= cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, u
->cgroup_path
);
414 static void scope_notify_cgroup_empty_event(Unit
*u
) {
418 log_unit_debug(u
, "cgroup is empty");
420 if (IN_SET(s
->state
, SCOPE_RUNNING
, SCOPE_ABANDONED
, SCOPE_STOP_SIGTERM
, SCOPE_STOP_SIGKILL
))
421 scope_enter_dead(s
, SCOPE_SUCCESS
);
424 static void scope_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
426 /* If we get a SIGCHLD event for one of the processes we were
427 interested in, then we look for others to watch, under the
428 assumption that we'll sooner or later get a SIGCHLD for
429 them, as the original process we watched was probably the
430 parent of them, and they are hence now our children. */
432 unit_tidy_watch_pids(u
, 0, 0);
433 unit_watch_all_pids(u
);
435 /* If the PID set is empty now, then let's finish this off */
436 if (set_isempty(u
->pids
))
437 scope_notify_cgroup_empty_event(u
);
440 static int scope_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
441 Scope
*s
= SCOPE(userdata
);
444 assert(s
->timer_event_source
== source
);
448 case SCOPE_STOP_SIGTERM
:
449 if (s
->kill_context
.send_sigkill
) {
450 log_unit_warning(UNIT(s
), "Stopping timed out. Killing.");
451 scope_enter_signal(s
, SCOPE_STOP_SIGKILL
, SCOPE_FAILURE_TIMEOUT
);
453 log_unit_warning(UNIT(s
), "Stopping timed out. Skipping SIGKILL.");
454 scope_enter_dead(s
, SCOPE_FAILURE_TIMEOUT
);
459 case SCOPE_STOP_SIGKILL
:
460 log_unit_warning(UNIT(s
), "Still around after SIGKILL. Ignoring.");
461 scope_enter_dead(s
, SCOPE_FAILURE_TIMEOUT
);
465 assert_not_reached("Timeout at wrong time.");
471 int scope_abandon(Scope
*s
) {
474 if (unit_has_name(UNIT(s
), SPECIAL_INIT_SCOPE
))
477 if (!IN_SET(s
->state
, SCOPE_RUNNING
, SCOPE_ABANDONED
))
480 s
->controller
= mfree(s
->controller
);
482 /* The client is no longer watching the remaining processes,
483 * so let's step in here, under the assumption that the
484 * remaining processes will be sooner or later reassigned to
487 unit_tidy_watch_pids(UNIT(s
), 0, 0);
488 unit_watch_all_pids(UNIT(s
));
490 /* If the PID set is empty now, then let's finish this off */
491 if (set_isempty(UNIT(s
)->pids
))
492 scope_notify_cgroup_empty_event(UNIT(s
));
494 scope_set_state(s
, SCOPE_ABANDONED
);
499 _pure_
static UnitActiveState
scope_active_state(Unit
*u
) {
502 return state_translation_table
[SCOPE(u
)->state
];
505 _pure_
static const char *scope_sub_state_to_string(Unit
*u
) {
508 return scope_state_to_string(SCOPE(u
)->state
);
511 static int scope_enumerate(Manager
*m
) {
517 /* Let's unconditionally add the "init.scope" special unit
518 * that encapsulates PID 1. Note that PID 1 already is in the
519 * cgroup for this, we hence just need to allocate the object
520 * for it and that's it. */
522 u
= manager_get_unit(m
, SPECIAL_INIT_SCOPE
);
524 u
= unit_new(m
, sizeof(Scope
));
528 r
= unit_add_name(u
, SPECIAL_INIT_SCOPE
);
531 return log_error_errno(r
, "Failed to add init.scope name");
536 u
->default_dependencies
= false;
538 u
->ignore_on_isolate
= true;
539 u
->refuse_manual_start
= true;
540 u
->refuse_manual_stop
= true;
541 SCOPE(u
)->deserialized_state
= SCOPE_RUNNING
;
542 SCOPE(u
)->kill_context
.kill_signal
= SIGRTMIN
+14;
544 /* Prettify things, if we can. */
546 u
->description
= strdup("System and Service Manager");
547 if (!u
->documentation
)
548 (void) strv_extend(&u
->documentation
, "man:systemd(1)");
550 unit_add_to_load_queue(u
);
551 unit_add_to_dbus_queue(u
);
556 static const char* const scope_result_table
[_SCOPE_RESULT_MAX
] = {
557 [SCOPE_SUCCESS
] = "success",
558 [SCOPE_FAILURE_RESOURCES
] = "resources",
559 [SCOPE_FAILURE_TIMEOUT
] = "timeout",
562 DEFINE_STRING_TABLE_LOOKUP(scope_result
, ScopeResult
);
564 const UnitVTable scope_vtable
= {
565 .object_size
= sizeof(Scope
),
566 .cgroup_context_offset
= offsetof(Scope
, cgroup_context
),
567 .kill_context_offset
= offsetof(Scope
, kill_context
),
573 .private_section
= "Scope",
576 .no_instances
= true,
582 .coldplug
= scope_coldplug
,
586 .start
= scope_start
,
591 .get_timeout
= scope_get_timeout
,
593 .serialize
= scope_serialize
,
594 .deserialize_item
= scope_deserialize_item
,
596 .active_state
= scope_active_state
,
597 .sub_state_to_string
= scope_sub_state_to_string
,
599 .check_gc
= scope_check_gc
,
601 .sigchld_event
= scope_sigchld_event
,
603 .reset_failed
= scope_reset_failed
,
605 .notify_cgroup_empty
= scope_notify_cgroup_empty_event
,
607 .bus_vtable
= bus_scope_vtable
,
608 .bus_set_property
= bus_scope_set_property
,
609 .bus_commit_properties
= bus_scope_commit_properties
,
611 .can_transient
= true,
613 .enumerate
= scope_enumerate
,