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