]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/unit.c
cgroup: memory limits on / are not supported
[thirdparty/systemd.git] / src / core / unit.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
87f0e418 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
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
a7334b09
LP
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
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
87f0e418
LP
22#include <assert.h>
23#include <errno.h>
24#include <string.h>
25#include <sys/epoll.h>
26#include <sys/timerfd.h>
27#include <sys/poll.h>
0301abf4
LP
28#include <stdlib.h>
29#include <unistd.h>
45fb0699 30#include <sys/stat.h>
87f0e418 31
718db961
LP
32#include "sd-id128.h"
33#include "sd-messages.h"
87f0e418
LP
34#include "set.h"
35#include "unit.h"
36#include "macro.h"
37#include "strv.h"
9eb977db 38#include "path-util.h"
87f0e418
LP
39#include "load-fragment.h"
40#include "load-dropin.h"
41#include "log.h"
9e2f7c11 42#include "unit-name.h"
4139c1b2 43#include "dbus-unit.h"
514f4ef5 44#include "special.h"
c6c18be3 45#include "cgroup-util.h"
4927fcae 46#include "missing.h"
71645aca 47#include "mkdir.h"
a5c32cff
HH
48#include "label.h"
49#include "fileio-label.h"
96aad8d1 50#include "bus-common-errors.h"
718db961 51#include "dbus.h"
613b411c 52#include "execute.h"
bc6aed7b 53#include "virt.h"
29686440 54#include "dropin.h"
87f0e418
LP
55
56const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
57 [UNIT_SERVICE] = &service_vtable,
87f0e418 58 [UNIT_SOCKET] = &socket_vtable,
e821075a 59 [UNIT_BUSNAME] = &busname_vtable,
87f0e418 60 [UNIT_TARGET] = &target_vtable,
e821075a 61 [UNIT_SNAPSHOT] = &snapshot_vtable,
87f0e418
LP
62 [UNIT_DEVICE] = &device_vtable,
63 [UNIT_MOUNT] = &mount_vtable,
64 [UNIT_AUTOMOUNT] = &automount_vtable,
01f78473 65 [UNIT_SWAP] = &swap_vtable,
e821075a 66 [UNIT_TIMER] = &timer_vtable,
a016b922 67 [UNIT_PATH] = &path_vtable,
6c12b52e
LP
68 [UNIT_SLICE] = &slice_vtable,
69 [UNIT_SCOPE] = &scope_vtable
87f0e418
LP
70};
71
d1fab3fe
ZJS
72static int maybe_warn_about_dependency(const char *id, const char *other, UnitDependency dependency);
73
7d17cfbc 74Unit *unit_new(Manager *m, size_t size) {
87f0e418
LP
75 Unit *u;
76
77 assert(m);
ac155bb8 78 assert(size >= sizeof(Unit));
87f0e418 79
7d17cfbc
MS
80 u = malloc0(size);
81 if (!u)
87f0e418
LP
82 return NULL;
83
d5099efc 84 u->names = set_new(&string_hash_ops);
ac155bb8 85 if (!u->names) {
87f0e418
LP
86 free(u);
87 return NULL;
88 }
89
ac155bb8
MS
90 u->manager = m;
91 u->type = _UNIT_TYPE_INVALID;
92 u->deserialized_job = _JOB_TYPE_INVALID;
93 u->default_dependencies = true;
94 u->unit_file_state = _UNIT_FILE_STATE_INVALID;
d2dc52db 95 u->unit_file_preset = -1;
d420282b 96 u->on_failure_job_mode = JOB_REPLACE;
87f0e418
LP
97
98 return u;
99}
100
f278026d
LP
101bool unit_has_name(Unit *u, const char *name) {
102 assert(u);
103 assert(name);
104
ac155bb8 105 return !!set_get(u->names, (char*) name);
f278026d
LP
106}
107
598459ce
LP
108static void unit_init(Unit *u) {
109 CGroupContext *cc;
110 ExecContext *ec;
111 KillContext *kc;
112
113 assert(u);
114 assert(u->manager);
115 assert(u->type >= 0);
116
117 cc = unit_get_cgroup_context(u);
118 if (cc) {
119 cgroup_context_init(cc);
120
121 /* Copy in the manager defaults into the cgroup
122 * context, _before_ the rest of the settings have
123 * been initialized */
124
125 cc->cpu_accounting = u->manager->default_cpu_accounting;
126 cc->blockio_accounting = u->manager->default_blockio_accounting;
127 cc->memory_accounting = u->manager->default_memory_accounting;
128 }
129
130 ec = unit_get_exec_context(u);
131 if (ec)
132 exec_context_init(ec);
133
134 kc = unit_get_kill_context(u);
135 if (kc)
136 kill_context_init(kc);
137
138 if (UNIT_VTABLE(u)->init)
139 UNIT_VTABLE(u)->init(u);
140}
141
87f0e418 142int unit_add_name(Unit *u, const char *text) {
598459ce 143 _cleanup_free_ char *s = NULL, *i = NULL;
87f0e418 144 UnitType t;
87f0e418
LP
145 int r;
146
147 assert(u);
148 assert(text);
149
9e2f7c11 150 if (unit_name_is_template(text)) {
598459ce 151
ac155bb8 152 if (!u->instance)
9e2f7c11 153 return -EINVAL;
87f0e418 154
ac155bb8 155 s = unit_name_replace_instance(text, u->instance);
9e2f7c11
LP
156 } else
157 s = strdup(text);
9e2f7c11
LP
158 if (!s)
159 return -ENOMEM;
87f0e418 160
598459ce
LP
161 if (!unit_name_is_valid(s, TEMPLATE_INVALID))
162 return -EINVAL;
e537352b 163
9e2f7c11 164 assert_se((t = unit_name_to_type(s)) >= 0);
87f0e418 165
598459ce
LP
166 if (u->type != _UNIT_TYPE_INVALID && t != u->type)
167 return -EINVAL;
87f0e418 168
e48614c4
ZJS
169 r = unit_name_to_instance(s, &i);
170 if (r < 0)
598459ce 171 return r;
87f0e418 172
598459ce
LP
173 if (i && unit_vtable[t]->no_instances)
174 return -EINVAL;
9e2f7c11 175
276c3e78
LP
176 /* Ensure that this unit is either instanced or not instanced,
177 * but not both. */
598459ce
LP
178 if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i)
179 return -EINVAL;
9e2f7c11
LP
180
181 if (unit_vtable[t]->no_alias &&
ac155bb8 182 !set_isempty(u->names) &&
598459ce
LP
183 !set_get(u->names, s))
184 return -EEXIST;
9e2f7c11 185
598459ce
LP
186 if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES)
187 return -E2BIG;
4f0f902f 188
e48614c4
ZJS
189 r = set_put(u->names, s);
190 if (r < 0) {
9e2f7c11 191 if (r == -EEXIST)
598459ce
LP
192 return 0;
193
194 return r;
87f0e418
LP
195 }
196
e48614c4
ZJS
197 r = hashmap_put(u->manager->units, s, u);
198 if (r < 0) {
ac155bb8 199 set_remove(u->names, s);
598459ce 200 return r;
87f0e418
LP
201 }
202
ac155bb8 203 if (u->type == _UNIT_TYPE_INVALID) {
ac155bb8
MS
204 u->type = t;
205 u->id = s;
206 u->instance = i;
9e2f7c11 207
71fda00f 208 LIST_PREPEND(units_by_type, u->manager->units_by_type[t], u);
e537352b 209
598459ce 210 unit_init(u);
87f0e418 211
598459ce
LP
212 i = NULL;
213 }
9e2f7c11 214
598459ce 215 s = NULL;
9e2f7c11 216
598459ce
LP
217 unit_add_to_dbus_queue(u);
218 return 0;
87f0e418
LP
219}
220
0ae97ec1 221int unit_choose_id(Unit *u, const char *name) {
68eda4bd 222 _cleanup_free_ char *t = NULL;
598459ce 223 char *s, *i;
276c3e78 224 int r;
0ae97ec1
LP
225
226 assert(u);
227 assert(name);
228
9e2f7c11
LP
229 if (unit_name_is_template(name)) {
230
ac155bb8 231 if (!u->instance)
9e2f7c11
LP
232 return -EINVAL;
233
e48614c4
ZJS
234 t = unit_name_replace_instance(name, u->instance);
235 if (!t)
9e2f7c11
LP
236 return -ENOMEM;
237
238 name = t;
239 }
240
0ae97ec1 241 /* Selects one of the names of this unit as the id */
ac155bb8 242 s = set_get(u->names, (char*) name);
9e2f7c11 243 if (!s)
0ae97ec1
LP
244 return -ENOENT;
245
e48614c4
ZJS
246 r = unit_name_to_instance(s, &i);
247 if (r < 0)
276c3e78
LP
248 return r;
249
ac155bb8 250 u->id = s;
276c3e78 251
ac155bb8
MS
252 free(u->instance);
253 u->instance = i;
276c3e78 254
c1e1601e 255 unit_add_to_dbus_queue(u);
9e2f7c11 256
0ae97ec1
LP
257 return 0;
258}
259
f50e0a01
LP
260int unit_set_description(Unit *u, const char *description) {
261 char *s;
262
263 assert(u);
264
8aec412f
LP
265 if (isempty(description))
266 s = NULL;
267 else {
268 s = strdup(description);
269 if (!s)
270 return -ENOMEM;
271 }
f50e0a01 272
ac155bb8
MS
273 free(u->description);
274 u->description = s;
c1e1601e
LP
275
276 unit_add_to_dbus_queue(u);
f50e0a01
LP
277 return 0;
278}
279
701cc384
LP
280bool unit_check_gc(Unit *u) {
281 assert(u);
282
283 if (UNIT_VTABLE(u)->no_gc)
284 return true;
285
ac155bb8 286 if (u->no_gc)
6c073082
LP
287 return true;
288
ac155bb8 289 if (u->job)
701cc384
LP
290 return true;
291
e0209d83
MS
292 if (u->nop_job)
293 return true;
294
701cc384
LP
295 if (unit_active_state(u) != UNIT_INACTIVE)
296 return true;
297
9d576438
LP
298 if (u->refs)
299 return true;
300
701cc384
LP
301 if (UNIT_VTABLE(u)->check_gc)
302 if (UNIT_VTABLE(u)->check_gc(u))
303 return true;
304
305 return false;
306}
307
87f0e418
LP
308void unit_add_to_load_queue(Unit *u) {
309 assert(u);
ac155bb8 310 assert(u->type != _UNIT_TYPE_INVALID);
87f0e418 311
ac155bb8 312 if (u->load_state != UNIT_STUB || u->in_load_queue)
87f0e418
LP
313 return;
314
71fda00f 315 LIST_PREPEND(load_queue, u->manager->load_queue, u);
ac155bb8 316 u->in_load_queue = true;
87f0e418
LP
317}
318
23a177ef
LP
319void unit_add_to_cleanup_queue(Unit *u) {
320 assert(u);
321
ac155bb8 322 if (u->in_cleanup_queue)
23a177ef
LP
323 return;
324
71fda00f 325 LIST_PREPEND(cleanup_queue, u->manager->cleanup_queue, u);
ac155bb8 326 u->in_cleanup_queue = true;
23a177ef
LP
327}
328
701cc384
LP
329void unit_add_to_gc_queue(Unit *u) {
330 assert(u);
331
ac155bb8 332 if (u->in_gc_queue || u->in_cleanup_queue)
701cc384
LP
333 return;
334
335 if (unit_check_gc(u))
336 return;
337
71fda00f 338 LIST_PREPEND(gc_queue, u->manager->gc_queue, u);
ac155bb8 339 u->in_gc_queue = true;
701cc384 340
ac155bb8 341 u->manager->n_in_gc_queue ++;
701cc384
LP
342}
343
c1e1601e
LP
344void unit_add_to_dbus_queue(Unit *u) {
345 assert(u);
ac155bb8 346 assert(u->type != _UNIT_TYPE_INVALID);
c1e1601e 347
ac155bb8 348 if (u->load_state == UNIT_STUB || u->in_dbus_queue)
c1e1601e
LP
349 return;
350
a567261a 351 /* Shortcut things if nobody cares */
8f8f05a9
LP
352 if (sd_bus_track_count(u->manager->subscribed) <= 0 &&
353 set_isempty(u->manager->private_buses)) {
ac155bb8 354 u->sent_dbus_new_signal = true;
94b6dfa2
LP
355 return;
356 }
357
71fda00f 358 LIST_PREPEND(dbus_queue, u->manager->dbus_unit_queue, u);
ac155bb8 359 u->in_dbus_queue = true;
c1e1601e
LP
360}
361
87f0e418
LP
362static void bidi_set_free(Unit *u, Set *s) {
363 Iterator i;
364 Unit *other;
365
366 assert(u);
367
368 /* Frees the set and makes sure we are dropped from the
369 * inverse pointers */
370
371 SET_FOREACH(other, s, i) {
372 UnitDependency d;
373
374 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
ac155bb8 375 set_remove(other->dependencies[d], u);
701cc384
LP
376
377 unit_add_to_gc_queue(other);
87f0e418
LP
378 }
379
380 set_free(s);
381}
382
c2756a68
LP
383static void unit_remove_transient(Unit *u) {
384 char **i;
385
386 assert(u);
387
388 if (!u->transient)
389 return;
390
391 if (u->fragment_path)
392 unlink(u->fragment_path);
393
394 STRV_FOREACH(i, u->dropin_paths) {
395 _cleanup_free_ char *p = NULL;
396 int r;
397
398 unlink(*i);
399
400 r = path_get_parent(*i, &p);
401 if (r >= 0)
402 rmdir(p);
403 }
404}
405
a57f7e2c
LP
406static void unit_free_requires_mounts_for(Unit *u) {
407 char **j;
408
409 STRV_FOREACH(j, u->requires_mounts_for) {
410 char s[strlen(*j) + 1];
411
412 PATH_FOREACH_PREFIX_MORE(s, *j) {
413 char *y;
414 Set *x;
415
416 x = hashmap_get2(u->manager->units_requiring_mounts_for, s, (void**) &y);
417 if (!x)
418 continue;
419
420 set_remove(x, u);
421
422 if (set_isempty(x)) {
423 hashmap_remove(u->manager->units_requiring_mounts_for, y);
424 free(y);
425 set_free(x);
426 }
427 }
428 }
429
430 strv_free(u->requires_mounts_for);
431 u->requires_mounts_for = NULL;
432}
433
598459ce
LP
434static void unit_done(Unit *u) {
435 ExecContext *ec;
436 CGroupContext *cc;
437
438 assert(u);
439
440 if (u->type < 0)
441 return;
442
443 if (UNIT_VTABLE(u)->done)
444 UNIT_VTABLE(u)->done(u);
445
446 ec = unit_get_exec_context(u);
447 if (ec)
448 exec_context_done(ec);
449
450 cc = unit_get_cgroup_context(u);
451 if (cc)
452 cgroup_context_done(cc);
453}
454
87f0e418
LP
455void unit_free(Unit *u) {
456 UnitDependency d;
457 Iterator i;
458 char *t;
459
460 assert(u);
461
c2756a68
LP
462 if (u->manager->n_reloading <= 0)
463 unit_remove_transient(u);
464
c1e1601e
LP
465 bus_unit_send_removed_signal(u);
466
598459ce 467 unit_done(u);
a013b84b 468
a57f7e2c
LP
469 unit_free_requires_mounts_for(u);
470
ac155bb8
MS
471 SET_FOREACH(t, u->names, i)
472 hashmap_remove_value(u->manager->units, t, u);
87f0e418 473
97e7d748
MS
474 if (u->job) {
475 Job *j = u->job;
476 job_uninstall(j);
477 job_free(j);
478 }
964e0949 479
e0209d83
MS
480 if (u->nop_job) {
481 Job *j = u->nop_job;
482 job_uninstall(j);
483 job_free(j);
484 }
485
964e0949 486 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
ac155bb8 487 bidi_set_free(u, u->dependencies[d]);
964e0949 488
ac155bb8 489 if (u->type != _UNIT_TYPE_INVALID)
71fda00f 490 LIST_REMOVE(units_by_type, u->manager->units_by_type[u->type], u);
ef734fd6 491
ac155bb8 492 if (u->in_load_queue)
71fda00f 493 LIST_REMOVE(load_queue, u->manager->load_queue, u);
87f0e418 494
ac155bb8 495 if (u->in_dbus_queue)
71fda00f 496 LIST_REMOVE(dbus_queue, u->manager->dbus_unit_queue, u);
c1e1601e 497
ac155bb8 498 if (u->in_cleanup_queue)
71fda00f 499 LIST_REMOVE(cleanup_queue, u->manager->cleanup_queue, u);
23a177ef 500
ac155bb8 501 if (u->in_gc_queue) {
71fda00f 502 LIST_REMOVE(gc_queue, u->manager->gc_queue, u);
ac155bb8 503 u->manager->n_in_gc_queue--;
701cc384
LP
504 }
505
4ad49000 506 if (u->in_cgroup_queue)
71fda00f 507 LIST_REMOVE(cgroup_queue, u->manager->cgroup_queue, u);
87f0e418 508
72673e86
LP
509 if (u->cgroup_path) {
510 hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
511 free(u->cgroup_path);
512 }
513
f755e3b7 514 set_remove(u->manager->failed_units, u);
db785129 515 set_remove(u->manager->startup_units, u);
f755e3b7 516
ac155bb8 517 free(u->description);
49dbfa7b 518 strv_free(u->documentation);
ac155bb8 519 free(u->fragment_path);
1b64d026 520 free(u->source_path);
ae7a7182 521 strv_free(u->dropin_paths);
ac155bb8 522 free(u->instance);
87f0e418 523
f189ab18
LP
524 free(u->job_timeout_reboot_arg);
525
ac155bb8 526 set_free_free(u->names);
87f0e418 527
a911bb9a
LP
528 unit_unwatch_all_pids(u);
529
ac155bb8 530 condition_free_list(u->conditions);
59fccdc5 531 condition_free_list(u->asserts);
52661efd 532
702a2d8f
LP
533 unit_ref_unset(&u->slice);
534
ac155bb8
MS
535 while (u->refs)
536 unit_ref_unset(u->refs);
57020a3a 537
87f0e418
LP
538 free(u);
539}
540
541UnitActiveState unit_active_state(Unit *u) {
542 assert(u);
543
ac155bb8 544 if (u->load_state == UNIT_MERGED)
6124958c
LP
545 return unit_active_state(unit_follow_merge(u));
546
547 /* After a reload it might happen that a unit is not correctly
548 * loaded but still has a process around. That's why we won't
fdf20a31 549 * shortcut failed loading to UNIT_INACTIVE_FAILED. */
87f0e418
LP
550
551 return UNIT_VTABLE(u)->active_state(u);
552}
553
10a94420
LP
554const char* unit_sub_state_to_string(Unit *u) {
555 assert(u);
556
557 return UNIT_VTABLE(u)->sub_state_to_string(u);
558}
559
7c0b05e5
MS
560static int complete_move(Set **s, Set **other) {
561 int r;
562
23a177ef
LP
563 assert(s);
564 assert(other);
87f0e418 565
23a177ef 566 if (!*other)
7c0b05e5 567 return 0;
87f0e418 568
7c0b05e5
MS
569 if (*s) {
570 r = set_move(*s, *other);
571 if (r < 0)
572 return r;
573 } else {
23a177ef
LP
574 *s = *other;
575 *other = NULL;
576 }
7c0b05e5
MS
577
578 return 0;
23a177ef 579}
87f0e418 580
7c0b05e5 581static int merge_names(Unit *u, Unit *other) {
23a177ef
LP
582 char *t;
583 Iterator i;
7c0b05e5 584 int r;
87f0e418 585
23a177ef
LP
586 assert(u);
587 assert(other);
588
7c0b05e5
MS
589 r = complete_move(&u->names, &other->names);
590 if (r < 0)
591 return r;
23a177ef 592
ac155bb8
MS
593 set_free_free(other->names);
594 other->names = NULL;
595 other->id = NULL;
23a177ef 596
ac155bb8
MS
597 SET_FOREACH(t, u->names, i)
598 assert_se(hashmap_replace(u->manager->units, t, u) == 0);
7c0b05e5
MS
599
600 return 0;
87f0e418
LP
601}
602
09a65f92
MS
603static int reserve_dependencies(Unit *u, Unit *other, UnitDependency d) {
604 unsigned n_reserve;
605
606 assert(u);
607 assert(other);
608 assert(d < _UNIT_DEPENDENCY_MAX);
609
610 /*
611 * If u does not have this dependency set allocated, there is no need
f131770b 612 * to reserve anything. In that case other's set will be transferred
09a65f92
MS
613 * as a whole to u by complete_move().
614 */
615 if (!u->dependencies[d])
616 return 0;
617
618 /* merge_dependencies() will skip a u-on-u dependency */
619 n_reserve = set_size(other->dependencies[d]) - !!set_get(other->dependencies[d], u);
620
621 return set_reserve(u->dependencies[d], n_reserve);
622}
623
d1fab3fe 624static void merge_dependencies(Unit *u, Unit *other, const char *other_id, UnitDependency d) {
23a177ef
LP
625 Iterator i;
626 Unit *back;
87f0e418 627 int r;
23a177ef
LP
628
629 assert(u);
630 assert(other);
631 assert(d < _UNIT_DEPENDENCY_MAX);
632
83a95334 633 /* Fix backwards pointers */
ac155bb8 634 SET_FOREACH(back, other->dependencies[d], i) {
23a177ef
LP
635 UnitDependency k;
636
e48614c4 637 for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++) {
e66047ff
ZJS
638 /* Do not add dependencies between u and itself */
639 if (back == u) {
d1fab3fe
ZJS
640 if (set_remove(back->dependencies[k], other))
641 maybe_warn_about_dependency(u->id, other_id, k);
e66047ff
ZJS
642 } else {
643 r = set_remove_and_put(back->dependencies[k], other, u);
644 if (r == -EEXIST)
645 set_remove(back->dependencies[k], other);
646 else
647 assert(r >= 0 || r == -ENOENT);
648 }
e48614c4 649 }
23a177ef
LP
650 }
651
e66047ff 652 /* Also do not move dependencies on u to itself */
d1fab3fe
ZJS
653 back = set_remove(other->dependencies[d], u);
654 if (back)
655 maybe_warn_about_dependency(u->id, other_id, d);
e66047ff 656
7c0b05e5
MS
657 /* The move cannot fail. The caller must have performed a reservation. */
658 assert_se(complete_move(&u->dependencies[d], &other->dependencies[d]) == 0);
23a177ef 659
ac155bb8
MS
660 set_free(other->dependencies[d]);
661 other->dependencies[d] = NULL;
23a177ef
LP
662}
663
664int unit_merge(Unit *u, Unit *other) {
87f0e418 665 UnitDependency d;
d1fab3fe 666 const char *other_id = NULL;
09a65f92 667 int r;
87f0e418
LP
668
669 assert(u);
670 assert(other);
ac155bb8
MS
671 assert(u->manager == other->manager);
672 assert(u->type != _UNIT_TYPE_INVALID);
87f0e418 673
cc916967
LP
674 other = unit_follow_merge(other);
675
23a177ef
LP
676 if (other == u)
677 return 0;
678
ac155bb8 679 if (u->type != other->type)
9e2f7c11
LP
680 return -EINVAL;
681
ac155bb8 682 if (!u->instance != !other->instance)
87f0e418
LP
683 return -EINVAL;
684
ac155bb8 685 if (other->load_state != UNIT_STUB &&
c2756a68 686 other->load_state != UNIT_NOT_FOUND)
23a177ef 687 return -EEXIST;
87f0e418 688
ac155bb8 689 if (other->job)
819e213f
LP
690 return -EEXIST;
691
e0209d83
MS
692 if (other->nop_job)
693 return -EEXIST;
694
fdf20a31 695 if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
819e213f
LP
696 return -EEXIST;
697
d1fab3fe
ZJS
698 if (other->id)
699 other_id = strdupa(other->id);
700
09a65f92
MS
701 /* Make reservations to ensure merge_dependencies() won't fail */
702 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
703 r = reserve_dependencies(u, other, d);
704 /*
705 * We don't rollback reservations if we fail. We don't have
706 * a way to undo reservations. A reservation is not a leak.
707 */
708 if (r < 0)
709 return r;
710 }
711
87f0e418 712 /* Merge names */
7c0b05e5
MS
713 r = merge_names(u, other);
714 if (r < 0)
715 return r;
87f0e418 716
57020a3a 717 /* Redirect all references */
ac155bb8
MS
718 while (other->refs)
719 unit_ref_set(other->refs, u);
57020a3a 720
87f0e418
LP
721 /* Merge dependencies */
722 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
d1fab3fe 723 merge_dependencies(u, other, other_id, d);
87f0e418 724
ac155bb8
MS
725 other->load_state = UNIT_MERGED;
726 other->merged_into = u;
23a177ef 727
3616a49c
LP
728 /* If there is still some data attached to the other node, we
729 * don't need it anymore, and can free it. */
ac155bb8 730 if (other->load_state != UNIT_STUB)
3616a49c
LP
731 if (UNIT_VTABLE(other)->done)
732 UNIT_VTABLE(other)->done(other);
733
734 unit_add_to_dbus_queue(u);
23a177ef
LP
735 unit_add_to_cleanup_queue(other);
736
737 return 0;
738}
739
740int unit_merge_by_name(Unit *u, const char *name) {
741 Unit *other;
9e2f7c11 742 int r;
68eda4bd 743 _cleanup_free_ char *s = NULL;
23a177ef
LP
744
745 assert(u);
746 assert(name);
747
9e2f7c11 748 if (unit_name_is_template(name)) {
ac155bb8 749 if (!u->instance)
9e2f7c11
LP
750 return -EINVAL;
751
e48614c4
ZJS
752 s = unit_name_replace_instance(name, u->instance);
753 if (!s)
9e2f7c11
LP
754 return -ENOMEM;
755
756 name = s;
757 }
758
c2756a68
LP
759 other = manager_get_unit(u->manager, name);
760 if (!other)
9e2f7c11
LP
761 r = unit_add_name(u, name);
762 else
763 r = unit_merge(u, other);
23a177ef 764
9e2f7c11 765 return r;
23a177ef
LP
766}
767
768Unit* unit_follow_merge(Unit *u) {
769 assert(u);
770
ac155bb8
MS
771 while (u->load_state == UNIT_MERGED)
772 assert_se(u = u->merged_into);
23a177ef
LP
773
774 return u;
775}
776
777int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
778 int r;
779
780 assert(u);
781 assert(c);
782
36be24c8
ZJS
783 if (c->working_directory) {
784 r = unit_require_mounts_for(u, c->working_directory);
785 if (r < 0)
786 return r;
787 }
788
789 if (c->root_directory) {
790 r = unit_require_mounts_for(u, c->root_directory);
791 if (r < 0)
792 return r;
793 }
794
b46a529c
LP
795 if (u->manager->running_as != SYSTEMD_SYSTEM)
796 return 0;
797
798 if (c->private_tmp) {
799 r = unit_require_mounts_for(u, "/tmp");
800 if (r < 0)
801 return r;
802
803 r = unit_require_mounts_for(u, "/var/tmp");
804 if (r < 0)
805 return r;
806 }
807
ecc6e2b8
LP
808 if (c->std_output != EXEC_OUTPUT_KMSG &&
809 c->std_output != EXEC_OUTPUT_SYSLOG &&
706343f4 810 c->std_output != EXEC_OUTPUT_JOURNAL &&
28dbc1e8
LP
811 c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
812 c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
706343f4 813 c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
ecc6e2b8 814 c->std_error != EXEC_OUTPUT_KMSG &&
085c98af 815 c->std_error != EXEC_OUTPUT_SYSLOG &&
706343f4 816 c->std_error != EXEC_OUTPUT_JOURNAL &&
085c98af 817 c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
706343f4 818 c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
28dbc1e8 819 c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE)
23a177ef
LP
820 return 0;
821
822 /* If syslog or kernel logging is requested, make sure our own
823 * logging daemon is run first. */
824
b46a529c
LP
825 r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true);
826 if (r < 0)
827 return r;
23a177ef 828
87f0e418
LP
829 return 0;
830}
831
87f0e418
LP
832const char *unit_description(Unit *u) {
833 assert(u);
834
ac155bb8
MS
835 if (u->description)
836 return u->description;
87f0e418 837
ac155bb8 838 return strna(u->id);
87f0e418
LP
839}
840
841void unit_dump(Unit *u, FILE *f, const char *prefix) {
49dbfa7b 842 char *t, **j;
87f0e418
LP
843 UnitDependency d;
844 Iterator i;
47be870b 845 const char *prefix2;
173e3821
LP
846 char
847 timestamp1[FORMAT_TIMESTAMP_MAX],
848 timestamp2[FORMAT_TIMESTAMP_MAX],
849 timestamp3[FORMAT_TIMESTAMP_MAX],
faf919f1
LP
850 timestamp4[FORMAT_TIMESTAMP_MAX],
851 timespan[FORMAT_TIMESPAN_MAX];
a7f241db 852 Unit *following;
eeaedb7c
LP
853 _cleanup_set_free_ Set *following_set = NULL;
854 int r;
87f0e418
LP
855
856 assert(u);
ac155bb8 857 assert(u->type >= 0);
87f0e418 858
4c940960
LP
859 prefix = strempty(prefix);
860 prefix2 = strappenda(prefix, "\t");
87f0e418
LP
861
862 fprintf(f,
40d50879 863 "%s-> Unit %s:\n"
87f0e418 864 "%s\tDescription: %s\n"
9e2f7c11 865 "%s\tInstance: %s\n"
87f0e418 866 "%s\tUnit Load State: %s\n"
2fad8195 867 "%s\tUnit Active State: %s\n"
173e3821 868 "%s\tInactive Exit Timestamp: %s\n"
2fad8195 869 "%s\tActive Enter Timestamp: %s\n"
701cc384 870 "%s\tActive Exit Timestamp: %s\n"
173e3821 871 "%s\tInactive Enter Timestamp: %s\n"
45fb0699 872 "%s\tGC Check Good: %s\n"
9444b1f2 873 "%s\tNeed Daemon Reload: %s\n"
c2756a68 874 "%s\tTransient: %s\n"
4ad49000
LP
875 "%s\tSlice: %s\n"
876 "%s\tCGroup: %s\n"
877 "%s\tCGroup realized: %s\n"
6414b7c9
DS
878 "%s\tCGroup mask: 0x%x\n"
879 "%s\tCGroup members mask: 0x%x\n",
ac155bb8 880 prefix, u->id,
87f0e418 881 prefix, unit_description(u),
ac155bb8
MS
882 prefix, strna(u->instance),
883 prefix, unit_load_state_to_string(u->load_state),
2fad8195 884 prefix, unit_active_state_to_string(unit_active_state(u)),
ac155bb8
MS
885 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->inactive_exit_timestamp.realtime)),
886 prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->active_enter_timestamp.realtime)),
887 prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)),
888 prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)),
45fb0699 889 prefix, yes_no(unit_check_gc(u)),
9444b1f2 890 prefix, yes_no(unit_need_daemon_reload(u)),
c2756a68 891 prefix, yes_no(u->transient),
4ad49000
LP
892 prefix, strna(unit_slice_name(u)),
893 prefix, strna(u->cgroup_path),
894 prefix, yes_no(u->cgroup_realized),
bc432dc7 895 prefix, u->cgroup_realized_mask,
6414b7c9 896 prefix, u->cgroup_members_mask);
0301abf4 897
ac155bb8 898 SET_FOREACH(t, u->names, i)
87f0e418
LP
899 fprintf(f, "%s\tName: %s\n", prefix, t);
900
49dbfa7b
LP
901 STRV_FOREACH(j, u->documentation)
902 fprintf(f, "%s\tDocumentation: %s\n", prefix, *j);
903
eeaedb7c
LP
904 following = unit_following(u);
905 if (following)
ac155bb8 906 fprintf(f, "%s\tFollowing: %s\n", prefix, following->id);
8fe914ec 907
eeaedb7c
LP
908 r = unit_following_set(u, &following_set);
909 if (r >= 0) {
910 Unit *other;
911
912 SET_FOREACH(other, following_set, i)
913 fprintf(f, "%s\tFollowing Set Member: %s\n", prefix, other->id);
914 }
915
ac155bb8
MS
916 if (u->fragment_path)
917 fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path);
23a177ef 918
1b64d026
LP
919 if (u->source_path)
920 fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path);
921
ae7a7182 922 STRV_FOREACH(j, u->dropin_paths)
2875e22b 923 fprintf(f, "%s\tDropIn Path: %s\n", prefix, *j);
ae7a7182 924
ac155bb8 925 if (u->job_timeout > 0)
2fa4092c 926 fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
faf919f1 927
f189ab18
LP
928 if (u->job_timeout_action != FAILURE_ACTION_NONE)
929 fprintf(f, "%s\tJob Timeout Action: %s\n", prefix, failure_action_to_string(u->job_timeout_action));
930
931 if (u->job_timeout_reboot_arg)
932 fprintf(f, "%s\tJob Timeout Reboot Argument: %s\n", prefix, u->job_timeout_reboot_arg);
933
59fccdc5
LP
934 condition_dump_list(u->conditions, f, prefix, condition_type_to_string);
935 condition_dump_list(u->asserts, f, prefix, assert_type_to_string);
52661efd 936
ac155bb8 937 if (dual_timestamp_is_set(&u->condition_timestamp))
2791a8f8
LP
938 fprintf(f,
939 "%s\tCondition Timestamp: %s\n"
940 "%s\tCondition Result: %s\n",
ac155bb8
MS
941 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->condition_timestamp.realtime)),
942 prefix, yes_no(u->condition_result));
2791a8f8 943
59fccdc5
LP
944 if (dual_timestamp_is_set(&u->assert_timestamp))
945 fprintf(f,
946 "%s\tAssert Timestamp: %s\n"
947 "%s\tAssert Result: %s\n",
948 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->assert_timestamp.realtime)),
949 prefix, yes_no(u->assert_result));
950
87f0e418
LP
951 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
952 Unit *other;
953
ac155bb8
MS
954 SET_FOREACH(other, u->dependencies[d], i)
955 fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
87f0e418
LP
956 }
957
7c8fa05c 958 if (!strv_isempty(u->requires_mounts_for)) {
7c8fa05c
LP
959 fprintf(f,
960 "%s\tRequiresMountsFor:", prefix);
961
962 STRV_FOREACH(j, u->requires_mounts_for)
963 fprintf(f, " %s", *j);
964
965 fputs("\n", f);
966 }
967
ac155bb8 968 if (u->load_state == UNIT_LOADED) {
ab1f0633 969
b0650475 970 fprintf(f,
a40eb732 971 "%s\tStopWhenUnneeded: %s\n"
b5e9dba8
LP
972 "%s\tRefuseManualStart: %s\n"
973 "%s\tRefuseManualStop: %s\n"
222ae6a8 974 "%s\tDefaultDependencies: %s\n"
d420282b 975 "%s\tOnFailureJobMode: %s\n"
7a6000a6
LP
976 "%s\tIgnoreOnIsolate: %s\n"
977 "%s\tIgnoreOnSnapshot: %s\n",
ac155bb8
MS
978 prefix, yes_no(u->stop_when_unneeded),
979 prefix, yes_no(u->refuse_manual_start),
980 prefix, yes_no(u->refuse_manual_stop),
981 prefix, yes_no(u->default_dependencies),
d420282b 982 prefix, job_mode_to_string(u->on_failure_job_mode),
ac155bb8
MS
983 prefix, yes_no(u->ignore_on_isolate),
984 prefix, yes_no(u->ignore_on_snapshot));
985
23a177ef
LP
986 if (UNIT_VTABLE(u)->dump)
987 UNIT_VTABLE(u)->dump(u, f, prefix2);
b0650475 988
ac155bb8 989 } else if (u->load_state == UNIT_MERGED)
b0650475
LP
990 fprintf(f,
991 "%s\tMerged into: %s\n",
ac155bb8
MS
992 prefix, u->merged_into->id);
993 else if (u->load_state == UNIT_ERROR)
994 fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->load_error));
8821a00f 995
87f0e418 996
ac155bb8
MS
997 if (u->job)
998 job_dump(u->job, f, prefix2);
87f0e418 999
e0209d83
MS
1000 if (u->nop_job)
1001 job_dump(u->nop_job, f, prefix2);
1002
87f0e418
LP
1003}
1004
1005/* Common implementation for multiple backends */
e537352b 1006int unit_load_fragment_and_dropin(Unit *u) {
23a177ef
LP
1007 int r;
1008
1009 assert(u);
23a177ef 1010
e48614c4 1011 /* Load a .{service,socket,...} file */
4ad49000
LP
1012 r = unit_load_fragment(u);
1013 if (r < 0)
23a177ef
LP
1014 return r;
1015
ac155bb8 1016 if (u->load_state == UNIT_STUB)
23a177ef
LP
1017 return -ENOENT;
1018
1019 /* Load drop-in directory data */
4ad49000
LP
1020 r = unit_load_dropin(unit_follow_merge(u));
1021 if (r < 0)
23a177ef
LP
1022 return r;
1023
1024 return 0;
1025}
1026
1027/* Common implementation for multiple backends */
e537352b 1028int unit_load_fragment_and_dropin_optional(Unit *u) {
23a177ef 1029 int r;
87f0e418
LP
1030
1031 assert(u);
1032
23a177ef
LP
1033 /* Same as unit_load_fragment_and_dropin(), but whether
1034 * something can be loaded or not doesn't matter. */
1035
1036 /* Load a .service file */
4ad49000
LP
1037 r = unit_load_fragment(u);
1038 if (r < 0)
87f0e418
LP
1039 return r;
1040
ac155bb8
MS
1041 if (u->load_state == UNIT_STUB)
1042 u->load_state = UNIT_LOADED;
d46de8a1 1043
87f0e418 1044 /* Load drop-in directory data */
4ad49000
LP
1045 r = unit_load_dropin(unit_follow_merge(u));
1046 if (r < 0)
87f0e418
LP
1047 return r;
1048
23a177ef 1049 return 0;
87f0e418
LP
1050}
1051
bba34eed 1052int unit_add_default_target_dependency(Unit *u, Unit *target) {
98bc2000
LP
1053 assert(u);
1054 assert(target);
1055
ac155bb8 1056 if (target->type != UNIT_TARGET)
98bc2000
LP
1057 return 0;
1058
35b8ca3a 1059 /* Only add the dependency if both units are loaded, so that
bba34eed 1060 * that loop check below is reliable */
ac155bb8
MS
1061 if (u->load_state != UNIT_LOADED ||
1062 target->load_state != UNIT_LOADED)
bba34eed
LP
1063 return 0;
1064
21256a2b
LP
1065 /* If either side wants no automatic dependencies, then let's
1066 * skip this */
ac155bb8
MS
1067 if (!u->default_dependencies ||
1068 !target->default_dependencies)
21256a2b
LP
1069 return 0;
1070
98bc2000 1071 /* Don't create loops */
ac155bb8 1072 if (set_get(target->dependencies[UNIT_BEFORE], u))
98bc2000
LP
1073 return 0;
1074
1075 return unit_add_dependency(target, UNIT_AFTER, u, true);
1076}
1077
e954c9cf 1078static int unit_add_target_dependencies(Unit *u) {
a016b922 1079
21256a2b
LP
1080 static const UnitDependency deps[] = {
1081 UNIT_REQUIRED_BY,
1082 UNIT_REQUIRED_BY_OVERRIDABLE,
1083 UNIT_WANTED_BY,
1084 UNIT_BOUND_BY
1085 };
1086
bba34eed 1087 Unit *target;
98bc2000 1088 Iterator i;
21256a2b 1089 unsigned k;
db57f3c6 1090 int r = 0;
98bc2000
LP
1091
1092 assert(u);
1093
21256a2b 1094 for (k = 0; k < ELEMENTSOF(deps); k++)
a016b922
LP
1095 SET_FOREACH(target, u->dependencies[deps[k]], i) {
1096 r = unit_add_default_target_dependency(u, target);
1097 if (r < 0)
21256a2b 1098 return r;
a016b922
LP
1099 }
1100
e954c9cf
LP
1101 return r;
1102}
4ad49000 1103
e954c9cf
LP
1104static int unit_add_slice_dependencies(Unit *u) {
1105 assert(u);
b81884e7 1106
e954c9cf
LP
1107 if (!unit_get_cgroup_context(u))
1108 return 0;
1109
1110 if (UNIT_ISSET(u->slice))
1111 return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true);
1112
d1fab3fe
ZJS
1113 if (streq(u->id, SPECIAL_ROOT_SLICE))
1114 return 0;
1115
e954c9cf 1116 return unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, SPECIAL_ROOT_SLICE, NULL, true);
98bc2000
LP
1117}
1118
e954c9cf 1119static int unit_add_mount_dependencies(Unit *u) {
9588bc32
LP
1120 char **i;
1121 int r;
1122
1123 assert(u);
1124
1125 STRV_FOREACH(i, u->requires_mounts_for) {
1126 char prefix[strlen(*i) + 1];
1127
1128 PATH_FOREACH_PREFIX_MORE(prefix, *i) {
1129 Unit *m;
1130
1131 r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m);
1132 if (r < 0)
1133 return r;
1134 if (r == 0)
1135 continue;
1136 if (m == u)
1137 continue;
1138
1139 if (m->load_state != UNIT_LOADED)
1140 continue;
1141
1142 r = unit_add_dependency(u, UNIT_AFTER, m, true);
1143 if (r < 0)
1144 return r;
1145
1146 if (m->fragment_path) {
1147 r = unit_add_dependency(u, UNIT_REQUIRES, m, true);
1148 if (r < 0)
1149 return r;
1150 }
1151 }
1152 }
1153
1154 return 0;
1155}
1156
95ae05c0
WC
1157static int unit_add_startup_units(Unit *u) {
1158 CGroupContext *c;
1159 int r = 0;
1160
1161 c = unit_get_cgroup_context(u);
db785129
LP
1162 if (!c)
1163 return 0;
1164
1165 if (c->startup_cpu_shares == (unsigned long) -1 &&
1166 c->startup_blockio_weight == (unsigned long) -1)
1167 return 0;
1168
1169 r = set_put(u->manager->startup_units, u);
1170 if (r == -EEXIST)
1171 return 0;
1172
95ae05c0
WC
1173 return r;
1174}
1175
87f0e418
LP
1176int unit_load(Unit *u) {
1177 int r;
1178
1179 assert(u);
1180
ac155bb8 1181 if (u->in_load_queue) {
71fda00f 1182 LIST_REMOVE(load_queue, u->manager->load_queue, u);
ac155bb8 1183 u->in_load_queue = false;
87f0e418
LP
1184 }
1185
ac155bb8 1186 if (u->type == _UNIT_TYPE_INVALID)
e537352b
LP
1187 return -EINVAL;
1188
ac155bb8 1189 if (u->load_state != UNIT_STUB)
87f0e418
LP
1190 return 0;
1191
c2756a68
LP
1192 if (UNIT_VTABLE(u)->load) {
1193 r = UNIT_VTABLE(u)->load(u);
1194 if (r < 0)
87f0e418 1195 goto fail;
c2756a68 1196 }
23a177ef 1197
ac155bb8 1198 if (u->load_state == UNIT_STUB) {
23a177ef
LP
1199 r = -ENOENT;
1200 goto fail;
1201 }
1202
7c8fa05c 1203 if (u->load_state == UNIT_LOADED) {
c2756a68 1204
e954c9cf
LP
1205 r = unit_add_target_dependencies(u);
1206 if (r < 0)
1207 goto fail;
1208
1209 r = unit_add_slice_dependencies(u);
1210 if (r < 0)
1211 goto fail;
c2756a68 1212
e954c9cf 1213 r = unit_add_mount_dependencies(u);
7c8fa05c 1214 if (r < 0)
c2756a68 1215 goto fail;
7c8fa05c 1216
95ae05c0
WC
1217 r = unit_add_startup_units(u);
1218 if (r < 0)
1219 goto fail;
1220
bc432dc7 1221 if (u->on_failure_job_mode == JOB_ISOLATE && set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
79008bdd 1222 log_unit_error(u->id, "More than one OnFailure= dependencies specified for %s but OnFailureJobMode=isolate set. Refusing.", u->id);
c2756a68
LP
1223 r = -EINVAL;
1224 goto fail;
1225 }
bc432dc7
LP
1226
1227 unit_update_cgroup_members_masks(u);
f68319bb
LP
1228 }
1229
ac155bb8 1230 assert((u->load_state != UNIT_MERGED) == !u->merged_into);
23a177ef
LP
1231
1232 unit_add_to_dbus_queue(unit_follow_merge(u));
701cc384 1233 unit_add_to_gc_queue(u);
87f0e418 1234
87f0e418
LP
1235 return 0;
1236
1237fail:
c2756a68 1238 u->load_state = u->load_state == UNIT_STUB ? UNIT_NOT_FOUND : UNIT_ERROR;
ac155bb8 1239 u->load_error = r;
c1e1601e 1240 unit_add_to_dbus_queue(u);
9a46fc3b 1241 unit_add_to_gc_queue(u);
23a177ef 1242
79008bdd 1243 log_unit_debug(u->id, "Failed to load configuration for %s: %s",
c1b6628d 1244 u->id, strerror(-r));
23a177ef 1245
87f0e418
LP
1246 return r;
1247}
1248
49365733
LP
1249static bool unit_condition_test_list(Unit *u, Condition *first, const char *(*to_string)(ConditionType t)) {
1250 Condition *c;
1251 int triggered = -1;
1252
1253 assert(u);
1254 assert(to_string);
1255
1256 /* If the condition list is empty, then it is true */
1257 if (!first)
1258 return true;
1259
1260 /* Otherwise, if all of the non-trigger conditions apply and
1261 * if any of the trigger conditions apply (unless there are
1262 * none) we return true */
1263 LIST_FOREACH(conditions, c, first) {
1264 int r;
1265
1266 r = condition_test(c);
1267 if (r < 0)
79008bdd 1268 log_unit_warning(u->id,
49365733
LP
1269 "Couldn't determine result for %s=%s%s%s for %s, assuming failed: %s",
1270 to_string(c->type),
1271 c->trigger ? "|" : "",
1272 c->negate ? "!" : "",
1273 c->parameter,
1274 u->id,
1275 strerror(-r));
1276 else
79008bdd 1277 log_unit_debug(u->id,
49365733
LP
1278 "%s=%s%s%s %s for %s.",
1279 to_string(c->type),
1280 c->trigger ? "|" : "",
1281 c->negate ? "!" : "",
1282 c->parameter,
1283 condition_result_to_string(c->result),
1284 u->id);
1285
1286 if (!c->trigger && r <= 0)
1287 return false;
1288
1289 if (c->trigger && triggered <= 0)
1290 triggered = r > 0;
1291 }
1292
1293 return triggered != 0;
1294}
1295
9588bc32 1296static bool unit_condition_test(Unit *u) {
90bbc946
LP
1297 assert(u);
1298
ac155bb8 1299 dual_timestamp_get(&u->condition_timestamp);
49365733 1300 u->condition_result = unit_condition_test_list(u, u->conditions, condition_type_to_string);
90bbc946 1301
ac155bb8 1302 return u->condition_result;
90bbc946
LP
1303}
1304
59fccdc5
LP
1305static bool unit_assert_test(Unit *u) {
1306 assert(u);
1307
1308 dual_timestamp_get(&u->assert_timestamp);
49365733 1309 u->assert_result = unit_condition_test_list(u, u->asserts, assert_type_to_string);
59fccdc5
LP
1310
1311 return u->assert_result;
1312}
1313
44a6b1b6 1314_pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
c6918296 1315 const UnitStatusMessageFormats *format_table;
877d54e9
LP
1316
1317 assert(u);
1318 assert(t >= 0);
1319 assert(t < _JOB_TYPE_MAX);
1320
1321 if (t != JOB_START && t != JOB_STOP)
1322 return NULL;
c6918296
MS
1323
1324 format_table = &UNIT_VTABLE(u)->status_message_formats;
1325 if (!format_table)
877d54e9
LP
1326 return NULL;
1327
1328 return format_table->starting_stopping[t == JOB_STOP];
1329}
1330
44a6b1b6 1331_pure_ static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) {
877d54e9
LP
1332 const char *format;
1333
1334 assert(u);
1335 assert(t >= 0);
1336 assert(t < _JOB_TYPE_MAX);
1337
1338 format = unit_get_status_message_format(u, t);
1339 if (format)
1340 return format;
1341
1342 /* Return generic strings */
1343 if (t == JOB_START)
1344 return "Starting %s.";
1345 else if (t == JOB_STOP)
1346 return "Stopping %s.";
1347 else if (t == JOB_RELOAD)
1348 return "Reloading %s.";
1349
1350 return NULL;
1351}
1352
1353static void unit_status_print_starting_stopping(Unit *u, JobType t) {
1354 const char *format;
1355
1356 assert(u);
1357
1358 /* We only print status messages for selected units on
1359 * selected operations. */
c6918296 1360
877d54e9 1361 format = unit_get_status_message_format(u, t);
c6918296
MS
1362 if (!format)
1363 return;
1364
bcfce235 1365 DISABLE_WARNING_FORMAT_NONLITERAL;
49b1d377 1366 unit_status_printf(u, "", format);
bcfce235 1367 REENABLE_WARNING;
c6918296
MS
1368}
1369
877d54e9
LP
1370static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
1371 const char *format;
1372 char buf[LINE_MAX];
1373 sd_id128_t mid;
1374
1375 assert(u);
1376
1377 if (t != JOB_START && t != JOB_STOP && t != JOB_RELOAD)
1378 return;
1379
81270860
LP
1380 if (log_on_console())
1381 return;
1382
877d54e9
LP
1383 /* We log status messages for all units and all operations. */
1384
1385 format = unit_get_status_message_format_try_harder(u, t);
1386 if (!format)
1387 return;
1388
bcfce235 1389 DISABLE_WARNING_FORMAT_NONLITERAL;
877d54e9
LP
1390 snprintf(buf, sizeof(buf), format, unit_description(u));
1391 char_array_0(buf);
bcfce235 1392 REENABLE_WARNING;
877d54e9
LP
1393
1394 mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
1395 t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
1396 SD_MESSAGE_UNIT_RELOADING;
1397
e2cc6eca
LP
1398 log_unit_struct(u->id,
1399 LOG_INFO,
1400 LOG_MESSAGE_ID(mid),
1401 LOG_MESSAGE("%s", buf),
c1b6628d 1402 NULL);
877d54e9 1403}
877d54e9 1404
87f0e418 1405/* Errors:
d5159713
LP
1406 * -EBADR: This unit type does not support starting.
1407 * -EALREADY: Unit is already started.
1408 * -EAGAIN: An operation is already in progress. Retry later.
1409 * -ECANCELED: Too many requests for now.
59fccdc5 1410 * -EPROTO: Assert failed
87f0e418
LP
1411 */
1412int unit_start(Unit *u) {
1413 UnitActiveState state;
92ab323c 1414 Unit *following;
87f0e418
LP
1415
1416 assert(u);
1417
ac155bb8 1418 if (u->load_state != UNIT_LOADED)
6124958c
LP
1419 return -EINVAL;
1420
a82e5507
LP
1421 /* If this is already started, then this will succeed. Note
1422 * that this will even succeed if this unit is not startable
1423 * by the user. This is relied on to detect when we need to
1424 * wait for units and when waiting is finished. */
87f0e418
LP
1425 state = unit_active_state(u);
1426 if (UNIT_IS_ACTIVE_OR_RELOADING(state))
1427 return -EALREADY;
1428
a82e5507
LP
1429 /* If the conditions failed, don't do anything at all. If we
1430 * already are activating this call might still be useful to
1431 * speed up activation in case there is some hold-off time,
1432 * but we don't want to recheck the condition in that case. */
1433 if (state != UNIT_ACTIVATING &&
1434 !unit_condition_test(u)) {
79008bdd 1435 log_unit_debug(u->id, "Starting of %s requested but condition failed. Not starting unit.", u->id);
52661efd
LP
1436 return -EALREADY;
1437 }
1438
59fccdc5
LP
1439 /* If the asserts failed, fail the entire job */
1440 if (state != UNIT_ACTIVATING &&
1441 !unit_assert_test(u)) {
79008bdd 1442 log_unit_debug(u->id, "Starting of %s requested but asserts failed.", u->id);
59fccdc5
LP
1443 return -EPROTO;
1444 }
1445
92ab323c 1446 /* Forward to the main object, if we aren't it. */
52990c2e
ZJS
1447 following = unit_following(u);
1448 if (following) {
79008bdd 1449 log_unit_debug(u->id, "Redirecting start request from %s to %s.", u->id, following->id);
92ab323c
LP
1450 return unit_start(following);
1451 }
1452
877d54e9
LP
1453 unit_status_log_starting_stopping_reloading(u, JOB_START);
1454 unit_status_print_starting_stopping(u, JOB_START);
c6918296 1455
0faacd47
LP
1456 if (UNIT_VTABLE(u)->supported && !UNIT_VTABLE(u)->supported(u->manager))
1457 return -ENOTSUP;
1458
92ab323c
LP
1459 /* If it is stopped, but we cannot start it, then fail */
1460 if (!UNIT_VTABLE(u)->start)
1461 return -EBADR;
1462
87f0e418
LP
1463 /* We don't suppress calls to ->start() here when we are
1464 * already starting, to allow this request to be used as a
1465 * "hurry up" call, for example when the unit is in some "auto
1466 * restart" state where it waits for a holdoff timer to elapse
1467 * before it will start again. */
1468
c1e1601e 1469 unit_add_to_dbus_queue(u);
9e58ff9c 1470
87f0e418
LP
1471 return UNIT_VTABLE(u)->start(u);
1472}
1473
1474bool unit_can_start(Unit *u) {
1475 assert(u);
1476
1477 return !!UNIT_VTABLE(u)->start;
1478}
1479
2528a7a6
LP
1480bool unit_can_isolate(Unit *u) {
1481 assert(u);
1482
1483 return unit_can_start(u) &&
ac155bb8 1484 u->allow_isolate;
2528a7a6
LP
1485}
1486
87f0e418
LP
1487/* Errors:
1488 * -EBADR: This unit type does not support stopping.
1489 * -EALREADY: Unit is already stopped.
1490 * -EAGAIN: An operation is already in progress. Retry later.
1491 */
1492int unit_stop(Unit *u) {
1493 UnitActiveState state;
92ab323c 1494 Unit *following;
87f0e418
LP
1495
1496 assert(u);
1497
87f0e418 1498 state = unit_active_state(u);
fdf20a31 1499 if (UNIT_IS_INACTIVE_OR_FAILED(state))
87f0e418
LP
1500 return -EALREADY;
1501
0faacd47
LP
1502 following = unit_following(u);
1503 if (following) {
1504 log_unit_debug(u->id, "Redirecting stop request from %s to %s.", u->id, following->id);
92ab323c
LP
1505 return unit_stop(following);
1506 }
1507
877d54e9
LP
1508 unit_status_log_starting_stopping_reloading(u, JOB_STOP);
1509 unit_status_print_starting_stopping(u, JOB_STOP);
c6918296 1510
7898b0cf
LP
1511 if (!UNIT_VTABLE(u)->stop)
1512 return -EBADR;
1513
c1e1601e 1514 unit_add_to_dbus_queue(u);
9e58ff9c 1515
87f0e418
LP
1516 return UNIT_VTABLE(u)->stop(u);
1517}
1518
1519/* Errors:
1520 * -EBADR: This unit type does not support reloading.
1521 * -ENOEXEC: Unit is not started.
1522 * -EAGAIN: An operation is already in progress. Retry later.
1523 */
1524int unit_reload(Unit *u) {
1525 UnitActiveState state;
92ab323c 1526 Unit *following;
87f0e418
LP
1527
1528 assert(u);
1529
ac155bb8 1530 if (u->load_state != UNIT_LOADED)
6124958c
LP
1531 return -EINVAL;
1532
87f0e418
LP
1533 if (!unit_can_reload(u))
1534 return -EBADR;
1535
1536 state = unit_active_state(u);
e364ad06 1537 if (state == UNIT_RELOADING)
87f0e418
LP
1538 return -EALREADY;
1539
6a371e23 1540 if (state != UNIT_ACTIVE) {
0faacd47 1541 log_unit_warning(u->id, "Unit %s cannot be reloaded because it is inactive.", u->id);
87f0e418 1542 return -ENOEXEC;
6a371e23 1543 }
87f0e418 1544
e48614c4
ZJS
1545 following = unit_following(u);
1546 if (following) {
0faacd47 1547 log_unit_debug(u->id, "Redirecting reload request from %s to %s.", u->id, following->id);
92ab323c
LP
1548 return unit_reload(following);
1549 }
1550
877d54e9
LP
1551 unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
1552
c1e1601e 1553 unit_add_to_dbus_queue(u);
87f0e418
LP
1554 return UNIT_VTABLE(u)->reload(u);
1555}
1556
1557bool unit_can_reload(Unit *u) {
1558 assert(u);
1559
1560 if (!UNIT_VTABLE(u)->reload)
1561 return false;
1562
1563 if (!UNIT_VTABLE(u)->can_reload)
1564 return true;
1565
1566 return UNIT_VTABLE(u)->can_reload(u);
1567}
1568
b4a16b7b 1569static void unit_check_unneeded(Unit *u) {
f3bff0eb
LP
1570 Iterator i;
1571 Unit *other;
1572
1573 assert(u);
1574
1575 /* If this service shall be shut down when unneeded then do
1576 * so. */
1577
ac155bb8 1578 if (!u->stop_when_unneeded)
f3bff0eb
LP
1579 return;
1580
1581 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1582 return;
1583
ac155bb8 1584 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
31afa0a4 1585 if (unit_active_or_pending(other))
f3bff0eb
LP
1586 return;
1587
ac155bb8 1588 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
31afa0a4 1589 if (unit_active_or_pending(other))
f3bff0eb
LP
1590 return;
1591
ac155bb8 1592 SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
31afa0a4 1593 if (unit_active_or_pending(other))
f3bff0eb
LP
1594 return;
1595
ac155bb8 1596 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
31afa0a4 1597 if (unit_active_or_pending(other))
b81884e7
LP
1598 return;
1599
79008bdd 1600 log_unit_info(u->id, "Unit %s is not needed anymore. Stopping.", u->id);
f3bff0eb
LP
1601
1602 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
ac155bb8 1603 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
f3bff0eb
LP
1604}
1605
ff502445
LP
1606static void unit_check_binds_to(Unit *u) {
1607 bool stop = false;
1608 Unit *other;
1609 Iterator i;
1610
1611 assert(u);
1612
1613 if (u->job)
1614 return;
1615
1616 if (unit_active_state(u) != UNIT_ACTIVE)
1617 return;
1618
1619 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i) {
1620 if (other->job)
1621 continue;
1622
1623 if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
1624 continue;
1625
1626 stop = true;
1627 }
1628
1629 if (!stop)
1630 return;
1631
79008bdd 1632 log_unit_info(u->id, "Unit %s is bound to inactive service. Stopping, too.", u->id);
ff502445
LP
1633
1634 /* A unit we need to run is gone. Sniff. Let's stop this. */
1635 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
1636}
1637
87f0e418
LP
1638static void retroactively_start_dependencies(Unit *u) {
1639 Iterator i;
1640 Unit *other;
1641
1642 assert(u);
1643 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1644
ac155bb8
MS
1645 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1646 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1647 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1648 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
b81884e7 1649
7f2cddae 1650 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
ac155bb8 1651 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1652 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1653 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
87f0e418 1654
ac155bb8
MS
1655 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1656 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1657 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1658 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
87f0e418 1659
ac155bb8
MS
1660 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1661 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1662 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1663 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
87f0e418 1664
ac155bb8 1665 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
b81884e7 1666 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1667 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
69dd2852 1668
ac155bb8 1669 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
b81884e7 1670 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1671 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
87f0e418
LP
1672}
1673
1674static void retroactively_stop_dependencies(Unit *u) {
1675 Iterator i;
1676 Unit *other;
1677
1678 assert(u);
1679 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1680
b81884e7 1681 /* Pull down units which are bound to us recursively if enabled */
ac155bb8 1682 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
b81884e7 1683 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1684 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
cd0504d0
MS
1685}
1686
1687static void check_unneeded_dependencies(Unit *u) {
1688 Iterator i;
1689 Unit *other;
1690
1691 assert(u);
1692 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
f3bff0eb
LP
1693
1694 /* Garbage collect services that might not be needed anymore, if enabled */
ac155bb8 1695 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
87f0e418 1696 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1697 unit_check_unneeded(other);
ac155bb8 1698 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
f3bff0eb 1699 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1700 unit_check_unneeded(other);
ac155bb8 1701 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
f3bff0eb 1702 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1703 unit_check_unneeded(other);
ac155bb8 1704 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
f3bff0eb 1705 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1706 unit_check_unneeded(other);
ac155bb8 1707 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
f3bff0eb 1708 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1709 unit_check_unneeded(other);
7f2cddae 1710 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
b81884e7
LP
1711 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1712 unit_check_unneeded(other);
87f0e418
LP
1713}
1714
3ecaa09b 1715void unit_start_on_failure(Unit *u) {
c0daa706
LP
1716 Unit *other;
1717 Iterator i;
1718
1719 assert(u);
1720
ac155bb8 1721 if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
222ae6a8
LP
1722 return;
1723
79008bdd 1724 log_unit_info(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
222ae6a8 1725
ac155bb8 1726 SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
222ae6a8
LP
1727 int r;
1728
d420282b 1729 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_job_mode, true, NULL, NULL);
c1b6628d 1730 if (r < 0)
31938a85 1731 log_unit_error_errno(u->id, r, "Failed to enqueue OnFailure= job: %m");
222ae6a8 1732 }
c0daa706
LP
1733}
1734
3ecaa09b
LP
1735void unit_trigger_notify(Unit *u) {
1736 Unit *other;
1737 Iterator i;
1738
1739 assert(u);
1740
1741 SET_FOREACH(other, u->dependencies[UNIT_TRIGGERED_BY], i)
1742 if (UNIT_VTABLE(other)->trigger_notify)
1743 UNIT_VTABLE(other)->trigger_notify(other, u);
1744}
1745
e2f3b44c 1746void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
546ac4f0 1747 Manager *m;
7e6e7b06 1748 bool unexpected;
a096ed36 1749
87f0e418
LP
1750 assert(u);
1751 assert(os < _UNIT_ACTIVE_STATE_MAX);
1752 assert(ns < _UNIT_ACTIVE_STATE_MAX);
87f0e418 1753
8e471ccd
LP
1754 /* Note that this is called for all low-level state changes,
1755 * even if they might map to the same high-level
865cc19a 1756 * UnitActiveState! That means that ns == os is an expected
c5315881 1757 * behavior here. For example: if a mount point is remounted
cd6d0a45 1758 * this function will be called too! */
87f0e418 1759
546ac4f0
MS
1760 m = u->manager;
1761
f755e3b7 1762 /* Update timestamps for state changes */
546ac4f0 1763 if (m->n_reloading <= 0) {
bdbf9951 1764 dual_timestamp ts;
173e3821 1765
bdbf9951 1766 dual_timestamp_get(&ts);
173e3821 1767
bdbf9951 1768 if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
ac155bb8 1769 u->inactive_exit_timestamp = ts;
bdbf9951 1770 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
ac155bb8 1771 u->inactive_enter_timestamp = ts;
bdbf9951
LP
1772
1773 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
ac155bb8 1774 u->active_enter_timestamp = ts;
bdbf9951 1775 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
ac155bb8 1776 u->active_exit_timestamp = ts;
bdbf9951 1777 }
87f0e418 1778
865cc19a 1779 /* Keep track of failed units */
3f3cc397 1780 if (ns == UNIT_FAILED)
f755e3b7 1781 set_put(u->manager->failed_units, u);
3f3cc397 1782 else
f755e3b7
LP
1783 set_remove(u->manager->failed_units, u);
1784
1785 /* Make sure the cgroup is always removed when we become inactive */
fdf20a31 1786 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
b1491eba 1787 unit_destroy_cgroup_if_empty(u);
fb385181 1788
9cd86184 1789 /* Note that this doesn't apply to RemainAfterExit services exiting
6f285378 1790 * successfully, since there's no change of state in that case. Which is
9cd86184 1791 * why it is handled in service_set_state() */
7ed9f6cd 1792 if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
b33918c2
LP
1793 ExecContext *ec;
1794
1795 ec = unit_get_exec_context(u);
7ed9f6cd 1796 if (ec && exec_context_may_touch_console(ec)) {
31a7eb86
ZJS
1797 if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1798 m->n_on_console --;
1799
1800 if (m->n_on_console == 0)
1801 /* unset no_console_output flag, since the console is free */
2f38577f 1802 m->no_console_output = false;
31a7eb86
ZJS
1803 } else
1804 m->n_on_console ++;
7ed9f6cd
MS
1805 }
1806 }
1807
ac155bb8 1808 if (u->job) {
7e6e7b06 1809 unexpected = false;
87f0e418 1810
ac155bb8 1811 if (u->job->state == JOB_WAITING)
87f0e418
LP
1812
1813 /* So we reached a different state for this
1814 * job. Let's see if we can run it now if it
1815 * failed previously due to EAGAIN. */
ac155bb8 1816 job_add_to_run_queue(u->job);
87f0e418 1817
b410e6b9 1818 /* Let's check whether this state change constitutes a
35b8ca3a 1819 * finished job, or maybe contradicts a running job and
b410e6b9 1820 * hence needs to invalidate jobs. */
87f0e418 1821
ac155bb8 1822 switch (u->job->type) {
87f0e418 1823
b410e6b9
LP
1824 case JOB_START:
1825 case JOB_VERIFY_ACTIVE:
87f0e418 1826
b410e6b9 1827 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
5273510e 1828 job_finish_and_invalidate(u->job, JOB_DONE, true);
ac155bb8 1829 else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
b410e6b9 1830 unexpected = true;
41b02ec7 1831
fdf20a31 1832 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1833 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
b410e6b9 1834 }
87f0e418 1835
b410e6b9 1836 break;
87f0e418 1837
b410e6b9
LP
1838 case JOB_RELOAD:
1839 case JOB_RELOAD_OR_START:
87f0e418 1840
ac155bb8 1841 if (u->job->state == JOB_RUNNING) {
a096ed36 1842 if (ns == UNIT_ACTIVE)
5273510e 1843 job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
032ff4af 1844 else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
a096ed36 1845 unexpected = true;
41b02ec7 1846
fdf20a31 1847 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1848 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
a096ed36 1849 }
b410e6b9 1850 }
87f0e418 1851
b410e6b9 1852 break;
87f0e418 1853
b410e6b9
LP
1854 case JOB_STOP:
1855 case JOB_RESTART:
1856 case JOB_TRY_RESTART:
87f0e418 1857
fdf20a31 1858 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1859 job_finish_and_invalidate(u->job, JOB_DONE, true);
ac155bb8 1860 else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
b410e6b9 1861 unexpected = true;
5273510e 1862 job_finish_and_invalidate(u->job, JOB_FAILED, true);
b410e6b9 1863 }
87f0e418 1864
b410e6b9 1865 break;
87f0e418 1866
b410e6b9
LP
1867 default:
1868 assert_not_reached("Job type unknown");
87f0e418 1869 }
87f0e418 1870
7e6e7b06
LP
1871 } else
1872 unexpected = true;
1873
546ac4f0 1874 if (m->n_reloading <= 0) {
f3bff0eb 1875
bdbf9951
LP
1876 /* If this state change happened without being
1877 * requested by a job, then let's retroactively start
1878 * or stop dependencies. We skip that step when
1879 * deserializing, since we don't want to create any
1880 * additional jobs just because something is already
1881 * activated. */
1882
1883 if (unexpected) {
1884 if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1885 retroactively_start_dependencies(u);
1886 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1887 retroactively_stop_dependencies(u);
1888 }
5de9682c 1889
cd0504d0 1890 /* stop unneeded units regardless if going down was expected or not */
b33918c2 1891 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
cd0504d0
MS
1892 check_unneeded_dependencies(u);
1893
bdbf9951 1894 if (ns != os && ns == UNIT_FAILED) {
79008bdd 1895 log_unit_notice(u->id, "Unit %s entered failed state.", u->id);
3ecaa09b 1896 unit_start_on_failure(u);
cd6d0a45 1897 }
3b2775c5 1898 }
e537352b 1899
3b2775c5
LP
1900 /* Some names are special */
1901 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
1902
1903 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
865cc19a 1904 /* The bus might have just become available,
3b2775c5
LP
1905 * hence try to connect to it, if we aren't
1906 * yet connected. */
546ac4f0 1907 bus_init(m, true);
3b2775c5 1908
ac155bb8 1909 if (u->type == UNIT_SERVICE &&
3b2775c5 1910 !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
546ac4f0 1911 m->n_reloading <= 0) {
3b2775c5 1912 /* Write audit record if we have just finished starting up */
546ac4f0 1913 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
ac155bb8 1914 u->in_audit = true;
3b2775c5 1915 }
e983b760 1916
3b2775c5 1917 if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
546ac4f0 1918 manager_send_unit_plymouth(m, u);
bdbf9951 1919
3b2775c5 1920 } else {
bdbf9951 1921
3b2775c5
LP
1922 /* We don't care about D-Bus here, since we'll get an
1923 * asynchronous notification for it anyway. */
cd6d0a45 1924
ac155bb8 1925 if (u->type == UNIT_SERVICE &&
3b2775c5
LP
1926 UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1927 !UNIT_IS_INACTIVE_OR_FAILED(os) &&
546ac4f0 1928 m->n_reloading <= 0) {
4927fcae 1929
3b2775c5
LP
1930 /* Hmm, if there was no start record written
1931 * write it now, so that we always have a nice
1932 * pair */
ac155bb8 1933 if (!u->in_audit) {
546ac4f0 1934 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
cd6d0a45 1935
3b2775c5 1936 if (ns == UNIT_INACTIVE)
546ac4f0 1937 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
3b2775c5
LP
1938 } else
1939 /* Write audit record if we have just finished shutting down */
546ac4f0 1940 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
bdbf9951 1941
ac155bb8 1942 u->in_audit = false;
cd6d0a45 1943 }
f278026d
LP
1944 }
1945
546ac4f0 1946 manager_recheck_journal(m);
3ecaa09b 1947 unit_trigger_notify(u);
3b2775c5 1948
ff502445
LP
1949 if (u->manager->n_reloading <= 0) {
1950 /* Maybe we finished startup and are now ready for
1951 * being stopped because unneeded? */
bf6dcfa6 1952 unit_check_unneeded(u);
c1e1601e 1953
ff502445
LP
1954 /* Maybe we finished startup, but something we needed
1955 * has vanished? Let's die then. (This happens when
1956 * something BindsTo= to a Type=oneshot unit, as these
1957 * units go directly from starting to inactive,
1958 * without ever entering started.) */
1959 unit_check_binds_to(u);
1960 }
1961
c1e1601e 1962 unit_add_to_dbus_queue(u);
701cc384 1963 unit_add_to_gc_queue(u);
87f0e418
LP
1964}
1965
87f0e418 1966int unit_watch_pid(Unit *u, pid_t pid) {
a911bb9a
LP
1967 int q, r;
1968
87f0e418
LP
1969 assert(u);
1970 assert(pid >= 1);
1971
5ba6985b
LP
1972 /* Watch a specific PID. We only support one or two units
1973 * watching each PID for now, not more. */
1974
d5099efc 1975 r = set_ensure_allocated(&u->pids, NULL);
5ba6985b
LP
1976 if (r < 0)
1977 return r;
1978
d5099efc 1979 r = hashmap_ensure_allocated(&u->manager->watch_pids1, NULL);
a911bb9a
LP
1980 if (r < 0)
1981 return r;
1982
5ba6985b
LP
1983 r = hashmap_put(u->manager->watch_pids1, LONG_TO_PTR(pid), u);
1984 if (r == -EEXIST) {
d5099efc 1985 r = hashmap_ensure_allocated(&u->manager->watch_pids2, NULL);
5ba6985b
LP
1986 if (r < 0)
1987 return r;
05e343b7 1988
5ba6985b
LP
1989 r = hashmap_put(u->manager->watch_pids2, LONG_TO_PTR(pid), u);
1990 }
a911bb9a 1991
5ba6985b 1992 q = set_put(u->pids, LONG_TO_PTR(pid));
a911bb9a
LP
1993 if (q < 0)
1994 return q;
1995
1996 return r;
87f0e418
LP
1997}
1998
1999void unit_unwatch_pid(Unit *u, pid_t pid) {
2000 assert(u);
2001 assert(pid >= 1);
2002
5ba6985b
LP
2003 hashmap_remove_value(u->manager->watch_pids1, LONG_TO_PTR(pid), u);
2004 hashmap_remove_value(u->manager->watch_pids2, LONG_TO_PTR(pid), u);
a911bb9a
LP
2005 set_remove(u->pids, LONG_TO_PTR(pid));
2006}
2007
bd44e61b
LP
2008void unit_unwatch_all_pids(Unit *u) {
2009 assert(u);
2010
2011 while (!set_isempty(u->pids))
2012 unit_unwatch_pid(u, PTR_TO_LONG(set_first(u->pids)));
2013
2014 set_free(u->pids);
2015 u->pids = NULL;
2016}
2017
2018static int unit_watch_pids_in_path(Unit *u, const char *path) {
a911bb9a
LP
2019 _cleanup_closedir_ DIR *d = NULL;
2020 _cleanup_fclose_ FILE *f = NULL;
2021 int ret = 0, r;
2022
2023 assert(u);
2024 assert(path);
2025
2026 /* Adds all PIDs from a specific cgroup path to the set of PIDs we watch. */
2027
2028 r = cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, path, &f);
2029 if (r >= 0) {
2030 pid_t pid;
2031
2032 while ((r = cg_read_pid(f, &pid)) > 0) {
2033 r = unit_watch_pid(u, pid);
2034 if (r < 0 && ret >= 0)
2035 ret = r;
2036 }
2037 if (r < 0 && ret >= 0)
2038 ret = r;
2039
2040 } else if (ret >= 0)
2041 ret = r;
2042
2043 r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, path, &d);
2044 if (r >= 0) {
2045 char *fn;
2046
2047 while ((r = cg_read_subgroup(d, &fn)) > 0) {
2048 _cleanup_free_ char *p = NULL;
2049
2050 p = strjoin(path, "/", fn, NULL);
2051 free(fn);
2052
2053 if (!p)
2054 return -ENOMEM;
2055
bd44e61b 2056 r = unit_watch_pids_in_path(u, p);
a911bb9a
LP
2057 if (r < 0 && ret >= 0)
2058 ret = r;
2059 }
2060 if (r < 0 && ret >= 0)
2061 ret = r;
2062
2063 } else if (ret >= 0)
2064 ret = r;
2065
2066 return ret;
2067}
2068
a911bb9a
LP
2069int unit_watch_all_pids(Unit *u) {
2070 assert(u);
2071
a911bb9a
LP
2072 /* Adds all PIDs from our cgroup to the set of PIDs we watch */
2073
bd44e61b
LP
2074 if (!u->cgroup_path)
2075 return -ENOENT;
a911bb9a 2076
bd44e61b 2077 return unit_watch_pids_in_path(u, u->cgroup_path);
a911bb9a
LP
2078}
2079
2080void unit_tidy_watch_pids(Unit *u, pid_t except1, pid_t except2) {
2081 Iterator i;
2082 void *e;
2083
2084 assert(u);
2085
2086 /* Cleans dead PIDs from our list */
2087
2088 SET_FOREACH(e, u->pids, i) {
2089 pid_t pid = PTR_TO_LONG(e);
2090
2091 if (pid == except1 || pid == except2)
2092 continue;
2093
9f5650ae 2094 if (!pid_is_unwaited(pid))
bd44e61b 2095 unit_unwatch_pid(u, pid);
a911bb9a 2096 }
87f0e418
LP
2097}
2098
87f0e418
LP
2099bool unit_job_is_applicable(Unit *u, JobType j) {
2100 assert(u);
2101 assert(j >= 0 && j < _JOB_TYPE_MAX);
2102
2103 switch (j) {
2104
2105 case JOB_VERIFY_ACTIVE:
2106 case JOB_START:
57339f47 2107 case JOB_STOP:
e0209d83 2108 case JOB_NOP:
87f0e418
LP
2109 return true;
2110
87f0e418
LP
2111 case JOB_RESTART:
2112 case JOB_TRY_RESTART:
2113 return unit_can_start(u);
2114
2115 case JOB_RELOAD:
2116 return unit_can_reload(u);
2117
2118 case JOB_RELOAD_OR_START:
2119 return unit_can_reload(u) && unit_can_start(u);
2120
2121 default:
2122 assert_not_reached("Invalid job type");
2123 }
2124}
2125
d1fab3fe 2126static int maybe_warn_about_dependency(const char *id, const char *other, UnitDependency dependency) {
3f3cc397
LP
2127 assert(id);
2128
d1fab3fe
ZJS
2129 switch (dependency) {
2130 case UNIT_REQUIRES:
2131 case UNIT_REQUIRES_OVERRIDABLE:
2132 case UNIT_WANTS:
2133 case UNIT_REQUISITE:
2134 case UNIT_REQUISITE_OVERRIDABLE:
2135 case UNIT_BINDS_TO:
2136 case UNIT_PART_OF:
2137 case UNIT_REQUIRED_BY:
2138 case UNIT_REQUIRED_BY_OVERRIDABLE:
2139 case UNIT_WANTED_BY:
2140 case UNIT_BOUND_BY:
2141 case UNIT_CONSISTS_OF:
2142 case UNIT_REFERENCES:
2143 case UNIT_REFERENCED_BY:
2144 case UNIT_PROPAGATES_RELOAD_TO:
2145 case UNIT_RELOAD_PROPAGATED_FROM:
2146 case UNIT_JOINS_NAMESPACE_OF:
2147 return 0;
2148
2149 case UNIT_CONFLICTS:
2150 case UNIT_CONFLICTED_BY:
2151 case UNIT_BEFORE:
2152 case UNIT_AFTER:
2153 case UNIT_ON_FAILURE:
2154 case UNIT_TRIGGERS:
2155 case UNIT_TRIGGERED_BY:
2156 if (streq_ptr(id, other))
79008bdd 2157 log_unit_warning(id, "Dependency %s=%s dropped from unit %s",
d1fab3fe
ZJS
2158 unit_dependency_to_string(dependency), id, other);
2159 else
79008bdd 2160 log_unit_warning(id, "Dependency %s=%s dropped from unit %s merged into %s",
d1fab3fe
ZJS
2161 unit_dependency_to_string(dependency), id,
2162 strna(other), id);
2163 return -EINVAL;
2164
2165 case _UNIT_DEPENDENCY_MAX:
2166 case _UNIT_DEPENDENCY_INVALID:
2167 break;
2168 }
3f3cc397 2169
d1fab3fe
ZJS
2170 assert_not_reached("Invalid dependency type");
2171}
2172
701cc384 2173int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
87f0e418
LP
2174
2175 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
2176 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
9e2f7c11 2177 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
87f0e418
LP
2178 [UNIT_WANTS] = UNIT_WANTED_BY,
2179 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
9e2f7c11 2180 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
7f2cddae 2181 [UNIT_BINDS_TO] = UNIT_BOUND_BY,
60649f17 2182 [UNIT_PART_OF] = UNIT_CONSISTS_OF,
87f0e418 2183 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
9e2f7c11 2184 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
87f0e418 2185 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
7f2cddae 2186 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
60649f17 2187 [UNIT_CONSISTS_OF] = UNIT_PART_OF,
69dd2852
LP
2188 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
2189 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
87f0e418 2190 [UNIT_BEFORE] = UNIT_AFTER,
701cc384 2191 [UNIT_AFTER] = UNIT_BEFORE,
5de9682c 2192 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
701cc384 2193 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
57020a3a
LP
2194 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
2195 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
4dcc1cb4 2196 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
7f2cddae 2197 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
85e9a101 2198 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
613b411c 2199 [UNIT_JOINS_NAMESPACE_OF] = UNIT_JOINS_NAMESPACE_OF,
87f0e418 2200 };
701cc384 2201 int r, q = 0, v = 0, w = 0;
d1fab3fe 2202 Unit *orig_u = u, *orig_other = other;
87f0e418
LP
2203
2204 assert(u);
2205 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
87f0e418
LP
2206 assert(other);
2207
9f151f29
LP
2208 u = unit_follow_merge(u);
2209 other = unit_follow_merge(other);
2210
87f0e418
LP
2211 /* We won't allow dependencies on ourselves. We will not
2212 * consider them an error however. */
d1fab3fe
ZJS
2213 if (u == other) {
2214 maybe_warn_about_dependency(orig_u->id, orig_other->id, d);
87f0e418 2215 return 0;
d1fab3fe 2216 }
87f0e418 2217
d5099efc 2218 r = set_ensure_allocated(&u->dependencies[d], NULL);
613b411c 2219 if (r < 0)
87f0e418
LP
2220 return r;
2221
613b411c 2222 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID) {
d5099efc 2223 r = set_ensure_allocated(&other->dependencies[inverse_table[d]], NULL);
613b411c
LP
2224 if (r < 0)
2225 return r;
2226 }
2227
2228 if (add_reference) {
d5099efc 2229 r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], NULL);
613b411c 2230 if (r < 0)
5de9682c
LP
2231 return r;
2232
d5099efc 2233 r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], NULL);
613b411c 2234 if (r < 0)
701cc384 2235 return r;
613b411c 2236 }
87f0e418 2237
613b411c
LP
2238 q = set_put(u->dependencies[d], other);
2239 if (q < 0)
701cc384 2240 return q;
87f0e418 2241
613b411c
LP
2242 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID && inverse_table[d] != d) {
2243 v = set_put(other->dependencies[inverse_table[d]], u);
2244 if (v < 0) {
5de9682c
LP
2245 r = v;
2246 goto fail;
2247 }
613b411c 2248 }
701cc384
LP
2249
2250 if (add_reference) {
613b411c
LP
2251 w = set_put(u->dependencies[UNIT_REFERENCES], other);
2252 if (w < 0) {
701cc384
LP
2253 r = w;
2254 goto fail;
2255 }
2256
613b411c
LP
2257 r = set_put(other->dependencies[UNIT_REFERENCED_BY], u);
2258 if (r < 0)
701cc384 2259 goto fail;
87f0e418
LP
2260 }
2261
c1e1601e 2262 unit_add_to_dbus_queue(u);
87f0e418 2263 return 0;
701cc384
LP
2264
2265fail:
2266 if (q > 0)
ac155bb8 2267 set_remove(u->dependencies[d], other);
701cc384
LP
2268
2269 if (v > 0)
ac155bb8 2270 set_remove(other->dependencies[inverse_table[d]], u);
701cc384
LP
2271
2272 if (w > 0)
ac155bb8 2273 set_remove(u->dependencies[UNIT_REFERENCES], other);
701cc384
LP
2274
2275 return r;
87f0e418 2276}
0301abf4 2277
2c966c03
LP
2278int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
2279 int r;
2280
2281 assert(u);
2282
3f3cc397
LP
2283 r = unit_add_dependency(u, d, other, add_reference);
2284 if (r < 0)
2c966c03
LP
2285 return r;
2286
3f3cc397
LP
2287 r = unit_add_dependency(u, e, other, add_reference);
2288 if (r < 0)
2c966c03
LP
2289 return r;
2290
2291 return 0;
2292}
2293
9e2f7c11
LP
2294static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
2295 char *s;
2296
2297 assert(u);
2298 assert(name || path);
8afbb8e1 2299 assert(p);
9e2f7c11
LP
2300
2301 if (!name)
2b6bf07d 2302 name = basename(path);
9e2f7c11
LP
2303
2304 if (!unit_name_is_template(name)) {
2305 *p = NULL;
2306 return name;
2307 }
2308
ac155bb8
MS
2309 if (u->instance)
2310 s = unit_name_replace_instance(name, u->instance);
9e2f7c11 2311 else {
ae018d9b 2312 _cleanup_free_ char *i = NULL;
9e2f7c11 2313
8afbb8e1
LP
2314 i = unit_name_to_prefix(u->id);
2315 if (!i)
9e2f7c11
LP
2316 return NULL;
2317
2318 s = unit_name_replace_instance(name, i);
9e2f7c11
LP
2319 }
2320
2321 if (!s)
2322 return NULL;
2323
2324 *p = s;
2325 return s;
2326}
2327
701cc384 2328int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
09b6b09f
LP
2329 Unit *other;
2330 int r;
8afbb8e1 2331 _cleanup_free_ char *s = NULL;
09b6b09f 2332
9e2f7c11
LP
2333 assert(u);
2334 assert(name || path);
09b6b09f 2335
8afbb8e1
LP
2336 name = resolve_template(u, name, path, &s);
2337 if (!name)
9e2f7c11 2338 return -ENOMEM;
09b6b09f 2339
8afbb8e1
LP
2340 r = manager_load_unit(u->manager, name, path, NULL, &other);
2341 if (r < 0)
2342 return r;
9e2f7c11 2343
8afbb8e1 2344 return unit_add_dependency(u, d, other, add_reference);
09b6b09f
LP
2345}
2346
2c966c03 2347int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
3f3cc397 2348 _cleanup_free_ char *s = NULL;
2c966c03
LP
2349 Unit *other;
2350 int r;
2c966c03
LP
2351
2352 assert(u);
2353 assert(name || path);
2354
3f3cc397
LP
2355 name = resolve_template(u, name, path, &s);
2356 if (!name)
2c966c03
LP
2357 return -ENOMEM;
2358
3f3cc397
LP
2359 r = manager_load_unit(u->manager, name, path, NULL, &other);
2360 if (r < 0)
68eda4bd 2361 return r;
2c966c03 2362
3f3cc397 2363 return unit_add_two_dependencies(u, d, e, other, add_reference);
2c966c03
LP
2364}
2365
701cc384 2366int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
bd77d0fc
LP
2367 Unit *other;
2368 int r;
68eda4bd 2369 _cleanup_free_ char *s = NULL;
bd77d0fc 2370
9e2f7c11
LP
2371 assert(u);
2372 assert(name || path);
bd77d0fc 2373
3f3cc397
LP
2374 name = resolve_template(u, name, path, &s);
2375 if (!name)
9e2f7c11 2376 return -ENOMEM;
bd77d0fc 2377
3f3cc397
LP
2378 r = manager_load_unit(u->manager, name, path, NULL, &other);
2379 if (r < 0)
68eda4bd 2380 return r;
9e2f7c11 2381
3f3cc397 2382 return unit_add_dependency(other, d, u, add_reference);
bd77d0fc
LP
2383}
2384
2c966c03
LP
2385int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
2386 Unit *other;
2387 int r;
68eda4bd 2388 _cleanup_free_ char *s = NULL;
2c966c03
LP
2389
2390 assert(u);
2391 assert(name || path);
2392
3f3cc397
LP
2393 name = resolve_template(u, name, path, &s);
2394 if (!name)
2c966c03
LP
2395 return -ENOMEM;
2396
3f3cc397
LP
2397 r = manager_load_unit(u->manager, name, path, NULL, &other);
2398 if (r < 0)
68eda4bd 2399 return r;
2c966c03 2400
3f3cc397
LP
2401 r = unit_add_two_dependencies(other, d, e, u, add_reference);
2402 if (r < 0)
68eda4bd 2403 return r;
2c966c03 2404
2c966c03
LP
2405 return r;
2406}
2407
0301abf4 2408int set_unit_path(const char *p) {
0301abf4 2409 /* This is mostly for debug purposes */
cf7d80a5 2410 if (setenv("SYSTEMD_UNIT_PATH", p, 0) < 0)
26d04f86 2411 return -errno;
0301abf4
LP
2412
2413 return 0;
2414}
88066b3a 2415
ea430986 2416char *unit_dbus_path(Unit *u) {
ea430986
LP
2417 assert(u);
2418
ac155bb8 2419 if (!u->id)
04ade7d2
LP
2420 return NULL;
2421
48899192 2422 return unit_dbus_path_from_name(u->id);
ea430986
LP
2423}
2424
41f9172f 2425char *unit_default_cgroup_path(Unit *u) {
d7bd3de0 2426 _cleanup_free_ char *escaped = NULL, *slice = NULL;
a016b922 2427 int r;
5954c074 2428
013b87c0
LP
2429 assert(u);
2430
4ad49000
LP
2431 if (unit_has_name(u, SPECIAL_ROOT_SLICE))
2432 return strdup(u->manager->cgroup_root);
2433
2434 if (UNIT_ISSET(u->slice) && !unit_has_name(UNIT_DEREF(u->slice), SPECIAL_ROOT_SLICE)) {
a016b922
LP
2435 r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice);
2436 if (r < 0)
2437 return NULL;
2438 }
2439
d7bd3de0
LP
2440 escaped = cg_escape(u->id);
2441 if (!escaped)
5954c074
LP
2442 return NULL;
2443
d7bd3de0
LP
2444 if (slice)
2445 return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL);
2446 else
2447 return strjoin(u->manager->cgroup_root, "/", escaped, NULL);
013b87c0
LP
2448}
2449
598459ce 2450int unit_add_default_slice(Unit *u, CGroupContext *c) {
a8833944
LP
2451 _cleanup_free_ char *b = NULL;
2452 const char *slice_name;
a016b922
LP
2453 Unit *slice;
2454 int r;
2455
2456 assert(u);
598459ce 2457 assert(c);
a016b922 2458
9444b1f2 2459 if (UNIT_ISSET(u->slice))
a016b922
LP
2460 return 0;
2461
a8833944
LP
2462 if (u->instance) {
2463 _cleanup_free_ char *prefix = NULL, *escaped = NULL;
68eda4bd 2464
a8833944
LP
2465 /* Implicitly place all instantiated units in their
2466 * own per-template slice */
2467
2468 prefix = unit_name_to_prefix(u->id);
2469 if (!prefix)
2470 return -ENOMEM;
2471
2472 /* The prefix is already escaped, but it might include
2473 * "-" which has a special meaning for slice units,
2474 * hence escape it here extra. */
2475 escaped = strreplace(prefix, "-", "\\x2d");
2476 if (!escaped)
2477 return -ENOMEM;
2478
2479 if (u->manager->running_as == SYSTEMD_SYSTEM)
2480 b = strjoin("system-", escaped, ".slice", NULL);
2481 else
2482 b = strappend(escaped, ".slice");
2483 if (!b)
2484 return -ENOMEM;
2485
2486 slice_name = b;
2487 } else
2488 slice_name =
2489 u->manager->running_as == SYSTEMD_SYSTEM
2490 ? SPECIAL_SYSTEM_SLICE
2491 : SPECIAL_ROOT_SLICE;
2492
2493 r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
a016b922
LP
2494 if (r < 0)
2495 return r;
2496
2497 unit_ref_set(&u->slice, slice);
2498 return 0;
2499}
2500
9444b1f2
LP
2501const char *unit_slice_name(Unit *u) {
2502 assert(u);
2503
2504 if (!UNIT_ISSET(u->slice))
2505 return NULL;
2506
2507 return UNIT_DEREF(u->slice)->id;
2508}
2509
f6ff8c29 2510int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
78edb35a 2511 _cleanup_free_ char *t = NULL;
f6ff8c29
LP
2512 int r;
2513
2514 assert(u);
2515 assert(type);
2516 assert(_found);
2517
78edb35a
LP
2518 t = unit_name_change_suffix(u->id, type);
2519 if (!t)
f6ff8c29
LP
2520 return -ENOMEM;
2521
2522 assert(!unit_has_name(u, t));
2523
ac155bb8 2524 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
9e2f7c11 2525 assert(r < 0 || *_found != u);
f6ff8c29
LP
2526 return r;
2527}
2528
05e343b7
LP
2529int unit_watch_bus_name(Unit *u, const char *name) {
2530 assert(u);
2531 assert(name);
2532
2533 /* Watch a specific name on the bus. We only support one unit
2534 * watching each name for now. */
2535
ac155bb8 2536 return hashmap_put(u->manager->watch_bus, name, u);
05e343b7
LP
2537}
2538
2539void unit_unwatch_bus_name(Unit *u, const char *name) {
2540 assert(u);
2541 assert(name);
2542
ac155bb8 2543 hashmap_remove_value(u->manager->watch_bus, name, u);
05e343b7
LP
2544}
2545
a16e1123
LP
2546bool unit_can_serialize(Unit *u) {
2547 assert(u);
2548
2549 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2550}
2551
6b78f9b4 2552int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
a16e1123
LP
2553 int r;
2554
2555 assert(u);
2556 assert(f);
2557 assert(fds);
2558
9bdb98c5
LP
2559 if (unit_can_serialize(u)) {
2560 ExecRuntime *rt;
a16e1123 2561
9bdb98c5 2562 r = UNIT_VTABLE(u)->serialize(u, f, fds);
613b411c
LP
2563 if (r < 0)
2564 return r;
9bdb98c5
LP
2565
2566 rt = unit_get_exec_runtime(u);
2567 if (rt) {
2568 r = exec_runtime_serialize(rt, u, f, fds);
2569 if (r < 0)
2570 return r;
2571 }
e0209d83
MS
2572 }
2573
ac155bb8
MS
2574 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2575 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2576 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2577 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2578 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
59fccdc5 2579 dual_timestamp_serialize(f, "assert-timestamp", &u->assert_timestamp);
2791a8f8 2580
ac155bb8
MS
2581 if (dual_timestamp_is_set(&u->condition_timestamp))
2582 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
10717a1a 2583
59fccdc5
LP
2584 if (dual_timestamp_is_set(&u->assert_timestamp))
2585 unit_serialize_item(u, f, "assert-result", yes_no(u->assert_result));
2586
c2756a68
LP
2587 unit_serialize_item(u, f, "transient", yes_no(u->transient));
2588
2589 if (u->cgroup_path)
2590 unit_serialize_item(u, f, "cgroup", u->cgroup_path);
2591
613b411c
LP
2592 if (serialize_jobs) {
2593 if (u->job) {
2594 fprintf(f, "job\n");
2595 job_serialize(u->job, f, fds);
2596 }
2597
2598 if (u->nop_job) {
2599 fprintf(f, "job\n");
2600 job_serialize(u->nop_job, f, fds);
2601 }
2602 }
2603
a16e1123
LP
2604 /* End marker */
2605 fputc('\n', f);
2606 return 0;
2607}
2608
2609void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2610 va_list ap;
2611
2612 assert(u);
2613 assert(f);
2614 assert(key);
2615 assert(format);
2616
2617 fputs(key, f);
2618 fputc('=', f);
2619
2620 va_start(ap, format);
2621 vfprintf(f, format, ap);
2622 va_end(ap);
2623
2624 fputc('\n', f);
2625}
2626
2627void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2628 assert(u);
2629 assert(f);
2630 assert(key);
2631 assert(value);
2632
2633 fprintf(f, "%s=%s\n", key, value);
2634}
2635
2636int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
28b99ccd 2637 ExecRuntime **rt = NULL;
9bdb98c5 2638 size_t offset;
a16e1123
LP
2639 int r;
2640
2641 assert(u);
2642 assert(f);
2643 assert(fds);
2644
613b411c
LP
2645 offset = UNIT_VTABLE(u)->exec_runtime_offset;
2646 if (offset > 0)
2647 rt = (ExecRuntime**) ((uint8_t*) u + offset);
2648
a16e1123 2649 for (;;) {
20c03b7b 2650 char line[LINE_MAX], *l, *v;
a16e1123
LP
2651 size_t k;
2652
2653 if (!fgets(line, sizeof(line), f)) {
2654 if (feof(f))
2655 return 0;
2656 return -errno;
2657 }
2658
10f8e83c 2659 char_array_0(line);
a16e1123
LP
2660 l = strstrip(line);
2661
2662 /* End marker */
2663 if (l[0] == 0)
2664 return 0;
2665
2666 k = strcspn(l, "=");
2667
2668 if (l[k] == '=') {
2669 l[k] = 0;
2670 v = l+k+1;
2671 } else
2672 v = l+k;
2673
cca098b0 2674 if (streq(l, "job")) {
39a18c60
MS
2675 if (v[0] == '\0') {
2676 /* new-style serialized job */
9c3349e2
LP
2677 Job *j;
2678
2679 j = job_new_raw(u);
39a18c60
MS
2680 if (!j)
2681 return -ENOMEM;
2682
2683 r = job_deserialize(j, f, fds);
2684 if (r < 0) {
2685 job_free(j);
2686 return r;
2687 }
cca098b0 2688
39a18c60
MS
2689 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2690 if (r < 0) {
2691 job_free(j);
2692 return r;
2693 }
e0209d83
MS
2694
2695 r = job_install_deserialized(j);
2696 if (r < 0) {
2697 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2698 job_free(j);
2699 return r;
2700 }
39a18c60
MS
2701 } else {
2702 /* legacy */
9c3349e2
LP
2703 JobType type;
2704
2705 type = job_type_from_string(v);
39a18c60
MS
2706 if (type < 0)
2707 log_debug("Failed to parse job type value %s", v);
2708 else
2709 u->deserialized_job = type;
2710 }
cca098b0 2711 continue;
8aaf019b 2712 } else if (streq(l, "inactive-exit-timestamp")) {
ac155bb8 2713 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
8aaf019b
LP
2714 continue;
2715 } else if (streq(l, "active-enter-timestamp")) {
ac155bb8 2716 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
8aaf019b
LP
2717 continue;
2718 } else if (streq(l, "active-exit-timestamp")) {
ac155bb8 2719 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
8aaf019b
LP
2720 continue;
2721 } else if (streq(l, "inactive-enter-timestamp")) {
ac155bb8 2722 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
8aaf019b 2723 continue;
2791a8f8 2724 } else if (streq(l, "condition-timestamp")) {
ac155bb8 2725 dual_timestamp_deserialize(v, &u->condition_timestamp);
2791a8f8 2726 continue;
59fccdc5
LP
2727 } else if (streq(l, "assert-timestamp")) {
2728 dual_timestamp_deserialize(v, &u->assert_timestamp);
2729 continue;
2791a8f8
LP
2730 } else if (streq(l, "condition-result")) {
2731 int b;
2732
c2756a68
LP
2733 b = parse_boolean(v);
2734 if (b < 0)
2791a8f8
LP
2735 log_debug("Failed to parse condition result value %s", v);
2736 else
ac155bb8 2737 u->condition_result = b;
efbac6d2
LP
2738
2739 continue;
c2756a68 2740
59fccdc5
LP
2741 } else if (streq(l, "assert-result")) {
2742 int b;
2743
2744 b = parse_boolean(v);
2745 if (b < 0)
2746 log_debug("Failed to parse assert result value %s", v);
2747 else
2748 u->assert_result = b;
2749
2750 continue;
2751
c2756a68
LP
2752 } else if (streq(l, "transient")) {
2753 int b;
2754
2755 b = parse_boolean(v);
2756 if (b < 0)
2757 log_debug("Failed to parse transient bool %s", v);
2758 else
2759 u->transient = b;
2760
2761 continue;
2762 } else if (streq(l, "cgroup")) {
2763 char *s;
2764
2765 s = strdup(v);
f440e1bb 2766 if (!s)
c2756a68
LP
2767 return -ENOMEM;
2768
4e595329
ZJS
2769 if (u->cgroup_path) {
2770 void *p;
2771
2772 p = hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
2773 log_info("Removing cgroup_path %s from hashmap (%p)",
2774 u->cgroup_path, p);
2775 free(u->cgroup_path);
2776 }
72673e86 2777
4e595329 2778 u->cgroup_path = s;
b58b8e11 2779 assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1);
4e595329 2780
c2756a68 2781 continue;
8aaf019b 2782 }
cca098b0 2783
9bdb98c5
LP
2784 if (unit_can_serialize(u)) {
2785 if (rt) {
2786 r = exec_runtime_deserialize_item(rt, u, l, v, fds);
2787 if (r < 0)
2788 return r;
2789 if (r > 0)
2790 continue;
2791 }
2792
2793 r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds);
613b411c
LP
2794 if (r < 0)
2795 return r;
613b411c 2796 }
a16e1123
LP
2797 }
2798}
2799
6e2ef85b
LP
2800int unit_add_node_link(Unit *u, const char *what, bool wants) {
2801 Unit *device;
68eda4bd 2802 _cleanup_free_ char *e = NULL;
6e2ef85b
LP
2803 int r;
2804
2805 assert(u);
2806
2807 if (!what)
2808 return 0;
2809
2810 /* Adds in links to the device node that this unit is based on */
2811
8407a5d0 2812 if (!is_device_path(what))
6e2ef85b
LP
2813 return 0;
2814
35eb6b12
LP
2815 e = unit_name_from_path(what, ".device");
2816 if (!e)
6e2ef85b
LP
2817 return -ENOMEM;
2818
ac155bb8 2819 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
68eda4bd 2820
6e2ef85b
LP
2821 if (r < 0)
2822 return r;
2823
faa368e3
LP
2824 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
2825 if (r < 0)
6e2ef85b
LP
2826 return r;
2827
faa368e3
LP
2828 if (wants) {
2829 r = unit_add_dependency(device, UNIT_WANTS, u, false);
2830 if (r < 0)
6e2ef85b 2831 return r;
faa368e3 2832 }
6e2ef85b
LP
2833
2834 return 0;
2835}
a16e1123 2836
cca098b0
LP
2837int unit_coldplug(Unit *u) {
2838 int r;
2839
2840 assert(u);
2841
2842 if (UNIT_VTABLE(u)->coldplug)
2843 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2844 return r;
2845
39a18c60
MS
2846 if (u->job) {
2847 r = job_coldplug(u->job);
2848 if (r < 0)
2849 return r;
2850 } else if (u->deserialized_job >= 0) {
2851 /* legacy */
2852 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2853 if (r < 0)
cca098b0
LP
2854 return r;
2855
ac155bb8 2856 u->deserialized_job = _JOB_TYPE_INVALID;
cca098b0
LP
2857 }
2858
2859 return 0;
2860}
2861
49b1d377 2862void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) {
bcfce235 2863 DISABLE_WARNING_FORMAT_NONLITERAL;
127d5fd1
ZJS
2864 manager_status_printf(u->manager, STATUS_TYPE_NORMAL,
2865 status, unit_status_msg_format, unit_description(u));
bcfce235 2866 REENABLE_WARNING;
49b1d377
MS
2867}
2868
45fb0699 2869bool unit_need_daemon_reload(Unit *u) {
ae7a7182
OS
2870 _cleanup_strv_free_ char **t = NULL;
2871 char **path;
1b64d026 2872 struct stat st;
ae7a7182 2873 unsigned loaded_cnt, current_cnt;
1b64d026 2874
45fb0699
LP
2875 assert(u);
2876
ac155bb8 2877 if (u->fragment_path) {
5f4b19f4 2878 zero(st);
ac155bb8 2879 if (stat(u->fragment_path, &st) < 0)
5f4b19f4
LP
2880 /* What, cannot access this anymore? */
2881 return true;
45fb0699 2882
ac155bb8
MS
2883 if (u->fragment_mtime > 0 &&
2884 timespec_load(&st.st_mtim) != u->fragment_mtime)
5f4b19f4
LP
2885 return true;
2886 }
2887
1b64d026
LP
2888 if (u->source_path) {
2889 zero(st);
2890 if (stat(u->source_path, &st) < 0)
2891 return true;
2892
2893 if (u->source_mtime > 0 &&
2894 timespec_load(&st.st_mtim) != u->source_mtime)
2895 return true;
2896 }
5f4b19f4 2897
1a7f1b38 2898 (void) unit_find_dropin_paths(u, &t);
ae7a7182
OS
2899 loaded_cnt = strv_length(t);
2900 current_cnt = strv_length(u->dropin_paths);
2901
2902 if (loaded_cnt == current_cnt) {
2903 if (loaded_cnt == 0)
2904 return false;
2905
2906 if (strv_overlap(u->dropin_paths, t)) {
2907 STRV_FOREACH(path, u->dropin_paths) {
2908 zero(st);
2909 if (stat(*path, &st) < 0)
2910 return true;
2911
2912 if (u->dropin_mtime > 0 &&
2913 timespec_load(&st.st_mtim) > u->dropin_mtime)
2914 return true;
2915 }
2916
2917 return false;
2918 } else
2919 return true;
2920 } else
2921 return true;
45fb0699
LP
2922}
2923
fdf20a31 2924void unit_reset_failed(Unit *u) {
5632e374
LP
2925 assert(u);
2926
fdf20a31
MM
2927 if (UNIT_VTABLE(u)->reset_failed)
2928 UNIT_VTABLE(u)->reset_failed(u);
5632e374
LP
2929}
2930
a7f241db
LP
2931Unit *unit_following(Unit *u) {
2932 assert(u);
2933
2934 if (UNIT_VTABLE(u)->following)
2935 return UNIT_VTABLE(u)->following(u);
2936
2937 return NULL;
2938}
2939
31afa0a4 2940bool unit_stop_pending(Unit *u) {
18ffdfda
LP
2941 assert(u);
2942
31afa0a4
LP
2943 /* This call does check the current state of the unit. It's
2944 * hence useful to be called from state change calls of the
2945 * unit itself, where the state isn't updated yet. This is
2946 * different from unit_inactive_or_pending() which checks both
2947 * the current state and for a queued job. */
18ffdfda 2948
31afa0a4
LP
2949 return u->job && u->job->type == JOB_STOP;
2950}
2951
2952bool unit_inactive_or_pending(Unit *u) {
2953 assert(u);
2954
2955 /* Returns true if the unit is inactive or going down */
18ffdfda 2956
d956ac29
LP
2957 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2958 return true;
2959
31afa0a4 2960 if (unit_stop_pending(u))
18ffdfda
LP
2961 return true;
2962
2963 return false;
2964}
2965
31afa0a4 2966bool unit_active_or_pending(Unit *u) {
f976f3f6
LP
2967 assert(u);
2968
f60c2665 2969 /* Returns true if the unit is active or going up */
f976f3f6
LP
2970
2971 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2972 return true;
2973
ac155bb8
MS
2974 if (u->job &&
2975 (u->job->type == JOB_START ||
2976 u->job->type == JOB_RELOAD_OR_START ||
2977 u->job->type == JOB_RESTART))
f976f3f6
LP
2978 return true;
2979
2980 return false;
2981}
2982
718db961 2983int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error) {
8a0867d6
LP
2984 assert(u);
2985 assert(w >= 0 && w < _KILL_WHO_MAX);
8a0867d6
LP
2986 assert(signo > 0);
2987 assert(signo < _NSIG);
2988
8a0867d6
LP
2989 if (!UNIT_VTABLE(u)->kill)
2990 return -ENOTSUP;
2991
c74f17d9 2992 return UNIT_VTABLE(u)->kill(u, w, signo, error);
8a0867d6
LP
2993}
2994
82659fd7
LP
2995static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
2996 Set *pid_set;
2997 int r;
2998
d5099efc 2999 pid_set = set_new(NULL);
82659fd7
LP
3000 if (!pid_set)
3001 return NULL;
3002
3003 /* Exclude the main/control pids from being killed via the cgroup */
3004 if (main_pid > 0) {
3005 r = set_put(pid_set, LONG_TO_PTR(main_pid));
3006 if (r < 0)
3007 goto fail;
3008 }
3009
3010 if (control_pid > 0) {
3011 r = set_put(pid_set, LONG_TO_PTR(control_pid));
3012 if (r < 0)
3013 goto fail;
3014 }
3015
3016 return pid_set;
3017
3018fail:
3019 set_free(pid_set);
3020 return NULL;
3021}
3022
d91c34f2
LP
3023int unit_kill_common(
3024 Unit *u,
3025 KillWho who,
3026 int signo,
3027 pid_t main_pid,
3028 pid_t control_pid,
718db961 3029 sd_bus_error *error) {
d91c34f2 3030
814cc562
MS
3031 int r = 0;
3032
3033 if (who == KILL_MAIN && main_pid <= 0) {
3034 if (main_pid < 0)
7358dc02 3035 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
814cc562 3036 else
7358dc02 3037 return sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
814cc562
MS
3038 }
3039
3040 if (who == KILL_CONTROL && control_pid <= 0) {
3041 if (control_pid < 0)
7358dc02 3042 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
814cc562 3043 else
7358dc02 3044 return sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
814cc562
MS
3045 }
3046
3047 if (who == KILL_CONTROL || who == KILL_ALL)
3048 if (control_pid > 0)
3049 if (kill(control_pid, signo) < 0)
3050 r = -errno;
3051
3052 if (who == KILL_MAIN || who == KILL_ALL)
3053 if (main_pid > 0)
3054 if (kill(main_pid, signo) < 0)
3055 r = -errno;
3056
4ad49000 3057 if (who == KILL_ALL && u->cgroup_path) {
814cc562
MS
3058 _cleanup_set_free_ Set *pid_set = NULL;
3059 int q;
3060
82659fd7
LP
3061 /* Exclude the main/control pids from being killed via the cgroup */
3062 pid_set = unit_pid_set(main_pid, control_pid);
814cc562
MS
3063 if (!pid_set)
3064 return -ENOMEM;
3065
4ad49000 3066 q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
814cc562
MS
3067 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
3068 r = q;
3069 }
3070
3071 return r;
3072}
3073
6210e7fc
LP
3074int unit_following_set(Unit *u, Set **s) {
3075 assert(u);
3076 assert(s);
3077
3078 if (UNIT_VTABLE(u)->following_set)
3079 return UNIT_VTABLE(u)->following_set(u, s);
3080
3081 *s = NULL;
3082 return 0;
3083}
3084
a4375746
LP
3085UnitFileState unit_get_unit_file_state(Unit *u) {
3086 assert(u);
3087
ac155bb8
MS
3088 if (u->unit_file_state < 0 && u->fragment_path)
3089 u->unit_file_state = unit_file_get_state(
67445f4e 3090 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
2b6bf07d 3091 NULL, basename(u->fragment_path));
a4375746 3092
ac155bb8 3093 return u->unit_file_state;
a4375746
LP
3094}
3095
d2dc52db
LP
3096int unit_get_unit_file_preset(Unit *u) {
3097 assert(u);
3098
3099 if (u->unit_file_preset < 0 && u->fragment_path)
3100 u->unit_file_preset = unit_file_query_preset(
3101 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
3102 NULL, basename(u->fragment_path));
3103
3104 return u->unit_file_preset;
3105}
3106
57020a3a
LP
3107Unit* unit_ref_set(UnitRef *ref, Unit *u) {
3108 assert(ref);
3109 assert(u);
3110
3111 if (ref->unit)
3112 unit_ref_unset(ref);
3113
3114 ref->unit = u;
71fda00f 3115 LIST_PREPEND(refs, u->refs, ref);
57020a3a
LP
3116 return u;
3117}
3118
3119void unit_ref_unset(UnitRef *ref) {
3120 assert(ref);
3121
3122 if (!ref->unit)
3123 return;
3124
71fda00f 3125 LIST_REMOVE(refs, ref->unit->refs, ref);
57020a3a
LP
3126 ref->unit = NULL;
3127}
3128
598459ce
LP
3129int unit_patch_contexts(Unit *u) {
3130 CGroupContext *cc;
3131 ExecContext *ec;
cba6e062
LP
3132 unsigned i;
3133 int r;
3134
e06c73cc 3135 assert(u);
e06c73cc 3136
598459ce
LP
3137 /* Patch in the manager defaults into the exec and cgroup
3138 * contexts, _after_ the rest of the settings have been
3139 * initialized */
085afe36 3140
598459ce
LP
3141 ec = unit_get_exec_context(u);
3142 if (ec) {
3143 /* This only copies in the ones that need memory */
3144 for (i = 0; i < _RLIMIT_MAX; i++)
3145 if (u->manager->rlimit[i] && !ec->rlimit[i]) {
3146 ec->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
3147 if (!ec->rlimit[i])
3148 return -ENOMEM;
3149 }
3150
3151 if (u->manager->running_as == SYSTEMD_USER &&
3152 !ec->working_directory) {
3153
3154 r = get_home_dir(&ec->working_directory);
3155 if (r < 0)
3156 return r;
cba6e062
LP
3157 }
3158
598459ce
LP
3159 if (u->manager->running_as == SYSTEMD_USER &&
3160 (ec->syscall_whitelist ||
3161 !set_isempty(ec->syscall_filter) ||
3162 !set_isempty(ec->syscall_archs) ||
3163 ec->address_families_whitelist ||
3164 !set_isempty(ec->address_families)))
3165 ec->no_new_privileges = true;
e06c73cc 3166
598459ce
LP
3167 if (ec->private_devices)
3168 ec->capability_bounding_set_drop |= (uint64_t) 1ULL << (uint64_t) CAP_MKNOD;
cba6e062
LP
3169 }
3170
598459ce
LP
3171 cc = unit_get_cgroup_context(u);
3172 if (cc) {
f513e420 3173
598459ce
LP
3174 if (ec &&
3175 ec->private_devices &&
3176 cc->device_policy == CGROUP_AUTO)
3177 cc->device_policy = CGROUP_CLOSED;
3178 }
f1660f96 3179
cba6e062 3180 return 0;
e06c73cc
LP
3181}
3182
3ef63c31
LP
3183ExecContext *unit_get_exec_context(Unit *u) {
3184 size_t offset;
3185 assert(u);
3186
598459ce
LP
3187 if (u->type < 0)
3188 return NULL;
3189
3ef63c31
LP
3190 offset = UNIT_VTABLE(u)->exec_context_offset;
3191 if (offset <= 0)
3192 return NULL;
3193
3194 return (ExecContext*) ((uint8_t*) u + offset);
3195}
3196
718db961
LP
3197KillContext *unit_get_kill_context(Unit *u) {
3198 size_t offset;
3199 assert(u);
3200
598459ce
LP
3201 if (u->type < 0)
3202 return NULL;
3203
718db961
LP
3204 offset = UNIT_VTABLE(u)->kill_context_offset;
3205 if (offset <= 0)
3206 return NULL;
3207
3208 return (KillContext*) ((uint8_t*) u + offset);
3209}
3210
4ad49000
LP
3211CGroupContext *unit_get_cgroup_context(Unit *u) {
3212 size_t offset;
3213
598459ce
LP
3214 if (u->type < 0)
3215 return NULL;
3216
4ad49000
LP
3217 offset = UNIT_VTABLE(u)->cgroup_context_offset;
3218 if (offset <= 0)
3219 return NULL;
3220
3221 return (CGroupContext*) ((uint8_t*) u + offset);
3222}
3223
613b411c
LP
3224ExecRuntime *unit_get_exec_runtime(Unit *u) {
3225 size_t offset;
3226
598459ce
LP
3227 if (u->type < 0)
3228 return NULL;
3229
613b411c
LP
3230 offset = UNIT_VTABLE(u)->exec_runtime_offset;
3231 if (offset <= 0)
3232 return NULL;
3233
3234 return *(ExecRuntime**) ((uint8_t*) u + offset);
3235}
3236
29686440 3237static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient, char **dir) {
26d04f86 3238 if (u->manager->running_as == SYSTEMD_USER) {
29686440 3239 int r;
26d04f86 3240
718880ba
SA
3241 if (mode == UNIT_PERSISTENT && !transient)
3242 r = user_config_home(dir);
3243 else
4d5dec23 3244 r = user_runtime_dir(dir);
718880ba 3245
26d04f86
LP
3246 if (r == 0)
3247 return -ENOENT;
29686440
ZJS
3248 return r;
3249 }
26d04f86 3250
29686440
ZJS
3251 if (mode == UNIT_PERSISTENT && !transient)
3252 *dir = strdup("/etc/systemd/system");
8e2af478 3253 else
29686440
ZJS
3254 *dir = strdup("/run/systemd/system");
3255 if (!*dir)
71645aca
LP
3256 return -ENOMEM;
3257
26d04f86 3258 return 0;
71645aca
LP
3259}
3260
29686440
ZJS
3261static int unit_drop_in_file(Unit *u,
3262 UnitSetPropertiesMode mode, const char *name, char **p, char **q) {
3263 _cleanup_free_ char *dir = NULL;
3264 int r;
3265
3266 assert(u);
3267
3268 r = unit_drop_in_dir(u, mode, u->transient, &dir);
3269 if (r < 0)
3270 return r;
3271
8eea8687 3272 return drop_in_file(dir, u->id, 50, name, p, q);
29686440
ZJS
3273}
3274
8e2af478 3275int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
29686440 3276
adb76a70 3277 _cleanup_free_ char *dir = NULL, *p = NULL, *q = NULL;
26d04f86 3278 int r;
71645aca
LP
3279
3280 assert(u);
3281
6d235724 3282 if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
8e2af478
LP
3283 return 0;
3284
29686440 3285 r = unit_drop_in_dir(u, mode, u->transient, &dir);
26d04f86
LP
3286 if (r < 0)
3287 return r;
71645aca 3288
adb76a70
WC
3289 r = write_drop_in(dir, u->id, 50, name, data);
3290 if (r < 0)
3291 return r;
3292
3293 r = drop_in_file(dir, u->id, 50, name, &p, &q);
3294 if (r < 0)
3295 return r;
3296
3297 r = strv_extend(&u->dropin_paths, q);
3298 if (r < 0)
3299 return r;
3300
3301 strv_sort(u->dropin_paths);
3302 strv_uniq(u->dropin_paths);
3303
3304 u->dropin_mtime = now(CLOCK_REALTIME);
3305
3306 return 0;
26d04f86 3307}
71645aca 3308
b9ec9359
LP
3309int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
3310 _cleanup_free_ char *p = NULL;
3311 va_list ap;
3312 int r;
3313
3314 assert(u);
3315 assert(name);
3316 assert(format);
3317
6d235724 3318 if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
b9ec9359
LP
3319 return 0;
3320
3321 va_start(ap, format);
3322 r = vasprintf(&p, format, ap);
3323 va_end(ap);
3324
3325 if (r < 0)
3326 return -ENOMEM;
3327
3328 return unit_write_drop_in(u, mode, name, p);
3329}
3330
3331int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
b42defe3
LP
3332 _cleanup_free_ char *ndata = NULL;
3333
3334 assert(u);
3335 assert(name);
3336 assert(data);
3337
3338 if (!UNIT_VTABLE(u)->private_section)
3339 return -EINVAL;
3340
6d235724 3341 if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
b9ec9359
LP
3342 return 0;
3343
b42defe3
LP
3344 ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
3345 if (!ndata)
3346 return -ENOMEM;
3347
3348 return unit_write_drop_in(u, mode, name, ndata);
3349}
3350
b9ec9359
LP
3351int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
3352 _cleanup_free_ char *p = NULL;
3353 va_list ap;
3354 int r;
3355
3356 assert(u);
3357 assert(name);
3358 assert(format);
3359
6d235724 3360 if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
b9ec9359
LP
3361 return 0;
3362
3363 va_start(ap, format);
3364 r = vasprintf(&p, format, ap);
3365 va_end(ap);
3366
3367 if (r < 0)
3368 return -ENOMEM;
3369
3370 return unit_write_drop_in_private(u, mode, name, p);
3371}
3372
8e2af478 3373int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
26d04f86
LP
3374 _cleanup_free_ char *p = NULL, *q = NULL;
3375 int r;
71645aca 3376
26d04f86 3377 assert(u);
71645aca 3378
6d235724 3379 if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
8e2af478
LP
3380 return 0;
3381
29686440 3382 r = unit_drop_in_file(u, mode, name, &p, &q);
6891529f
ZJS
3383 if (r < 0)
3384 return r;
3385
71645aca 3386 if (unlink(q) < 0)
241da328 3387 r = errno == ENOENT ? 0 : -errno;
26d04f86 3388 else
241da328 3389 r = 1;
71645aca
LP
3390
3391 rmdir(p);
26d04f86 3392 return r;
71645aca
LP
3393}
3394
c2756a68
LP
3395int unit_make_transient(Unit *u) {
3396 int r;
3397
3398 assert(u);
3399
3400 u->load_state = UNIT_STUB;
3401 u->load_error = 0;
3402 u->transient = true;
3403
3404 free(u->fragment_path);
3405 u->fragment_path = NULL;
3406
3407 if (u->manager->running_as == SYSTEMD_USER) {
3408 _cleanup_free_ char *c = NULL;
3409
4d5dec23 3410 r = user_runtime_dir(&c);
c2756a68
LP
3411 if (r < 0)
3412 return r;
3413 if (r == 0)
3414 return -ENOENT;
3415
3416 u->fragment_path = strjoin(c, "/", u->id, NULL);
3417 if (!u->fragment_path)
3418 return -ENOMEM;
3419
3420 mkdir_p(c, 0755);
3421 } else {
3422 u->fragment_path = strappend("/run/systemd/system/", u->id);
3423 if (!u->fragment_path)
3424 return -ENOMEM;
3425
3426 mkdir_p("/run/systemd/system", 0755);
3427 }
3428
3429 return write_string_file_atomic_label(u->fragment_path, "# Transient stub");
3430}
3431
cd2086fe
LP
3432int unit_kill_context(
3433 Unit *u,
3434 KillContext *c,
db2cb23b 3435 KillOperation k,
cd2086fe
LP
3436 pid_t main_pid,
3437 pid_t control_pid,
3438 bool main_pid_alien) {
3439
bc6aed7b 3440 int sig, wait_for_exit = false, r;
cd2086fe
LP
3441
3442 assert(u);
3443 assert(c);
3444
3445 if (c->kill_mode == KILL_NONE)
3446 return 0;
3447
db2cb23b
UTL
3448 switch (k) {
3449 case KILL_KILL:
3450 sig = SIGKILL;
3451 break;
3452 case KILL_ABORT:
3453 sig = SIGABRT;
3454 break;
3455 case KILL_TERMINATE:
3456 sig = c->kill_signal;
3457 break;
3458 default:
3459 assert_not_reached("KillOperation unknown");
3460 }
cd2086fe
LP
3461
3462 if (main_pid > 0) {
3463 r = kill_and_sigcont(main_pid, sig);
3464
3465 if (r < 0 && r != -ESRCH) {
3466 _cleanup_free_ char *comm = NULL;
3467 get_process_comm(main_pid, &comm);
3468
31938a85 3469 log_unit_warning_errno(u->id, r, "Failed to kill main process " PID_FMT " (%s): %m", main_pid, strna(comm));
82659fd7 3470 } else {
bc6aed7b
LP
3471 if (!main_pid_alien)
3472 wait_for_exit = true;
82659fd7 3473
db2cb23b 3474 if (c->send_sighup && k != KILL_KILL)
82659fd7
LP
3475 kill(main_pid, SIGHUP);
3476 }
cd2086fe
LP
3477 }
3478
3479 if (control_pid > 0) {
3480 r = kill_and_sigcont(control_pid, sig);
3481
3482 if (r < 0 && r != -ESRCH) {
3483 _cleanup_free_ char *comm = NULL;
3484 get_process_comm(control_pid, &comm);
3485
31938a85 3486 log_unit_warning_errno(u->id, r, "Failed to kill control process " PID_FMT " (%s): %m", control_pid, strna(comm));
82659fd7 3487 } else {
cd2086fe 3488 wait_for_exit = true;
82659fd7 3489
db2cb23b 3490 if (c->send_sighup && k != KILL_KILL)
82659fd7
LP
3491 kill(control_pid, SIGHUP);
3492 }
cd2086fe
LP
3493 }
3494
db2cb23b 3495 if ((c->kill_mode == KILL_CONTROL_GROUP || (c->kill_mode == KILL_MIXED && k == KILL_KILL)) && u->cgroup_path) {
cd2086fe
LP
3496 _cleanup_set_free_ Set *pid_set = NULL;
3497
82659fd7
LP
3498 /* Exclude the main/control pids from being killed via the cgroup */
3499 pid_set = unit_pid_set(main_pid, control_pid);
cd2086fe
LP
3500 if (!pid_set)
3501 return -ENOMEM;
3502
4ad49000 3503 r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set);
cd2086fe
LP
3504 if (r < 0) {
3505 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
31938a85 3506 log_unit_warning_errno(u->id, r, "Failed to kill control group: %m");
82659fd7 3507 } else if (r > 0) {
bc6aed7b 3508
743970d2
LP
3509 /* FIXME: For now, we will not wait for the
3510 * cgroup members to die, simply because
3511 * cgroup notification is unreliable. It
3512 * doesn't work at all in containers, and
3513 * outside of containers it can be confused
3514 * easily by leaving directories in the
3515 * cgroup. */
3516
3517 /* wait_for_exit = true; */
58ea275a 3518
db2cb23b 3519 if (c->send_sighup && k != KILL_KILL) {
82659fd7
LP
3520 set_free(pid_set);
3521
3522 pid_set = unit_pid_set(main_pid, control_pid);
3523 if (!pid_set)
3524 return -ENOMEM;
3525
8190da36 3526 cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, SIGHUP, false, true, false, pid_set);
82659fd7
LP
3527 }
3528 }
cd2086fe
LP
3529 }
3530
3531 return wait_for_exit;
3532}
3533
a57f7e2c
LP
3534int unit_require_mounts_for(Unit *u, const char *path) {
3535 char prefix[strlen(path) + 1], *p;
3536 int r;
3537
3538 assert(u);
3539 assert(path);
3540
3541 /* Registers a unit for requiring a certain path and all its
3542 * prefixes. We keep a simple array of these paths in the
3543 * unit, since its usually short. However, we build a prefix
3544 * table for all possible prefixes so that new appearing mount
3545 * units can easily determine which units to make themselves a
3546 * dependency of. */
3547
70b64bd3
ZJS
3548 if (!path_is_absolute(path))
3549 return -EINVAL;
3550
a57f7e2c
LP
3551 p = strdup(path);
3552 if (!p)
3553 return -ENOMEM;
3554
3555 path_kill_slashes(p);
3556
a57f7e2c
LP
3557 if (!path_is_safe(p)) {
3558 free(p);
3559 return -EPERM;
3560 }
3561
3562 if (strv_contains(u->requires_mounts_for, p)) {
3563 free(p);
3564 return 0;
3565 }
3566
6e18964d
ZJS
3567 r = strv_consume(&u->requires_mounts_for, p);
3568 if (r < 0)
a57f7e2c 3569 return r;
a57f7e2c
LP
3570
3571 PATH_FOREACH_PREFIX_MORE(prefix, p) {
3572 Set *x;
3573
3574 x = hashmap_get(u->manager->units_requiring_mounts_for, prefix);
3575 if (!x) {
3576 char *q;
3577
3578 if (!u->manager->units_requiring_mounts_for) {
d5099efc 3579 u->manager->units_requiring_mounts_for = hashmap_new(&string_hash_ops);
a57f7e2c
LP
3580 if (!u->manager->units_requiring_mounts_for)
3581 return -ENOMEM;
3582 }
3583
3584 q = strdup(prefix);
3585 if (!q)
3586 return -ENOMEM;
3587
d5099efc 3588 x = set_new(NULL);
a57f7e2c
LP
3589 if (!x) {
3590 free(q);
3591 return -ENOMEM;
3592 }
3593
3594 r = hashmap_put(u->manager->units_requiring_mounts_for, q, x);
3595 if (r < 0) {
3596 free(q);
3597 set_free(x);
3598 return r;
3599 }
3600 }
3601
3602 r = set_put(x, u);
3603 if (r < 0)
3604 return r;
3605 }
3606
3607 return 0;
3608}
3609
613b411c
LP
3610int unit_setup_exec_runtime(Unit *u) {
3611 ExecRuntime **rt;
3612 size_t offset;
3613 Iterator i;
3614 Unit *other;
3615
3616 offset = UNIT_VTABLE(u)->exec_runtime_offset;
3617 assert(offset > 0);
3618
06b643e7 3619 /* Check if there already is an ExecRuntime for this unit? */
613b411c
LP
3620 rt = (ExecRuntime**) ((uint8_t*) u + offset);
3621 if (*rt)
3622 return 0;
3623
3624 /* Try to get it from somebody else */
3625 SET_FOREACH(other, u->dependencies[UNIT_JOINS_NAMESPACE_OF], i) {
3626
3627 *rt = unit_get_exec_runtime(other);
3628 if (*rt) {
3629 exec_runtime_ref(*rt);
3630 return 0;
3631 }
3632 }
3633
3634 return exec_runtime_make(rt, unit_get_exec_context(u), u->id);
3635}
3636
94f04347
LP
3637static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
3638 [UNIT_ACTIVE] = "active",
032ff4af 3639 [UNIT_RELOADING] = "reloading",
94f04347 3640 [UNIT_INACTIVE] = "inactive",
fdf20a31 3641 [UNIT_FAILED] = "failed",
94f04347
LP
3642 [UNIT_ACTIVATING] = "activating",
3643 [UNIT_DEACTIVATING] = "deactivating"
3644};
3645
3646DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);