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