]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/scope.c
10454d56b04651e7fe45c71b3774ccae849388ff
[thirdparty/systemd.git] / src / core / scope.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2013 Lennart Poettering
6
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.
11
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.
16
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/>.
19 ***/
20
21 #include <errno.h>
22 #include <unistd.h>
23
24 #include "alloc-util.h"
25 #include "dbus-scope.h"
26 #include "load-dropin.h"
27 #include "log.h"
28 #include "scope.h"
29 #include "special.h"
30 #include "string-table.h"
31 #include "string-util.h"
32 #include "strv.h"
33 #include "unit-name.h"
34 #include "unit.h"
35
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
43 };
44
45 static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
46
47 static void scope_init(Unit *u) {
48 Scope *s = SCOPE(u);
49
50 assert(u);
51 assert(u->load_state == UNIT_STUB);
52
53 s->timeout_stop_usec = u->manager->default_timeout_stop_usec;
54 u->ignore_on_isolate = true;
55 }
56
57 static void scope_done(Unit *u) {
58 Scope *s = SCOPE(u);
59
60 assert(u);
61
62 s->controller = mfree(s->controller);
63 s->controller_track = sd_bus_track_unref(s->controller_track);
64
65 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
66 }
67
68 static int scope_arm_timer(Scope *s, usec_t usec) {
69 int r;
70
71 assert(s);
72
73 if (s->timer_event_source) {
74 r = sd_event_source_set_time(s->timer_event_source, usec);
75 if (r < 0)
76 return r;
77
78 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
79 }
80
81 if (usec == USEC_INFINITY)
82 return 0;
83
84 r = sd_event_add_time(
85 UNIT(s)->manager->event,
86 &s->timer_event_source,
87 CLOCK_MONOTONIC,
88 usec, 0,
89 scope_dispatch_timer, s);
90 if (r < 0)
91 return r;
92
93 (void) sd_event_source_set_description(s->timer_event_source, "scope-timer");
94
95 return 0;
96 }
97
98 static void scope_set_state(Scope *s, ScopeState state) {
99 ScopeState old_state;
100 assert(s);
101
102 old_state = s->state;
103 s->state = state;
104
105 if (!IN_SET(state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
106 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
107
108 if (IN_SET(state, SCOPE_DEAD, SCOPE_FAILED))
109 unit_unwatch_all_pids(UNIT(s));
110
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));
113
114 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
115 }
116
117 static int scope_add_default_dependencies(Scope *s) {
118 int r;
119
120 assert(s);
121
122 if (!UNIT(s)->default_dependencies)
123 return 0;
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 UNIT_DEPENDENCY_DEFAULT);
131 if (r < 0)
132 return r;
133
134 return 0;
135 }
136
137 static int scope_verify(Scope *s) {
138 assert(s);
139
140 if (UNIT(s)->load_state != UNIT_LOADED)
141 return 0;
142
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.");
147 return -EINVAL;
148 }
149
150 return 0;
151 }
152
153 static int scope_load_init_scope(Unit *u) {
154 assert(u);
155
156 if (!unit_has_name(u, SPECIAL_INIT_SCOPE))
157 return 0;
158
159 u->transient = true;
160 u->perpetual = true;
161
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. */
164
165 u->default_dependencies = false;
166 u->ignore_on_isolate = true;
167
168 SCOPE(u)->kill_context.kill_signal = SIGRTMIN+14;
169
170 /* Prettify things, if we can. */
171 if (!u->description)
172 u->description = strdup("System and Service Manager");
173 if (!u->documentation)
174 (void) strv_extend(&u->documentation, "man:systemd(1)");
175
176 return 1;
177 }
178
179 static int scope_load(Unit *u) {
180 Scope *s = SCOPE(u);
181 int r;
182
183 assert(s);
184 assert(u->load_state == UNIT_STUB);
185
186 if (!u->transient && !MANAGER_IS_RELOADING(u->manager))
187 /* Refuse to load non-transient scope units, but allow them while reloading. */
188 return -ENOENT;
189
190 r = scope_load_init_scope(u);
191 if (r < 0)
192 return r;
193 r = unit_load_fragment_and_dropin_optional(u);
194 if (r < 0)
195 return r;
196
197 if (u->load_state == UNIT_LOADED) {
198 r = unit_patch_contexts(u);
199 if (r < 0)
200 return r;
201
202 r = unit_set_default_slice(u);
203 if (r < 0)
204 return r;
205
206 r = scope_add_default_dependencies(s);
207 if (r < 0)
208 return r;
209 }
210
211 return scope_verify(s);
212 }
213
214 static int scope_coldplug(Unit *u) {
215 Scope *s = SCOPE(u);
216 int r;
217
218 assert(s);
219 assert(s->state == SCOPE_DEAD);
220
221 if (s->deserialized_state == s->state)
222 return 0;
223
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));
226 if (r < 0)
227 return r;
228 }
229
230 if (!IN_SET(s->deserialized_state, SCOPE_DEAD, SCOPE_FAILED))
231 unit_watch_all_pids(UNIT(s));
232
233 bus_scope_track_controller(s);
234
235 scope_set_state(s, s->deserialized_state);
236 return 0;
237 }
238
239 static void scope_dump(Unit *u, FILE *f, const char *prefix) {
240 Scope *s = SCOPE(u);
241
242 assert(s);
243 assert(f);
244
245 fprintf(f,
246 "%sScope State: %s\n"
247 "%sResult: %s\n",
248 prefix, scope_state_to_string(s->state),
249 prefix, scope_result_to_string(s->result));
250
251 cgroup_context_dump(&s->cgroup_context, f, prefix);
252 kill_context_dump(&s->kill_context, f, prefix);
253 }
254
255 static void scope_enter_dead(Scope *s, ScopeResult f) {
256 assert(s);
257
258 if (s->result == SCOPE_SUCCESS)
259 s->result = f;
260
261 if (s->result != SCOPE_SUCCESS)
262 log_unit_warning(UNIT(s), "Failed with result '%s'.", scope_result_to_string(s->result));
263
264 scope_set_state(s, s->result != SCOPE_SUCCESS ? SCOPE_FAILED : SCOPE_DEAD);
265 }
266
267 static void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) {
268 bool skip_signal = false;
269 int r;
270
271 assert(s);
272
273 if (s->result == SCOPE_SUCCESS)
274 s->result = f;
275
276 unit_watch_all_pids(UNIT(s));
277
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;
282
283 if (skip_signal)
284 r = 1; /* wait */
285 else {
286 r = unit_kill_context(
287 UNIT(s),
288 &s->kill_context,
289 state != SCOPE_STOP_SIGTERM ? KILL_KILL :
290 s->was_abandoned ? KILL_TERMINATE_AND_LOG :
291 KILL_TERMINATE,
292 -1, -1, false);
293 if (r < 0)
294 goto fail;
295 }
296
297 if (r > 0) {
298 r = scope_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->timeout_stop_usec));
299 if (r < 0)
300 goto fail;
301
302 scope_set_state(s, state);
303 } else if (state == SCOPE_STOP_SIGTERM)
304 scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_SUCCESS);
305 else
306 scope_enter_dead(s, SCOPE_SUCCESS);
307
308 return;
309
310 fail:
311 log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
312
313 scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
314 }
315
316 static int scope_start(Unit *u) {
317 Scope *s = SCOPE(u);
318 int r;
319
320 assert(s);
321
322 if (unit_has_name(u, SPECIAL_INIT_SCOPE))
323 return -EPERM;
324
325 if (s->state == SCOPE_FAILED)
326 return -EPERM;
327
328 /* We can't fulfill this right now, please try again later */
329 if (IN_SET(s->state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
330 return -EAGAIN;
331
332 assert(s->state == SCOPE_DEAD);
333
334 if (!u->transient && !MANAGER_IS_RELOADING(u->manager))
335 return -ENOENT;
336
337 (void) bus_scope_track_controller(s);
338
339 r = unit_acquire_invocation_id(u);
340 if (r < 0)
341 return r;
342
343 (void) unit_realize_cgroup(u);
344 (void) unit_reset_cpu_accounting(u);
345 (void) unit_reset_ip_accounting(u);
346
347 unit_export_state_files(UNIT(s));
348
349 r = unit_attach_pids_to_cgroup(u);
350 if (r < 0) {
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);
353 return r;
354 }
355
356 s->result = SCOPE_SUCCESS;
357
358 scope_set_state(s, SCOPE_RUNNING);
359 return 1;
360 }
361
362 static int scope_stop(Unit *u) {
363 Scope *s = SCOPE(u);
364
365 assert(s);
366
367 if (IN_SET(s->state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
368 return 0;
369
370 assert(IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED));
371
372 scope_enter_signal(s, SCOPE_STOP_SIGTERM, SCOPE_SUCCESS);
373 return 1;
374 }
375
376 static void scope_reset_failed(Unit *u) {
377 Scope *s = SCOPE(u);
378
379 assert(s);
380
381 if (s->state == SCOPE_FAILED)
382 scope_set_state(s, SCOPE_DEAD);
383
384 s->result = SCOPE_SUCCESS;
385 }
386
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);
389 }
390
391 static int scope_get_timeout(Unit *u, usec_t *timeout) {
392 Scope *s = SCOPE(u);
393 usec_t t;
394 int r;
395
396 if (!s->timer_event_source)
397 return 0;
398
399 r = sd_event_source_get_time(s->timer_event_source, &t);
400 if (r < 0)
401 return r;
402 if (t == USEC_INFINITY)
403 return 0;
404
405 *timeout = t;
406 return 1;
407 }
408
409 static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
410 Scope *s = SCOPE(u);
411
412 assert(s);
413 assert(f);
414 assert(fds);
415
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));
418
419 if (s->controller)
420 unit_serialize_item(u, f, "controller", s->controller);
421
422 return 0;
423 }
424
425 static int scope_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
426 Scope *s = SCOPE(u);
427 int r;
428
429 assert(u);
430 assert(key);
431 assert(value);
432 assert(fds);
433
434 if (streq(key, "state")) {
435 ScopeState state;
436
437 state = scope_state_from_string(value);
438 if (state < 0)
439 log_unit_debug(u, "Failed to parse state value: %s", value);
440 else
441 s->deserialized_state = state;
442
443 } else if (streq(key, "was-abandoned")) {
444 int k;
445
446 k = parse_boolean(value);
447 if (k < 0)
448 log_unit_debug(u, "Failed to parse boolean value: %s", value);
449 else
450 s->was_abandoned = k;
451 } else if (streq(key, "controller")) {
452
453 r = free_and_strdup(&s->controller, value);
454 if (r < 0)
455 log_oom();
456
457 } else
458 log_unit_debug(u, "Unknown serialization key: %s", key);
459
460 return 0;
461 }
462
463 static void scope_notify_cgroup_empty_event(Unit *u) {
464 Scope *s = SCOPE(u);
465 assert(u);
466
467 log_unit_debug(u, "cgroup is empty");
468
469 if (IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
470 scope_enter_dead(s, SCOPE_SUCCESS);
471 }
472
473 static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
474
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. */
480
481 unit_tidy_watch_pids(u, 0, 0);
482 unit_watch_all_pids(u);
483
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);
488 }
489
490 static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
491 Scope *s = SCOPE(userdata);
492
493 assert(s);
494 assert(s->timer_event_source == source);
495
496 switch (s->state) {
497
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);
502 } else {
503 log_unit_warning(UNIT(s), "Stopping timed out. Skipping SIGKILL.");
504 scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
505 }
506
507 break;
508
509 case SCOPE_STOP_SIGKILL:
510 log_unit_warning(UNIT(s), "Still around after SIGKILL. Ignoring.");
511 scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
512 break;
513
514 default:
515 assert_not_reached("Timeout at wrong time.");
516 }
517
518 return 0;
519 }
520
521 int scope_abandon(Scope *s) {
522 assert(s);
523
524 if (unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE))
525 return -EPERM;
526
527 if (!IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED))
528 return -ESTALE;
529
530 s->was_abandoned = true;
531
532 s->controller = mfree(s->controller);
533 s->controller_track = sd_bus_track_unref(s->controller_track);
534
535 scope_set_state(s, SCOPE_ABANDONED);
536
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
540 * us as parent. */
541
542 unit_tidy_watch_pids(UNIT(s), 0, 0);
543 unit_watch_all_pids(UNIT(s));
544
545 return 0;
546 }
547
548 _pure_ static UnitActiveState scope_active_state(Unit *u) {
549 assert(u);
550
551 return state_translation_table[SCOPE(u)->state];
552 }
553
554 _pure_ static const char *scope_sub_state_to_string(Unit *u) {
555 assert(u);
556
557 return scope_state_to_string(SCOPE(u)->state);
558 }
559
560 static void scope_enumerate(Manager *m) {
561 Unit *u;
562 int r;
563
564 assert(m);
565
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. */
570
571 u = manager_get_unit(m, SPECIAL_INIT_SCOPE);
572 if (!u) {
573 r = unit_new_for_name(m, sizeof(Scope), SPECIAL_INIT_SCOPE, &u);
574 if (r < 0) {
575 log_error_errno(r, "Failed to allocate the special " SPECIAL_INIT_SCOPE " unit: %m");
576 return;
577 }
578 }
579
580 u->transient = true;
581 u->perpetual = true;
582 SCOPE(u)->deserialized_state = SCOPE_RUNNING;
583
584 unit_add_to_load_queue(u);
585 unit_add_to_dbus_queue(u);
586 }
587
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",
592 };
593
594 DEFINE_STRING_TABLE_LOOKUP(scope_result, ScopeResult);
595
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),
600
601 .sections =
602 "Unit\0"
603 "Scope\0"
604 "Install\0",
605 .private_section = "Scope",
606
607 .can_transient = true,
608
609 .init = scope_init,
610 .load = scope_load,
611 .done = scope_done,
612
613 .coldplug = scope_coldplug,
614
615 .dump = scope_dump,
616
617 .start = scope_start,
618 .stop = scope_stop,
619
620 .kill = scope_kill,
621
622 .get_timeout = scope_get_timeout,
623
624 .serialize = scope_serialize,
625 .deserialize_item = scope_deserialize_item,
626
627 .active_state = scope_active_state,
628 .sub_state_to_string = scope_sub_state_to_string,
629
630 .sigchld_event = scope_sigchld_event,
631
632 .reset_failed = scope_reset_failed,
633
634 .notify_cgroup_empty = scope_notify_cgroup_empty_event,
635
636 .bus_vtable = bus_scope_vtable,
637 .bus_set_property = bus_scope_set_property,
638 .bus_commit_properties = bus_scope_commit_properties,
639
640 .enumerate = scope_enumerate,
641 };