1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2013 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include "alloc-util.h"
25 #include "dbus-scope.h"
26 #include "load-dropin.h"
30 #include "string-table.h"
31 #include "string-util.h"
33 #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
;
54 u
->ignore_on_isolate
= true;
57 static void scope_done(Unit
*u
) {
62 s
->controller
= mfree(s
->controller
);
63 s
->controller_track
= sd_bus_track_unref(s
->controller_track
);
65 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
68 static int scope_arm_timer(Scope
*s
, usec_t usec
) {
73 if (s
->timer_event_source
) {
74 r
= sd_event_source_set_time(s
->timer_event_source
, usec
);
78 return sd_event_source_set_enabled(s
->timer_event_source
, SD_EVENT_ONESHOT
);
81 if (usec
== USEC_INFINITY
)
84 r
= sd_event_add_time(
85 UNIT(s
)->manager
->event
,
86 &s
->timer_event_source
,
89 scope_dispatch_timer
, s
);
93 (void) sd_event_source_set_description(s
->timer_event_source
, "scope-timer");
98 static void scope_set_state(Scope
*s
, ScopeState state
) {
102 old_state
= s
->state
;
105 if (!IN_SET(state
, SCOPE_STOP_SIGTERM
, SCOPE_STOP_SIGKILL
))
106 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
108 if (IN_SET(state
, SCOPE_DEAD
, SCOPE_FAILED
))
109 unit_unwatch_all_pids(UNIT(s
));
111 if (state
!= old_state
)
112 log_debug("%s changed %s -> %s", UNIT(s
)->id
, scope_state_to_string(old_state
), scope_state_to_string(state
));
114 unit_notify(UNIT(s
), state_translation_table
[old_state
], state_translation_table
[state
], true);
117 static int scope_add_default_dependencies(Scope
*s
) {
122 if (!UNIT(s
)->default_dependencies
)
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,
130 UNIT_DEPENDENCY_DEFAULT
);
137 static int scope_verify(Scope
*s
) {
140 if (UNIT(s
)->load_state
!= UNIT_LOADED
)
143 if (set_isempty(UNIT(s
)->pids
) &&
144 !MANAGER_IS_RELOADING(UNIT(s
)->manager
) &&
145 !unit_has_name(UNIT(s
), SPECIAL_INIT_SCOPE
)) {
146 log_unit_error(UNIT(s
), "Scope has no PIDs. Refusing.");
153 static int scope_load_init_scope(Unit
*u
) {
156 if (!unit_has_name(u
, SPECIAL_INIT_SCOPE
))
162 /* init.scope is a bit special, as it has to stick around forever. Because of its special semantics we
163 * synthesize it here, instead of relying on the unit file on disk. */
165 u
->default_dependencies
= false;
166 u
->ignore_on_isolate
= true;
168 SCOPE(u
)->kill_context
.kill_signal
= SIGRTMIN
+14;
170 /* Prettify things, if we can. */
172 u
->description
= strdup("System and Service Manager");
173 if (!u
->documentation
)
174 (void) strv_extend(&u
->documentation
, "man:systemd(1)");
179 static int scope_load(Unit
*u
) {
184 assert(u
->load_state
== UNIT_STUB
);
186 if (!u
->transient
&& !MANAGER_IS_RELOADING(u
->manager
))
187 /* Refuse to load non-transient scope units, but allow them while reloading. */
190 r
= scope_load_init_scope(u
);
193 r
= unit_load_fragment_and_dropin_optional(u
);
197 if (u
->load_state
== UNIT_LOADED
) {
198 r
= unit_patch_contexts(u
);
202 r
= unit_set_default_slice(u
);
206 r
= scope_add_default_dependencies(s
);
211 return scope_verify(s
);
214 static int scope_coldplug(Unit
*u
) {
219 assert(s
->state
== SCOPE_DEAD
);
221 if (s
->deserialized_state
== s
->state
)
224 if (IN_SET(s
->deserialized_state
, SCOPE_STOP_SIGKILL
, SCOPE_STOP_SIGTERM
)) {
225 r
= scope_arm_timer(s
, usec_add(u
->state_change_timestamp
.monotonic
, s
->timeout_stop_usec
));
230 if (!IN_SET(s
->deserialized_state
, SCOPE_DEAD
, SCOPE_FAILED
))
231 unit_watch_all_pids(UNIT(s
));
233 bus_scope_track_controller(s
);
235 scope_set_state(s
, s
->deserialized_state
);
239 static void scope_dump(Unit
*u
, FILE *f
, const char *prefix
) {
246 "%sScope State: %s\n"
248 prefix
, scope_state_to_string(s
->state
),
249 prefix
, scope_result_to_string(s
->result
));
251 cgroup_context_dump(&s
->cgroup_context
, f
, prefix
);
252 kill_context_dump(&s
->kill_context
, f
, prefix
);
255 static void scope_enter_dead(Scope
*s
, ScopeResult f
) {
258 if (s
->result
== SCOPE_SUCCESS
)
261 if (s
->result
!= SCOPE_SUCCESS
)
262 log_unit_warning(UNIT(s
), "Failed with result '%s'.", scope_result_to_string(s
->result
));
264 scope_set_state(s
, s
->result
!= SCOPE_SUCCESS
? SCOPE_FAILED
: SCOPE_DEAD
);
267 static void scope_enter_signal(Scope
*s
, ScopeState state
, ScopeResult f
) {
268 bool skip_signal
= false;
273 if (s
->result
== SCOPE_SUCCESS
)
276 unit_watch_all_pids(UNIT(s
));
278 /* If we have a controller set let's ask the controller nicely to terminate the scope, instead of us going
279 * directly into SIGTERM berserk mode */
280 if (state
== SCOPE_STOP_SIGTERM
)
281 skip_signal
= bus_scope_send_request_stop(s
) > 0;
286 r
= unit_kill_context(
289 state
!= SCOPE_STOP_SIGTERM
? KILL_KILL
:
290 s
->was_abandoned
? KILL_TERMINATE_AND_LOG
:
298 r
= scope_arm_timer(s
, usec_add(now(CLOCK_MONOTONIC
), s
->timeout_stop_usec
));
302 scope_set_state(s
, state
);
303 } else if (state
== SCOPE_STOP_SIGTERM
)
304 scope_enter_signal(s
, SCOPE_STOP_SIGKILL
, SCOPE_SUCCESS
);
306 scope_enter_dead(s
, SCOPE_SUCCESS
);
311 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
313 scope_enter_dead(s
, SCOPE_FAILURE_RESOURCES
);
316 static int scope_start(Unit
*u
) {
322 if (unit_has_name(u
, SPECIAL_INIT_SCOPE
))
325 if (s
->state
== SCOPE_FAILED
)
328 /* We can't fulfill this right now, please try again later */
329 if (IN_SET(s
->state
, SCOPE_STOP_SIGTERM
, SCOPE_STOP_SIGKILL
))
332 assert(s
->state
== SCOPE_DEAD
);
334 if (!u
->transient
&& !MANAGER_IS_RELOADING(u
->manager
))
337 (void) bus_scope_track_controller(s
);
339 r
= unit_acquire_invocation_id(u
);
343 (void) unit_realize_cgroup(u
);
344 (void) unit_reset_cpu_accounting(u
);
345 (void) unit_reset_ip_accounting(u
);
347 unit_export_state_files(UNIT(s
));
349 r
= unit_attach_pids_to_cgroup(u
);
351 log_unit_warning_errno(UNIT(s
), r
, "Failed to add PIDs to scope's control group: %m");
352 scope_enter_dead(s
, SCOPE_FAILURE_RESOURCES
);
356 s
->result
= SCOPE_SUCCESS
;
358 scope_set_state(s
, SCOPE_RUNNING
);
362 static int scope_stop(Unit
*u
) {
367 if (IN_SET(s
->state
, SCOPE_STOP_SIGTERM
, SCOPE_STOP_SIGKILL
))
370 assert(IN_SET(s
->state
, SCOPE_RUNNING
, SCOPE_ABANDONED
));
372 scope_enter_signal(s
, SCOPE_STOP_SIGTERM
, SCOPE_SUCCESS
);
376 static void scope_reset_failed(Unit
*u
) {
381 if (s
->state
== SCOPE_FAILED
)
382 scope_set_state(s
, SCOPE_DEAD
);
384 s
->result
= SCOPE_SUCCESS
;
387 static int scope_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
388 return unit_kill_common(u
, who
, signo
, -1, -1, error
);
391 static int scope_get_timeout(Unit
*u
, usec_t
*timeout
) {
396 if (!s
->timer_event_source
)
399 r
= sd_event_source_get_time(s
->timer_event_source
, &t
);
402 if (t
== USEC_INFINITY
)
409 static int scope_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
416 unit_serialize_item(u
, f
, "state", scope_state_to_string(s
->state
));
417 unit_serialize_item(u
, f
, "was-abandoned", yes_no(s
->was_abandoned
));
420 unit_serialize_item(u
, f
, "controller", s
->controller
);
425 static int scope_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
434 if (streq(key
, "state")) {
437 state
= scope_state_from_string(value
);
439 log_unit_debug(u
, "Failed to parse state value: %s", value
);
441 s
->deserialized_state
= state
;
443 } else if (streq(key
, "was-abandoned")) {
446 k
= parse_boolean(value
);
448 log_unit_debug(u
, "Failed to parse boolean value: %s", value
);
450 s
->was_abandoned
= k
;
451 } else if (streq(key
, "controller")) {
453 r
= free_and_strdup(&s
->controller
, value
);
458 log_unit_debug(u
, "Unknown serialization key: %s", key
);
463 static void scope_notify_cgroup_empty_event(Unit
*u
) {
467 log_unit_debug(u
, "cgroup is empty");
469 if (IN_SET(s
->state
, SCOPE_RUNNING
, SCOPE_ABANDONED
, SCOPE_STOP_SIGTERM
, SCOPE_STOP_SIGKILL
))
470 scope_enter_dead(s
, SCOPE_SUCCESS
);
473 static void scope_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
475 /* If we get a SIGCHLD event for one of the processes we were
476 interested in, then we look for others to watch, under the
477 assumption that we'll sooner or later get a SIGCHLD for
478 them, as the original process we watched was probably the
479 parent of them, and they are hence now our children. */
481 unit_tidy_watch_pids(u
, 0, 0);
482 unit_watch_all_pids(u
);
484 /* If the PID set is empty now, then let's finish this off
485 (On unified we use proper notifications) */
486 if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER
) == 0 && set_isempty(u
->pids
))
487 scope_notify_cgroup_empty_event(u
);
490 static int scope_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
491 Scope
*s
= SCOPE(userdata
);
494 assert(s
->timer_event_source
== source
);
498 case SCOPE_STOP_SIGTERM
:
499 if (s
->kill_context
.send_sigkill
) {
500 log_unit_warning(UNIT(s
), "Stopping timed out. Killing.");
501 scope_enter_signal(s
, SCOPE_STOP_SIGKILL
, SCOPE_FAILURE_TIMEOUT
);
503 log_unit_warning(UNIT(s
), "Stopping timed out. Skipping SIGKILL.");
504 scope_enter_dead(s
, SCOPE_FAILURE_TIMEOUT
);
509 case SCOPE_STOP_SIGKILL
:
510 log_unit_warning(UNIT(s
), "Still around after SIGKILL. Ignoring.");
511 scope_enter_dead(s
, SCOPE_FAILURE_TIMEOUT
);
515 assert_not_reached("Timeout at wrong time.");
521 int scope_abandon(Scope
*s
) {
524 if (unit_has_name(UNIT(s
), SPECIAL_INIT_SCOPE
))
527 if (!IN_SET(s
->state
, SCOPE_RUNNING
, SCOPE_ABANDONED
))
530 s
->was_abandoned
= true;
532 s
->controller
= mfree(s
->controller
);
533 s
->controller_track
= sd_bus_track_unref(s
->controller_track
);
535 scope_set_state(s
, SCOPE_ABANDONED
);
537 /* The client is no longer watching the remaining processes,
538 * so let's step in here, under the assumption that the
539 * remaining processes will be sooner or later reassigned to
542 unit_tidy_watch_pids(UNIT(s
), 0, 0);
543 unit_watch_all_pids(UNIT(s
));
548 _pure_
static UnitActiveState
scope_active_state(Unit
*u
) {
551 return state_translation_table
[SCOPE(u
)->state
];
554 _pure_
static const char *scope_sub_state_to_string(Unit
*u
) {
557 return scope_state_to_string(SCOPE(u
)->state
);
560 static void scope_enumerate(Manager
*m
) {
566 /* Let's unconditionally add the "init.scope" special unit
567 * that encapsulates PID 1. Note that PID 1 already is in the
568 * cgroup for this, we hence just need to allocate the object
569 * for it and that's it. */
571 u
= manager_get_unit(m
, SPECIAL_INIT_SCOPE
);
573 r
= unit_new_for_name(m
, sizeof(Scope
), SPECIAL_INIT_SCOPE
, &u
);
575 log_error_errno(r
, "Failed to allocate the special " SPECIAL_INIT_SCOPE
" unit: %m");
582 SCOPE(u
)->deserialized_state
= SCOPE_RUNNING
;
584 unit_add_to_load_queue(u
);
585 unit_add_to_dbus_queue(u
);
588 static const char* const scope_result_table
[_SCOPE_RESULT_MAX
] = {
589 [SCOPE_SUCCESS
] = "success",
590 [SCOPE_FAILURE_RESOURCES
] = "resources",
591 [SCOPE_FAILURE_TIMEOUT
] = "timeout",
594 DEFINE_STRING_TABLE_LOOKUP(scope_result
, ScopeResult
);
596 const UnitVTable scope_vtable
= {
597 .object_size
= sizeof(Scope
),
598 .cgroup_context_offset
= offsetof(Scope
, cgroup_context
),
599 .kill_context_offset
= offsetof(Scope
, kill_context
),
605 .private_section
= "Scope",
607 .can_transient
= true,
613 .coldplug
= scope_coldplug
,
617 .start
= scope_start
,
622 .get_timeout
= scope_get_timeout
,
624 .serialize
= scope_serialize
,
625 .deserialize_item
= scope_deserialize_item
,
627 .active_state
= scope_active_state
,
628 .sub_state_to_string
= scope_sub_state_to_string
,
630 .sigchld_event
= scope_sigchld_event
,
632 .reset_failed
= scope_reset_failed
,
634 .notify_cgroup_empty
= scope_notify_cgroup_empty_event
,
636 .bus_vtable
= bus_scope_vtable
,
637 .bus_set_property
= bus_scope_set_property
,
638 .bus_commit_properties
= bus_scope_commit_properties
,
640 .enumerate
= scope_enumerate
,