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 "alloc-util.h"
26 #include "dbus-scope.h"
27 #include "load-dropin.h"
31 #include "string-table.h"
32 #include "string-util.h"
34 #include "unit-name.h"
37 static const UnitActiveState state_translation_table
[_SCOPE_STATE_MAX
] = {
38 [SCOPE_DEAD
] = UNIT_INACTIVE
,
39 [SCOPE_RUNNING
] = UNIT_ACTIVE
,
40 [SCOPE_ABANDONED
] = UNIT_ACTIVE
,
41 [SCOPE_STOP_SIGTERM
] = UNIT_DEACTIVATING
,
42 [SCOPE_STOP_SIGKILL
] = UNIT_DEACTIVATING
,
43 [SCOPE_FAILED
] = UNIT_FAILED
46 static int scope_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
48 static void scope_init(Unit
*u
) {
52 assert(u
->load_state
== UNIT_STUB
);
54 s
->timeout_stop_usec
= u
->manager
->default_timeout_stop_usec
;
56 UNIT(s
)->ignore_on_isolate
= true;
59 static void scope_done(Unit
*u
) {
66 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
69 static int scope_arm_timer(Scope
*s
) {
74 if (s
->timeout_stop_usec
<= 0) {
75 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
79 if (s
->timer_event_source
) {
80 r
= sd_event_source_set_time(s
->timer_event_source
, now(CLOCK_MONOTONIC
) + s
->timeout_stop_usec
);
84 return sd_event_source_set_enabled(s
->timer_event_source
, SD_EVENT_ONESHOT
);
87 r
= sd_event_add_time(
88 UNIT(s
)->manager
->event
,
89 &s
->timer_event_source
,
91 now(CLOCK_MONOTONIC
) + s
->timeout_stop_usec
, 0,
92 scope_dispatch_timer
, s
);
96 (void) sd_event_source_set_description(s
->timer_event_source
, "scope-timer");
101 static void scope_set_state(Scope
*s
, ScopeState state
) {
102 ScopeState old_state
;
105 old_state
= s
->state
;
108 if (!IN_SET(state
, SCOPE_STOP_SIGTERM
, SCOPE_STOP_SIGKILL
))
109 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
111 if (IN_SET(state
, SCOPE_DEAD
, SCOPE_FAILED
))
112 unit_unwatch_all_pids(UNIT(s
));
114 if (state
!= old_state
)
115 log_debug("%s changed %s -> %s", UNIT(s
)->id
, scope_state_to_string(old_state
), scope_state_to_string(state
));
117 unit_notify(UNIT(s
), state_translation_table
[old_state
], state_translation_table
[state
], true);
120 static int scope_add_default_dependencies(Scope
*s
) {
125 if (!UNIT(s
)->default_dependencies
)
128 /* Make sure scopes are unloaded on shutdown */
129 r
= unit_add_two_dependencies_by_name(
131 UNIT_BEFORE
, UNIT_CONFLICTS
,
132 SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
139 static int scope_verify(Scope
*s
) {
142 if (UNIT(s
)->load_state
!= UNIT_LOADED
)
145 if (set_isempty(UNIT(s
)->pids
) &&
146 !manager_is_reloading_or_reexecuting(UNIT(s
)->manager
) &&
147 !unit_has_name(UNIT(s
), SPECIAL_INIT_SCOPE
)) {
148 log_unit_error(UNIT(s
), "Scope has no PIDs. Refusing.");
155 static int scope_load(Unit
*u
) {
160 assert(u
->load_state
== UNIT_STUB
);
162 if (!u
->transient
&& !manager_is_reloading_or_reexecuting(u
->manager
))
165 u
->load_state
= UNIT_LOADED
;
167 r
= unit_load_dropin(u
);
171 r
= unit_patch_contexts(u
);
175 r
= unit_set_default_slice(u
);
179 r
= scope_add_default_dependencies(s
);
183 return scope_verify(s
);
186 static int scope_coldplug(Unit
*u
) {
191 assert(s
->state
== SCOPE_DEAD
);
193 if (s
->deserialized_state
!= s
->state
) {
195 if (IN_SET(s
->deserialized_state
, SCOPE_STOP_SIGKILL
, SCOPE_STOP_SIGTERM
)) {
196 r
= scope_arm_timer(s
);
201 if (!IN_SET(s
->deserialized_state
, SCOPE_DEAD
, SCOPE_FAILED
))
202 unit_watch_all_pids(UNIT(s
));
204 scope_set_state(s
, s
->deserialized_state
);
210 static void scope_dump(Unit
*u
, FILE *f
, const char *prefix
) {
217 "%sScope State: %s\n"
219 prefix
, scope_state_to_string(s
->state
),
220 prefix
, scope_result_to_string(s
->result
));
222 cgroup_context_dump(&s
->cgroup_context
, f
, prefix
);
223 kill_context_dump(&s
->kill_context
, f
, prefix
);
226 static void scope_enter_dead(Scope
*s
, ScopeResult f
) {
229 if (f
!= SCOPE_SUCCESS
)
232 scope_set_state(s
, s
->result
!= SCOPE_SUCCESS
? SCOPE_FAILED
: SCOPE_DEAD
);
235 static void scope_enter_signal(Scope
*s
, ScopeState state
, ScopeResult f
) {
236 bool skip_signal
= false;
241 if (f
!= SCOPE_SUCCESS
)
244 unit_watch_all_pids(UNIT(s
));
246 /* If we have a controller set let's ask the controller nicely
247 * to terminate the scope, instead of us going directly into
248 * SIGTERM beserk mode */
249 if (state
== SCOPE_STOP_SIGTERM
)
250 skip_signal
= bus_scope_send_request_stop(s
) > 0;
253 r
= unit_kill_context(
256 state
!= SCOPE_STOP_SIGTERM
? KILL_KILL
: KILL_TERMINATE
,
264 r
= scope_arm_timer(s
);
268 scope_set_state(s
, state
);
269 } else if (state
== SCOPE_STOP_SIGTERM
)
270 scope_enter_signal(s
, SCOPE_STOP_SIGKILL
, SCOPE_SUCCESS
);
272 scope_enter_dead(s
, SCOPE_SUCCESS
);
277 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
279 scope_enter_dead(s
, SCOPE_FAILURE_RESOURCES
);
282 static int scope_start(Unit
*u
) {
288 if (unit_has_name(u
, SPECIAL_INIT_SCOPE
))
291 if (s
->state
== SCOPE_FAILED
)
294 /* We can't fulfill this right now, please try again later */
295 if (s
->state
== SCOPE_STOP_SIGTERM
||
296 s
->state
== SCOPE_STOP_SIGKILL
)
299 assert(s
->state
== SCOPE_DEAD
);
301 if (!u
->transient
&& !manager_is_reloading_or_reexecuting(u
->manager
))
304 (void) unit_realize_cgroup(u
);
305 (void) unit_reset_cpu_usage(u
);
307 r
= unit_attach_pids_to_cgroup(u
);
309 log_unit_warning_errno(UNIT(s
), r
, "Failed to add PIDs to scope's control group: %m");
310 scope_enter_dead(s
, SCOPE_FAILURE_RESOURCES
);
314 s
->result
= SCOPE_SUCCESS
;
316 scope_set_state(s
, SCOPE_RUNNING
);
320 static int scope_stop(Unit
*u
) {
325 if (s
->state
== SCOPE_STOP_SIGTERM
||
326 s
->state
== SCOPE_STOP_SIGKILL
)
329 assert(s
->state
== SCOPE_RUNNING
||
330 s
->state
== SCOPE_ABANDONED
);
332 scope_enter_signal(s
, SCOPE_STOP_SIGTERM
, SCOPE_SUCCESS
);
336 static void scope_reset_failed(Unit
*u
) {
341 if (s
->state
== SCOPE_FAILED
)
342 scope_set_state(s
, SCOPE_DEAD
);
344 s
->result
= SCOPE_SUCCESS
;
347 static int scope_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
348 return unit_kill_common(u
, who
, signo
, -1, -1, error
);
351 static int scope_get_timeout(Unit
*u
, uint64_t *timeout
) {
355 if (!s
->timer_event_source
)
358 r
= sd_event_source_get_time(s
->timer_event_source
, timeout
);
365 static int scope_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
372 unit_serialize_item(u
, f
, "state", scope_state_to_string(s
->state
));
376 static int scope_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
384 if (streq(key
, "state")) {
387 state
= scope_state_from_string(value
);
389 log_unit_debug(u
, "Failed to parse state value: %s", value
);
391 s
->deserialized_state
= state
;
394 log_unit_debug(u
, "Unknown serialization key: %s", key
);
399 static bool scope_check_gc(Unit
*u
) {
402 /* Never clean up scopes that still have a process around,
403 * even if the scope is formally dead. */
408 return cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, u
->cgroup_path
) <= 0;
411 static void scope_notify_cgroup_empty_event(Unit
*u
) {
415 log_unit_debug(u
, "cgroup is empty");
417 if (IN_SET(s
->state
, SCOPE_RUNNING
, SCOPE_ABANDONED
, SCOPE_STOP_SIGTERM
, SCOPE_STOP_SIGKILL
))
418 scope_enter_dead(s
, SCOPE_SUCCESS
);
421 static void scope_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
423 /* If we get a SIGCHLD event for one of the processes we were
424 interested in, then we look for others to watch, under the
425 assumption that we'll sooner or later get a SIGCHLD for
426 them, as the original process we watched was probably the
427 parent of them, and they are hence now our children. */
429 unit_tidy_watch_pids(u
, 0, 0);
430 unit_watch_all_pids(u
);
432 /* If the PID set is empty now, then let's finish this off */
433 if (set_isempty(u
->pids
))
434 scope_notify_cgroup_empty_event(u
);
437 static int scope_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
438 Scope
*s
= SCOPE(userdata
);
441 assert(s
->timer_event_source
== source
);
445 case SCOPE_STOP_SIGTERM
:
446 if (s
->kill_context
.send_sigkill
) {
447 log_unit_warning(UNIT(s
), "Stopping timed out. Killing.");
448 scope_enter_signal(s
, SCOPE_STOP_SIGKILL
, SCOPE_FAILURE_TIMEOUT
);
450 log_unit_warning(UNIT(s
), "Stopping timed out. Skipping SIGKILL.");
451 scope_enter_dead(s
, SCOPE_FAILURE_TIMEOUT
);
456 case SCOPE_STOP_SIGKILL
:
457 log_unit_warning(UNIT(s
), "Still around after SIGKILL. Ignoring.");
458 scope_enter_dead(s
, SCOPE_FAILURE_TIMEOUT
);
462 assert_not_reached("Timeout at wrong time.");
468 int scope_abandon(Scope
*s
) {
471 if (unit_has_name(UNIT(s
), SPECIAL_INIT_SCOPE
))
474 if (!IN_SET(s
->state
, SCOPE_RUNNING
, SCOPE_ABANDONED
))
477 s
->controller
= mfree(s
->controller
);
479 /* The client is no longer watching the remaining processes,
480 * so let's step in here, under the assumption that the
481 * remaining processes will be sooner or later reassigned to
484 unit_tidy_watch_pids(UNIT(s
), 0, 0);
485 unit_watch_all_pids(UNIT(s
));
487 /* If the PID set is empty now, then let's finish this off */
488 if (set_isempty(UNIT(s
)->pids
))
489 scope_notify_cgroup_empty_event(UNIT(s
));
491 scope_set_state(s
, SCOPE_ABANDONED
);
496 _pure_
static UnitActiveState
scope_active_state(Unit
*u
) {
499 return state_translation_table
[SCOPE(u
)->state
];
502 _pure_
static const char *scope_sub_state_to_string(Unit
*u
) {
505 return scope_state_to_string(SCOPE(u
)->state
);
508 static void scope_enumerate(Manager
*m
) {
514 /* Let's unconditionally add the "init.scope" special unit
515 * that encapsulates PID 1. Note that PID 1 already is in the
516 * cgroup for this, we hence just need to allocate the object
517 * for it and that's it. */
519 u
= manager_get_unit(m
, SPECIAL_INIT_SCOPE
);
521 u
= unit_new(m
, sizeof(Scope
));
527 r
= unit_add_name(u
, SPECIAL_INIT_SCOPE
);
530 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
);
554 static const char* const scope_result_table
[_SCOPE_RESULT_MAX
] = {
555 [SCOPE_SUCCESS
] = "success",
556 [SCOPE_FAILURE_RESOURCES
] = "resources",
557 [SCOPE_FAILURE_TIMEOUT
] = "timeout",
560 DEFINE_STRING_TABLE_LOOKUP(scope_result
, ScopeResult
);
562 const UnitVTable scope_vtable
= {
563 .object_size
= sizeof(Scope
),
564 .cgroup_context_offset
= offsetof(Scope
, cgroup_context
),
565 .kill_context_offset
= offsetof(Scope
, kill_context
),
571 .private_section
= "Scope",
574 .no_instances
= true,
575 .can_transient
= true,
581 .coldplug
= scope_coldplug
,
585 .start
= scope_start
,
590 .get_timeout
= scope_get_timeout
,
592 .serialize
= scope_serialize
,
593 .deserialize_item
= scope_deserialize_item
,
595 .active_state
= scope_active_state
,
596 .sub_state_to_string
= scope_sub_state_to_string
,
598 .check_gc
= scope_check_gc
,
600 .sigchld_event
= scope_sigchld_event
,
602 .reset_failed
= scope_reset_failed
,
604 .notify_cgroup_empty
= scope_notify_cgroup_empty_event
,
606 .bus_vtable
= bus_scope_vtable
,
607 .bus_set_property
= bus_scope_set_property
,
608 .bus_commit_properties
= bus_scope_commit_properties
,
610 .enumerate
= scope_enumerate
,