scope.c revision 13b84ec7df103ce388910a2b868fe1668c1e27ef
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen This file is part of systemd.
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen Copyright 2013 Lennart Poettering
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen systemd is free software; you can redistribute it and/or modify it
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen under the terms of the GNU Lesser General Public License as published by
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen the Free Software Foundation; either version 2.1 of the License, or
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen (at your option) any later version.
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen systemd is distributed in the hope that it will be useful, but
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen WITHOUT ANY WARRANTY; without even the implied warranty of
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen Lesser General Public License for more details.
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen You should have received a copy of the GNU Lesser General Public License
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen along with systemd; If not, see <http://www.gnu.org/licenses/>.
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poetteringstatic const UnitActiveState state_translation_table[_SCOPE_STATE_MAX] = {
a4783bd17ad96f55b0fe83a50959da13555292bfZbigniew Jędrzejewski-Szmek assert(u->load_state == UNIT_STUB);
a4783bd17ad96f55b0fe83a50959da13555292bfZbigniew Jędrzejewski-Szmekstatic void scope_done(Unit *u) {
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chenstatic void scope_set_state(Scope *s, ScopeState state) {
a4783bd17ad96f55b0fe83a50959da13555292bfZbigniew Jędrzejewski-Szmek unit_unwatch_timer(UNIT(s), &s->timer_watch);
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poetteringstatic int scope_add_default_dependencies(Scope *s) {
ffbd2c4d45787ba5ba85a32db6551efba66a1ee6Nathaniel Chen /* Make sure scopes are unloaded on shutdown */
fea7838e7e0b2724f5e0bc028121a08b42995045Zbigniew Jędrzejewski-Szmek r = unit_add_two_dependencies_by_name(
6656aefb42385b468dd96867118d049f945cbf81WaLyong Cho if (set_size(s->pids) <= 0 && UNIT(s)->manager->n_reloading <= 0) {
a4783bd17ad96f55b0fe83a50959da13555292bfZbigniew Jędrzejewski-Szmek log_error_unit(UNIT(s)->id, "Scope %s has no PIDs. Refusing.", UNIT(s)->id);
6656aefb42385b468dd96867118d049f945cbf81WaLyong Cho if (!u->transient && UNIT(s)->manager->n_reloading <= 0)
6656aefb42385b468dd96867118d049f945cbf81WaLyong Cho if ((s->deserialized_state == SCOPE_STOP_SIGKILL || s->deserialized_state == SCOPE_STOP_SIGTERM)
6656aefb42385b468dd96867118d049f945cbf81WaLyong Cho r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_stop_usec, &s->timer_watch);
6656aefb42385b468dd96867118d049f945cbf81WaLyong Chostatic void scope_dump(Unit *u, FILE *f, const char *prefix) {
6656aefb42385b468dd96867118d049f945cbf81WaLyong Cho "%sScope State: %s\n"
6656aefb42385b468dd96867118d049f945cbf81WaLyong Cho "%sResult: %s\n",
a4783bd17ad96f55b0fe83a50959da13555292bfZbigniew Jędrzejewski-Szmek cgroup_context_dump(&s->cgroup_context, f, prefix);
a4783bd17ad96f55b0fe83a50959da13555292bfZbigniew Jędrzejewski-Szmekstatic void scope_enter_dead(Scope *s, ScopeResult f) {
a4783bd17ad96f55b0fe83a50959da13555292bfZbigniew Jędrzejewski-Szmek scope_set_state(s, s->result != SCOPE_SUCCESS ? SCOPE_FAILED : SCOPE_DEAD);
ae176752f9c91073d234448b28ae95b37b97b719Casey Schauflerstatic void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) {
ae176752f9c91073d234448b28ae95b37b97b719Casey Schaufler r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_stop_usec, &s->timer_watch);
ae176752f9c91073d234448b28ae95b37b97b719Casey Schaufler "%s failed to kill processes: %s", UNIT(s)->id, strerror(-r));
ae176752f9c91073d234448b28ae95b37b97b719Casey Schaufler scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
ae176752f9c91073d234448b28ae95b37b97b719Casey Schaufler if (!u->transient && UNIT(s)->manager->n_reloading <= 0)
ae176752f9c91073d234448b28ae95b37b97b719Casey Schaufler log_error("Failed to realize cgroup: %s", strerror(-r));
ae176752f9c91073d234448b28ae95b37b97b719Casey Schaufler r = cg_attach_many_everywhere(u->manager->cgroup_supported, u->cgroup_path, s->pids);
a4783bd17ad96f55b0fe83a50959da13555292bfZbigniew Jędrzejewski-Szmek if (s->state == SCOPE_STOP_SIGTERM ||
a4783bd17ad96f55b0fe83a50959da13555292bfZbigniew Jędrzejewski-Szmek scope_enter_signal(s, SCOPE_STOP_SIGTERM, SCOPE_SUCCESS);
ae176752f9c91073d234448b28ae95b37b97b719Casey Schauflerstatic int scope_kill(Unit *u, KillWho who, int signo, DBusError *error) {
ae176752f9c91073d234448b28ae95b37b97b719Casey Schaufler return unit_kill_common(u, who, signo, -1, -1, error);
ae176752f9c91073d234448b28ae95b37b97b719Casey Schauflerstatic int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
abbacb1defaaecb8d2477685f7bb3fabcf58585bNathaniel Chen unit_serialize_item(u, f, "state", scope_state_to_string(s->state));
6656aefb42385b468dd96867118d049f945cbf81WaLyong Chostatic int scope_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
ae176752f9c91073d234448b28ae95b37b97b719Casey Schaufler log_debug("Failed to parse state value %s", value);
ae176752f9c91073d234448b28ae95b37b97b719Casey Schaufler log_debug("Unknown serialization key '%s'", key);
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski /* Never clean up scopes that still have a process around,
2b3e18de74ca89b374dd4f7a2c30e5731d347841Karol Lewandowski * even if the scope is formally dead. */
assert(s);
switch (s->state) {
case SCOPE_STOP_SIGTERM:
case SCOPE_STOP_SIGKILL:
assert(u);
switch (s->state) {
case SCOPE_RUNNING:
case SCOPE_STOP_SIGTERM:
case SCOPE_STOP_SIGKILL:
assert(u);
assert(u);
.sections =
.no_alias = true,
.no_instances = true,
.can_transient = true