chiark / gitweb /
update TODO
[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_unit_error(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 ? KILL_KILL : KILL_TERMINATE,
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_unit_warning(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                 return log_error_errno(r, "Failed to realize cgroup: %m");
294
295         r = cg_attach_many_everywhere(u->manager->cgroup_supported, u->cgroup_path, UNIT(s)->pids);
296         if (r < 0)
297                 return r;
298
299         s->result = SCOPE_SUCCESS;
300
301         scope_set_state(s, SCOPE_RUNNING);
302         return 0;
303 }
304
305 static int scope_stop(Unit *u) {
306         Scope *s = SCOPE(u);
307
308         assert(s);
309
310         if (s->state == SCOPE_STOP_SIGTERM ||
311             s->state == SCOPE_STOP_SIGKILL)
312                 return 0;
313
314         assert(s->state == SCOPE_RUNNING ||
315                s->state == SCOPE_ABANDONED);
316
317         scope_enter_signal(s, SCOPE_STOP_SIGTERM, SCOPE_SUCCESS);
318         return 0;
319 }
320
321 static void scope_reset_failed(Unit *u) {
322         Scope *s = SCOPE(u);
323
324         assert(s);
325
326         if (s->state == SCOPE_FAILED)
327                 scope_set_state(s, SCOPE_DEAD);
328
329         s->result = SCOPE_SUCCESS;
330 }
331
332 static int scope_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
333         return unit_kill_common(u, who, signo, -1, -1, error);
334 }
335
336 static int scope_get_timeout(Unit *u, uint64_t *timeout) {
337         Scope *s = SCOPE(u);
338         int r;
339
340         if (!s->timer_event_source)
341                 return 0;
342
343         r = sd_event_source_get_time(s->timer_event_source, timeout);
344         if (r < 0)
345                 return r;
346
347         return 1;
348 }
349
350 static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
351         Scope *s = SCOPE(u);
352
353         assert(s);
354         assert(f);
355         assert(fds);
356
357         unit_serialize_item(u, f, "state", scope_state_to_string(s->state));
358         return 0;
359 }
360
361 static int scope_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
362         Scope *s = SCOPE(u);
363
364         assert(u);
365         assert(key);
366         assert(value);
367         assert(fds);
368
369         if (streq(key, "state")) {
370                 ScopeState state;
371
372                 state = scope_state_from_string(value);
373                 if (state < 0)
374                         log_debug("Failed to parse state value %s", value);
375                 else
376                         s->deserialized_state = state;
377
378         } else
379                 log_debug("Unknown serialization key '%s'", key);
380
381         return 0;
382 }
383
384 static bool scope_check_gc(Unit *u) {
385         assert(u);
386
387         /* Never clean up scopes that still have a process around,
388          * even if the scope is formally dead. */
389
390         if (u->cgroup_path) {
391                 int r;
392
393                 r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, true);
394                 if (r <= 0)
395                         return true;
396         }
397
398         return false;
399 }
400
401 static void scope_notify_cgroup_empty_event(Unit *u) {
402         Scope *s = SCOPE(u);
403         assert(u);
404
405         log_unit_debug(u->id, "%s: cgroup is empty", u->id);
406
407         if (IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED, SCOPE_STOP_SIGTERM, SCOPE_STOP_SIGKILL))
408                 scope_enter_dead(s, SCOPE_SUCCESS);
409 }
410
411 static void scope_sigchld_event(Unit *u, pid_t pid, int code, int status) {
412
413         /* If we get a SIGCHLD event for one of the processes we were
414            interested in, then we look for others to watch, under the
415            assumption that we'll sooner or later get a SIGCHLD for
416            them, as the original process we watched was probably the
417            parent of them, and they are hence now our children. */
418
419         unit_tidy_watch_pids(u, 0, 0);
420         unit_watch_all_pids(u);
421
422         /* If the PID set is empty now, then let's finish this off */
423         if (set_isempty(u->pids))
424                 scope_notify_cgroup_empty_event(u);
425 }
426
427 static int scope_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
428         Scope *s = SCOPE(userdata);
429
430         assert(s);
431         assert(s->timer_event_source == source);
432
433         switch (s->state) {
434
435         case SCOPE_STOP_SIGTERM:
436                 if (s->kill_context.send_sigkill) {
437                         log_unit_warning(UNIT(s)->id, "%s stopping timed out. Killing.", UNIT(s)->id);
438                         scope_enter_signal(s, SCOPE_STOP_SIGKILL, SCOPE_FAILURE_TIMEOUT);
439                 } else {
440                         log_unit_warning(UNIT(s)->id, "%s stopping timed out. Skipping SIGKILL.", UNIT(s)->id);
441                         scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
442                 }
443
444                 break;
445
446         case SCOPE_STOP_SIGKILL:
447                 log_unit_warning(UNIT(s)->id, "%s still around after SIGKILL. Ignoring.", UNIT(s)->id);
448                 scope_enter_dead(s, SCOPE_FAILURE_TIMEOUT);
449                 break;
450
451         default:
452                 assert_not_reached("Timeout at wrong time.");
453         }
454
455         return 0;
456 }
457
458 int scope_abandon(Scope *s) {
459         assert(s);
460
461         if (!IN_SET(s->state, SCOPE_RUNNING, SCOPE_ABANDONED))
462                 return -ESTALE;
463
464         free(s->controller);
465         s->controller = NULL;
466
467         /* The client is no longer watching the remaining processes,
468          * so let's step in here, under the assumption that the
469          * remaining processes will be sooner or later reassigned to
470          * us as parent. */
471
472         unit_tidy_watch_pids(UNIT(s), 0, 0);
473         unit_watch_all_pids(UNIT(s));
474
475         /* If the PID set is empty now, then let's finish this off */
476         if (set_isempty(UNIT(s)->pids))
477                 scope_notify_cgroup_empty_event(UNIT(s));
478         else
479                 scope_set_state(s, SCOPE_ABANDONED);
480
481         return 0;
482 }
483
484 _pure_ static UnitActiveState scope_active_state(Unit *u) {
485         assert(u);
486
487         return state_translation_table[SCOPE(u)->state];
488 }
489
490 _pure_ static const char *scope_sub_state_to_string(Unit *u) {
491         assert(u);
492
493         return scope_state_to_string(SCOPE(u)->state);
494 }
495
496 static const char* const scope_state_table[_SCOPE_STATE_MAX] = {
497         [SCOPE_DEAD] = "dead",
498         [SCOPE_RUNNING] = "running",
499         [SCOPE_ABANDONED] = "abandoned",
500         [SCOPE_STOP_SIGTERM] = "stop-sigterm",
501         [SCOPE_STOP_SIGKILL] = "stop-sigkill",
502         [SCOPE_FAILED] = "failed",
503 };
504
505 DEFINE_STRING_TABLE_LOOKUP(scope_state, ScopeState);
506
507 static const char* const scope_result_table[_SCOPE_RESULT_MAX] = {
508         [SCOPE_SUCCESS] = "success",
509         [SCOPE_FAILURE_RESOURCES] = "resources",
510         [SCOPE_FAILURE_TIMEOUT] = "timeout",
511 };
512
513 DEFINE_STRING_TABLE_LOOKUP(scope_result, ScopeResult);
514
515 const UnitVTable scope_vtable = {
516         .object_size = sizeof(Scope),
517         .cgroup_context_offset = offsetof(Scope, cgroup_context),
518         .kill_context_offset = offsetof(Scope, kill_context),
519
520         .sections =
521                 "Unit\0"
522                 "Scope\0"
523                 "Install\0",
524         .private_section = "Scope",
525
526         .no_alias = true,
527         .no_instances = true,
528
529         .init = scope_init,
530         .load = scope_load,
531         .done = scope_done,
532
533         .coldplug = scope_coldplug,
534
535         .dump = scope_dump,
536
537         .start = scope_start,
538         .stop = scope_stop,
539
540         .kill = scope_kill,
541
542         .get_timeout = scope_get_timeout,
543
544         .serialize = scope_serialize,
545         .deserialize_item = scope_deserialize_item,
546
547         .active_state = scope_active_state,
548         .sub_state_to_string = scope_sub_state_to_string,
549
550         .check_gc = scope_check_gc,
551
552         .sigchld_event = scope_sigchld_event,
553
554         .reset_failed = scope_reset_failed,
555
556         .notify_cgroup_empty = scope_notify_cgroup_empty_event,
557
558         .bus_interface = "org.freedesktop.systemd1.Scope",
559         .bus_vtable = bus_scope_vtable,
560         .bus_set_property = bus_scope_set_property,
561         .bus_commit_properties = bus_scope_commit_properties,
562
563         .can_transient = true
564 };