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-table.h"
30 #include "string-util.h"
32 #include "unit-name.h"
36 static const UnitActiveState state_translation_table
[_SCOPE_STATE_MAX
] = {
37 [SCOPE_DEAD
] = UNIT_INACTIVE
,
38 [SCOPE_RUNNING
] = UNIT_ACTIVE
,
39 [SCOPE_ABANDONED
] = UNIT_ACTIVE
,
40 [SCOPE_STOP_SIGTERM
] = UNIT_DEACTIVATING
,
41 [SCOPE_STOP_SIGKILL
] = UNIT_DEACTIVATING
,
42 [SCOPE_FAILED
] = UNIT_FAILED
45 static int scope_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
47 static void scope_init(Unit
*u
) {
51 assert(u
->load_state
== UNIT_STUB
);
53 s
->timeout_stop_usec
= u
->manager
->default_timeout_stop_usec
;
55 UNIT(s
)->ignore_on_isolate
= true;
56 UNIT(s
)->ignore_on_snapshot
= 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 /* Make sure scopes are unloaded on shutdown */
126 r
= unit_add_two_dependencies_by_name(
128 UNIT_BEFORE
, UNIT_CONFLICTS
,
129 SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
136 static int scope_verify(Scope
*s
) {
139 if (UNIT(s
)->load_state
!= UNIT_LOADED
)
142 if (set_isempty(UNIT(s
)->pids
) &&
143 !manager_is_reloading_or_reexecuting(UNIT(s
)->manager
) &&
144 !unit_has_name(UNIT(s
), SPECIAL_INIT_SCOPE
)) {
145 log_unit_error(UNIT(s
), "Scope has no PIDs. Refusing.");
152 static int scope_load(Unit
*u
) {
157 assert(u
->load_state
== UNIT_STUB
);
159 if (!u
->transient
&& !manager_is_reloading_or_reexecuting(u
->manager
))
162 u
->load_state
= UNIT_LOADED
;
164 r
= unit_load_dropin(u
);
168 r
= unit_patch_contexts(u
);
172 r
= unit_set_default_slice(u
);
176 if (u
->default_dependencies
) {
177 r
= scope_add_default_dependencies(s
);
182 return scope_verify(s
);
185 static int scope_coldplug(Unit
*u
) {
190 assert(s
->state
== SCOPE_DEAD
);
192 if (s
->deserialized_state
!= s
->state
) {
194 if (IN_SET(s
->deserialized_state
, SCOPE_STOP_SIGKILL
, SCOPE_STOP_SIGTERM
)) {
195 r
= scope_arm_timer(s
);
200 if (!IN_SET(s
->deserialized_state
, SCOPE_DEAD
, SCOPE_FAILED
))
201 unit_watch_all_pids(UNIT(s
));
203 scope_set_state(s
, s
->deserialized_state
);
209 static void scope_dump(Unit
*u
, FILE *f
, const char *prefix
) {
216 "%sScope State: %s\n"
218 prefix
, scope_state_to_string(s
->state
),
219 prefix
, scope_result_to_string(s
->result
));
221 cgroup_context_dump(&s
->cgroup_context
, f
, prefix
);
222 kill_context_dump(&s
->kill_context
, f
, prefix
);
225 static void scope_enter_dead(Scope
*s
, ScopeResult f
) {
228 if (f
!= SCOPE_SUCCESS
)
231 scope_set_state(s
, s
->result
!= SCOPE_SUCCESS
? SCOPE_FAILED
: SCOPE_DEAD
);
234 static void scope_enter_signal(Scope
*s
, ScopeState state
, ScopeResult f
) {
235 bool skip_signal
= false;
240 if (f
!= SCOPE_SUCCESS
)
243 unit_watch_all_pids(UNIT(s
));
245 /* If we have a controller set let's ask the controller nicely
246 * to terminate the scope, instead of us going directly into
247 * SIGTERM beserk mode */
248 if (state
== SCOPE_STOP_SIGTERM
)
249 skip_signal
= bus_scope_send_request_stop(s
) > 0;
252 r
= unit_kill_context(
255 state
!= SCOPE_STOP_SIGTERM
? KILL_KILL
: KILL_TERMINATE
,
263 r
= scope_arm_timer(s
);
267 scope_set_state(s
, state
);
268 } else if (state
== SCOPE_STOP_SIGTERM
)
269 scope_enter_signal(s
, SCOPE_STOP_SIGKILL
, SCOPE_SUCCESS
);
271 scope_enter_dead(s
, SCOPE_SUCCESS
);
276 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
278 scope_enter_dead(s
, SCOPE_FAILURE_RESOURCES
);
281 static int scope_start(Unit
*u
) {
287 if (unit_has_name(u
, SPECIAL_INIT_SCOPE
))
290 if (s
->state
== SCOPE_FAILED
)
293 /* We can't fulfill this right now, please try again later */
294 if (s
->state
== SCOPE_STOP_SIGTERM
||
295 s
->state
== SCOPE_STOP_SIGKILL
)
298 assert(s
->state
== SCOPE_DEAD
);
300 if (!u
->transient
&& !manager_is_reloading_or_reexecuting(u
->manager
))
303 (void) unit_realize_cgroup(u
);
304 (void) unit_reset_cpu_usage(u
);
306 r
= unit_attach_pids_to_cgroup(u
);
308 log_unit_warning_errno(UNIT(s
), r
, "Failed to add PIDs to scope's control group: %m");
309 scope_enter_dead(s
, SCOPE_FAILURE_RESOURCES
);
313 s
->result
= SCOPE_SUCCESS
;
315 scope_set_state(s
, SCOPE_RUNNING
);
319 static int scope_stop(Unit
*u
) {
324 if (s
->state
== SCOPE_STOP_SIGTERM
||
325 s
->state
== SCOPE_STOP_SIGKILL
)
328 assert(s
->state
== SCOPE_RUNNING
||
329 s
->state
== SCOPE_ABANDONED
);
331 scope_enter_signal(s
, SCOPE_STOP_SIGTERM
, SCOPE_SUCCESS
);
335 static void scope_reset_failed(Unit
*u
) {
340 if (s
->state
== SCOPE_FAILED
)
341 scope_set_state(s
, SCOPE_DEAD
);
343 s
->result
= SCOPE_SUCCESS
;
346 static int scope_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
347 return unit_kill_common(u
, who
, signo
, -1, -1, error
);
350 static int scope_get_timeout(Unit
*u
, uint64_t *timeout
) {
354 if (!s
->timer_event_source
)
357 r
= sd_event_source_get_time(s
->timer_event_source
, timeout
);
364 static int scope_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
371 unit_serialize_item(u
, f
, "state", scope_state_to_string(s
->state
));
375 static int scope_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
383 if (streq(key
, "state")) {
386 state
= scope_state_from_string(value
);
388 log_unit_debug(u
, "Failed to parse state value: %s", value
);
390 s
->deserialized_state
= state
;
393 log_unit_debug(u
, "Unknown serialization key: %s", key
);
398 static bool scope_check_gc(Unit
*u
) {
401 /* Never clean up scopes that still have a process around,
402 * even if the scope is formally dead. */
404 if (u
->cgroup_path
) {
407 r
= cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, u
->cgroup_path
);
415 static void scope_notify_cgroup_empty_event(Unit
*u
) {
419 log_unit_debug(u
, "cgroup is empty");
421 if (IN_SET(s
->state
, SCOPE_RUNNING
, SCOPE_ABANDONED
, SCOPE_STOP_SIGTERM
, SCOPE_STOP_SIGKILL
))
422 scope_enter_dead(s
, SCOPE_SUCCESS
);
425 static void scope_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
427 /* If we get a SIGCHLD event for one of the processes we were
428 interested in, then we look for others to watch, under the
429 assumption that we'll sooner or later get a SIGCHLD for
430 them, as the original process we watched was probably the
431 parent of them, and they are hence now our children. */
433 unit_tidy_watch_pids(u
, 0, 0);
434 unit_watch_all_pids(u
);
436 /* If the PID set is empty now, then let's finish this off */
437 if (set_isempty(u
->pids
))
438 scope_notify_cgroup_empty_event(u
);
441 static int scope_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
442 Scope
*s
= SCOPE(userdata
);
445 assert(s
->timer_event_source
== source
);
449 case SCOPE_STOP_SIGTERM
:
450 if (s
->kill_context
.send_sigkill
) {
451 log_unit_warning(UNIT(s
), "Stopping timed out. Killing.");
452 scope_enter_signal(s
, SCOPE_STOP_SIGKILL
, SCOPE_FAILURE_TIMEOUT
);
454 log_unit_warning(UNIT(s
), "Stopping timed out. Skipping SIGKILL.");
455 scope_enter_dead(s
, SCOPE_FAILURE_TIMEOUT
);
460 case SCOPE_STOP_SIGKILL
:
461 log_unit_warning(UNIT(s
), "Still around after SIGKILL. Ignoring.");
462 scope_enter_dead(s
, SCOPE_FAILURE_TIMEOUT
);
466 assert_not_reached("Timeout at wrong time.");
472 int scope_abandon(Scope
*s
) {
475 if (unit_has_name(UNIT(s
), SPECIAL_INIT_SCOPE
))
478 if (!IN_SET(s
->state
, SCOPE_RUNNING
, SCOPE_ABANDONED
))
481 s
->controller
= mfree(s
->controller
);
483 /* The client is no longer watching the remaining processes,
484 * so let's step in here, under the assumption that the
485 * remaining processes will be sooner or later reassigned to
488 unit_tidy_watch_pids(UNIT(s
), 0, 0);
489 unit_watch_all_pids(UNIT(s
));
491 /* If the PID set is empty now, then let's finish this off */
492 if (set_isempty(UNIT(s
)->pids
))
493 scope_notify_cgroup_empty_event(UNIT(s
));
495 scope_set_state(s
, SCOPE_ABANDONED
);
500 _pure_
static UnitActiveState
scope_active_state(Unit
*u
) {
503 return state_translation_table
[SCOPE(u
)->state
];
506 _pure_
static const char *scope_sub_state_to_string(Unit
*u
) {
509 return scope_state_to_string(SCOPE(u
)->state
);
512 static int scope_enumerate(Manager
*m
) {
518 /* Let's unconditionally add the "init.scope" special unit
519 * that encapsulates PID 1. Note that PID 1 already is in the
520 * cgroup for this, we hence just need to allocate the object
521 * for it and that's it. */
523 u
= manager_get_unit(m
, SPECIAL_INIT_SCOPE
);
525 u
= unit_new(m
, sizeof(Scope
));
529 r
= unit_add_name(u
, SPECIAL_INIT_SCOPE
);
532 return log_error_errno(r
, "Failed to add init.scope name");
537 u
->default_dependencies
= false;
539 u
->ignore_on_isolate
= true;
540 u
->refuse_manual_start
= true;
541 u
->refuse_manual_stop
= true;
542 SCOPE(u
)->deserialized_state
= SCOPE_RUNNING
;
543 SCOPE(u
)->kill_context
.kill_signal
= SIGRTMIN
+14;
545 /* Prettify things, if we can. */
547 u
->description
= strdup("System and Service Manager");
548 if (!u
->documentation
)
549 (void) strv_extend(&u
->documentation
, "man:systemd(1)");
551 unit_add_to_load_queue(u
);
552 unit_add_to_dbus_queue(u
);
557 static const char* const scope_result_table
[_SCOPE_RESULT_MAX
] = {
558 [SCOPE_SUCCESS
] = "success",
559 [SCOPE_FAILURE_RESOURCES
] = "resources",
560 [SCOPE_FAILURE_TIMEOUT
] = "timeout",
563 DEFINE_STRING_TABLE_LOOKUP(scope_result
, ScopeResult
);
565 const UnitVTable scope_vtable
= {
566 .object_size
= sizeof(Scope
),
567 .cgroup_context_offset
= offsetof(Scope
, cgroup_context
),
568 .kill_context_offset
= offsetof(Scope
, kill_context
),
574 .private_section
= "Scope",
577 .no_instances
= true,
583 .coldplug
= scope_coldplug
,
587 .start
= scope_start
,
592 .get_timeout
= scope_get_timeout
,
594 .serialize
= scope_serialize
,
595 .deserialize_item
= scope_deserialize_item
,
597 .active_state
= scope_active_state
,
598 .sub_state_to_string
= scope_sub_state_to_string
,
600 .check_gc
= scope_check_gc
,
602 .sigchld_event
= scope_sigchld_event
,
604 .reset_failed
= scope_reset_failed
,
606 .notify_cgroup_empty
= scope_notify_cgroup_empty_event
,
608 .bus_vtable
= bus_scope_vtable
,
609 .bus_set_property
= bus_scope_set_property
,
610 .bus_commit_properties
= bus_scope_commit_properties
,
612 .can_transient
= true,
614 .enumerate
= scope_enumerate
,