]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/scope.c
Add SPDX license identifiers to source files under the LGPL
[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 free(s->controller);
63
64 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
65 }
66
67 static int scope_arm_timer(Scope *s, usec_t usec) {
68 int r;
69
70 assert(s);
71
72 if (s->timer_event_source) {
73 r = sd_event_source_set_time(s->timer_event_source, usec);
74 if (r < 0)
75 return r;
76
77 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
78 }
79
80 if (usec == USEC_INFINITY)
81 return 0;
82
83 r = sd_event_add_time(
84 UNIT(s)->manager->event,
85 &s->timer_event_source,
86 CLOCK_MONOTONIC,
87 usec, 0,
88 scope_dispatch_timer, s);
89 if (r < 0)
90 return r;
91
92 (void) sd_event_source_set_description(s->timer_event_source, "scope-timer");
93
94 return 0;
95 }
96
97 static void scope_set_state(Scope *s, ScopeState state) {
98 ScopeState old_state;
99 assert(s);
100
101 old_state = s->state;
102 s->state = state;
103
104 if (!IN_SET(state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
105 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
106
107 if (IN_SET(state, SCOPE_DEAD, SCOPE_FAILED))
108 unit_unwatch_all_pids(UNIT(s));
109
110 if (state != old_state)
111 log_debug("%s changed %s -> %s", UNIT(s)->id, scope_state_to_string(old_state), scope_state_to_string(state));
112
113 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
114 }
115
116 static int scope_add_default_dependencies(Scope *s) {
117 int r;
118
119 assert(s);
120
121 if (!UNIT(s)->default_dependencies)
122 return 0;
123
124 /* Make sure scopes are unloaded on shutdown */
125 r = unit_add_two_dependencies_by_name(
126 UNIT(s),
127 UNIT_BEFORE, UNIT_CONFLICTS,
128 SPECIAL_SHUTDOWN_TARGET, NULL, true,
129 UNIT_DEPENDENCY_DEFAULT);
130 if (r < 0)
131 return r;
132
133 return 0;
134 }
135
136 static int scope_verify(Scope *s) {
137 assert(s);
138
139 if (UNIT(s)->load_state != UNIT_LOADED)
140 return 0;
141
142 if (set_isempty(UNIT(s)->pids) &&
143 !MANAGER_IS_RELOADING(UNIT(s)->manager) &&
144 !unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE)) {
145 log_unit_error(UNIT(s), "Scope has no PIDs. Refusing.");
146 return -EINVAL;
147 }
148
149 return 0;
150 }
151
152 static int scope_load_init_scope(Unit *u) {
153 assert(u);
154
155 if (!unit_has_name(u, SPECIAL_INIT_SCOPE))
156 return 0;
157
158 u->transient = true;
159 u->perpetual = true;
160
161 /* init.scope is a bit special, as it has to stick around forever. Because of its special semantics we
162 * synthesize it here, instead of relying on the unit file on disk. */
163
164 u->default_dependencies = false;
165 u->ignore_on_isolate = true;
166
167 SCOPE(u)->kill_context.kill_signal = SIGRTMIN+14;
168
169 /* Prettify things, if we can. */
170 if (!u->description)
171 u->description = strdup("System and Service Manager");
172 if (!u->documentation)
173 (void) strv_extend(&u->documentation, "man:systemd(1)");
174
175 return 1;
176 }
177
178 static int scope_load(Unit *u) {
179 Scope *s = SCOPE(u);
180 int r;
181
182 assert(s);
183 assert(u->load_state == UNIT_STUB);
184
185 if (!u->transient && !MANAGER_IS_RELOADING(u->manager))
186 /* Refuse to load non-transient scope units, but allow them while reloading. */
187 return -ENOENT;
188
189 r = scope_load_init_scope(u);
190 if (r < 0)
191 return r;
192 r = unit_load_fragment_and_dropin_optional(u);
193 if (r < 0)
194 return r;
195
196 if (u->load_state == UNIT_LOADED) {
197 r = unit_patch_contexts(u);
198 if (r < 0)
199 return r;
200
201 r = unit_set_default_slice(u);
202 if (r < 0)
203 return r;
204
205 r = scope_add_default_dependencies(s);
206 if (r < 0)
207 return r;
208 }
209
210 return scope_verify(s);
211 }
212
213 static int scope_coldplug(Unit *u) {
214 Scope *s = SCOPE(u);
215 int r;
216
217 assert(s);
218 assert(s->state == SCOPE_DEAD);
219
220 if (s->deserialized_state == s->state)
221 return 0;
222
223 if (IN_SET(s->deserialized_state, SCOPE_STOP_SIGKILL, SCOPE_STOP_SIGTERM)) {
224 r = scope_arm_timer(s, usec_add(u->state_change_timestamp.monotonic, s->timeout_stop_usec));
225 if (r < 0)
226 return r;
227 }
228
229 if (!IN_SET(s->deserialized_state, SCOPE_DEAD, SCOPE_FAILED))
230 unit_watch_all_pids(UNIT(s));
231
232 scope_set_state(s, s->deserialized_state);
233 return 0;
234 }
235
236 static void scope_dump(Unit *u, FILE *f, const char *prefix) {
237 Scope *s = SCOPE(u);
238
239 assert(s);
240 assert(f);
241
242 fprintf(f,
243 "%sScope State: %s\n"
244 "%sResult: %s\n",
245 prefix, scope_state_to_string(s->state),
246 prefix, scope_result_to_string(s->result));
247
248 cgroup_context_dump(&s->cgroup_context, f, prefix);
249 kill_context_dump(&s->kill_context, f, prefix);
250 }
251
252 static void scope_enter_dead(Scope *s, ScopeResult f) {
253 assert(s);
254
255 if (s->result == SCOPE_SUCCESS)
256 s->result = f;
257
258 if (s->result != SCOPE_SUCCESS)
259 log_unit_warning(UNIT(s), "Failed with result '%s'.", scope_result_to_string(s->result));
260
261 scope_set_state(s, s->result != SCOPE_SUCCESS ? SCOPE_FAILED : SCOPE_DEAD);
262 }
263
264 static void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) {
265 bool skip_signal = false;
266 int r;
267
268 assert(s);
269
270 if (s->result == SCOPE_SUCCESS)
271 s->result = f;
272
273 unit_watch_all_pids(UNIT(s));
274
275 /* If we have a controller set let's ask the controller nicely
276 * to terminate the scope, instead of us going directly into
277 * SIGTERM berserk mode */
278 if (state == SCOPE_STOP_SIGTERM)
279 skip_signal = bus_scope_send_request_stop(s) > 0;
280
281 if (skip_signal)
282 r = 1; /* wait */
283 else {
284 r = unit_kill_context(
285 UNIT(s),
286 &s->kill_context,
287 state != SCOPE_STOP_SIGTERM ? KILL_KILL :
288 s->was_abandoned ? KILL_TERMINATE_AND_LOG :
289 KILL_TERMINATE,
290 -1, -1, false);
291 if (r < 0)
292 goto fail;
293 }
294
295 if (r > 0) {
296 r = scope_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->timeout_stop_usec));
297 if (r < 0)
298 goto fail;
299
300 scope_set_state(s, state);
301 } else if (state == SCOPE_STOP_SIGTERM)
302 scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_SUCCESS);
303 else
304 scope_enter_dead(s, SCOPE_SUCCESS);
305
306 return;
307
308 fail:
309 log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
310
311 scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
312 }
313
314 static int scope_start(Unit *u) {
315 Scope *s = SCOPE(u);
316 int r;
317
318 assert(s);
319
320 if (unit_has_name(u, SPECIAL_INIT_SCOPE))
321 return -EPERM;
322
323 if (s->state == SCOPE_FAILED)
324 return -EPERM;
325
326 /* We can't fulfill this right now, please try again later */
327 if (IN_SET(s->state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
328 return -EAGAIN;
329
330 assert(s->state == SCOPE_DEAD);
331
332 if (!u->transient && !MANAGER_IS_RELOADING(u->manager))
333 return -ENOENT;
334
335 r = unit_acquire_invocation_id(u);
336 if (r < 0)
337 return r;
338
339 (void) unit_realize_cgroup(u);
340 (void) unit_reset_cpu_accounting(u);
341 (void) unit_reset_ip_accounting(u);
342
343 unit_export_state_files(UNIT(s));
344
345 r = unit_attach_pids_to_cgroup(u);
346 if (r < 0) {
347 log_unit_warning_errno(UNIT(s), r, "Failed to add PIDs to scope's control group: %m");
348 scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
349 return r;
350 }
351
352 s->result = SCOPE_SUCCESS;
353
354 scope_set_state(s, SCOPE_RUNNING);
355 return 1;
356 }
357
358 static int scope_stop(Unit *u) {
359 Scope *s = SCOPE(u);
360
361 assert(s);
362
363 if (IN_SET(s->state, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
364 return 0;
365
366 assert(IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED));
367
368 scope_enter_signal(s, SCOPE_STOP_SIGTERM, SCOPE_SUCCESS);
369 return 1;
370 }
371
372 static void scope_reset_failed(Unit *u) {
373 Scope *s = SCOPE(u);
374
375 assert(s);
376
377 if (s->state == SCOPE_FAILED)
378 scope_set_state(s, SCOPE_DEAD);
379
380 s->result = SCOPE_SUCCESS;
381 }
382
383 static int scope_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
384 return unit_kill_common(u, who, signo, -1, -1, error);
385 }
386
387 static int scope_get_timeout(Unit *u, usec_t *timeout) {
388 Scope *s = SCOPE(u);
389 usec_t t;
390 int r;
391
392 if (!s->timer_event_source)
393 return 0;
394
395 r = sd_event_source_get_time(s->timer_event_source, &t);
396 if (r < 0)
397 return r;
398 if (t == USEC_INFINITY)
399 return 0;
400
401 *timeout = t;
402 return 1;
403 }
404
405 static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
406 Scope *s = SCOPE(u);
407
408 assert(s);
409 assert(f);
410 assert(fds);
411
412 unit_serialize_item(u, f, "state", scope_state_to_string(s->state));
413 unit_serialize_item(u, f, "was-abandoned", yes_no(s->was_abandoned));
414 return 0;
415 }
416
417 static int scope_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
418 Scope *s = SCOPE(u);
419
420 assert(u);
421 assert(key);
422 assert(value);
423 assert(fds);
424
425 if (streq(key, "state")) {
426 ScopeState state;
427
428 state = scope_state_from_string(value);
429 if (state < 0)
430 log_unit_debug(u, "Failed to parse state value: %s", value);
431 else
432 s->deserialized_state = state;
433
434 } else if (streq(key, "was-abandoned")) {
435 int k;
436
437 k = parse_boolean(value);
438 if (k < 0)
439 log_unit_debug(u, "Failed to parse boolean value: %s", value);
440 else
441 s->was_abandoned = k;
442 } else
443 log_unit_debug(u, "Unknown serialization key: %s", key);
444
445 return 0;
446 }
447
448 static bool scope_check_gc(Unit *u) {
449 assert(u);
450
451 /* Never clean up scopes that still have a process around,
452 * even if the scope is formally dead. */
453
454 if (!u->cgroup_path)
455 return false;
456
457 return cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path) <= 0;
458 }
459
460 static void scope_notify_cgroup_empty_event(Unit *u) {
461 Scope *s = SCOPE(u);
462 assert(u);
463
464 log_unit_debug(u, "cgroup is empty");
465
466 if (IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
467 scope_enter_dead(s, SCOPE_SUCCESS);
468 }
469
470 static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
471
472 /* If we get a SIGCHLD event for one of the processes we were
473 interested in, then we look for others to watch, under the
474 assumption that we'll sooner or later get a SIGCHLD for
475 them, as the original process we watched was probably the
476 parent of them, and they are hence now our children. */
477
478 unit_tidy_watch_pids(u, 0, 0);
479 unit_watch_all_pids(u);
480
481 /* If the PID set is empty now, then let's finish this off
482 (On unified we use proper notifications) */
483 if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) == 0 && set_isempty(u->pids))
484 scope_notify_cgroup_empty_event(u);
485 }
486
487 static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
488 Scope *s = SCOPE(userdata);
489
490 assert(s);
491 assert(s->timer_event_source == source);
492
493 switch (s->state) {
494
495 case SCOPE_STOP_SIGTERM:
496 if (s->kill_context.send_sigkill) {
497 log_unit_warning(UNIT(s), "Stopping timed out. Killing.");
498 scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_FAILURE_TIMEOUT);
499 } else {
500 log_unit_warning(UNIT(s), "Stopping timed out. Skipping SIGKILL.");
501 scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
502 }
503
504 break;
505
506 case SCOPE_STOP_SIGKILL:
507 log_unit_warning(UNIT(s), "Still around after SIGKILL. Ignoring.");
508 scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
509 break;
510
511 default:
512 assert_not_reached("Timeout at wrong time.");
513 }
514
515 return 0;
516 }
517
518 int scope_abandon(Scope *s) {
519 assert(s);
520
521 if (unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE))
522 return -EPERM;
523
524 if (!IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED))
525 return -ESTALE;
526
527 s->was_abandoned = true;
528 s->controller = mfree(s->controller);
529 scope_set_state(s, SCOPE_ABANDONED);
530
531 /* The client is no longer watching the remaining processes,
532 * so let's step in here, under the assumption that the
533 * remaining processes will be sooner or later reassigned to
534 * us as parent. */
535
536 unit_tidy_watch_pids(UNIT(s), 0, 0);
537 unit_watch_all_pids(UNIT(s));
538
539 return 0;
540 }
541
542 _pure_ static UnitActiveState scope_active_state(Unit *u) {
543 assert(u);
544
545 return state_translation_table[SCOPE(u)->state];
546 }
547
548 _pure_ static const char *scope_sub_state_to_string(Unit *u) {
549 assert(u);
550
551 return scope_state_to_string(SCOPE(u)->state);
552 }
553
554 static void scope_enumerate(Manager *m) {
555 Unit *u;
556 int r;
557
558 assert(m);
559
560 /* Let's unconditionally add the "init.scope" special unit
561 * that encapsulates PID 1. Note that PID 1 already is in the
562 * cgroup for this, we hence just need to allocate the object
563 * for it and that's it. */
564
565 u = manager_get_unit(m, SPECIAL_INIT_SCOPE);
566 if (!u) {
567 r = unit_new_for_name(m, sizeof(Scope), SPECIAL_INIT_SCOPE, &u);
568 if (r < 0) {
569 log_error_errno(r, "Failed to allocate the special " SPECIAL_INIT_SCOPE " unit: %m");
570 return;
571 }
572 }
573
574 u->transient = true;
575 u->perpetual = true;
576 SCOPE(u)->deserialized_state = SCOPE_RUNNING;
577
578 unit_add_to_load_queue(u);
579 unit_add_to_dbus_queue(u);
580 }
581
582 static const char* const scope_result_table[_SCOPE_RESULT_MAX] = {
583 [SCOPE_SUCCESS] = "success",
584 [SCOPE_FAILURE_RESOURCES] = "resources",
585 [SCOPE_FAILURE_TIMEOUT] = "timeout",
586 };
587
588 DEFINE_STRING_TABLE_LOOKUP(scope_result, ScopeResult);
589
590 const UnitVTable scope_vtable = {
591 .object_size = sizeof(Scope),
592 .cgroup_context_offset = offsetof(Scope, cgroup_context),
593 .kill_context_offset = offsetof(Scope, kill_context),
594
595 .sections =
596 "Unit\0"
597 "Scope\0"
598 "Install\0",
599 .private_section = "Scope",
600
601 .can_transient = true,
602
603 .init = scope_init,
604 .load = scope_load,
605 .done = scope_done,
606
607 .coldplug = scope_coldplug,
608
609 .dump = scope_dump,
610
611 .start = scope_start,
612 .stop = scope_stop,
613
614 .kill = scope_kill,
615
616 .get_timeout = scope_get_timeout,
617
618 .serialize = scope_serialize,
619 .deserialize_item = scope_deserialize_item,
620
621 .active_state = scope_active_state,
622 .sub_state_to_string = scope_sub_state_to_string,
623
624 .check_gc = scope_check_gc,
625
626 .sigchld_event = scope_sigchld_event,
627
628 .reset_failed = scope_reset_failed,
629
630 .notify_cgroup_empty = scope_notify_cgroup_empty_event,
631
632 .bus_vtable = bus_scope_vtable,
633 .bus_set_property = bus_scope_set_property,
634 .bus_commit_properties = bus_scope_commit_properties,
635
636 .enumerate = scope_enumerate,
637 };