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