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