]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/scope.c
Merge pull request #1359 from jengelh/ue
[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 "alloc-util.h"
26 #include "dbus-scope.h"
27 #include "load-dropin.h"
28 #include "log.h"
29 #include "scope.h"
30 #include "special.h"
31 #include "string-table.h"
32 #include "string-util.h"
33 #include "strv.h"
34 #include "unit-name.h"
35 #include "unit.h"
36
37 static const UnitActiveState state_translation_table[_SCOPE_STATE_MAX] = {
38 [SCOPE_DEAD] = UNIT_INACTIVE,
39 [SCOPE_RUNNING] = UNIT_ACTIVE,
40 [SCOPE_ABANDONED] = UNIT_ACTIVE,
41 [SCOPE_STOP_SIGTERM] = UNIT_DEACTIVATING,
42 [SCOPE_STOP_SIGKILL] = UNIT_DEACTIVATING,
43 [SCOPE_FAILED] = UNIT_FAILED
44 };
45
46 static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
47
48 static void scope_init(Unit *u) {
49 Scope *s = SCOPE(u);
50
51 assert(u);
52 assert(u->load_state == UNIT_STUB);
53
54 s->timeout_stop_usec = u->manager->default_timeout_stop_usec;
55
56 UNIT(s)->ignore_on_isolate = 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 if (!UNIT(s)->default_dependencies)
126 return 0;
127
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
139 static int scope_verify(Scope *s) {
140 assert(s);
141
142 if (UNIT(s)->load_state != UNIT_LOADED)
143 return 0;
144
145 if (set_isempty(UNIT(s)->pids) &&
146 !manager_is_reloading_or_reexecuting(UNIT(s)->manager) &&
147 !unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE)) {
148 log_unit_error(UNIT(s), "Scope has no PIDs. Refusing.");
149 return -EINVAL;
150 }
151
152 return 0;
153 }
154
155 static 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
162 if (!u->transient && !manager_is_reloading_or_reexecuting(u->manager))
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
171 r = unit_patch_contexts(u);
172 if (r < 0)
173 return r;
174
175 r = unit_set_default_slice(u);
176 if (r < 0)
177 return r;
178
179 r = scope_add_default_dependencies(s);
180 if (r < 0)
181 return r;
182
183 return scope_verify(s);
184 }
185
186 static int scope_coldplug(Unit *u) {
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
195 if (IN_SET(s->deserialized_state, SCOPE_STOP_SIGKILL, SCOPE_STOP_SIGTERM)) {
196 r = scope_arm_timer(s);
197 if (r < 0)
198 return r;
199 }
200
201 if (!IN_SET(s->deserialized_state, SCOPE_DEAD, SCOPE_FAILED))
202 unit_watch_all_pids(UNIT(s));
203
204 scope_set_state(s, s->deserialized_state);
205 }
206
207 return 0;
208 }
209
210 static 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
226 static 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
235 static void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) {
236 bool skip_signal = false;
237 int r;
238
239 assert(s);
240
241 if (f != SCOPE_SUCCESS)
242 s->result = f;
243
244 unit_watch_all_pids(UNIT(s));
245
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,
256 state != SCOPE_STOP_SIGTERM ? KILL_KILL : KILL_TERMINATE,
257 -1, -1, false);
258 if (r < 0)
259 goto fail;
260 } else
261 r = 1;
262
263 if (r > 0) {
264 r = scope_arm_timer(s);
265 if (r < 0)
266 goto fail;
267
268 scope_set_state(s, state);
269 } else if (state == SCOPE_STOP_SIGTERM)
270 scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_SUCCESS);
271 else
272 scope_enter_dead(s, SCOPE_SUCCESS);
273
274 return;
275
276 fail:
277 log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
278
279 scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
280 }
281
282 static int scope_start(Unit *u) {
283 Scope *s = SCOPE(u);
284 int r;
285
286 assert(s);
287
288 if (unit_has_name(u, SPECIAL_INIT_SCOPE))
289 return -EPERM;
290
291 if (s->state == SCOPE_FAILED)
292 return -EPERM;
293
294 /* We can't fulfill this right now, please try again later */
295 if (s->state == SCOPE_STOP_SIGTERM ||
296 s->state == SCOPE_STOP_SIGKILL)
297 return -EAGAIN;
298
299 assert(s->state == SCOPE_DEAD);
300
301 if (!u->transient && !manager_is_reloading_or_reexecuting(u->manager))
302 return -ENOENT;
303
304 (void) unit_realize_cgroup(u);
305 (void) unit_reset_cpu_usage(u);
306
307 r = unit_attach_pids_to_cgroup(u);
308 if (r < 0) {
309 log_unit_warning_errno(UNIT(s), r, "Failed to add PIDs to scope's control group: %m");
310 scope_enter_dead(s, SCOPE_FAILURE_RESOURCES);
311 return r;
312 }
313
314 s->result = SCOPE_SUCCESS;
315
316 scope_set_state(s, SCOPE_RUNNING);
317 return 1;
318 }
319
320 static int scope_stop(Unit *u) {
321 Scope *s = SCOPE(u);
322
323 assert(s);
324
325 if (s->state == SCOPE_STOP_SIGTERM ||
326 s->state == SCOPE_STOP_SIGKILL)
327 return 0;
328
329 assert(s->state == SCOPE_RUNNING ||
330 s->state == SCOPE_ABANDONED);
331
332 scope_enter_signal(s, SCOPE_STOP_SIGTERM, SCOPE_SUCCESS);
333 return 1;
334 }
335
336 static 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
347 static int scope_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
348 return unit_kill_common(u, who, signo, -1, -1, error);
349 }
350
351 static 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
365 static 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
376 static 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)
389 log_unit_debug(u, "Failed to parse state value: %s", value);
390 else
391 s->deserialized_state = state;
392
393 } else
394 log_unit_debug(u, "Unknown serialization key: %s", key);
395
396 return 0;
397 }
398
399 static bool scope_check_gc(Unit *u) {
400 assert(u);
401
402 /* Never clean up scopes that still have a process around,
403 * even if the scope is formally dead. */
404
405 if (!u->cgroup_path)
406 return false;
407
408 return cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path) <= 0;
409 }
410
411 static void scope_notify_cgroup_empty_event(Unit *u) {
412 Scope *s = SCOPE(u);
413 assert(u);
414
415 log_unit_debug(u, "cgroup is empty");
416
417 if (IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
418 scope_enter_dead(s, SCOPE_SUCCESS);
419 }
420
421 static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
422
423 /* If we get a SIGCHLD event for one of the processes we were
424 interested in, then we look for others to watch, under the
425 assumption that we'll sooner or later get a SIGCHLD for
426 them, as the original process we watched was probably the
427 parent of them, and they are hence now our children. */
428
429 unit_tidy_watch_pids(u, 0, 0);
430 unit_watch_all_pids(u);
431
432 /* If the PID set is empty now, then let's finish this off */
433 if (set_isempty(u->pids))
434 scope_notify_cgroup_empty_event(u);
435 }
436
437 static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
438 Scope *s = SCOPE(userdata);
439
440 assert(s);
441 assert(s->timer_event_source == source);
442
443 switch (s->state) {
444
445 case SCOPE_STOP_SIGTERM:
446 if (s->kill_context.send_sigkill) {
447 log_unit_warning(UNIT(s), "Stopping timed out. Killing.");
448 scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_FAILURE_TIMEOUT);
449 } else {
450 log_unit_warning(UNIT(s), "Stopping timed out. Skipping SIGKILL.");
451 scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
452 }
453
454 break;
455
456 case SCOPE_STOP_SIGKILL:
457 log_unit_warning(UNIT(s), "Still around after SIGKILL. Ignoring.");
458 scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
459 break;
460
461 default:
462 assert_not_reached("Timeout at wrong time.");
463 }
464
465 return 0;
466 }
467
468 int scope_abandon(Scope *s) {
469 assert(s);
470
471 if (unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE))
472 return -EPERM;
473
474 if (!IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED))
475 return -ESTALE;
476
477 s->controller = mfree(s->controller);
478
479 /* The client is no longer watching the remaining processes,
480 * so let's step in here, under the assumption that the
481 * remaining processes will be sooner or later reassigned to
482 * us as parent. */
483
484 unit_tidy_watch_pids(UNIT(s), 0, 0);
485 unit_watch_all_pids(UNIT(s));
486
487 /* If the PID set is empty now, then let's finish this off */
488 if (set_isempty(UNIT(s)->pids))
489 scope_notify_cgroup_empty_event(UNIT(s));
490 else
491 scope_set_state(s, SCOPE_ABANDONED);
492
493 return 0;
494 }
495
496 _pure_ static UnitActiveState scope_active_state(Unit *u) {
497 assert(u);
498
499 return state_translation_table[SCOPE(u)->state];
500 }
501
502 _pure_ static const char *scope_sub_state_to_string(Unit *u) {
503 assert(u);
504
505 return scope_state_to_string(SCOPE(u)->state);
506 }
507
508 static void scope_enumerate(Manager *m) {
509 Unit *u;
510 int r;
511
512 assert(m);
513
514 /* Let's unconditionally add the "init.scope" special unit
515 * that encapsulates PID 1. Note that PID 1 already is in the
516 * cgroup for this, we hence just need to allocate the object
517 * for it and that's it. */
518
519 u = manager_get_unit(m, SPECIAL_INIT_SCOPE);
520 if (!u) {
521 u = unit_new(m, sizeof(Scope));
522 if (!u) {
523 log_oom();
524 return;
525 }
526
527 r = unit_add_name(u, SPECIAL_INIT_SCOPE);
528 if (r < 0) {
529 unit_free(u);
530 log_error_errno(r, "Failed to add init.scope name");
531 return;
532 }
533 }
534
535 u->transient = true;
536 u->default_dependencies = false;
537 u->no_gc = true;
538 u->ignore_on_isolate = true;
539 u->refuse_manual_start = true;
540 u->refuse_manual_stop = true;
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
554 static const char* const scope_result_table[_SCOPE_RESULT_MAX] = {
555 [SCOPE_SUCCESS] = "success",
556 [SCOPE_FAILURE_RESOURCES] = "resources",
557 [SCOPE_FAILURE_TIMEOUT] = "timeout",
558 };
559
560 DEFINE_STRING_TABLE_LOOKUP(scope_result, ScopeResult);
561
562 const UnitVTable scope_vtable = {
563 .object_size = sizeof(Scope),
564 .cgroup_context_offset = offsetof(Scope, cgroup_context),
565 .kill_context_offset = offsetof(Scope, kill_context),
566
567 .sections =
568 "Unit\0"
569 "Scope\0"
570 "Install\0",
571 .private_section = "Scope",
572
573 .no_alias = true,
574 .no_instances = true,
575 .can_transient = 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
590 .get_timeout = scope_get_timeout,
591
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
600 .sigchld_event = scope_sigchld_event,
601
602 .reset_failed = scope_reset_failed,
603
604 .notify_cgroup_empty = scope_notify_cgroup_empty_event,
605
606 .bus_vtable = bus_scope_vtable,
607 .bus_set_property = bus_scope_set_property,
608 .bus_commit_properties = bus_scope_commit_properties,
609
610 .enumerate = scope_enumerate,
611 };