]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/unit.c
networkd: failing to track links is a serious problem so log at warning level rather...
[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
612 * to reserve anything. In that case other's set will be transfered
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
92ab323c
LP
1456 /* If it is stopped, but we cannot start it, then fail */
1457 if (!UNIT_VTABLE(u)->start)
1458 return -EBADR;
1459
87f0e418
LP
1460 /* We don't suppress calls to ->start() here when we are
1461 * already starting, to allow this request to be used as a
1462 * "hurry up" call, for example when the unit is in some "auto
1463 * restart" state where it waits for a holdoff timer to elapse
1464 * before it will start again. */
1465
c1e1601e 1466 unit_add_to_dbus_queue(u);
9e58ff9c 1467
87f0e418
LP
1468 return UNIT_VTABLE(u)->start(u);
1469}
1470
1471bool unit_can_start(Unit *u) {
1472 assert(u);
1473
1474 return !!UNIT_VTABLE(u)->start;
1475}
1476
2528a7a6
LP
1477bool unit_can_isolate(Unit *u) {
1478 assert(u);
1479
1480 return unit_can_start(u) &&
ac155bb8 1481 u->allow_isolate;
2528a7a6
LP
1482}
1483
87f0e418
LP
1484/* Errors:
1485 * -EBADR: This unit type does not support stopping.
1486 * -EALREADY: Unit is already stopped.
1487 * -EAGAIN: An operation is already in progress. Retry later.
1488 */
1489int unit_stop(Unit *u) {
1490 UnitActiveState state;
92ab323c 1491 Unit *following;
87f0e418
LP
1492
1493 assert(u);
1494
87f0e418 1495 state = unit_active_state(u);
fdf20a31 1496 if (UNIT_IS_INACTIVE_OR_FAILED(state))
87f0e418
LP
1497 return -EALREADY;
1498
92ab323c 1499 if ((following = unit_following(u))) {
79008bdd 1500 log_unit_debug(u->id, "Redirecting stop request from %s to %s.",
c1b6628d 1501 u->id, following->id);
92ab323c
LP
1502 return unit_stop(following);
1503 }
1504
877d54e9
LP
1505 unit_status_log_starting_stopping_reloading(u, JOB_STOP);
1506 unit_status_print_starting_stopping(u, JOB_STOP);
c6918296 1507
7898b0cf
LP
1508 if (!UNIT_VTABLE(u)->stop)
1509 return -EBADR;
1510
c1e1601e 1511 unit_add_to_dbus_queue(u);
9e58ff9c 1512
87f0e418
LP
1513 return UNIT_VTABLE(u)->stop(u);
1514}
1515
1516/* Errors:
1517 * -EBADR: This unit type does not support reloading.
1518 * -ENOEXEC: Unit is not started.
1519 * -EAGAIN: An operation is already in progress. Retry later.
1520 */
1521int unit_reload(Unit *u) {
1522 UnitActiveState state;
92ab323c 1523 Unit *following;
87f0e418
LP
1524
1525 assert(u);
1526
ac155bb8 1527 if (u->load_state != UNIT_LOADED)
6124958c
LP
1528 return -EINVAL;
1529
87f0e418
LP
1530 if (!unit_can_reload(u))
1531 return -EBADR;
1532
1533 state = unit_active_state(u);
e364ad06 1534 if (state == UNIT_RELOADING)
87f0e418
LP
1535 return -EALREADY;
1536
6a371e23 1537 if (state != UNIT_ACTIVE) {
79008bdd 1538 log_unit_warning(u->id, "Unit %s cannot be reloaded because it is inactive.",
6a371e23 1539 u->id);
87f0e418 1540 return -ENOEXEC;
6a371e23 1541 }
87f0e418 1542
e48614c4
ZJS
1543 following = unit_following(u);
1544 if (following) {
79008bdd 1545 log_unit_debug(u->id, "Redirecting reload request from %s to %s.",
c1b6628d 1546 u->id, following->id);
92ab323c
LP
1547 return unit_reload(following);
1548 }
1549
877d54e9
LP
1550 unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
1551
c1e1601e 1552 unit_add_to_dbus_queue(u);
87f0e418
LP
1553 return UNIT_VTABLE(u)->reload(u);
1554}
1555
1556bool unit_can_reload(Unit *u) {
1557 assert(u);
1558
1559 if (!UNIT_VTABLE(u)->reload)
1560 return false;
1561
1562 if (!UNIT_VTABLE(u)->can_reload)
1563 return true;
1564
1565 return UNIT_VTABLE(u)->can_reload(u);
1566}
1567
b4a16b7b 1568static void unit_check_unneeded(Unit *u) {
f3bff0eb
LP
1569 Iterator i;
1570 Unit *other;
1571
1572 assert(u);
1573
1574 /* If this service shall be shut down when unneeded then do
1575 * so. */
1576
ac155bb8 1577 if (!u->stop_when_unneeded)
f3bff0eb
LP
1578 return;
1579
1580 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1581 return;
1582
ac155bb8 1583 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
31afa0a4 1584 if (unit_active_or_pending(other))
f3bff0eb
LP
1585 return;
1586
ac155bb8 1587 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
31afa0a4 1588 if (unit_active_or_pending(other))
f3bff0eb
LP
1589 return;
1590
ac155bb8 1591 SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
31afa0a4 1592 if (unit_active_or_pending(other))
f3bff0eb
LP
1593 return;
1594
ac155bb8 1595 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
31afa0a4 1596 if (unit_active_or_pending(other))
b81884e7
LP
1597 return;
1598
79008bdd 1599 log_unit_info(u->id, "Unit %s is not needed anymore. Stopping.", u->id);
f3bff0eb
LP
1600
1601 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
ac155bb8 1602 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
f3bff0eb
LP
1603}
1604
ff502445
LP
1605static void unit_check_binds_to(Unit *u) {
1606 bool stop = false;
1607 Unit *other;
1608 Iterator i;
1609
1610 assert(u);
1611
1612 if (u->job)
1613 return;
1614
1615 if (unit_active_state(u) != UNIT_ACTIVE)
1616 return;
1617
1618 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i) {
1619 if (other->job)
1620 continue;
1621
1622 if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
1623 continue;
1624
1625 stop = true;
1626 }
1627
1628 if (!stop)
1629 return;
1630
79008bdd 1631 log_unit_info(u->id, "Unit %s is bound to inactive service. Stopping, too.", u->id);
ff502445
LP
1632
1633 /* A unit we need to run is gone. Sniff. Let's stop this. */
1634 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
1635}
1636
87f0e418
LP
1637static void retroactively_start_dependencies(Unit *u) {
1638 Iterator i;
1639 Unit *other;
1640
1641 assert(u);
1642 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1643
ac155bb8
MS
1644 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1645 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1646 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1647 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
b81884e7 1648
7f2cddae 1649 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
ac155bb8 1650 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1651 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1652 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
87f0e418 1653
ac155bb8
MS
1654 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1655 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1656 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1657 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
87f0e418 1658
ac155bb8
MS
1659 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1660 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1661 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1662 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
87f0e418 1663
ac155bb8 1664 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
b81884e7 1665 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1666 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
69dd2852 1667
ac155bb8 1668 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
b81884e7 1669 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1670 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
87f0e418
LP
1671}
1672
1673static void retroactively_stop_dependencies(Unit *u) {
1674 Iterator i;
1675 Unit *other;
1676
1677 assert(u);
1678 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1679
b81884e7 1680 /* Pull down units which are bound to us recursively if enabled */
ac155bb8 1681 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
b81884e7 1682 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1683 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
cd0504d0
MS
1684}
1685
1686static void check_unneeded_dependencies(Unit *u) {
1687 Iterator i;
1688 Unit *other;
1689
1690 assert(u);
1691 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
f3bff0eb
LP
1692
1693 /* Garbage collect services that might not be needed anymore, if enabled */
ac155bb8 1694 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
87f0e418 1695 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1696 unit_check_unneeded(other);
ac155bb8 1697 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
f3bff0eb 1698 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1699 unit_check_unneeded(other);
ac155bb8 1700 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
f3bff0eb 1701 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1702 unit_check_unneeded(other);
ac155bb8 1703 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
f3bff0eb 1704 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1705 unit_check_unneeded(other);
ac155bb8 1706 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
f3bff0eb 1707 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1708 unit_check_unneeded(other);
7f2cddae 1709 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
b81884e7
LP
1710 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1711 unit_check_unneeded(other);
87f0e418
LP
1712}
1713
3ecaa09b 1714void unit_start_on_failure(Unit *u) {
c0daa706
LP
1715 Unit *other;
1716 Iterator i;
1717
1718 assert(u);
1719
ac155bb8 1720 if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
222ae6a8
LP
1721 return;
1722
79008bdd 1723 log_unit_info(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
222ae6a8 1724
ac155bb8 1725 SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
222ae6a8
LP
1726 int r;
1727
d420282b 1728 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_job_mode, true, NULL, NULL);
c1b6628d 1729 if (r < 0)
31938a85 1730 log_unit_error_errno(u->id, r, "Failed to enqueue OnFailure= job: %m");
222ae6a8 1731 }
c0daa706
LP
1732}
1733
3ecaa09b
LP
1734void unit_trigger_notify(Unit *u) {
1735 Unit *other;
1736 Iterator i;
1737
1738 assert(u);
1739
1740 SET_FOREACH(other, u->dependencies[UNIT_TRIGGERED_BY], i)
1741 if (UNIT_VTABLE(other)->trigger_notify)
1742 UNIT_VTABLE(other)->trigger_notify(other, u);
1743}
1744
e2f3b44c 1745void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
546ac4f0 1746 Manager *m;
7e6e7b06 1747 bool unexpected;
a096ed36 1748
87f0e418
LP
1749 assert(u);
1750 assert(os < _UNIT_ACTIVE_STATE_MAX);
1751 assert(ns < _UNIT_ACTIVE_STATE_MAX);
87f0e418 1752
8e471ccd
LP
1753 /* Note that this is called for all low-level state changes,
1754 * even if they might map to the same high-level
865cc19a 1755 * UnitActiveState! That means that ns == os is an expected
c5315881 1756 * behavior here. For example: if a mount point is remounted
cd6d0a45 1757 * this function will be called too! */
87f0e418 1758
546ac4f0
MS
1759 m = u->manager;
1760
f755e3b7 1761 /* Update timestamps for state changes */
546ac4f0 1762 if (m->n_reloading <= 0) {
bdbf9951 1763 dual_timestamp ts;
173e3821 1764
bdbf9951 1765 dual_timestamp_get(&ts);
173e3821 1766
bdbf9951 1767 if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
ac155bb8 1768 u->inactive_exit_timestamp = ts;
bdbf9951 1769 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
ac155bb8 1770 u->inactive_enter_timestamp = ts;
bdbf9951
LP
1771
1772 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
ac155bb8 1773 u->active_enter_timestamp = ts;
bdbf9951 1774 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
ac155bb8 1775 u->active_exit_timestamp = ts;
bdbf9951 1776 }
87f0e418 1777
865cc19a 1778 /* Keep track of failed units */
3f3cc397 1779 if (ns == UNIT_FAILED)
f755e3b7 1780 set_put(u->manager->failed_units, u);
3f3cc397 1781 else
f755e3b7
LP
1782 set_remove(u->manager->failed_units, u);
1783
1784 /* Make sure the cgroup is always removed when we become inactive */
fdf20a31 1785 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
b1491eba 1786 unit_destroy_cgroup_if_empty(u);
fb385181 1787
9cd86184 1788 /* Note that this doesn't apply to RemainAfterExit services exiting
6f285378 1789 * successfully, since there's no change of state in that case. Which is
9cd86184 1790 * why it is handled in service_set_state() */
7ed9f6cd 1791 if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
b33918c2
LP
1792 ExecContext *ec;
1793
1794 ec = unit_get_exec_context(u);
7ed9f6cd 1795 if (ec && exec_context_may_touch_console(ec)) {
31a7eb86
ZJS
1796 if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1797 m->n_on_console --;
1798
1799 if (m->n_on_console == 0)
1800 /* unset no_console_output flag, since the console is free */
2f38577f 1801 m->no_console_output = false;
31a7eb86
ZJS
1802 } else
1803 m->n_on_console ++;
7ed9f6cd
MS
1804 }
1805 }
1806
ac155bb8 1807 if (u->job) {
7e6e7b06 1808 unexpected = false;
87f0e418 1809
ac155bb8 1810 if (u->job->state == JOB_WAITING)
87f0e418
LP
1811
1812 /* So we reached a different state for this
1813 * job. Let's see if we can run it now if it
1814 * failed previously due to EAGAIN. */
ac155bb8 1815 job_add_to_run_queue(u->job);
87f0e418 1816
b410e6b9 1817 /* Let's check whether this state change constitutes a
35b8ca3a 1818 * finished job, or maybe contradicts a running job and
b410e6b9 1819 * hence needs to invalidate jobs. */
87f0e418 1820
ac155bb8 1821 switch (u->job->type) {
87f0e418 1822
b410e6b9
LP
1823 case JOB_START:
1824 case JOB_VERIFY_ACTIVE:
87f0e418 1825
b410e6b9 1826 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
5273510e 1827 job_finish_and_invalidate(u->job, JOB_DONE, true);
ac155bb8 1828 else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
b410e6b9 1829 unexpected = true;
41b02ec7 1830
fdf20a31 1831 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1832 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
b410e6b9 1833 }
87f0e418 1834
b410e6b9 1835 break;
87f0e418 1836
b410e6b9
LP
1837 case JOB_RELOAD:
1838 case JOB_RELOAD_OR_START:
87f0e418 1839
ac155bb8 1840 if (u->job->state == JOB_RUNNING) {
a096ed36 1841 if (ns == UNIT_ACTIVE)
5273510e 1842 job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
032ff4af 1843 else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
a096ed36 1844 unexpected = true;
41b02ec7 1845
fdf20a31 1846 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1847 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
a096ed36 1848 }
b410e6b9 1849 }
87f0e418 1850
b410e6b9 1851 break;
87f0e418 1852
b410e6b9
LP
1853 case JOB_STOP:
1854 case JOB_RESTART:
1855 case JOB_TRY_RESTART:
87f0e418 1856
fdf20a31 1857 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1858 job_finish_and_invalidate(u->job, JOB_DONE, true);
ac155bb8 1859 else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
b410e6b9 1860 unexpected = true;
5273510e 1861 job_finish_and_invalidate(u->job, JOB_FAILED, true);
b410e6b9 1862 }
87f0e418 1863
b410e6b9 1864 break;
87f0e418 1865
b410e6b9
LP
1866 default:
1867 assert_not_reached("Job type unknown");
87f0e418 1868 }
87f0e418 1869
7e6e7b06
LP
1870 } else
1871 unexpected = true;
1872
546ac4f0 1873 if (m->n_reloading <= 0) {
f3bff0eb 1874
bdbf9951
LP
1875 /* If this state change happened without being
1876 * requested by a job, then let's retroactively start
1877 * or stop dependencies. We skip that step when
1878 * deserializing, since we don't want to create any
1879 * additional jobs just because something is already
1880 * activated. */
1881
1882 if (unexpected) {
1883 if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1884 retroactively_start_dependencies(u);
1885 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1886 retroactively_stop_dependencies(u);
1887 }
5de9682c 1888
cd0504d0 1889 /* stop unneeded units regardless if going down was expected or not */
b33918c2 1890 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
cd0504d0
MS
1891 check_unneeded_dependencies(u);
1892
bdbf9951 1893 if (ns != os && ns == UNIT_FAILED) {
79008bdd 1894 log_unit_notice(u->id, "Unit %s entered failed state.", u->id);
3ecaa09b 1895 unit_start_on_failure(u);
cd6d0a45 1896 }
3b2775c5 1897 }
e537352b 1898
3b2775c5
LP
1899 /* Some names are special */
1900 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
1901
1902 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
865cc19a 1903 /* The bus might have just become available,
3b2775c5
LP
1904 * hence try to connect to it, if we aren't
1905 * yet connected. */
546ac4f0 1906 bus_init(m, true);
3b2775c5 1907
ac155bb8 1908 if (u->type == UNIT_SERVICE &&
3b2775c5 1909 !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
546ac4f0 1910 m->n_reloading <= 0) {
3b2775c5 1911 /* Write audit record if we have just finished starting up */
546ac4f0 1912 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
ac155bb8 1913 u->in_audit = true;
3b2775c5 1914 }
e983b760 1915
3b2775c5 1916 if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
546ac4f0 1917 manager_send_unit_plymouth(m, u);
bdbf9951 1918
3b2775c5 1919 } else {
bdbf9951 1920
3b2775c5
LP
1921 /* We don't care about D-Bus here, since we'll get an
1922 * asynchronous notification for it anyway. */
cd6d0a45 1923
ac155bb8 1924 if (u->type == UNIT_SERVICE &&
3b2775c5
LP
1925 UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1926 !UNIT_IS_INACTIVE_OR_FAILED(os) &&
546ac4f0 1927 m->n_reloading <= 0) {
4927fcae 1928
3b2775c5
LP
1929 /* Hmm, if there was no start record written
1930 * write it now, so that we always have a nice
1931 * pair */
ac155bb8 1932 if (!u->in_audit) {
546ac4f0 1933 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
cd6d0a45 1934
3b2775c5 1935 if (ns == UNIT_INACTIVE)
546ac4f0 1936 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
3b2775c5
LP
1937 } else
1938 /* Write audit record if we have just finished shutting down */
546ac4f0 1939 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
bdbf9951 1940
ac155bb8 1941 u->in_audit = false;
cd6d0a45 1942 }
f278026d
LP
1943 }
1944
546ac4f0 1945 manager_recheck_journal(m);
3ecaa09b 1946 unit_trigger_notify(u);
3b2775c5 1947
ff502445
LP
1948 if (u->manager->n_reloading <= 0) {
1949 /* Maybe we finished startup and are now ready for
1950 * being stopped because unneeded? */
bf6dcfa6 1951 unit_check_unneeded(u);
c1e1601e 1952
ff502445
LP
1953 /* Maybe we finished startup, but something we needed
1954 * has vanished? Let's die then. (This happens when
1955 * something BindsTo= to a Type=oneshot unit, as these
1956 * units go directly from starting to inactive,
1957 * without ever entering started.) */
1958 unit_check_binds_to(u);
1959 }
1960
c1e1601e 1961 unit_add_to_dbus_queue(u);
701cc384 1962 unit_add_to_gc_queue(u);
87f0e418
LP
1963}
1964
87f0e418 1965int unit_watch_pid(Unit *u, pid_t pid) {
a911bb9a
LP
1966 int q, r;
1967
87f0e418
LP
1968 assert(u);
1969 assert(pid >= 1);
1970
5ba6985b
LP
1971 /* Watch a specific PID. We only support one or two units
1972 * watching each PID for now, not more. */
1973
d5099efc 1974 r = set_ensure_allocated(&u->pids, NULL);
5ba6985b
LP
1975 if (r < 0)
1976 return r;
1977
d5099efc 1978 r = hashmap_ensure_allocated(&u->manager->watch_pids1, NULL);
a911bb9a
LP
1979 if (r < 0)
1980 return r;
1981
5ba6985b
LP
1982 r = hashmap_put(u->manager->watch_pids1, LONG_TO_PTR(pid), u);
1983 if (r == -EEXIST) {
d5099efc 1984 r = hashmap_ensure_allocated(&u->manager->watch_pids2, NULL);
5ba6985b
LP
1985 if (r < 0)
1986 return r;
05e343b7 1987
5ba6985b
LP
1988 r = hashmap_put(u->manager->watch_pids2, LONG_TO_PTR(pid), u);
1989 }
a911bb9a 1990
5ba6985b 1991 q = set_put(u->pids, LONG_TO_PTR(pid));
a911bb9a
LP
1992 if (q < 0)
1993 return q;
1994
1995 return r;
87f0e418
LP
1996}
1997
1998void unit_unwatch_pid(Unit *u, pid_t pid) {
1999 assert(u);
2000 assert(pid >= 1);
2001
5ba6985b
LP
2002 hashmap_remove_value(u->manager->watch_pids1, LONG_TO_PTR(pid), u);
2003 hashmap_remove_value(u->manager->watch_pids2, LONG_TO_PTR(pid), u);
a911bb9a
LP
2004 set_remove(u->pids, LONG_TO_PTR(pid));
2005}
2006
bd44e61b
LP
2007void unit_unwatch_all_pids(Unit *u) {
2008 assert(u);
2009
2010 while (!set_isempty(u->pids))
2011 unit_unwatch_pid(u, PTR_TO_LONG(set_first(u->pids)));
2012
2013 set_free(u->pids);
2014 u->pids = NULL;
2015}
2016
2017static int unit_watch_pids_in_path(Unit *u, const char *path) {
a911bb9a
LP
2018 _cleanup_closedir_ DIR *d = NULL;
2019 _cleanup_fclose_ FILE *f = NULL;
2020 int ret = 0, r;
2021
2022 assert(u);
2023 assert(path);
2024
2025 /* Adds all PIDs from a specific cgroup path to the set of PIDs we watch. */
2026
2027 r = cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, path, &f);
2028 if (r >= 0) {
2029 pid_t pid;
2030
2031 while ((r = cg_read_pid(f, &pid)) > 0) {
2032 r = unit_watch_pid(u, pid);
2033 if (r < 0 && ret >= 0)
2034 ret = r;
2035 }
2036 if (r < 0 && ret >= 0)
2037 ret = r;
2038
2039 } else if (ret >= 0)
2040 ret = r;
2041
2042 r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, path, &d);
2043 if (r >= 0) {
2044 char *fn;
2045
2046 while ((r = cg_read_subgroup(d, &fn)) > 0) {
2047 _cleanup_free_ char *p = NULL;
2048
2049 p = strjoin(path, "/", fn, NULL);
2050 free(fn);
2051
2052 if (!p)
2053 return -ENOMEM;
2054
bd44e61b 2055 r = unit_watch_pids_in_path(u, p);
a911bb9a
LP
2056 if (r < 0 && ret >= 0)
2057 ret = r;
2058 }
2059 if (r < 0 && ret >= 0)
2060 ret = r;
2061
2062 } else if (ret >= 0)
2063 ret = r;
2064
2065 return ret;
2066}
2067
a911bb9a
LP
2068int unit_watch_all_pids(Unit *u) {
2069 assert(u);
2070
a911bb9a
LP
2071 /* Adds all PIDs from our cgroup to the set of PIDs we watch */
2072
bd44e61b
LP
2073 if (!u->cgroup_path)
2074 return -ENOENT;
a911bb9a 2075
bd44e61b 2076 return unit_watch_pids_in_path(u, u->cgroup_path);
a911bb9a
LP
2077}
2078
2079void unit_tidy_watch_pids(Unit *u, pid_t except1, pid_t except2) {
2080 Iterator i;
2081 void *e;
2082
2083 assert(u);
2084
2085 /* Cleans dead PIDs from our list */
2086
2087 SET_FOREACH(e, u->pids, i) {
2088 pid_t pid = PTR_TO_LONG(e);
2089
2090 if (pid == except1 || pid == except2)
2091 continue;
2092
9f5650ae 2093 if (!pid_is_unwaited(pid))
bd44e61b 2094 unit_unwatch_pid(u, pid);
a911bb9a 2095 }
87f0e418
LP
2096}
2097
87f0e418
LP
2098bool unit_job_is_applicable(Unit *u, JobType j) {
2099 assert(u);
2100 assert(j >= 0 && j < _JOB_TYPE_MAX);
2101
2102 switch (j) {
2103
2104 case JOB_VERIFY_ACTIVE:
2105 case JOB_START:
57339f47 2106 case JOB_STOP:
e0209d83 2107 case JOB_NOP:
87f0e418
LP
2108 return true;
2109
87f0e418
LP
2110 case JOB_RESTART:
2111 case JOB_TRY_RESTART:
2112 return unit_can_start(u);
2113
2114 case JOB_RELOAD:
2115 return unit_can_reload(u);
2116
2117 case JOB_RELOAD_OR_START:
2118 return unit_can_reload(u) && unit_can_start(u);
2119
2120 default:
2121 assert_not_reached("Invalid job type");
2122 }
2123}
2124
d1fab3fe 2125static int maybe_warn_about_dependency(const char *id, const char *other, UnitDependency dependency) {
3f3cc397
LP
2126 assert(id);
2127
d1fab3fe
ZJS
2128 switch (dependency) {
2129 case UNIT_REQUIRES:
2130 case UNIT_REQUIRES_OVERRIDABLE:
2131 case UNIT_WANTS:
2132 case UNIT_REQUISITE:
2133 case UNIT_REQUISITE_OVERRIDABLE:
2134 case UNIT_BINDS_TO:
2135 case UNIT_PART_OF:
2136 case UNIT_REQUIRED_BY:
2137 case UNIT_REQUIRED_BY_OVERRIDABLE:
2138 case UNIT_WANTED_BY:
2139 case UNIT_BOUND_BY:
2140 case UNIT_CONSISTS_OF:
2141 case UNIT_REFERENCES:
2142 case UNIT_REFERENCED_BY:
2143 case UNIT_PROPAGATES_RELOAD_TO:
2144 case UNIT_RELOAD_PROPAGATED_FROM:
2145 case UNIT_JOINS_NAMESPACE_OF:
2146 return 0;
2147
2148 case UNIT_CONFLICTS:
2149 case UNIT_CONFLICTED_BY:
2150 case UNIT_BEFORE:
2151 case UNIT_AFTER:
2152 case UNIT_ON_FAILURE:
2153 case UNIT_TRIGGERS:
2154 case UNIT_TRIGGERED_BY:
2155 if (streq_ptr(id, other))
79008bdd 2156 log_unit_warning(id, "Dependency %s=%s dropped from unit %s",
d1fab3fe
ZJS
2157 unit_dependency_to_string(dependency), id, other);
2158 else
79008bdd 2159 log_unit_warning(id, "Dependency %s=%s dropped from unit %s merged into %s",
d1fab3fe
ZJS
2160 unit_dependency_to_string(dependency), id,
2161 strna(other), id);
2162 return -EINVAL;
2163
2164 case _UNIT_DEPENDENCY_MAX:
2165 case _UNIT_DEPENDENCY_INVALID:
2166 break;
2167 }
3f3cc397 2168
d1fab3fe
ZJS
2169 assert_not_reached("Invalid dependency type");
2170}
2171
701cc384 2172int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
87f0e418
LP
2173
2174 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
2175 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
9e2f7c11 2176 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
87f0e418
LP
2177 [UNIT_WANTS] = UNIT_WANTED_BY,
2178 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
9e2f7c11 2179 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
7f2cddae 2180 [UNIT_BINDS_TO] = UNIT_BOUND_BY,
60649f17 2181 [UNIT_PART_OF] = UNIT_CONSISTS_OF,
87f0e418 2182 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
9e2f7c11 2183 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
87f0e418 2184 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
7f2cddae 2185 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
60649f17 2186 [UNIT_CONSISTS_OF] = UNIT_PART_OF,
69dd2852
LP
2187 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
2188 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
87f0e418 2189 [UNIT_BEFORE] = UNIT_AFTER,
701cc384 2190 [UNIT_AFTER] = UNIT_BEFORE,
5de9682c 2191 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
701cc384 2192 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
57020a3a
LP
2193 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
2194 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
4dcc1cb4 2195 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
7f2cddae 2196 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
85e9a101 2197 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
613b411c 2198 [UNIT_JOINS_NAMESPACE_OF] = UNIT_JOINS_NAMESPACE_OF,
87f0e418 2199 };
701cc384 2200 int r, q = 0, v = 0, w = 0;
d1fab3fe 2201 Unit *orig_u = u, *orig_other = other;
87f0e418
LP
2202
2203 assert(u);
2204 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
87f0e418
LP
2205 assert(other);
2206
9f151f29
LP
2207 u = unit_follow_merge(u);
2208 other = unit_follow_merge(other);
2209
87f0e418
LP
2210 /* We won't allow dependencies on ourselves. We will not
2211 * consider them an error however. */
d1fab3fe
ZJS
2212 if (u == other) {
2213 maybe_warn_about_dependency(orig_u->id, orig_other->id, d);
87f0e418 2214 return 0;
d1fab3fe 2215 }
87f0e418 2216
d5099efc 2217 r = set_ensure_allocated(&u->dependencies[d], NULL);
613b411c 2218 if (r < 0)
87f0e418
LP
2219 return r;
2220
613b411c 2221 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID) {
d5099efc 2222 r = set_ensure_allocated(&other->dependencies[inverse_table[d]], NULL);
613b411c
LP
2223 if (r < 0)
2224 return r;
2225 }
2226
2227 if (add_reference) {
d5099efc 2228 r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], NULL);
613b411c 2229 if (r < 0)
5de9682c
LP
2230 return r;
2231
d5099efc 2232 r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], NULL);
613b411c 2233 if (r < 0)
701cc384 2234 return r;
613b411c 2235 }
87f0e418 2236
613b411c
LP
2237 q = set_put(u->dependencies[d], other);
2238 if (q < 0)
701cc384 2239 return q;
87f0e418 2240
613b411c
LP
2241 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID && inverse_table[d] != d) {
2242 v = set_put(other->dependencies[inverse_table[d]], u);
2243 if (v < 0) {
5de9682c
LP
2244 r = v;
2245 goto fail;
2246 }
613b411c 2247 }
701cc384
LP
2248
2249 if (add_reference) {
613b411c
LP
2250 w = set_put(u->dependencies[UNIT_REFERENCES], other);
2251 if (w < 0) {
701cc384
LP
2252 r = w;
2253 goto fail;
2254 }
2255
613b411c
LP
2256 r = set_put(other->dependencies[UNIT_REFERENCED_BY], u);
2257 if (r < 0)
701cc384 2258 goto fail;
87f0e418
LP
2259 }
2260
c1e1601e 2261 unit_add_to_dbus_queue(u);
87f0e418 2262 return 0;
701cc384
LP
2263
2264fail:
2265 if (q > 0)
ac155bb8 2266 set_remove(u->dependencies[d], other);
701cc384
LP
2267
2268 if (v > 0)
ac155bb8 2269 set_remove(other->dependencies[inverse_table[d]], u);
701cc384
LP
2270
2271 if (w > 0)
ac155bb8 2272 set_remove(u->dependencies[UNIT_REFERENCES], other);
701cc384
LP
2273
2274 return r;
87f0e418 2275}
0301abf4 2276
2c966c03
LP
2277int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
2278 int r;
2279
2280 assert(u);
2281
3f3cc397
LP
2282 r = unit_add_dependency(u, d, other, add_reference);
2283 if (r < 0)
2c966c03
LP
2284 return r;
2285
3f3cc397
LP
2286 r = unit_add_dependency(u, e, other, add_reference);
2287 if (r < 0)
2c966c03
LP
2288 return r;
2289
2290 return 0;
2291}
2292
9e2f7c11
LP
2293static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
2294 char *s;
2295
2296 assert(u);
2297 assert(name || path);
8afbb8e1 2298 assert(p);
9e2f7c11
LP
2299
2300 if (!name)
2b6bf07d 2301 name = basename(path);
9e2f7c11
LP
2302
2303 if (!unit_name_is_template(name)) {
2304 *p = NULL;
2305 return name;
2306 }
2307
ac155bb8
MS
2308 if (u->instance)
2309 s = unit_name_replace_instance(name, u->instance);
9e2f7c11 2310 else {
ae018d9b 2311 _cleanup_free_ char *i = NULL;
9e2f7c11 2312
8afbb8e1
LP
2313 i = unit_name_to_prefix(u->id);
2314 if (!i)
9e2f7c11
LP
2315 return NULL;
2316
2317 s = unit_name_replace_instance(name, i);
9e2f7c11
LP
2318 }
2319
2320 if (!s)
2321 return NULL;
2322
2323 *p = s;
2324 return s;
2325}
2326
701cc384 2327int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
09b6b09f
LP
2328 Unit *other;
2329 int r;
8afbb8e1 2330 _cleanup_free_ char *s = NULL;
09b6b09f 2331
9e2f7c11
LP
2332 assert(u);
2333 assert(name || path);
09b6b09f 2334
8afbb8e1
LP
2335 name = resolve_template(u, name, path, &s);
2336 if (!name)
9e2f7c11 2337 return -ENOMEM;
09b6b09f 2338
8afbb8e1
LP
2339 r = manager_load_unit(u->manager, name, path, NULL, &other);
2340 if (r < 0)
2341 return r;
9e2f7c11 2342
8afbb8e1 2343 return unit_add_dependency(u, d, other, add_reference);
09b6b09f
LP
2344}
2345
2c966c03 2346int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
3f3cc397 2347 _cleanup_free_ char *s = NULL;
2c966c03
LP
2348 Unit *other;
2349 int r;
2c966c03
LP
2350
2351 assert(u);
2352 assert(name || path);
2353
3f3cc397
LP
2354 name = resolve_template(u, name, path, &s);
2355 if (!name)
2c966c03
LP
2356 return -ENOMEM;
2357
3f3cc397
LP
2358 r = manager_load_unit(u->manager, name, path, NULL, &other);
2359 if (r < 0)
68eda4bd 2360 return r;
2c966c03 2361
3f3cc397 2362 return unit_add_two_dependencies(u, d, e, other, add_reference);
2c966c03
LP
2363}
2364
701cc384 2365int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
bd77d0fc
LP
2366 Unit *other;
2367 int r;
68eda4bd 2368 _cleanup_free_ char *s = NULL;
bd77d0fc 2369
9e2f7c11
LP
2370 assert(u);
2371 assert(name || path);
bd77d0fc 2372
3f3cc397
LP
2373 name = resolve_template(u, name, path, &s);
2374 if (!name)
9e2f7c11 2375 return -ENOMEM;
bd77d0fc 2376
3f3cc397
LP
2377 r = manager_load_unit(u->manager, name, path, NULL, &other);
2378 if (r < 0)
68eda4bd 2379 return r;
9e2f7c11 2380
3f3cc397 2381 return unit_add_dependency(other, d, u, add_reference);
bd77d0fc
LP
2382}
2383
2c966c03
LP
2384int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
2385 Unit *other;
2386 int r;
68eda4bd 2387 _cleanup_free_ char *s = NULL;
2c966c03
LP
2388
2389 assert(u);
2390 assert(name || path);
2391
3f3cc397
LP
2392 name = resolve_template(u, name, path, &s);
2393 if (!name)
2c966c03
LP
2394 return -ENOMEM;
2395
3f3cc397
LP
2396 r = manager_load_unit(u->manager, name, path, NULL, &other);
2397 if (r < 0)
68eda4bd 2398 return r;
2c966c03 2399
3f3cc397
LP
2400 r = unit_add_two_dependencies(other, d, e, u, add_reference);
2401 if (r < 0)
68eda4bd 2402 return r;
2c966c03 2403
2c966c03
LP
2404 return r;
2405}
2406
0301abf4 2407int set_unit_path(const char *p) {
0301abf4 2408 /* This is mostly for debug purposes */
cf7d80a5 2409 if (setenv("SYSTEMD_UNIT_PATH", p, 0) < 0)
26d04f86 2410 return -errno;
0301abf4
LP
2411
2412 return 0;
2413}
88066b3a 2414
ea430986 2415char *unit_dbus_path(Unit *u) {
ea430986
LP
2416 assert(u);
2417
ac155bb8 2418 if (!u->id)
04ade7d2
LP
2419 return NULL;
2420
48899192 2421 return unit_dbus_path_from_name(u->id);
ea430986
LP
2422}
2423
41f9172f 2424char *unit_default_cgroup_path(Unit *u) {
d7bd3de0 2425 _cleanup_free_ char *escaped = NULL, *slice = NULL;
a016b922 2426 int r;
5954c074 2427
013b87c0
LP
2428 assert(u);
2429
4ad49000
LP
2430 if (unit_has_name(u, SPECIAL_ROOT_SLICE))
2431 return strdup(u->manager->cgroup_root);
2432
2433 if (UNIT_ISSET(u->slice) && !unit_has_name(UNIT_DEREF(u->slice), SPECIAL_ROOT_SLICE)) {
a016b922
LP
2434 r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice);
2435 if (r < 0)
2436 return NULL;
2437 }
2438
d7bd3de0
LP
2439 escaped = cg_escape(u->id);
2440 if (!escaped)
5954c074
LP
2441 return NULL;
2442
d7bd3de0
LP
2443 if (slice)
2444 return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL);
2445 else
2446 return strjoin(u->manager->cgroup_root, "/", escaped, NULL);
013b87c0
LP
2447}
2448
598459ce 2449int unit_add_default_slice(Unit *u, CGroupContext *c) {
a8833944
LP
2450 _cleanup_free_ char *b = NULL;
2451 const char *slice_name;
a016b922
LP
2452 Unit *slice;
2453 int r;
2454
2455 assert(u);
598459ce 2456 assert(c);
a016b922 2457
9444b1f2 2458 if (UNIT_ISSET(u->slice))
a016b922
LP
2459 return 0;
2460
a8833944
LP
2461 if (u->instance) {
2462 _cleanup_free_ char *prefix = NULL, *escaped = NULL;
68eda4bd 2463
a8833944
LP
2464 /* Implicitly place all instantiated units in their
2465 * own per-template slice */
2466
2467 prefix = unit_name_to_prefix(u->id);
2468 if (!prefix)
2469 return -ENOMEM;
2470
2471 /* The prefix is already escaped, but it might include
2472 * "-" which has a special meaning for slice units,
2473 * hence escape it here extra. */
2474 escaped = strreplace(prefix, "-", "\\x2d");
2475 if (!escaped)
2476 return -ENOMEM;
2477
2478 if (u->manager->running_as == SYSTEMD_SYSTEM)
2479 b = strjoin("system-", escaped, ".slice", NULL);
2480 else
2481 b = strappend(escaped, ".slice");
2482 if (!b)
2483 return -ENOMEM;
2484
2485 slice_name = b;
2486 } else
2487 slice_name =
2488 u->manager->running_as == SYSTEMD_SYSTEM
2489 ? SPECIAL_SYSTEM_SLICE
2490 : SPECIAL_ROOT_SLICE;
2491
2492 r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
a016b922
LP
2493 if (r < 0)
2494 return r;
2495
2496 unit_ref_set(&u->slice, slice);
2497 return 0;
2498}
2499
9444b1f2
LP
2500const char *unit_slice_name(Unit *u) {
2501 assert(u);
2502
2503 if (!UNIT_ISSET(u->slice))
2504 return NULL;
2505
2506 return UNIT_DEREF(u->slice)->id;
2507}
2508
f6ff8c29 2509int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
78edb35a 2510 _cleanup_free_ char *t = NULL;
f6ff8c29
LP
2511 int r;
2512
2513 assert(u);
2514 assert(type);
2515 assert(_found);
2516
78edb35a
LP
2517 t = unit_name_change_suffix(u->id, type);
2518 if (!t)
f6ff8c29
LP
2519 return -ENOMEM;
2520
2521 assert(!unit_has_name(u, t));
2522
ac155bb8 2523 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
9e2f7c11 2524 assert(r < 0 || *_found != u);
f6ff8c29
LP
2525 return r;
2526}
2527
05e343b7
LP
2528int unit_watch_bus_name(Unit *u, const char *name) {
2529 assert(u);
2530 assert(name);
2531
2532 /* Watch a specific name on the bus. We only support one unit
2533 * watching each name for now. */
2534
ac155bb8 2535 return hashmap_put(u->manager->watch_bus, name, u);
05e343b7
LP
2536}
2537
2538void unit_unwatch_bus_name(Unit *u, const char *name) {
2539 assert(u);
2540 assert(name);
2541
ac155bb8 2542 hashmap_remove_value(u->manager->watch_bus, name, u);
05e343b7
LP
2543}
2544
a16e1123
LP
2545bool unit_can_serialize(Unit *u) {
2546 assert(u);
2547
2548 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2549}
2550
6b78f9b4 2551int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
a16e1123
LP
2552 int r;
2553
2554 assert(u);
2555 assert(f);
2556 assert(fds);
2557
9bdb98c5
LP
2558 if (unit_can_serialize(u)) {
2559 ExecRuntime *rt;
a16e1123 2560
9bdb98c5 2561 r = UNIT_VTABLE(u)->serialize(u, f, fds);
613b411c
LP
2562 if (r < 0)
2563 return r;
9bdb98c5
LP
2564
2565 rt = unit_get_exec_runtime(u);
2566 if (rt) {
2567 r = exec_runtime_serialize(rt, u, f, fds);
2568 if (r < 0)
2569 return r;
2570 }
e0209d83
MS
2571 }
2572
ac155bb8
MS
2573 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2574 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2575 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2576 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2577 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
59fccdc5 2578 dual_timestamp_serialize(f, "assert-timestamp", &u->assert_timestamp);
2791a8f8 2579
ac155bb8
MS
2580 if (dual_timestamp_is_set(&u->condition_timestamp))
2581 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
10717a1a 2582
59fccdc5
LP
2583 if (dual_timestamp_is_set(&u->assert_timestamp))
2584 unit_serialize_item(u, f, "assert-result", yes_no(u->assert_result));
2585
c2756a68
LP
2586 unit_serialize_item(u, f, "transient", yes_no(u->transient));
2587
2588 if (u->cgroup_path)
2589 unit_serialize_item(u, f, "cgroup", u->cgroup_path);
2590
613b411c
LP
2591 if (serialize_jobs) {
2592 if (u->job) {
2593 fprintf(f, "job\n");
2594 job_serialize(u->job, f, fds);
2595 }
2596
2597 if (u->nop_job) {
2598 fprintf(f, "job\n");
2599 job_serialize(u->nop_job, f, fds);
2600 }
2601 }
2602
a16e1123
LP
2603 /* End marker */
2604 fputc('\n', f);
2605 return 0;
2606}
2607
2608void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2609 va_list ap;
2610
2611 assert(u);
2612 assert(f);
2613 assert(key);
2614 assert(format);
2615
2616 fputs(key, f);
2617 fputc('=', f);
2618
2619 va_start(ap, format);
2620 vfprintf(f, format, ap);
2621 va_end(ap);
2622
2623 fputc('\n', f);
2624}
2625
2626void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2627 assert(u);
2628 assert(f);
2629 assert(key);
2630 assert(value);
2631
2632 fprintf(f, "%s=%s\n", key, value);
2633}
2634
2635int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
28b99ccd 2636 ExecRuntime **rt = NULL;
9bdb98c5 2637 size_t offset;
a16e1123
LP
2638 int r;
2639
2640 assert(u);
2641 assert(f);
2642 assert(fds);
2643
613b411c
LP
2644 offset = UNIT_VTABLE(u)->exec_runtime_offset;
2645 if (offset > 0)
2646 rt = (ExecRuntime**) ((uint8_t*) u + offset);
2647
a16e1123 2648 for (;;) {
20c03b7b 2649 char line[LINE_MAX], *l, *v;
a16e1123
LP
2650 size_t k;
2651
2652 if (!fgets(line, sizeof(line), f)) {
2653 if (feof(f))
2654 return 0;
2655 return -errno;
2656 }
2657
10f8e83c 2658 char_array_0(line);
a16e1123
LP
2659 l = strstrip(line);
2660
2661 /* End marker */
2662 if (l[0] == 0)
2663 return 0;
2664
2665 k = strcspn(l, "=");
2666
2667 if (l[k] == '=') {
2668 l[k] = 0;
2669 v = l+k+1;
2670 } else
2671 v = l+k;
2672
cca098b0 2673 if (streq(l, "job")) {
39a18c60
MS
2674 if (v[0] == '\0') {
2675 /* new-style serialized job */
2676 Job *j = job_new_raw(u);
2677 if (!j)
2678 return -ENOMEM;
2679
2680 r = job_deserialize(j, f, fds);
2681 if (r < 0) {
2682 job_free(j);
2683 return r;
2684 }
cca098b0 2685
39a18c60
MS
2686 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2687 if (r < 0) {
2688 job_free(j);
2689 return r;
2690 }
e0209d83
MS
2691
2692 r = job_install_deserialized(j);
2693 if (r < 0) {
2694 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2695 job_free(j);
2696 return r;
2697 }
6b19ad24
MS
2698
2699 if (j->state == JOB_RUNNING)
2700 u->manager->n_running_jobs++;
39a18c60
MS
2701 } else {
2702 /* legacy */
2703 JobType type = job_type_from_string(v);
2704 if (type < 0)
2705 log_debug("Failed to parse job type value %s", v);
2706 else
2707 u->deserialized_job = type;
2708 }
cca098b0 2709 continue;
8aaf019b 2710 } else if (streq(l, "inactive-exit-timestamp")) {
ac155bb8 2711 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
8aaf019b
LP
2712 continue;
2713 } else if (streq(l, "active-enter-timestamp")) {
ac155bb8 2714 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
8aaf019b
LP
2715 continue;
2716 } else if (streq(l, "active-exit-timestamp")) {
ac155bb8 2717 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
8aaf019b
LP
2718 continue;
2719 } else if (streq(l, "inactive-enter-timestamp")) {
ac155bb8 2720 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
8aaf019b 2721 continue;
2791a8f8 2722 } else if (streq(l, "condition-timestamp")) {
ac155bb8 2723 dual_timestamp_deserialize(v, &u->condition_timestamp);
2791a8f8 2724 continue;
59fccdc5
LP
2725 } else if (streq(l, "assert-timestamp")) {
2726 dual_timestamp_deserialize(v, &u->assert_timestamp);
2727 continue;
2791a8f8
LP
2728 } else if (streq(l, "condition-result")) {
2729 int b;
2730
c2756a68
LP
2731 b = parse_boolean(v);
2732 if (b < 0)
2791a8f8
LP
2733 log_debug("Failed to parse condition result value %s", v);
2734 else
ac155bb8 2735 u->condition_result = b;
efbac6d2
LP
2736
2737 continue;
c2756a68 2738
59fccdc5
LP
2739 } else if (streq(l, "assert-result")) {
2740 int b;
2741
2742 b = parse_boolean(v);
2743 if (b < 0)
2744 log_debug("Failed to parse assert result value %s", v);
2745 else
2746 u->assert_result = b;
2747
2748 continue;
2749
c2756a68
LP
2750 } else if (streq(l, "transient")) {
2751 int b;
2752
2753 b = parse_boolean(v);
2754 if (b < 0)
2755 log_debug("Failed to parse transient bool %s", v);
2756 else
2757 u->transient = b;
2758
2759 continue;
2760 } else if (streq(l, "cgroup")) {
2761 char *s;
2762
2763 s = strdup(v);
f440e1bb 2764 if (!s)
c2756a68
LP
2765 return -ENOMEM;
2766
4e595329
ZJS
2767 if (u->cgroup_path) {
2768 void *p;
2769
2770 p = hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
2771 log_info("Removing cgroup_path %s from hashmap (%p)",
2772 u->cgroup_path, p);
2773 free(u->cgroup_path);
2774 }
72673e86 2775
4e595329 2776 u->cgroup_path = s;
b58b8e11 2777 assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1);
4e595329 2778
c2756a68 2779 continue;
8aaf019b 2780 }
cca098b0 2781
9bdb98c5
LP
2782 if (unit_can_serialize(u)) {
2783 if (rt) {
2784 r = exec_runtime_deserialize_item(rt, u, l, v, fds);
2785 if (r < 0)
2786 return r;
2787 if (r > 0)
2788 continue;
2789 }
2790
2791 r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds);
613b411c
LP
2792 if (r < 0)
2793 return r;
613b411c 2794 }
a16e1123
LP
2795 }
2796}
2797
6e2ef85b
LP
2798int unit_add_node_link(Unit *u, const char *what, bool wants) {
2799 Unit *device;
68eda4bd 2800 _cleanup_free_ char *e = NULL;
6e2ef85b
LP
2801 int r;
2802
2803 assert(u);
2804
2805 if (!what)
2806 return 0;
2807
2808 /* Adds in links to the device node that this unit is based on */
2809
8407a5d0 2810 if (!is_device_path(what))
6e2ef85b
LP
2811 return 0;
2812
35eb6b12
LP
2813 e = unit_name_from_path(what, ".device");
2814 if (!e)
6e2ef85b
LP
2815 return -ENOMEM;
2816
ac155bb8 2817 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
68eda4bd 2818
6e2ef85b
LP
2819 if (r < 0)
2820 return r;
2821
faa368e3
LP
2822 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
2823 if (r < 0)
6e2ef85b
LP
2824 return r;
2825
faa368e3
LP
2826 if (wants) {
2827 r = unit_add_dependency(device, UNIT_WANTS, u, false);
2828 if (r < 0)
6e2ef85b 2829 return r;
faa368e3 2830 }
6e2ef85b
LP
2831
2832 return 0;
2833}
a16e1123 2834
cca098b0
LP
2835int unit_coldplug(Unit *u) {
2836 int r;
2837
2838 assert(u);
2839
2840 if (UNIT_VTABLE(u)->coldplug)
2841 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2842 return r;
2843
39a18c60
MS
2844 if (u->job) {
2845 r = job_coldplug(u->job);
2846 if (r < 0)
2847 return r;
2848 } else if (u->deserialized_job >= 0) {
2849 /* legacy */
2850 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2851 if (r < 0)
cca098b0
LP
2852 return r;
2853
ac155bb8 2854 u->deserialized_job = _JOB_TYPE_INVALID;
cca098b0
LP
2855 }
2856
2857 return 0;
2858}
2859
49b1d377 2860void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) {
bcfce235 2861 DISABLE_WARNING_FORMAT_NONLITERAL;
127d5fd1
ZJS
2862 manager_status_printf(u->manager, STATUS_TYPE_NORMAL,
2863 status, unit_status_msg_format, unit_description(u));
bcfce235 2864 REENABLE_WARNING;
49b1d377
MS
2865}
2866
45fb0699 2867bool unit_need_daemon_reload(Unit *u) {
ae7a7182
OS
2868 _cleanup_strv_free_ char **t = NULL;
2869 char **path;
1b64d026 2870 struct stat st;
ae7a7182 2871 unsigned loaded_cnt, current_cnt;
1b64d026 2872
45fb0699
LP
2873 assert(u);
2874
ac155bb8 2875 if (u->fragment_path) {
5f4b19f4 2876 zero(st);
ac155bb8 2877 if (stat(u->fragment_path, &st) < 0)
5f4b19f4
LP
2878 /* What, cannot access this anymore? */
2879 return true;
45fb0699 2880
ac155bb8
MS
2881 if (u->fragment_mtime > 0 &&
2882 timespec_load(&st.st_mtim) != u->fragment_mtime)
5f4b19f4
LP
2883 return true;
2884 }
2885
1b64d026
LP
2886 if (u->source_path) {
2887 zero(st);
2888 if (stat(u->source_path, &st) < 0)
2889 return true;
2890
2891 if (u->source_mtime > 0 &&
2892 timespec_load(&st.st_mtim) != u->source_mtime)
2893 return true;
2894 }
5f4b19f4 2895
ae7a7182
OS
2896 t = unit_find_dropin_paths(u);
2897 loaded_cnt = strv_length(t);
2898 current_cnt = strv_length(u->dropin_paths);
2899
2900 if (loaded_cnt == current_cnt) {
2901 if (loaded_cnt == 0)
2902 return false;
2903
2904 if (strv_overlap(u->dropin_paths, t)) {
2905 STRV_FOREACH(path, u->dropin_paths) {
2906 zero(st);
2907 if (stat(*path, &st) < 0)
2908 return true;
2909
2910 if (u->dropin_mtime > 0 &&
2911 timespec_load(&st.st_mtim) > u->dropin_mtime)
2912 return true;
2913 }
2914
2915 return false;
2916 } else
2917 return true;
2918 } else
2919 return true;
45fb0699
LP
2920}
2921
fdf20a31 2922void unit_reset_failed(Unit *u) {
5632e374
LP
2923 assert(u);
2924
fdf20a31
MM
2925 if (UNIT_VTABLE(u)->reset_failed)
2926 UNIT_VTABLE(u)->reset_failed(u);
5632e374
LP
2927}
2928
a7f241db
LP
2929Unit *unit_following(Unit *u) {
2930 assert(u);
2931
2932 if (UNIT_VTABLE(u)->following)
2933 return UNIT_VTABLE(u)->following(u);
2934
2935 return NULL;
2936}
2937
31afa0a4 2938bool unit_stop_pending(Unit *u) {
18ffdfda
LP
2939 assert(u);
2940
31afa0a4
LP
2941 /* This call does check the current state of the unit. It's
2942 * hence useful to be called from state change calls of the
2943 * unit itself, where the state isn't updated yet. This is
2944 * different from unit_inactive_or_pending() which checks both
2945 * the current state and for a queued job. */
18ffdfda 2946
31afa0a4
LP
2947 return u->job && u->job->type == JOB_STOP;
2948}
2949
2950bool unit_inactive_or_pending(Unit *u) {
2951 assert(u);
2952
2953 /* Returns true if the unit is inactive or going down */
18ffdfda 2954
d956ac29
LP
2955 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2956 return true;
2957
31afa0a4 2958 if (unit_stop_pending(u))
18ffdfda
LP
2959 return true;
2960
2961 return false;
2962}
2963
31afa0a4 2964bool unit_active_or_pending(Unit *u) {
f976f3f6
LP
2965 assert(u);
2966
f60c2665 2967 /* Returns true if the unit is active or going up */
f976f3f6
LP
2968
2969 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2970 return true;
2971
ac155bb8
MS
2972 if (u->job &&
2973 (u->job->type == JOB_START ||
2974 u->job->type == JOB_RELOAD_OR_START ||
2975 u->job->type == JOB_RESTART))
f976f3f6
LP
2976 return true;
2977
2978 return false;
2979}
2980
718db961 2981int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error) {
8a0867d6
LP
2982 assert(u);
2983 assert(w >= 0 && w < _KILL_WHO_MAX);
8a0867d6
LP
2984 assert(signo > 0);
2985 assert(signo < _NSIG);
2986
8a0867d6
LP
2987 if (!UNIT_VTABLE(u)->kill)
2988 return -ENOTSUP;
2989
c74f17d9 2990 return UNIT_VTABLE(u)->kill(u, w, signo, error);
8a0867d6
LP
2991}
2992
82659fd7
LP
2993static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
2994 Set *pid_set;
2995 int r;
2996
d5099efc 2997 pid_set = set_new(NULL);
82659fd7
LP
2998 if (!pid_set)
2999 return NULL;
3000
3001 /* Exclude the main/control pids from being killed via the cgroup */
3002 if (main_pid > 0) {
3003 r = set_put(pid_set, LONG_TO_PTR(main_pid));
3004 if (r < 0)
3005 goto fail;
3006 }
3007
3008 if (control_pid > 0) {
3009 r = set_put(pid_set, LONG_TO_PTR(control_pid));
3010 if (r < 0)
3011 goto fail;
3012 }
3013
3014 return pid_set;
3015
3016fail:
3017 set_free(pid_set);
3018 return NULL;
3019}
3020
d91c34f2
LP
3021int unit_kill_common(
3022 Unit *u,
3023 KillWho who,
3024 int signo,
3025 pid_t main_pid,
3026 pid_t control_pid,
718db961 3027 sd_bus_error *error) {
d91c34f2 3028
814cc562
MS
3029 int r = 0;
3030
3031 if (who == KILL_MAIN && main_pid <= 0) {
3032 if (main_pid < 0)
7358dc02 3033 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
814cc562 3034 else
7358dc02 3035 return sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
814cc562
MS
3036 }
3037
3038 if (who == KILL_CONTROL && control_pid <= 0) {
3039 if (control_pid < 0)
7358dc02 3040 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
814cc562 3041 else
7358dc02 3042 return sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
814cc562
MS
3043 }
3044
3045 if (who == KILL_CONTROL || who == KILL_ALL)
3046 if (control_pid > 0)
3047 if (kill(control_pid, signo) < 0)
3048 r = -errno;
3049
3050 if (who == KILL_MAIN || who == KILL_ALL)
3051 if (main_pid > 0)
3052 if (kill(main_pid, signo) < 0)
3053 r = -errno;
3054
4ad49000 3055 if (who == KILL_ALL && u->cgroup_path) {
814cc562
MS
3056 _cleanup_set_free_ Set *pid_set = NULL;
3057 int q;
3058
82659fd7
LP
3059 /* Exclude the main/control pids from being killed via the cgroup */
3060 pid_set = unit_pid_set(main_pid, control_pid);
814cc562
MS
3061 if (!pid_set)
3062 return -ENOMEM;
3063
4ad49000 3064 q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
814cc562
MS
3065 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
3066 r = q;
3067 }
3068
3069 return r;
3070}
3071
6210e7fc
LP
3072int unit_following_set(Unit *u, Set **s) {
3073 assert(u);
3074 assert(s);
3075
3076 if (UNIT_VTABLE(u)->following_set)
3077 return UNIT_VTABLE(u)->following_set(u, s);
3078
3079 *s = NULL;
3080 return 0;
3081}
3082
a4375746
LP
3083UnitFileState unit_get_unit_file_state(Unit *u) {
3084 assert(u);
3085
ac155bb8
MS
3086 if (u->unit_file_state < 0 && u->fragment_path)
3087 u->unit_file_state = unit_file_get_state(
67445f4e 3088 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
2b6bf07d 3089 NULL, basename(u->fragment_path));
a4375746 3090
ac155bb8 3091 return u->unit_file_state;
a4375746
LP
3092}
3093
d2dc52db
LP
3094int unit_get_unit_file_preset(Unit *u) {
3095 assert(u);
3096
3097 if (u->unit_file_preset < 0 && u->fragment_path)
3098 u->unit_file_preset = unit_file_query_preset(
3099 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
3100 NULL, basename(u->fragment_path));
3101
3102 return u->unit_file_preset;
3103}
3104
57020a3a
LP
3105Unit* unit_ref_set(UnitRef *ref, Unit *u) {
3106 assert(ref);
3107 assert(u);
3108
3109 if (ref->unit)
3110 unit_ref_unset(ref);
3111
3112 ref->unit = u;
71fda00f 3113 LIST_PREPEND(refs, u->refs, ref);
57020a3a
LP
3114 return u;
3115}
3116
3117void unit_ref_unset(UnitRef *ref) {
3118 assert(ref);
3119
3120 if (!ref->unit)
3121 return;
3122
71fda00f 3123 LIST_REMOVE(refs, ref->unit->refs, ref);
57020a3a
LP
3124 ref->unit = NULL;
3125}
3126
598459ce
LP
3127int unit_patch_contexts(Unit *u) {
3128 CGroupContext *cc;
3129 ExecContext *ec;
cba6e062
LP
3130 unsigned i;
3131 int r;
3132
e06c73cc 3133 assert(u);
e06c73cc 3134
598459ce
LP
3135 /* Patch in the manager defaults into the exec and cgroup
3136 * contexts, _after_ the rest of the settings have been
3137 * initialized */
085afe36 3138
598459ce
LP
3139 ec = unit_get_exec_context(u);
3140 if (ec) {
3141 /* This only copies in the ones that need memory */
3142 for (i = 0; i < _RLIMIT_MAX; i++)
3143 if (u->manager->rlimit[i] && !ec->rlimit[i]) {
3144 ec->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
3145 if (!ec->rlimit[i])
3146 return -ENOMEM;
3147 }
3148
3149 if (u->manager->running_as == SYSTEMD_USER &&
3150 !ec->working_directory) {
3151
3152 r = get_home_dir(&ec->working_directory);
3153 if (r < 0)
3154 return r;
cba6e062
LP
3155 }
3156
598459ce
LP
3157 if (u->manager->running_as == SYSTEMD_USER &&
3158 (ec->syscall_whitelist ||
3159 !set_isempty(ec->syscall_filter) ||
3160 !set_isempty(ec->syscall_archs) ||
3161 ec->address_families_whitelist ||
3162 !set_isempty(ec->address_families)))
3163 ec->no_new_privileges = true;
e06c73cc 3164
598459ce
LP
3165 if (ec->private_devices)
3166 ec->capability_bounding_set_drop |= (uint64_t) 1ULL << (uint64_t) CAP_MKNOD;
cba6e062
LP
3167 }
3168
598459ce
LP
3169 cc = unit_get_cgroup_context(u);
3170 if (cc) {
f513e420 3171
598459ce
LP
3172 if (ec &&
3173 ec->private_devices &&
3174 cc->device_policy == CGROUP_AUTO)
3175 cc->device_policy = CGROUP_CLOSED;
3176 }
f1660f96 3177
cba6e062 3178 return 0;
e06c73cc
LP
3179}
3180
3ef63c31
LP
3181ExecContext *unit_get_exec_context(Unit *u) {
3182 size_t offset;
3183 assert(u);
3184
598459ce
LP
3185 if (u->type < 0)
3186 return NULL;
3187
3ef63c31
LP
3188 offset = UNIT_VTABLE(u)->exec_context_offset;
3189 if (offset <= 0)
3190 return NULL;
3191
3192 return (ExecContext*) ((uint8_t*) u + offset);
3193}
3194
718db961
LP
3195KillContext *unit_get_kill_context(Unit *u) {
3196 size_t offset;
3197 assert(u);
3198
598459ce
LP
3199 if (u->type < 0)
3200 return NULL;
3201
718db961
LP
3202 offset = UNIT_VTABLE(u)->kill_context_offset;
3203 if (offset <= 0)
3204 return NULL;
3205
3206 return (KillContext*) ((uint8_t*) u + offset);
3207}
3208
4ad49000
LP
3209CGroupContext *unit_get_cgroup_context(Unit *u) {
3210 size_t offset;
3211
598459ce
LP
3212 if (u->type < 0)
3213 return NULL;
3214
4ad49000
LP
3215 offset = UNIT_VTABLE(u)->cgroup_context_offset;
3216 if (offset <= 0)
3217 return NULL;
3218
3219 return (CGroupContext*) ((uint8_t*) u + offset);
3220}
3221
613b411c
LP
3222ExecRuntime *unit_get_exec_runtime(Unit *u) {
3223 size_t offset;
3224
598459ce
LP
3225 if (u->type < 0)
3226 return NULL;
3227
613b411c
LP
3228 offset = UNIT_VTABLE(u)->exec_runtime_offset;
3229 if (offset <= 0)
3230 return NULL;
3231
3232 return *(ExecRuntime**) ((uint8_t*) u + offset);
3233}
3234
29686440 3235static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient, char **dir) {
26d04f86 3236 if (u->manager->running_as == SYSTEMD_USER) {
29686440 3237 int r;
26d04f86 3238
718880ba
SA
3239 if (mode == UNIT_PERSISTENT && !transient)
3240 r = user_config_home(dir);
3241 else
4d5dec23 3242 r = user_runtime_dir(dir);
718880ba 3243
26d04f86
LP
3244 if (r == 0)
3245 return -ENOENT;
29686440
ZJS
3246 return r;
3247 }
26d04f86 3248
29686440
ZJS
3249 if (mode == UNIT_PERSISTENT && !transient)
3250 *dir = strdup("/etc/systemd/system");
8e2af478 3251 else
29686440
ZJS
3252 *dir = strdup("/run/systemd/system");
3253 if (!*dir)
71645aca
LP
3254 return -ENOMEM;
3255
26d04f86 3256 return 0;
71645aca
LP
3257}
3258
29686440
ZJS
3259static int unit_drop_in_file(Unit *u,
3260 UnitSetPropertiesMode mode, const char *name, char **p, char **q) {
3261 _cleanup_free_ char *dir = NULL;
3262 int r;
3263
3264 assert(u);
3265
3266 r = unit_drop_in_dir(u, mode, u->transient, &dir);
3267 if (r < 0)
3268 return r;
3269
8eea8687 3270 return drop_in_file(dir, u->id, 50, name, p, q);
29686440
ZJS
3271}
3272
8e2af478 3273int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
29686440 3274
adb76a70 3275 _cleanup_free_ char *dir = NULL, *p = NULL, *q = NULL;
26d04f86 3276 int r;
71645aca
LP
3277
3278 assert(u);
3279
6d235724 3280 if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
8e2af478
LP
3281 return 0;
3282
29686440 3283 r = unit_drop_in_dir(u, mode, u->transient, &dir);
26d04f86
LP
3284 if (r < 0)
3285 return r;
71645aca 3286
adb76a70
WC
3287 r = write_drop_in(dir, u->id, 50, name, data);
3288 if (r < 0)
3289 return r;
3290
3291 r = drop_in_file(dir, u->id, 50, name, &p, &q);
3292 if (r < 0)
3293 return r;
3294
3295 r = strv_extend(&u->dropin_paths, q);
3296 if (r < 0)
3297 return r;
3298
3299 strv_sort(u->dropin_paths);
3300 strv_uniq(u->dropin_paths);
3301
3302 u->dropin_mtime = now(CLOCK_REALTIME);
3303
3304 return 0;
26d04f86 3305}
71645aca 3306
b9ec9359
LP
3307int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
3308 _cleanup_free_ char *p = NULL;
3309 va_list ap;
3310 int r;
3311
3312 assert(u);
3313 assert(name);
3314 assert(format);
3315
6d235724 3316 if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
b9ec9359
LP
3317 return 0;
3318
3319 va_start(ap, format);
3320 r = vasprintf(&p, format, ap);
3321 va_end(ap);
3322
3323 if (r < 0)
3324 return -ENOMEM;
3325
3326 return unit_write_drop_in(u, mode, name, p);
3327}
3328
3329int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
b42defe3
LP
3330 _cleanup_free_ char *ndata = NULL;
3331
3332 assert(u);
3333 assert(name);
3334 assert(data);
3335
3336 if (!UNIT_VTABLE(u)->private_section)
3337 return -EINVAL;
3338
6d235724 3339 if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
b9ec9359
LP
3340 return 0;
3341
b42defe3
LP
3342 ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
3343 if (!ndata)
3344 return -ENOMEM;
3345
3346 return unit_write_drop_in(u, mode, name, ndata);
3347}
3348
b9ec9359
LP
3349int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
3350 _cleanup_free_ char *p = NULL;
3351 va_list ap;
3352 int r;
3353
3354 assert(u);
3355 assert(name);
3356 assert(format);
3357
6d235724 3358 if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
b9ec9359
LP
3359 return 0;
3360
3361 va_start(ap, format);
3362 r = vasprintf(&p, format, ap);
3363 va_end(ap);
3364
3365 if (r < 0)
3366 return -ENOMEM;
3367
3368 return unit_write_drop_in_private(u, mode, name, p);
3369}
3370
8e2af478 3371int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
26d04f86
LP
3372 _cleanup_free_ char *p = NULL, *q = NULL;
3373 int r;
71645aca 3374
26d04f86 3375 assert(u);
71645aca 3376
6d235724 3377 if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME))
8e2af478
LP
3378 return 0;
3379
29686440 3380 r = unit_drop_in_file(u, mode, name, &p, &q);
6891529f
ZJS
3381 if (r < 0)
3382 return r;
3383
71645aca 3384 if (unlink(q) < 0)
241da328 3385 r = errno == ENOENT ? 0 : -errno;
26d04f86 3386 else
241da328 3387 r = 1;
71645aca
LP
3388
3389 rmdir(p);
26d04f86 3390 return r;
71645aca
LP
3391}
3392
c2756a68
LP
3393int unit_make_transient(Unit *u) {
3394 int r;
3395
3396 assert(u);
3397
3398 u->load_state = UNIT_STUB;
3399 u->load_error = 0;
3400 u->transient = true;
3401
3402 free(u->fragment_path);
3403 u->fragment_path = NULL;
3404
3405 if (u->manager->running_as == SYSTEMD_USER) {
3406 _cleanup_free_ char *c = NULL;
3407
4d5dec23 3408 r = user_runtime_dir(&c);
c2756a68
LP
3409 if (r < 0)
3410 return r;
3411 if (r == 0)
3412 return -ENOENT;
3413
3414 u->fragment_path = strjoin(c, "/", u->id, NULL);
3415 if (!u->fragment_path)
3416 return -ENOMEM;
3417
3418 mkdir_p(c, 0755);
3419 } else {
3420 u->fragment_path = strappend("/run/systemd/system/", u->id);
3421 if (!u->fragment_path)
3422 return -ENOMEM;
3423
3424 mkdir_p("/run/systemd/system", 0755);
3425 }
3426
3427 return write_string_file_atomic_label(u->fragment_path, "# Transient stub");
3428}
3429
cd2086fe
LP
3430int unit_kill_context(
3431 Unit *u,
3432 KillContext *c,
db2cb23b 3433 KillOperation k,
cd2086fe
LP
3434 pid_t main_pid,
3435 pid_t control_pid,
3436 bool main_pid_alien) {
3437
bc6aed7b 3438 int sig, wait_for_exit = false, r;
cd2086fe
LP
3439
3440 assert(u);
3441 assert(c);
3442
3443 if (c->kill_mode == KILL_NONE)
3444 return 0;
3445
db2cb23b
UTL
3446 switch (k) {
3447 case KILL_KILL:
3448 sig = SIGKILL;
3449 break;
3450 case KILL_ABORT:
3451 sig = SIGABRT;
3452 break;
3453 case KILL_TERMINATE:
3454 sig = c->kill_signal;
3455 break;
3456 default:
3457 assert_not_reached("KillOperation unknown");
3458 }
cd2086fe
LP
3459
3460 if (main_pid > 0) {
3461 r = kill_and_sigcont(main_pid, sig);
3462
3463 if (r < 0 && r != -ESRCH) {
3464 _cleanup_free_ char *comm = NULL;
3465 get_process_comm(main_pid, &comm);
3466
31938a85 3467 log_unit_warning_errno(u->id, r, "Failed to kill main process " PID_FMT " (%s): %m", main_pid, strna(comm));
82659fd7 3468 } else {
bc6aed7b
LP
3469 if (!main_pid_alien)
3470 wait_for_exit = true;
82659fd7 3471
db2cb23b 3472 if (c->send_sighup && k != KILL_KILL)
82659fd7
LP
3473 kill(main_pid, SIGHUP);
3474 }
cd2086fe
LP
3475 }
3476
3477 if (control_pid > 0) {
3478 r = kill_and_sigcont(control_pid, sig);
3479
3480 if (r < 0 && r != -ESRCH) {
3481 _cleanup_free_ char *comm = NULL;
3482 get_process_comm(control_pid, &comm);
3483
31938a85 3484 log_unit_warning_errno(u->id, r, "Failed to kill control process " PID_FMT " (%s): %m", control_pid, strna(comm));
82659fd7 3485 } else {
cd2086fe 3486 wait_for_exit = true;
82659fd7 3487
db2cb23b 3488 if (c->send_sighup && k != KILL_KILL)
82659fd7
LP
3489 kill(control_pid, SIGHUP);
3490 }
cd2086fe
LP
3491 }
3492
db2cb23b 3493 if ((c->kill_mode == KILL_CONTROL_GROUP || (c->kill_mode == KILL_MIXED && k == KILL_KILL)) && u->cgroup_path) {
cd2086fe
LP
3494 _cleanup_set_free_ Set *pid_set = NULL;
3495
82659fd7
LP
3496 /* Exclude the main/control pids from being killed via the cgroup */
3497 pid_set = unit_pid_set(main_pid, control_pid);
cd2086fe
LP
3498 if (!pid_set)
3499 return -ENOMEM;
3500
4ad49000 3501 r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set);
cd2086fe
LP
3502 if (r < 0) {
3503 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
31938a85 3504 log_unit_warning_errno(u->id, r, "Failed to kill control group: %m");
82659fd7 3505 } else if (r > 0) {
bc6aed7b 3506
743970d2
LP
3507 /* FIXME: For now, we will not wait for the
3508 * cgroup members to die, simply because
3509 * cgroup notification is unreliable. It
3510 * doesn't work at all in containers, and
3511 * outside of containers it can be confused
3512 * easily by leaving directories in the
3513 * cgroup. */
3514
3515 /* wait_for_exit = true; */
58ea275a 3516
db2cb23b 3517 if (c->send_sighup && k != KILL_KILL) {
82659fd7
LP
3518 set_free(pid_set);
3519
3520 pid_set = unit_pid_set(main_pid, control_pid);
3521 if (!pid_set)
3522 return -ENOMEM;
3523
8190da36 3524 cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, SIGHUP, false, true, false, pid_set);
82659fd7
LP
3525 }
3526 }
cd2086fe
LP
3527 }
3528
3529 return wait_for_exit;
3530}
3531
a57f7e2c
LP
3532int unit_require_mounts_for(Unit *u, const char *path) {
3533 char prefix[strlen(path) + 1], *p;
3534 int r;
3535
3536 assert(u);
3537 assert(path);
3538
3539 /* Registers a unit for requiring a certain path and all its
3540 * prefixes. We keep a simple array of these paths in the
3541 * unit, since its usually short. However, we build a prefix
3542 * table for all possible prefixes so that new appearing mount
3543 * units can easily determine which units to make themselves a
3544 * dependency of. */
3545
70b64bd3
ZJS
3546 if (!path_is_absolute(path))
3547 return -EINVAL;
3548
a57f7e2c
LP
3549 p = strdup(path);
3550 if (!p)
3551 return -ENOMEM;
3552
3553 path_kill_slashes(p);
3554
a57f7e2c
LP
3555 if (!path_is_safe(p)) {
3556 free(p);
3557 return -EPERM;
3558 }
3559
3560 if (strv_contains(u->requires_mounts_for, p)) {
3561 free(p);
3562 return 0;
3563 }
3564
6e18964d
ZJS
3565 r = strv_consume(&u->requires_mounts_for, p);
3566 if (r < 0)
a57f7e2c 3567 return r;
a57f7e2c
LP
3568
3569 PATH_FOREACH_PREFIX_MORE(prefix, p) {
3570 Set *x;
3571
3572 x = hashmap_get(u->manager->units_requiring_mounts_for, prefix);
3573 if (!x) {
3574 char *q;
3575
3576 if (!u->manager->units_requiring_mounts_for) {
d5099efc 3577 u->manager->units_requiring_mounts_for = hashmap_new(&string_hash_ops);
a57f7e2c
LP
3578 if (!u->manager->units_requiring_mounts_for)
3579 return -ENOMEM;
3580 }
3581
3582 q = strdup(prefix);
3583 if (!q)
3584 return -ENOMEM;
3585
d5099efc 3586 x = set_new(NULL);
a57f7e2c
LP
3587 if (!x) {
3588 free(q);
3589 return -ENOMEM;
3590 }
3591
3592 r = hashmap_put(u->manager->units_requiring_mounts_for, q, x);
3593 if (r < 0) {
3594 free(q);
3595 set_free(x);
3596 return r;
3597 }
3598 }
3599
3600 r = set_put(x, u);
3601 if (r < 0)
3602 return r;
3603 }
3604
3605 return 0;
3606}
3607
613b411c
LP
3608int unit_setup_exec_runtime(Unit *u) {
3609 ExecRuntime **rt;
3610 size_t offset;
3611 Iterator i;
3612 Unit *other;
3613
3614 offset = UNIT_VTABLE(u)->exec_runtime_offset;
3615 assert(offset > 0);
3616
06b643e7 3617 /* Check if there already is an ExecRuntime for this unit? */
613b411c
LP
3618 rt = (ExecRuntime**) ((uint8_t*) u + offset);
3619 if (*rt)
3620 return 0;
3621
3622 /* Try to get it from somebody else */
3623 SET_FOREACH(other, u->dependencies[UNIT_JOINS_NAMESPACE_OF], i) {
3624
3625 *rt = unit_get_exec_runtime(other);
3626 if (*rt) {
3627 exec_runtime_ref(*rt);
3628 return 0;
3629 }
3630 }
3631
3632 return exec_runtime_make(rt, unit_get_exec_context(u), u->id);
3633}
3634
94f04347
LP
3635static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
3636 [UNIT_ACTIVE] = "active",
032ff4af 3637 [UNIT_RELOADING] = "reloading",
94f04347 3638 [UNIT_INACTIVE] = "inactive",
fdf20a31 3639 [UNIT_FAILED] = "failed",
94f04347
LP
3640 [UNIT_ACTIVATING] = "activating",
3641 [UNIT_DEACTIVATING] = "deactivating"
3642};
3643
3644DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);