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 "dbus-scope.h"
30 #include "unit-name.h"
31 #include "load-dropin.h"
33 static const UnitActiveState state_translation_table
[_SCOPE_STATE_MAX
] = {
34 [SCOPE_DEAD
] = UNIT_INACTIVE
,
35 [SCOPE_RUNNING
] = UNIT_ACTIVE
,
36 [SCOPE_ABANDONED
] = UNIT_ACTIVE
,
37 [SCOPE_STOP_SIGTERM
] = UNIT_DEACTIVATING
,
38 [SCOPE_STOP_SIGKILL
] = UNIT_DEACTIVATING
,
39 [SCOPE_FAILED
] = UNIT_FAILED
42 static int scope_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
44 static void scope_init(Unit
*u
) {
48 assert(u
->load_state
== UNIT_STUB
);
50 s
->timeout_stop_usec
= u
->manager
->default_timeout_stop_usec
;
52 UNIT(s
)->ignore_on_isolate
= true;
53 UNIT(s
)->ignore_on_snapshot
= true;
56 static void scope_done(Unit
*u
) {
63 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
66 static int scope_arm_timer(Scope
*s
) {
71 if (s
->timeout_stop_usec
<= 0) {
72 s
->timer_event_source
= sd_event_source_unref(s
->timer_event_source
);
76 if (s
->timer_event_source
) {
77 r
= sd_event_source_set_time(s
->timer_event_source
, now(CLOCK_MONOTONIC
) + s
->timeout_stop_usec
);
81 return sd_event_source_set_enabled(s
->timer_event_source
, SD_EVENT_ONESHOT
);
84 r
= sd_event_add_time(
85 UNIT(s
)->manager
->event
,
86 &s
->timer_event_source
,
88 now(CLOCK_MONOTONIC
) + s
->timeout_stop_usec
, 0,
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 /* Make sure scopes are unloaded on shutdown */
123 r
= unit_add_two_dependencies_by_name(
125 UNIT_BEFORE
, UNIT_CONFLICTS
,
126 SPECIAL_SHUTDOWN_TARGET
, NULL
, true);
133 static int scope_verify(Scope
*s
) {
136 if (UNIT(s
)->load_state
!= UNIT_LOADED
)
139 if (set_isempty(UNIT(s
)->pids
) && UNIT(s
)->manager
->n_reloading
<= 0) {
140 log_unit_error(UNIT(s
), "Scope has no PIDs. Refusing.");
147 static int scope_load(Unit
*u
) {
152 assert(u
->load_state
== UNIT_STUB
);
154 if (!u
->transient
&& UNIT(s
)->manager
->n_reloading
<= 0)
157 u
->load_state
= UNIT_LOADED
;
159 r
= unit_load_dropin(u
);
163 r
= unit_patch_contexts(u
);
167 r
= unit_set_default_slice(u
);
171 if (u
->default_dependencies
) {
172 r
= scope_add_default_dependencies(s
);
177 return scope_verify(s
);
180 static int scope_coldplug(Unit
*u
) {
185 assert(s
->state
== SCOPE_DEAD
);
187 if (s
->deserialized_state
!= s
->state
) {
189 if (IN_SET(s
->deserialized_state
, SCOPE_STOP_SIGKILL
, SCOPE_STOP_SIGTERM
)) {
190 r
= scope_arm_timer(s
);
195 if (!IN_SET(s
->deserialized_state
, SCOPE_DEAD
, SCOPE_FAILED
))
196 unit_watch_all_pids(UNIT(s
));
198 scope_set_state(s
, s
->deserialized_state
);
204 static void scope_dump(Unit
*u
, FILE *f
, const char *prefix
) {
211 "%sScope State: %s\n"
213 prefix
, scope_state_to_string(s
->state
),
214 prefix
, scope_result_to_string(s
->result
));
216 cgroup_context_dump(&s
->cgroup_context
, f
, prefix
);
217 kill_context_dump(&s
->kill_context
, f
, prefix
);
220 static void scope_enter_dead(Scope
*s
, ScopeResult f
) {
223 if (f
!= SCOPE_SUCCESS
)
226 scope_set_state(s
, s
->result
!= SCOPE_SUCCESS
? SCOPE_FAILED
: SCOPE_DEAD
);
229 static void scope_enter_signal(Scope
*s
, ScopeState state
, ScopeResult f
) {
230 bool skip_signal
= false;
235 if (f
!= SCOPE_SUCCESS
)
238 unit_watch_all_pids(UNIT(s
));
240 /* If we have a controller set let's ask the controller nicely
241 * to terminate the scope, instead of us going directly into
242 * SIGTERM beserk mode */
243 if (state
== SCOPE_STOP_SIGTERM
)
244 skip_signal
= bus_scope_send_request_stop(s
) > 0;
247 r
= unit_kill_context(
250 state
!= SCOPE_STOP_SIGTERM
? KILL_KILL
: KILL_TERMINATE
,
258 r
= scope_arm_timer(s
);
262 scope_set_state(s
, state
);
263 } else if (state
== SCOPE_STOP_SIGTERM
)
264 scope_enter_signal(s
, SCOPE_STOP_SIGKILL
, SCOPE_SUCCESS
);
266 scope_enter_dead(s
, SCOPE_SUCCESS
);
271 log_unit_warning_errno(UNIT(s
), r
, "Failed to kill processes: %m");
273 scope_enter_dead(s
, SCOPE_FAILURE_RESOURCES
);
276 static int scope_start(Unit
*u
) {
282 if (s
->state
== SCOPE_FAILED
)
285 /* We can't fulfill this right now, please try again later */
286 if (s
->state
== SCOPE_STOP_SIGTERM
||
287 s
->state
== SCOPE_STOP_SIGKILL
)
290 assert(s
->state
== SCOPE_DEAD
);
292 if (!u
->transient
&& UNIT(s
)->manager
->n_reloading
<= 0)
295 (void) unit_realize_cgroup(u
);
296 (void) unit_reset_cpu_usage(u
);
298 r
= unit_attach_pids_to_cgroup(u
);
300 log_unit_warning_errno(UNIT(s
), r
, "Failed to add PIDs to scope's control group: %m");
301 scope_enter_dead(s
, SCOPE_FAILURE_RESOURCES
);
305 s
->result
= SCOPE_SUCCESS
;
307 scope_set_state(s
, SCOPE_RUNNING
);
311 static int scope_stop(Unit
*u
) {
316 if (s
->state
== SCOPE_STOP_SIGTERM
||
317 s
->state
== SCOPE_STOP_SIGKILL
)
320 assert(s
->state
== SCOPE_RUNNING
||
321 s
->state
== SCOPE_ABANDONED
);
323 scope_enter_signal(s
, SCOPE_STOP_SIGTERM
, SCOPE_SUCCESS
);
327 static void scope_reset_failed(Unit
*u
) {
332 if (s
->state
== SCOPE_FAILED
)
333 scope_set_state(s
, SCOPE_DEAD
);
335 s
->result
= SCOPE_SUCCESS
;
338 static int scope_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
339 return unit_kill_common(u
, who
, signo
, -1, -1, error
);
342 static int scope_get_timeout(Unit
*u
, uint64_t *timeout
) {
346 if (!s
->timer_event_source
)
349 r
= sd_event_source_get_time(s
->timer_event_source
, timeout
);
356 static int scope_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
363 unit_serialize_item(u
, f
, "state", scope_state_to_string(s
->state
));
367 static int scope_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
375 if (streq(key
, "state")) {
378 state
= scope_state_from_string(value
);
380 log_unit_debug(u
, "Failed to parse state value: %s", value
);
382 s
->deserialized_state
= state
;
385 log_unit_debug(u
, "Unknown serialization key: %s", key
);
390 static bool scope_check_gc(Unit
*u
) {
393 /* Never clean up scopes that still have a process around,
394 * even if the scope is formally dead. */
396 if (u
->cgroup_path
) {
399 r
= cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, u
->cgroup_path
, true);
407 static void scope_notify_cgroup_empty_event(Unit
*u
) {
411 log_unit_debug(u
, "cgroup is empty");
413 if (IN_SET(s
->state
, SCOPE_RUNNING
, SCOPE_ABANDONED
, SCOPE_STOP_SIGTERM
, SCOPE_STOP_SIGKILL
))
414 scope_enter_dead(s
, SCOPE_SUCCESS
);
417 static void scope_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
419 /* If we get a SIGCHLD event for one of the processes we were
420 interested in, then we look for others to watch, under the
421 assumption that we'll sooner or later get a SIGCHLD for
422 them, as the original process we watched was probably the
423 parent of them, and they are hence now our children. */
425 unit_tidy_watch_pids(u
, 0, 0);
426 unit_watch_all_pids(u
);
428 /* If the PID set is empty now, then let's finish this off */
429 if (set_isempty(u
->pids
))
430 scope_notify_cgroup_empty_event(u
);
433 static int scope_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
434 Scope
*s
= SCOPE(userdata
);
437 assert(s
->timer_event_source
== source
);
441 case SCOPE_STOP_SIGTERM
:
442 if (s
->kill_context
.send_sigkill
) {
443 log_unit_warning(UNIT(s
), "Stopping timed out. Killing.");
444 scope_enter_signal(s
, SCOPE_STOP_SIGKILL
, SCOPE_FAILURE_TIMEOUT
);
446 log_unit_warning(UNIT(s
), "Stopping timed out. Skipping SIGKILL.");
447 scope_enter_dead(s
, SCOPE_FAILURE_TIMEOUT
);
452 case SCOPE_STOP_SIGKILL
:
453 log_unit_warning(UNIT(s
), "Still around after SIGKILL. Ignoring.");
454 scope_enter_dead(s
, SCOPE_FAILURE_TIMEOUT
);
458 assert_not_reached("Timeout at wrong time.");
464 int scope_abandon(Scope
*s
) {
467 if (!IN_SET(s
->state
, SCOPE_RUNNING
, SCOPE_ABANDONED
))
471 s
->controller
= NULL
;
473 /* The client is no longer watching the remaining processes,
474 * so let's step in here, under the assumption that the
475 * remaining processes will be sooner or later reassigned to
478 unit_tidy_watch_pids(UNIT(s
), 0, 0);
479 unit_watch_all_pids(UNIT(s
));
481 /* If the PID set is empty now, then let's finish this off */
482 if (set_isempty(UNIT(s
)->pids
))
483 scope_notify_cgroup_empty_event(UNIT(s
));
485 scope_set_state(s
, SCOPE_ABANDONED
);
490 _pure_
static UnitActiveState
scope_active_state(Unit
*u
) {
493 return state_translation_table
[SCOPE(u
)->state
];
496 _pure_
static const char *scope_sub_state_to_string(Unit
*u
) {
499 return scope_state_to_string(SCOPE(u
)->state
);
502 static const char* const scope_state_table
[_SCOPE_STATE_MAX
] = {
503 [SCOPE_DEAD
] = "dead",
504 [SCOPE_RUNNING
] = "running",
505 [SCOPE_ABANDONED
] = "abandoned",
506 [SCOPE_STOP_SIGTERM
] = "stop-sigterm",
507 [SCOPE_STOP_SIGKILL
] = "stop-sigkill",
508 [SCOPE_FAILED
] = "failed",
511 DEFINE_STRING_TABLE_LOOKUP(scope_state
, ScopeState
);
513 static const char* const scope_result_table
[_SCOPE_RESULT_MAX
] = {
514 [SCOPE_SUCCESS
] = "success",
515 [SCOPE_FAILURE_RESOURCES
] = "resources",
516 [SCOPE_FAILURE_TIMEOUT
] = "timeout",
519 DEFINE_STRING_TABLE_LOOKUP(scope_result
, ScopeResult
);
521 const UnitVTable scope_vtable
= {
522 .object_size
= sizeof(Scope
),
523 .cgroup_context_offset
= offsetof(Scope
, cgroup_context
),
524 .kill_context_offset
= offsetof(Scope
, kill_context
),
530 .private_section
= "Scope",
533 .no_instances
= true,
539 .coldplug
= scope_coldplug
,
543 .start
= scope_start
,
548 .get_timeout
= scope_get_timeout
,
550 .serialize
= scope_serialize
,
551 .deserialize_item
= scope_deserialize_item
,
553 .active_state
= scope_active_state
,
554 .sub_state_to_string
= scope_sub_state_to_string
,
556 .check_gc
= scope_check_gc
,
558 .sigchld_event
= scope_sigchld_event
,
560 .reset_failed
= scope_reset_failed
,
562 .notify_cgroup_empty
= scope_notify_cgroup_empty_event
,
564 .bus_vtable
= bus_scope_vtable
,
565 .bus_set_property
= bus_scope_set_property
,
566 .bus_commit_properties
= bus_scope_commit_properties
,
568 .can_transient
= true