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