]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/scope.c
core: pull in dbus.socket from Type=dbus services
[thirdparty/systemd.git] / src / core / scope.c
CommitLineData
6c12b52e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
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.
12
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.
17
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/>.
20***/
21
22#include <errno.h>
6c12b52e
LP
23#include <unistd.h>
24
b5efdb8a 25#include "alloc-util.h"
07630cea
LP
26#include "dbus-scope.h"
27#include "load-dropin.h"
6c12b52e 28#include "log.h"
b5efdb8a 29#include "scope.h"
6c12b52e 30#include "special.h"
8b43440b 31#include "string-table.h"
07630cea
LP
32#include "string-util.h"
33#include "strv.h"
6c12b52e 34#include "unit-name.h"
efdb0237 35#include "unit.h"
6c12b52e
LP
36
37static const UnitActiveState state_translation_table[_SCOPE_STATE_MAX] = {
38 [SCOPE_DEAD] = UNIT_INACTIVE,
39 [SCOPE_RUNNING] = UNIT_ACTIVE,
a911bb9a 40 [SCOPE_ABANDONED] = UNIT_ACTIVE,
6c12b52e
LP
41 [SCOPE_STOP_SIGTERM] = UNIT_DEACTIVATING,
42 [SCOPE_STOP_SIGKILL] = UNIT_DEACTIVATING,
43 [SCOPE_FAILED] = UNIT_FAILED
44};
45
718db961
LP
46static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
47
6c12b52e
LP
48static void scope_init(Unit *u) {
49 Scope *s = SCOPE(u);
50
51 assert(u);
52 assert(u->load_state == UNIT_STUB);
53
1f19a534 54 s->timeout_stop_usec = u->manager->default_timeout_stop_usec;
6c12b52e 55
6c12b52e 56 UNIT(s)->ignore_on_isolate = true;
6c12b52e
LP
57}
58
59static void scope_done(Unit *u) {
60 Scope *s = SCOPE(u);
61
62 assert(u);
63
2d4a39e7
LP
64 free(s->controller);
65
718db961
LP
66 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
67}
68
69static int scope_arm_timer(Scope *s) {
70 int r;
71
72 assert(s);
73
74 if (s->timeout_stop_usec <= 0) {
75 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
76 return 0;
77 }
78
79 if (s->timer_event_source) {
80 r = sd_event_source_set_time(s->timer_event_source, now(CLOCK_MONOTONIC) + s->timeout_stop_usec);
81 if (r < 0)
82 return r;
83
84 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
85 }
86
cbf60d0a 87 r = sd_event_add_time(
6a0f1f6d
LP
88 UNIT(s)->manager->event,
89 &s->timer_event_source,
90 CLOCK_MONOTONIC,
91 now(CLOCK_MONOTONIC) + s->timeout_stop_usec, 0,
92 scope_dispatch_timer, s);
7dfbe2e3
TG
93 if (r < 0)
94 return r;
95
96 (void) sd_event_source_set_description(s->timer_event_source, "scope-timer");
97
98 return 0;
6c12b52e
LP
99}
100
101static void scope_set_state(Scope *s, ScopeState state) {
102 ScopeState old_state;
103 assert(s);
104
105 old_state = s->state;
106 s->state = state;
107
a911bb9a 108 if (!IN_SET(state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
718db961 109 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
6c12b52e 110
a911bb9a
LP
111 if (IN_SET(state, SCOPE_DEAD, SCOPE_FAILED))
112 unit_unwatch_all_pids(UNIT(s));
113
6c12b52e 114 if (state != old_state)
a911bb9a 115 log_debug("%s changed %s -> %s", UNIT(s)->id, scope_state_to_string(old_state), scope_state_to_string(state));
6c12b52e
LP
116
117 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
118}
119
120static int scope_add_default_dependencies(Scope *s) {
121 int r;
122
123 assert(s);
124
125 /* Make sure scopes are unloaded on shutdown */
126 r = unit_add_two_dependencies_by_name(
127 UNIT(s),
128 UNIT_BEFORE, UNIT_CONFLICTS,
129 SPECIAL_SHUTDOWN_TARGET, NULL, true);
130 if (r < 0)
131 return r;
132
133 return 0;
134}
135
136static int scope_verify(Scope *s) {
137 assert(s);
138
139 if (UNIT(s)->load_state != UNIT_LOADED)
140 return 0;
141
efdb0237 142 if (set_isempty(UNIT(s)->pids) &&
09d2f5b1 143 !manager_is_reloading_or_reexecuting(UNIT(s)->manager) &&
efdb0237 144 !unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE)) {
f2341e0a 145 log_unit_error(UNIT(s), "Scope has no PIDs. Refusing.");
6c12b52e
LP
146 return -EINVAL;
147 }
148
149 return 0;
150}
151
152static int scope_load(Unit *u) {
153 Scope *s = SCOPE(u);
154 int r;
155
156 assert(s);
157 assert(u->load_state == UNIT_STUB);
158
efdb0237 159 if (!u->transient && !manager_is_reloading_or_reexecuting(u->manager))
6c12b52e
LP
160 return -ENOENT;
161
162 u->load_state = UNIT_LOADED;
163
164 r = unit_load_dropin(u);
165 if (r < 0)
166 return r;
167
598459ce
LP
168 r = unit_patch_contexts(u);
169 if (r < 0)
170 return r;
171
d79200e2 172 r = unit_set_default_slice(u);
6c12b52e
LP
173 if (r < 0)
174 return r;
175
176 if (u->default_dependencies) {
177 r = scope_add_default_dependencies(s);
178 if (r < 0)
179 return r;
180 }
181
182 return scope_verify(s);
183}
184
be847e82 185static int scope_coldplug(Unit *u) {
6c12b52e
LP
186 Scope *s = SCOPE(u);
187 int r;
188
189 assert(s);
190 assert(s->state == SCOPE_DEAD);
191
192 if (s->deserialized_state != s->state) {
193
a911bb9a 194 if (IN_SET(s->deserialized_state, SCOPE_STOP_SIGKILL, SCOPE_STOP_SIGTERM)) {
718db961 195 r = scope_arm_timer(s);
6c12b52e 196 if (r < 0)
6c12b52e
LP
197 return r;
198 }
199
a911bb9a
LP
200 if (!IN_SET(s->deserialized_state, SCOPE_DEAD, SCOPE_FAILED))
201 unit_watch_all_pids(UNIT(s));
202
6c12b52e
LP
203 scope_set_state(s, s->deserialized_state);
204 }
205
206 return 0;
207}
208
209static void scope_dump(Unit *u, FILE *f, const char *prefix) {
210 Scope *s = SCOPE(u);
211
212 assert(s);
213 assert(f);
214
215 fprintf(f,
216 "%sScope State: %s\n"
217 "%sResult: %s\n",
218 prefix, scope_state_to_string(s->state),
219 prefix, scope_result_to_string(s->result));
220
221 cgroup_context_dump(&s->cgroup_context, f, prefix);
222 kill_context_dump(&s->kill_context, f, prefix);
223}
224
225static void scope_enter_dead(Scope *s, ScopeResult f) {
226 assert(s);
227
228 if (f != SCOPE_SUCCESS)
229 s->result = f;
230
231 scope_set_state(s, s->result != SCOPE_SUCCESS ? SCOPE_FAILED : SCOPE_DEAD);
232}
233
234static void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) {
2d4a39e7 235 bool skip_signal = false;
6c12b52e
LP
236 int r;
237
238 assert(s);
239
240 if (f != SCOPE_SUCCESS)
241 s->result = f;
242
a911bb9a
LP
243 unit_watch_all_pids(UNIT(s));
244
2d4a39e7
LP
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;
250
251 if (!skip_signal) {
252 r = unit_kill_context(
253 UNIT(s),
254 &s->kill_context,
db2cb23b 255 state != SCOPE_STOP_SIGTERM ? KILL_KILL : KILL_TERMINATE,
2d4a39e7
LP
256 -1, -1, false);
257 if (r < 0)
258 goto fail;
259 } else
260 r = 1;
6c12b52e
LP
261
262 if (r > 0) {
718db961
LP
263 r = scope_arm_timer(s);
264 if (r < 0)
265 goto fail;
6c12b52e
LP
266
267 scope_set_state(s, state);
ac84d1fb
LP
268 } else if (state == SCOPE_STOP_SIGTERM)
269 scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_SUCCESS);
270 else
6c12b52e
LP
271 scope_enter_dead(s, SCOPE_SUCCESS);
272
273 return;
274
275fail:
f2341e0a 276 log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
6c12b52e
LP
277
278 scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
279}
280
281static int scope_start(Unit *u) {
282 Scope *s = SCOPE(u);
283 int r;
284
285 assert(s);
286
efdb0237
LP
287 if (unit_has_name(u, SPECIAL_INIT_SCOPE))
288 return -EPERM;
289
7b617155
LP
290 if (s->state == SCOPE_FAILED)
291 return -EPERM;
292
dd305ec9 293 /* We can't fulfill this right now, please try again later */
6c12b52e
LP
294 if (s->state == SCOPE_STOP_SIGTERM ||
295 s->state == SCOPE_STOP_SIGKILL)
296 return -EAGAIN;
297
298 assert(s->state == SCOPE_DEAD);
299
efdb0237 300 if (!u->transient && !manager_is_reloading_or_reexecuting(u->manager))
6c12b52e
LP
301 return -ENOENT;
302
5ad096b3
LP
303 (void) unit_realize_cgroup(u);
304 (void) unit_reset_cpu_usage(u);
305
7b3fd631 306 r = unit_attach_pids_to_cgroup(u);
dd305ec9 307 if (r < 0) {
f2341e0a 308 log_unit_warning_errno(UNIT(s), r, "Failed to add PIDs to scope's control group: %m");
68a01fb6 309 scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
6c12b52e 310 return r;
dd305ec9 311 }
6c12b52e 312
6c12b52e
LP
313 s->result = SCOPE_SUCCESS;
314
315 scope_set_state(s, SCOPE_RUNNING);
82a2b6bb 316 return 1;
6c12b52e
LP
317}
318
319static int scope_stop(Unit *u) {
320 Scope *s = SCOPE(u);
321
322 assert(s);
6c12b52e
LP
323
324 if (s->state == SCOPE_STOP_SIGTERM ||
325 s->state == SCOPE_STOP_SIGKILL)
326 return 0;
327
a911bb9a
LP
328 assert(s->state == SCOPE_RUNNING ||
329 s->state == SCOPE_ABANDONED);
6c12b52e
LP
330
331 scope_enter_signal(s, SCOPE_STOP_SIGTERM, SCOPE_SUCCESS);
82a2b6bb 332 return 1;
6c12b52e
LP
333}
334
8bcca7e2
LP
335static void scope_reset_failed(Unit *u) {
336 Scope *s = SCOPE(u);
337
338 assert(s);
339
340 if (s->state == SCOPE_FAILED)
341 scope_set_state(s, SCOPE_DEAD);
342
343 s->result = SCOPE_SUCCESS;
344}
345
718db961 346static int scope_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
6c12b52e
LP
347 return unit_kill_common(u, who, signo, -1, -1, error);
348}
349
68db7a3b
ZJS
350static int scope_get_timeout(Unit *u, uint64_t *timeout) {
351 Scope *s = SCOPE(u);
352 int r;
353
354 if (!s->timer_event_source)
355 return 0;
356
357 r = sd_event_source_get_time(s->timer_event_source, timeout);
358 if (r < 0)
359 return r;
360
361 return 1;
362}
363
6c12b52e
LP
364static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
365 Scope *s = SCOPE(u);
366
367 assert(s);
368 assert(f);
369 assert(fds);
370
371 unit_serialize_item(u, f, "state", scope_state_to_string(s->state));
372 return 0;
373}
374
375static int scope_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
376 Scope *s = SCOPE(u);
377
378 assert(u);
379 assert(key);
380 assert(value);
381 assert(fds);
382
383 if (streq(key, "state")) {
384 ScopeState state;
385
386 state = scope_state_from_string(value);
387 if (state < 0)
f2341e0a 388 log_unit_debug(u, "Failed to parse state value: %s", value);
6c12b52e
LP
389 else
390 s->deserialized_state = state;
391
392 } else
f2341e0a 393 log_unit_debug(u, "Unknown serialization key: %s", key);
6c12b52e
LP
394
395 return 0;
396}
397
398static bool scope_check_gc(Unit *u) {
4e2744fc 399 assert(u);
6c12b52e
LP
400
401 /* Never clean up scopes that still have a process around,
402 * even if the scope is formally dead. */
403
a911bb9a 404 if (u->cgroup_path) {
4e2744fc
RC
405 int r;
406
6f883237 407 r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path);
6c12b52e
LP
408 if (r <= 0)
409 return true;
410 }
411
412 return false;
413}
414
a911bb9a
LP
415static void scope_notify_cgroup_empty_event(Unit *u) {
416 Scope *s = SCOPE(u);
417 assert(u);
418
f2341e0a 419 log_unit_debug(u, "cgroup is empty");
a911bb9a
LP
420
421 if (IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
422 scope_enter_dead(s, SCOPE_SUCCESS);
423}
424
425static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
426
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. */
432
433 unit_tidy_watch_pids(u, 0, 0);
434 unit_watch_all_pids(u);
435
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);
439}
440
718db961
LP
441static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
442 Scope *s = SCOPE(userdata);
6c12b52e
LP
443
444 assert(s);
718db961 445 assert(s->timer_event_source == source);
6c12b52e
LP
446
447 switch (s->state) {
448
449 case SCOPE_STOP_SIGTERM:
450 if (s->kill_context.send_sigkill) {
f2341e0a 451 log_unit_warning(UNIT(s), "Stopping timed out. Killing.");
6c12b52e
LP
452 scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_FAILURE_TIMEOUT);
453 } else {
f2341e0a 454 log_unit_warning(UNIT(s), "Stopping timed out. Skipping SIGKILL.");
6c12b52e
LP
455 scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
456 }
457
458 break;
459
460 case SCOPE_STOP_SIGKILL:
f2341e0a 461 log_unit_warning(UNIT(s), "Still around after SIGKILL. Ignoring.");
6c12b52e
LP
462 scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
463 break;
464
465 default:
466 assert_not_reached("Timeout at wrong time.");
467 }
718db961
LP
468
469 return 0;
6c12b52e
LP
470}
471
a911bb9a
LP
472int scope_abandon(Scope *s) {
473 assert(s);
6c12b52e 474
efdb0237
LP
475 if (unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE))
476 return -EPERM;
477
a911bb9a
LP
478 if (!IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED))
479 return -ESTALE;
6c12b52e 480
a1e58e8e 481 s->controller = mfree(s->controller);
6c12b52e 482
a911bb9a
LP
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
486 * us as parent. */
6c12b52e 487
a911bb9a
LP
488 unit_tidy_watch_pids(UNIT(s), 0, 0);
489 unit_watch_all_pids(UNIT(s));
6c12b52e 490
a911bb9a
LP
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));
494 else
495 scope_set_state(s, SCOPE_ABANDONED);
496
497 return 0;
6c12b52e
LP
498}
499
500_pure_ static UnitActiveState scope_active_state(Unit *u) {
501 assert(u);
502
503 return state_translation_table[SCOPE(u)->state];
504}
505
506_pure_ static const char *scope_sub_state_to_string(Unit *u) {
507 assert(u);
508
509 return scope_state_to_string(SCOPE(u)->state);
510}
511
ba64af90 512static void scope_enumerate(Manager *m) {
efdb0237
LP
513 Unit *u;
514 int r;
515
516 assert(m);
517
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. */
522
523 u = manager_get_unit(m, SPECIAL_INIT_SCOPE);
524 if (!u) {
525 u = unit_new(m, sizeof(Scope));
ba64af90
LP
526 if (!u) {
527 log_oom();
528 return;
529 }
efdb0237
LP
530
531 r = unit_add_name(u, SPECIAL_INIT_SCOPE);
532 if (r < 0) {
533 unit_free(u);
ba64af90
LP
534 log_error_errno(r, "Failed to add init.scope name");
535 return;
efdb0237
LP
536 }
537 }
538
539 u->transient = true;
540 u->default_dependencies = false;
541 u->no_gc = true;
41780022
LP
542 u->ignore_on_isolate = true;
543 u->refuse_manual_start = true;
544 u->refuse_manual_stop = true;
efdb0237
LP
545 SCOPE(u)->deserialized_state = SCOPE_RUNNING;
546 SCOPE(u)->kill_context.kill_signal = SIGRTMIN+14;
547
548 /* Prettify things, if we can. */
549 if (!u->description)
550 u->description = strdup("System and Service Manager");
551 if (!u->documentation)
552 (void) strv_extend(&u->documentation, "man:systemd(1)");
553
554 unit_add_to_load_queue(u);
555 unit_add_to_dbus_queue(u);
efdb0237
LP
556}
557
6c12b52e
LP
558static const char* const scope_result_table[_SCOPE_RESULT_MAX] = {
559 [SCOPE_SUCCESS] = "success",
560 [SCOPE_FAILURE_RESOURCES] = "resources",
561 [SCOPE_FAILURE_TIMEOUT] = "timeout",
562};
563
564DEFINE_STRING_TABLE_LOOKUP(scope_result, ScopeResult);
565
566const UnitVTable scope_vtable = {
567 .object_size = sizeof(Scope),
718db961
LP
568 .cgroup_context_offset = offsetof(Scope, cgroup_context),
569 .kill_context_offset = offsetof(Scope, kill_context),
570
6c12b52e
LP
571 .sections =
572 "Unit\0"
573 "Scope\0"
574 "Install\0",
6c12b52e 575 .private_section = "Scope",
6c12b52e
LP
576
577 .no_alias = true,
578 .no_instances = true,
579
580 .init = scope_init,
581 .load = scope_load,
582 .done = scope_done,
583
584 .coldplug = scope_coldplug,
585
586 .dump = scope_dump,
587
588 .start = scope_start,
589 .stop = scope_stop,
590
591 .kill = scope_kill,
592
68db7a3b
ZJS
593 .get_timeout = scope_get_timeout,
594
6c12b52e
LP
595 .serialize = scope_serialize,
596 .deserialize_item = scope_deserialize_item,
597
598 .active_state = scope_active_state,
599 .sub_state_to_string = scope_sub_state_to_string,
600
601 .check_gc = scope_check_gc,
602
a911bb9a
LP
603 .sigchld_event = scope_sigchld_event,
604
8bcca7e2
LP
605 .reset_failed = scope_reset_failed,
606
6c12b52e
LP
607 .notify_cgroup_empty = scope_notify_cgroup_empty_event,
608
718db961 609 .bus_vtable = bus_scope_vtable,
6c12b52e
LP
610 .bus_set_property = bus_scope_set_property,
611 .bus_commit_properties = bus_scope_commit_properties,
612
efdb0237
LP
613 .can_transient = true,
614
615 .enumerate = scope_enumerate,
6c12b52e 616};