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