]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/unit.c
systemd: log failed conditions
[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
877d54e9
LP
32#include "systemd/sd-id128.h"
33#include "systemd/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"
814cc562 50#include "bus-errors.h"
87f0e418
LP
51
52const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
53 [UNIT_SERVICE] = &service_vtable,
54 [UNIT_TIMER] = &timer_vtable,
55 [UNIT_SOCKET] = &socket_vtable,
56 [UNIT_TARGET] = &target_vtable,
57 [UNIT_DEVICE] = &device_vtable,
58 [UNIT_MOUNT] = &mount_vtable,
59 [UNIT_AUTOMOUNT] = &automount_vtable,
07b0b134 60 [UNIT_SNAPSHOT] = &snapshot_vtable,
01f78473 61 [UNIT_SWAP] = &swap_vtable,
a016b922 62 [UNIT_PATH] = &path_vtable,
6c12b52e
LP
63 [UNIT_SLICE] = &slice_vtable,
64 [UNIT_SCOPE] = &scope_vtable
87f0e418
LP
65};
66
7d17cfbc 67Unit *unit_new(Manager *m, size_t size) {
87f0e418
LP
68 Unit *u;
69
70 assert(m);
ac155bb8 71 assert(size >= sizeof(Unit));
87f0e418 72
7d17cfbc
MS
73 u = malloc0(size);
74 if (!u)
87f0e418
LP
75 return NULL;
76
ac155bb8
MS
77 u->names = set_new(string_hash_func, string_compare_func);
78 if (!u->names) {
87f0e418
LP
79 free(u);
80 return NULL;
81 }
82
ac155bb8
MS
83 u->manager = m;
84 u->type = _UNIT_TYPE_INVALID;
85 u->deserialized_job = _JOB_TYPE_INVALID;
86 u->default_dependencies = true;
87 u->unit_file_state = _UNIT_FILE_STATE_INVALID;
87f0e418
LP
88
89 return u;
90}
91
f278026d
LP
92bool unit_has_name(Unit *u, const char *name) {
93 assert(u);
94 assert(name);
95
ac155bb8 96 return !!set_get(u->names, (char*) name);
f278026d
LP
97}
98
87f0e418
LP
99int unit_add_name(Unit *u, const char *text) {
100 UnitType t;
276c3e78 101 char *s, *i = NULL;
87f0e418
LP
102 int r;
103
104 assert(u);
105 assert(text);
106
9e2f7c11 107 if (unit_name_is_template(text)) {
ac155bb8 108 if (!u->instance)
9e2f7c11 109 return -EINVAL;
87f0e418 110
ac155bb8 111 s = unit_name_replace_instance(text, u->instance);
9e2f7c11
LP
112 } else
113 s = strdup(text);
87f0e418 114
9e2f7c11
LP
115 if (!s)
116 return -ENOMEM;
87f0e418 117
b9c0d441 118 if (!unit_name_is_valid(s, false)) {
9e2f7c11
LP
119 r = -EINVAL;
120 goto fail;
121 }
e537352b 122
9e2f7c11 123 assert_se((t = unit_name_to_type(s)) >= 0);
87f0e418 124
ac155bb8 125 if (u->type != _UNIT_TYPE_INVALID && t != u->type) {
9e2f7c11
LP
126 r = -EINVAL;
127 goto fail;
128 }
87f0e418 129
9e2f7c11
LP
130 if ((r = unit_name_to_instance(s, &i)) < 0)
131 goto fail;
87f0e418 132
796ba554
LP
133 if (i && unit_vtable[t]->no_instances) {
134 r = -EINVAL;
9e2f7c11 135 goto fail;
796ba554 136 }
9e2f7c11 137
276c3e78
LP
138 /* Ensure that this unit is either instanced or not instanced,
139 * but not both. */
ac155bb8 140 if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) {
9e2f7c11
LP
141 r = -EINVAL;
142 goto fail;
143 }
144
145 if (unit_vtable[t]->no_alias &&
ac155bb8
MS
146 !set_isempty(u->names) &&
147 !set_get(u->names, s)) {
9e2f7c11
LP
148 r = -EEXIST;
149 goto fail;
150 }
151
ac155bb8 152 if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) {
4f0f902f
LP
153 r = -E2BIG;
154 goto fail;
155 }
156
ac155bb8 157 if ((r = set_put(u->names, s)) < 0) {
9e2f7c11
LP
158 if (r == -EEXIST)
159 r = 0;
160 goto fail;
87f0e418
LP
161 }
162
ac155bb8
MS
163 if ((r = hashmap_put(u->manager->units, s, u)) < 0) {
164 set_remove(u->names, s);
9e2f7c11 165 goto fail;
87f0e418
LP
166 }
167
ac155bb8 168 if (u->type == _UNIT_TYPE_INVALID) {
ef734fd6 169
ac155bb8
MS
170 u->type = t;
171 u->id = s;
172 u->instance = i;
9e2f7c11 173
ac155bb8 174 LIST_PREPEND(Unit, units_by_type, u->manager->units_by_type[t], u);
e537352b
LP
175
176 if (UNIT_VTABLE(u)->init)
177 UNIT_VTABLE(u)->init(u);
9e2f7c11
LP
178 } else
179 free(i);
87f0e418 180
c1e1601e 181 unit_add_to_dbus_queue(u);
87f0e418 182 return 0;
9e2f7c11
LP
183
184fail:
185 free(s);
186 free(i);
187
188 return r;
87f0e418
LP
189}
190
0ae97ec1 191int unit_choose_id(Unit *u, const char *name) {
276c3e78
LP
192 char *s, *t = NULL, *i;
193 int r;
0ae97ec1
LP
194
195 assert(u);
196 assert(name);
197
9e2f7c11
LP
198 if (unit_name_is_template(name)) {
199
ac155bb8 200 if (!u->instance)
9e2f7c11
LP
201 return -EINVAL;
202
ac155bb8 203 if (!(t = unit_name_replace_instance(name, u->instance)))
9e2f7c11
LP
204 return -ENOMEM;
205
206 name = t;
207 }
208
0ae97ec1 209 /* Selects one of the names of this unit as the id */
ac155bb8 210 s = set_get(u->names, (char*) name);
9e2f7c11 211 free(t);
0ae97ec1 212
9e2f7c11 213 if (!s)
0ae97ec1
LP
214 return -ENOENT;
215
276c3e78
LP
216 if ((r = unit_name_to_instance(s, &i)) < 0)
217 return r;
218
ac155bb8 219 u->id = s;
276c3e78 220
ac155bb8
MS
221 free(u->instance);
222 u->instance = i;
276c3e78 223
c1e1601e 224 unit_add_to_dbus_queue(u);
9e2f7c11 225
0ae97ec1
LP
226 return 0;
227}
228
f50e0a01
LP
229int unit_set_description(Unit *u, const char *description) {
230 char *s;
231
232 assert(u);
233
8aec412f
LP
234 if (isempty(description))
235 s = NULL;
236 else {
237 s = strdup(description);
238 if (!s)
239 return -ENOMEM;
240 }
f50e0a01 241
ac155bb8
MS
242 free(u->description);
243 u->description = s;
c1e1601e
LP
244
245 unit_add_to_dbus_queue(u);
f50e0a01
LP
246 return 0;
247}
248
701cc384
LP
249bool unit_check_gc(Unit *u) {
250 assert(u);
251
ac155bb8 252 if (u->load_state == UNIT_STUB)
b86d44e5
LP
253 return true;
254
701cc384
LP
255 if (UNIT_VTABLE(u)->no_gc)
256 return true;
257
ac155bb8 258 if (u->no_gc)
6c073082
LP
259 return true;
260
ac155bb8 261 if (u->job)
701cc384
LP
262 return true;
263
e0209d83
MS
264 if (u->nop_job)
265 return true;
266
701cc384
LP
267 if (unit_active_state(u) != UNIT_INACTIVE)
268 return true;
269
9d576438
LP
270 if (u->refs)
271 return true;
272
701cc384
LP
273 if (UNIT_VTABLE(u)->check_gc)
274 if (UNIT_VTABLE(u)->check_gc(u))
275 return true;
276
277 return false;
278}
279
87f0e418
LP
280void unit_add_to_load_queue(Unit *u) {
281 assert(u);
ac155bb8 282 assert(u->type != _UNIT_TYPE_INVALID);
87f0e418 283
ac155bb8 284 if (u->load_state != UNIT_STUB || u->in_load_queue)
87f0e418
LP
285 return;
286
ac155bb8
MS
287 LIST_PREPEND(Unit, load_queue, u->manager->load_queue, u);
288 u->in_load_queue = true;
87f0e418
LP
289}
290
23a177ef
LP
291void unit_add_to_cleanup_queue(Unit *u) {
292 assert(u);
293
ac155bb8 294 if (u->in_cleanup_queue)
23a177ef
LP
295 return;
296
ac155bb8
MS
297 LIST_PREPEND(Unit, cleanup_queue, u->manager->cleanup_queue, u);
298 u->in_cleanup_queue = true;
23a177ef
LP
299}
300
701cc384
LP
301void unit_add_to_gc_queue(Unit *u) {
302 assert(u);
303
ac155bb8 304 if (u->in_gc_queue || u->in_cleanup_queue)
701cc384
LP
305 return;
306
307 if (unit_check_gc(u))
308 return;
309
ac155bb8
MS
310 LIST_PREPEND(Unit, gc_queue, u->manager->gc_queue, u);
311 u->in_gc_queue = true;
701cc384 312
ac155bb8 313 u->manager->n_in_gc_queue ++;
701cc384
LP
314}
315
c1e1601e
LP
316void unit_add_to_dbus_queue(Unit *u) {
317 assert(u);
ac155bb8 318 assert(u->type != _UNIT_TYPE_INVALID);
c1e1601e 319
ac155bb8 320 if (u->load_state == UNIT_STUB || u->in_dbus_queue)
c1e1601e
LP
321 return;
322
a567261a 323 /* Shortcut things if nobody cares */
ac155bb8
MS
324 if (!bus_has_subscriber(u->manager)) {
325 u->sent_dbus_new_signal = true;
94b6dfa2
LP
326 return;
327 }
328
ac155bb8
MS
329 LIST_PREPEND(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
330 u->in_dbus_queue = true;
c1e1601e
LP
331}
332
87f0e418
LP
333static void bidi_set_free(Unit *u, Set *s) {
334 Iterator i;
335 Unit *other;
336
337 assert(u);
338
339 /* Frees the set and makes sure we are dropped from the
340 * inverse pointers */
341
342 SET_FOREACH(other, s, i) {
343 UnitDependency d;
344
345 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
ac155bb8 346 set_remove(other->dependencies[d], u);
701cc384
LP
347
348 unit_add_to_gc_queue(other);
87f0e418
LP
349 }
350
351 set_free(s);
352}
353
c2756a68
LP
354static void unit_remove_transient(Unit *u) {
355 char **i;
356
357 assert(u);
358
359 if (!u->transient)
360 return;
361
362 if (u->fragment_path)
363 unlink(u->fragment_path);
364
365 STRV_FOREACH(i, u->dropin_paths) {
366 _cleanup_free_ char *p = NULL;
367 int r;
368
369 unlink(*i);
370
371 r = path_get_parent(*i, &p);
372 if (r >= 0)
373 rmdir(p);
374 }
375}
376
87f0e418
LP
377void unit_free(Unit *u) {
378 UnitDependency d;
379 Iterator i;
380 char *t;
381
382 assert(u);
383
c2756a68
LP
384 if (u->manager->n_reloading <= 0)
385 unit_remove_transient(u);
386
c1e1601e
LP
387 bus_unit_send_removed_signal(u);
388
ac155bb8 389 if (u->load_state != UNIT_STUB)
a013b84b
LP
390 if (UNIT_VTABLE(u)->done)
391 UNIT_VTABLE(u)->done(u);
392
ac155bb8
MS
393 SET_FOREACH(t, u->names, i)
394 hashmap_remove_value(u->manager->units, t, u);
87f0e418 395
97e7d748
MS
396 if (u->job) {
397 Job *j = u->job;
398 job_uninstall(j);
399 job_free(j);
400 }
964e0949 401
e0209d83
MS
402 if (u->nop_job) {
403 Job *j = u->nop_job;
404 job_uninstall(j);
405 job_free(j);
406 }
407
964e0949 408 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
ac155bb8 409 bidi_set_free(u, u->dependencies[d]);
964e0949 410
7c8fa05c
LP
411 if (u->requires_mounts_for) {
412 LIST_REMOVE(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u);
413 strv_free(u->requires_mounts_for);
414 }
415
ac155bb8
MS
416 if (u->type != _UNIT_TYPE_INVALID)
417 LIST_REMOVE(Unit, units_by_type, u->manager->units_by_type[u->type], u);
ef734fd6 418
ac155bb8
MS
419 if (u->in_load_queue)
420 LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u);
87f0e418 421
ac155bb8
MS
422 if (u->in_dbus_queue)
423 LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
c1e1601e 424
ac155bb8
MS
425 if (u->in_cleanup_queue)
426 LIST_REMOVE(Unit, cleanup_queue, u->manager->cleanup_queue, u);
23a177ef 427
ac155bb8
MS
428 if (u->in_gc_queue) {
429 LIST_REMOVE(Unit, gc_queue, u->manager->gc_queue, u);
430 u->manager->n_in_gc_queue--;
701cc384
LP
431 }
432
4ad49000
LP
433 if (u->in_cgroup_queue)
434 LIST_REMOVE(Unit, cgroup_queue, u->manager->cgroup_queue, u);
87f0e418 435
72673e86
LP
436 if (u->cgroup_path) {
437 hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
438 free(u->cgroup_path);
439 }
440
ac155bb8 441 free(u->description);
49dbfa7b 442 strv_free(u->documentation);
ac155bb8 443 free(u->fragment_path);
1b64d026 444 free(u->source_path);
ae7a7182 445 strv_free(u->dropin_paths);
ac155bb8 446 free(u->instance);
87f0e418 447
ac155bb8 448 set_free_free(u->names);
87f0e418 449
ac155bb8 450 condition_free_list(u->conditions);
52661efd 451
702a2d8f
LP
452 unit_ref_unset(&u->slice);
453
ac155bb8
MS
454 while (u->refs)
455 unit_ref_unset(u->refs);
57020a3a 456
87f0e418
LP
457 free(u);
458}
459
460UnitActiveState unit_active_state(Unit *u) {
461 assert(u);
462
ac155bb8 463 if (u->load_state == UNIT_MERGED)
6124958c
LP
464 return unit_active_state(unit_follow_merge(u));
465
466 /* After a reload it might happen that a unit is not correctly
467 * loaded but still has a process around. That's why we won't
fdf20a31 468 * shortcut failed loading to UNIT_INACTIVE_FAILED. */
87f0e418
LP
469
470 return UNIT_VTABLE(u)->active_state(u);
471}
472
10a94420
LP
473const char* unit_sub_state_to_string(Unit *u) {
474 assert(u);
475
476 return UNIT_VTABLE(u)->sub_state_to_string(u);
477}
478
23a177ef
LP
479static void complete_move(Set **s, Set **other) {
480 assert(s);
481 assert(other);
87f0e418 482
23a177ef
LP
483 if (!*other)
484 return;
87f0e418
LP
485
486 if (*s)
23a177ef
LP
487 set_move(*s, *other);
488 else {
489 *s = *other;
490 *other = NULL;
491 }
492}
87f0e418 493
23a177ef
LP
494static void merge_names(Unit *u, Unit *other) {
495 char *t;
496 Iterator i;
87f0e418 497
23a177ef
LP
498 assert(u);
499 assert(other);
500
ac155bb8 501 complete_move(&u->names, &other->names);
23a177ef 502
ac155bb8
MS
503 set_free_free(other->names);
504 other->names = NULL;
505 other->id = NULL;
23a177ef 506
ac155bb8
MS
507 SET_FOREACH(t, u->names, i)
508 assert_se(hashmap_replace(u->manager->units, t, u) == 0);
87f0e418
LP
509}
510
23a177ef
LP
511static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
512 Iterator i;
513 Unit *back;
87f0e418 514 int r;
23a177ef
LP
515
516 assert(u);
517 assert(other);
518 assert(d < _UNIT_DEPENDENCY_MAX);
519
83a95334 520 /* Fix backwards pointers */
ac155bb8 521 SET_FOREACH(back, other->dependencies[d], i) {
23a177ef
LP
522 UnitDependency k;
523
524 for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++)
ac155bb8 525 if ((r = set_remove_and_put(back->dependencies[k], other, u)) < 0) {
23a177ef
LP
526
527 if (r == -EEXIST)
ac155bb8 528 set_remove(back->dependencies[k], other);
23a177ef
LP
529 else
530 assert(r == -ENOENT);
531 }
532 }
533
ac155bb8 534 complete_move(&u->dependencies[d], &other->dependencies[d]);
23a177ef 535
ac155bb8
MS
536 set_free(other->dependencies[d]);
537 other->dependencies[d] = NULL;
23a177ef
LP
538}
539
540int unit_merge(Unit *u, Unit *other) {
87f0e418
LP
541 UnitDependency d;
542
543 assert(u);
544 assert(other);
ac155bb8
MS
545 assert(u->manager == other->manager);
546 assert(u->type != _UNIT_TYPE_INVALID);
87f0e418 547
cc916967
LP
548 other = unit_follow_merge(other);
549
23a177ef
LP
550 if (other == u)
551 return 0;
552
ac155bb8 553 if (u->type != other->type)
9e2f7c11
LP
554 return -EINVAL;
555
ac155bb8 556 if (!u->instance != !other->instance)
87f0e418
LP
557 return -EINVAL;
558
ac155bb8 559 if (other->load_state != UNIT_STUB &&
c2756a68 560 other->load_state != UNIT_NOT_FOUND)
23a177ef 561 return -EEXIST;
87f0e418 562
ac155bb8 563 if (other->job)
819e213f
LP
564 return -EEXIST;
565
e0209d83
MS
566 if (other->nop_job)
567 return -EEXIST;
568
fdf20a31 569 if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
819e213f
LP
570 return -EEXIST;
571
87f0e418 572 /* Merge names */
23a177ef 573 merge_names(u, other);
87f0e418 574
57020a3a 575 /* Redirect all references */
ac155bb8
MS
576 while (other->refs)
577 unit_ref_set(other->refs, u);
57020a3a 578
87f0e418
LP
579 /* Merge dependencies */
580 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
23a177ef 581 merge_dependencies(u, other, d);
87f0e418 582
ac155bb8
MS
583 other->load_state = UNIT_MERGED;
584 other->merged_into = u;
23a177ef 585
3616a49c
LP
586 /* If there is still some data attached to the other node, we
587 * don't need it anymore, and can free it. */
ac155bb8 588 if (other->load_state != UNIT_STUB)
3616a49c
LP
589 if (UNIT_VTABLE(other)->done)
590 UNIT_VTABLE(other)->done(other);
591
592 unit_add_to_dbus_queue(u);
23a177ef
LP
593 unit_add_to_cleanup_queue(other);
594
595 return 0;
596}
597
598int unit_merge_by_name(Unit *u, const char *name) {
599 Unit *other;
9e2f7c11
LP
600 int r;
601 char *s = NULL;
23a177ef
LP
602
603 assert(u);
604 assert(name);
605
9e2f7c11 606 if (unit_name_is_template(name)) {
ac155bb8 607 if (!u->instance)
9e2f7c11
LP
608 return -EINVAL;
609
ac155bb8 610 if (!(s = unit_name_replace_instance(name, u->instance)))
9e2f7c11
LP
611 return -ENOMEM;
612
613 name = s;
614 }
615
c2756a68
LP
616 other = manager_get_unit(u->manager, name);
617 if (!other)
9e2f7c11
LP
618 r = unit_add_name(u, name);
619 else
620 r = unit_merge(u, other);
23a177ef 621
9e2f7c11
LP
622 free(s);
623 return r;
23a177ef
LP
624}
625
626Unit* unit_follow_merge(Unit *u) {
627 assert(u);
628
ac155bb8
MS
629 while (u->load_state == UNIT_MERGED)
630 assert_se(u = u->merged_into);
23a177ef
LP
631
632 return u;
633}
634
635int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
636 int r;
637
638 assert(u);
639 assert(c);
640
ecc6e2b8
LP
641 if (c->std_output != EXEC_OUTPUT_KMSG &&
642 c->std_output != EXEC_OUTPUT_SYSLOG &&
706343f4 643 c->std_output != EXEC_OUTPUT_JOURNAL &&
28dbc1e8
LP
644 c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
645 c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
706343f4 646 c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
ecc6e2b8 647 c->std_error != EXEC_OUTPUT_KMSG &&
085c98af 648 c->std_error != EXEC_OUTPUT_SYSLOG &&
706343f4 649 c->std_error != EXEC_OUTPUT_JOURNAL &&
085c98af 650 c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
706343f4 651 c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
28dbc1e8 652 c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE)
23a177ef
LP
653 return 0;
654
655 /* If syslog or kernel logging is requested, make sure our own
656 * logging daemon is run first. */
657
9d246da3
MS
658 if (u->manager->running_as == SYSTEMD_SYSTEM) {
659 r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true);
660 if (r < 0)
23a177ef 661 return r;
9d246da3 662 }
23a177ef 663
87f0e418
LP
664 return 0;
665}
666
87f0e418
LP
667const char *unit_description(Unit *u) {
668 assert(u);
669
ac155bb8
MS
670 if (u->description)
671 return u->description;
87f0e418 672
ac155bb8 673 return strna(u->id);
87f0e418
LP
674}
675
676void unit_dump(Unit *u, FILE *f, const char *prefix) {
49dbfa7b 677 char *t, **j;
87f0e418
LP
678 UnitDependency d;
679 Iterator i;
47be870b
LP
680 char *p2;
681 const char *prefix2;
173e3821
LP
682 char
683 timestamp1[FORMAT_TIMESTAMP_MAX],
684 timestamp2[FORMAT_TIMESTAMP_MAX],
685 timestamp3[FORMAT_TIMESTAMP_MAX],
faf919f1
LP
686 timestamp4[FORMAT_TIMESTAMP_MAX],
687 timespan[FORMAT_TIMESPAN_MAX];
a7f241db 688 Unit *following;
87f0e418
LP
689
690 assert(u);
ac155bb8 691 assert(u->type >= 0);
87f0e418
LP
692
693 if (!prefix)
694 prefix = "";
47be870b
LP
695 p2 = strappend(prefix, "\t");
696 prefix2 = p2 ? p2 : prefix;
87f0e418
LP
697
698 fprintf(f,
40d50879 699 "%s-> Unit %s:\n"
87f0e418 700 "%s\tDescription: %s\n"
9e2f7c11 701 "%s\tInstance: %s\n"
87f0e418 702 "%s\tUnit Load State: %s\n"
2fad8195 703 "%s\tUnit Active State: %s\n"
173e3821 704 "%s\tInactive Exit Timestamp: %s\n"
2fad8195 705 "%s\tActive Enter Timestamp: %s\n"
701cc384 706 "%s\tActive Exit Timestamp: %s\n"
173e3821 707 "%s\tInactive Enter Timestamp: %s\n"
45fb0699 708 "%s\tGC Check Good: %s\n"
9444b1f2 709 "%s\tNeed Daemon Reload: %s\n"
c2756a68 710 "%s\tTransient: %s\n"
4ad49000
LP
711 "%s\tSlice: %s\n"
712 "%s\tCGroup: %s\n"
713 "%s\tCGroup realized: %s\n"
714 "%s\tCGroup mask: 0x%x\n",
ac155bb8 715 prefix, u->id,
87f0e418 716 prefix, unit_description(u),
ac155bb8
MS
717 prefix, strna(u->instance),
718 prefix, unit_load_state_to_string(u->load_state),
2fad8195 719 prefix, unit_active_state_to_string(unit_active_state(u)),
ac155bb8
MS
720 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->inactive_exit_timestamp.realtime)),
721 prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->active_enter_timestamp.realtime)),
722 prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)),
723 prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)),
45fb0699 724 prefix, yes_no(unit_check_gc(u)),
9444b1f2 725 prefix, yes_no(unit_need_daemon_reload(u)),
c2756a68 726 prefix, yes_no(u->transient),
4ad49000
LP
727 prefix, strna(unit_slice_name(u)),
728 prefix, strna(u->cgroup_path),
729 prefix, yes_no(u->cgroup_realized),
730 prefix, u->cgroup_mask);
0301abf4 731
ac155bb8 732 SET_FOREACH(t, u->names, i)
87f0e418
LP
733 fprintf(f, "%s\tName: %s\n", prefix, t);
734
49dbfa7b
LP
735 STRV_FOREACH(j, u->documentation)
736 fprintf(f, "%s\tDocumentation: %s\n", prefix, *j);
737
a7f241db 738 if ((following = unit_following(u)))
ac155bb8 739 fprintf(f, "%s\tFollowing: %s\n", prefix, following->id);
8fe914ec 740
ac155bb8
MS
741 if (u->fragment_path)
742 fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path);
23a177ef 743
1b64d026
LP
744 if (u->source_path)
745 fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path);
746
ae7a7182 747 STRV_FOREACH(j, u->dropin_paths)
2875e22b 748 fprintf(f, "%s\tDropIn Path: %s\n", prefix, *j);
ae7a7182 749
ac155bb8 750 if (u->job_timeout > 0)
2fa4092c 751 fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
faf919f1 752
ac155bb8 753 condition_dump_list(u->conditions, f, prefix);
52661efd 754
ac155bb8 755 if (dual_timestamp_is_set(&u->condition_timestamp))
2791a8f8
LP
756 fprintf(f,
757 "%s\tCondition Timestamp: %s\n"
758 "%s\tCondition Result: %s\n",
ac155bb8
MS
759 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->condition_timestamp.realtime)),
760 prefix, yes_no(u->condition_result));
2791a8f8 761
87f0e418
LP
762 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
763 Unit *other;
764
ac155bb8
MS
765 SET_FOREACH(other, u->dependencies[d], i)
766 fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
87f0e418
LP
767 }
768
7c8fa05c 769 if (!strv_isempty(u->requires_mounts_for)) {
7c8fa05c
LP
770 fprintf(f,
771 "%s\tRequiresMountsFor:", prefix);
772
773 STRV_FOREACH(j, u->requires_mounts_for)
774 fprintf(f, " %s", *j);
775
776 fputs("\n", f);
777 }
778
ac155bb8 779 if (u->load_state == UNIT_LOADED) {
ab1f0633 780
b0650475 781 fprintf(f,
a40eb732 782 "%s\tStopWhenUnneeded: %s\n"
b5e9dba8
LP
783 "%s\tRefuseManualStart: %s\n"
784 "%s\tRefuseManualStop: %s\n"
222ae6a8 785 "%s\tDefaultDependencies: %s\n"
c8f4d764 786 "%s\tOnFailureIsolate: %s\n"
7a6000a6
LP
787 "%s\tIgnoreOnIsolate: %s\n"
788 "%s\tIgnoreOnSnapshot: %s\n",
ac155bb8
MS
789 prefix, yes_no(u->stop_when_unneeded),
790 prefix, yes_no(u->refuse_manual_start),
791 prefix, yes_no(u->refuse_manual_stop),
792 prefix, yes_no(u->default_dependencies),
793 prefix, yes_no(u->on_failure_isolate),
794 prefix, yes_no(u->ignore_on_isolate),
795 prefix, yes_no(u->ignore_on_snapshot));
796
23a177ef
LP
797 if (UNIT_VTABLE(u)->dump)
798 UNIT_VTABLE(u)->dump(u, f, prefix2);
b0650475 799
ac155bb8 800 } else if (u->load_state == UNIT_MERGED)
b0650475
LP
801 fprintf(f,
802 "%s\tMerged into: %s\n",
ac155bb8
MS
803 prefix, u->merged_into->id);
804 else if (u->load_state == UNIT_ERROR)
805 fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->load_error));
8821a00f 806
87f0e418 807
ac155bb8
MS
808 if (u->job)
809 job_dump(u->job, f, prefix2);
87f0e418 810
e0209d83
MS
811 if (u->nop_job)
812 job_dump(u->nop_job, f, prefix2);
813
47be870b 814 free(p2);
87f0e418
LP
815}
816
817/* Common implementation for multiple backends */
e537352b 818int unit_load_fragment_and_dropin(Unit *u) {
23a177ef
LP
819 int r;
820
821 assert(u);
23a177ef
LP
822
823 /* Load a .service file */
4ad49000
LP
824 r = unit_load_fragment(u);
825 if (r < 0)
23a177ef
LP
826 return r;
827
ac155bb8 828 if (u->load_state == UNIT_STUB)
23a177ef
LP
829 return -ENOENT;
830
831 /* Load drop-in directory data */
4ad49000
LP
832 r = unit_load_dropin(unit_follow_merge(u));
833 if (r < 0)
23a177ef
LP
834 return r;
835
836 return 0;
837}
838
839/* Common implementation for multiple backends */
e537352b 840int unit_load_fragment_and_dropin_optional(Unit *u) {
23a177ef 841 int r;
87f0e418
LP
842
843 assert(u);
844
23a177ef
LP
845 /* Same as unit_load_fragment_and_dropin(), but whether
846 * something can be loaded or not doesn't matter. */
847
848 /* Load a .service file */
4ad49000
LP
849 r = unit_load_fragment(u);
850 if (r < 0)
87f0e418
LP
851 return r;
852
ac155bb8
MS
853 if (u->load_state == UNIT_STUB)
854 u->load_state = UNIT_LOADED;
d46de8a1 855
87f0e418 856 /* Load drop-in directory data */
4ad49000
LP
857 r = unit_load_dropin(unit_follow_merge(u));
858 if (r < 0)
87f0e418
LP
859 return r;
860
23a177ef 861 return 0;
87f0e418
LP
862}
863
bba34eed 864int unit_add_default_target_dependency(Unit *u, Unit *target) {
98bc2000
LP
865 assert(u);
866 assert(target);
867
ac155bb8 868 if (target->type != UNIT_TARGET)
98bc2000
LP
869 return 0;
870
35b8ca3a 871 /* Only add the dependency if both units are loaded, so that
bba34eed 872 * that loop check below is reliable */
ac155bb8
MS
873 if (u->load_state != UNIT_LOADED ||
874 target->load_state != UNIT_LOADED)
bba34eed
LP
875 return 0;
876
21256a2b
LP
877 /* If either side wants no automatic dependencies, then let's
878 * skip this */
ac155bb8
MS
879 if (!u->default_dependencies ||
880 !target->default_dependencies)
21256a2b
LP
881 return 0;
882
98bc2000 883 /* Don't create loops */
ac155bb8 884 if (set_get(target->dependencies[UNIT_BEFORE], u))
98bc2000
LP
885 return 0;
886
887 return unit_add_dependency(target, UNIT_AFTER, u, true);
888}
889
890static int unit_add_default_dependencies(Unit *u) {
a016b922 891
21256a2b
LP
892 static const UnitDependency deps[] = {
893 UNIT_REQUIRED_BY,
894 UNIT_REQUIRED_BY_OVERRIDABLE,
895 UNIT_WANTED_BY,
896 UNIT_BOUND_BY
897 };
898
bba34eed 899 Unit *target;
98bc2000
LP
900 Iterator i;
901 int r;
21256a2b 902 unsigned k;
98bc2000
LP
903
904 assert(u);
905
21256a2b 906 for (k = 0; k < ELEMENTSOF(deps); k++)
a016b922
LP
907 SET_FOREACH(target, u->dependencies[deps[k]], i) {
908 r = unit_add_default_target_dependency(u, target);
909 if (r < 0)
21256a2b 910 return r;
a016b922
LP
911 }
912
4ad49000
LP
913 if (u->default_dependencies && unit_get_cgroup_context(u)) {
914 if (UNIT_ISSET(u->slice))
915 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true);
916 else
917 r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, SPECIAL_ROOT_SLICE, NULL, true);
918
a016b922
LP
919 if (r < 0)
920 return r;
921 }
b81884e7 922
98bc2000
LP
923 return 0;
924}
925
87f0e418
LP
926int unit_load(Unit *u) {
927 int r;
928
929 assert(u);
930
ac155bb8
MS
931 if (u->in_load_queue) {
932 LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u);
933 u->in_load_queue = false;
87f0e418
LP
934 }
935
ac155bb8 936 if (u->type == _UNIT_TYPE_INVALID)
e537352b
LP
937 return -EINVAL;
938
ac155bb8 939 if (u->load_state != UNIT_STUB)
87f0e418
LP
940 return 0;
941
c2756a68
LP
942 if (UNIT_VTABLE(u)->load) {
943 r = UNIT_VTABLE(u)->load(u);
944 if (r < 0)
87f0e418 945 goto fail;
c2756a68 946 }
23a177ef 947
ac155bb8 948 if (u->load_state == UNIT_STUB) {
23a177ef
LP
949 r = -ENOENT;
950 goto fail;
951 }
952
7c8fa05c 953 if (u->load_state == UNIT_LOADED) {
c2756a68
LP
954
955 if (u->default_dependencies) {
956 r = unit_add_default_dependencies(u);
957 if (r < 0)
958 goto fail;
959 }
960
7c8fa05c
LP
961 r = unit_add_mount_links(u);
962 if (r < 0)
c2756a68 963 goto fail;
7c8fa05c 964
c2756a68
LP
965 if (u->on_failure_isolate &&
966 set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
f68319bb 967
c2756a68
LP
968 log_error_unit(u->id,
969 "More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.", u->id);
f68319bb 970
c2756a68
LP
971 r = -EINVAL;
972 goto fail;
973 }
f68319bb
LP
974 }
975
ac155bb8 976 assert((u->load_state != UNIT_MERGED) == !u->merged_into);
23a177ef
LP
977
978 unit_add_to_dbus_queue(unit_follow_merge(u));
701cc384 979 unit_add_to_gc_queue(u);
87f0e418 980
87f0e418
LP
981 return 0;
982
983fail:
c2756a68 984 u->load_state = u->load_state == UNIT_STUB ? UNIT_NOT_FOUND : UNIT_ERROR;
ac155bb8 985 u->load_error = r;
c1e1601e 986 unit_add_to_dbus_queue(u);
9a46fc3b 987 unit_add_to_gc_queue(u);
23a177ef 988
c1b6628d
ZJS
989 log_debug_unit(u->id, "Failed to load configuration for %s: %s",
990 u->id, strerror(-r));
23a177ef 991
87f0e418
LP
992 return r;
993}
994
90bbc946
LP
995bool unit_condition_test(Unit *u) {
996 assert(u);
997
ac155bb8 998 dual_timestamp_get(&u->condition_timestamp);
4b744dfa 999 u->condition_result = condition_test_list(u->id, u->conditions);
90bbc946 1000
ac155bb8 1001 return u->condition_result;
90bbc946
LP
1002}
1003
44a6b1b6 1004_pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
c6918296 1005 const UnitStatusMessageFormats *format_table;
877d54e9
LP
1006
1007 assert(u);
1008 assert(t >= 0);
1009 assert(t < _JOB_TYPE_MAX);
1010
1011 if (t != JOB_START && t != JOB_STOP)
1012 return NULL;
c6918296
MS
1013
1014 format_table = &UNIT_VTABLE(u)->status_message_formats;
1015 if (!format_table)
877d54e9
LP
1016 return NULL;
1017
1018 return format_table->starting_stopping[t == JOB_STOP];
1019}
1020
44a6b1b6 1021_pure_ static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) {
877d54e9
LP
1022 const char *format;
1023
1024 assert(u);
1025 assert(t >= 0);
1026 assert(t < _JOB_TYPE_MAX);
1027
1028 format = unit_get_status_message_format(u, t);
1029 if (format)
1030 return format;
1031
1032 /* Return generic strings */
1033 if (t == JOB_START)
1034 return "Starting %s.";
1035 else if (t == JOB_STOP)
1036 return "Stopping %s.";
1037 else if (t == JOB_RELOAD)
1038 return "Reloading %s.";
1039
1040 return NULL;
1041}
1042
1043static void unit_status_print_starting_stopping(Unit *u, JobType t) {
1044 const char *format;
1045
1046 assert(u);
1047
1048 /* We only print status messages for selected units on
1049 * selected operations. */
c6918296 1050
877d54e9 1051 format = unit_get_status_message_format(u, t);
c6918296
MS
1052 if (!format)
1053 return;
1054
49b1d377 1055 unit_status_printf(u, "", format);
c6918296
MS
1056}
1057
877d54e9
LP
1058#pragma GCC diagnostic push
1059#pragma GCC diagnostic ignored "-Wformat-nonliteral"
1060static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
1061 const char *format;
1062 char buf[LINE_MAX];
1063 sd_id128_t mid;
1064
1065 assert(u);
1066
1067 if (t != JOB_START && t != JOB_STOP && t != JOB_RELOAD)
1068 return;
1069
81270860
LP
1070 if (log_on_console())
1071 return;
1072
877d54e9
LP
1073 /* We log status messages for all units and all operations. */
1074
1075 format = unit_get_status_message_format_try_harder(u, t);
1076 if (!format)
1077 return;
1078
1079 snprintf(buf, sizeof(buf), format, unit_description(u));
1080 char_array_0(buf);
1081
1082 mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
1083 t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
1084 SD_MESSAGE_UNIT_RELOADING;
1085
bbc9006e 1086 log_struct_unit(LOG_INFO,
c1b6628d
ZJS
1087 u->id,
1088 MESSAGE_ID(mid),
1089 "MESSAGE=%s", buf,
1090 NULL);
877d54e9
LP
1091}
1092#pragma GCC diagnostic pop
1093
87f0e418 1094/* Errors:
d5159713
LP
1095 * -EBADR: This unit type does not support starting.
1096 * -EALREADY: Unit is already started.
1097 * -EAGAIN: An operation is already in progress. Retry later.
1098 * -ECANCELED: Too many requests for now.
87f0e418
LP
1099 */
1100int unit_start(Unit *u) {
1101 UnitActiveState state;
92ab323c 1102 Unit *following;
87f0e418
LP
1103
1104 assert(u);
1105
ac155bb8 1106 if (u->load_state != UNIT_LOADED)
6124958c
LP
1107 return -EINVAL;
1108
a82e5507
LP
1109 /* If this is already started, then this will succeed. Note
1110 * that this will even succeed if this unit is not startable
1111 * by the user. This is relied on to detect when we need to
1112 * wait for units and when waiting is finished. */
87f0e418
LP
1113 state = unit_active_state(u);
1114 if (UNIT_IS_ACTIVE_OR_RELOADING(state))
1115 return -EALREADY;
1116
a82e5507
LP
1117 /* If the conditions failed, don't do anything at all. If we
1118 * already are activating this call might still be useful to
1119 * speed up activation in case there is some hold-off time,
1120 * but we don't want to recheck the condition in that case. */
1121 if (state != UNIT_ACTIVATING &&
1122 !unit_condition_test(u)) {
c1b6628d 1123 log_debug_unit(u->id, "Starting of %s requested but condition failed. Ignoring.", u->id);
52661efd
LP
1124 return -EALREADY;
1125 }
1126
92ab323c
LP
1127 /* Forward to the main object, if we aren't it. */
1128 if ((following = unit_following(u))) {
c1b6628d
ZJS
1129 log_debug_unit(u->id, "Redirecting start request from %s to %s.",
1130 u->id, following->id);
92ab323c
LP
1131 return unit_start(following);
1132 }
1133
877d54e9
LP
1134 unit_status_log_starting_stopping_reloading(u, JOB_START);
1135 unit_status_print_starting_stopping(u, JOB_START);
c6918296 1136
92ab323c
LP
1137 /* If it is stopped, but we cannot start it, then fail */
1138 if (!UNIT_VTABLE(u)->start)
1139 return -EBADR;
1140
87f0e418
LP
1141 /* We don't suppress calls to ->start() here when we are
1142 * already starting, to allow this request to be used as a
1143 * "hurry up" call, for example when the unit is in some "auto
1144 * restart" state where it waits for a holdoff timer to elapse
1145 * before it will start again. */
1146
c1e1601e 1147 unit_add_to_dbus_queue(u);
9e58ff9c 1148
87f0e418
LP
1149 return UNIT_VTABLE(u)->start(u);
1150}
1151
1152bool unit_can_start(Unit *u) {
1153 assert(u);
1154
1155 return !!UNIT_VTABLE(u)->start;
1156}
1157
2528a7a6
LP
1158bool unit_can_isolate(Unit *u) {
1159 assert(u);
1160
1161 return unit_can_start(u) &&
ac155bb8 1162 u->allow_isolate;
2528a7a6
LP
1163}
1164
87f0e418
LP
1165/* Errors:
1166 * -EBADR: This unit type does not support stopping.
1167 * -EALREADY: Unit is already stopped.
1168 * -EAGAIN: An operation is already in progress. Retry later.
1169 */
1170int unit_stop(Unit *u) {
1171 UnitActiveState state;
92ab323c 1172 Unit *following;
87f0e418
LP
1173
1174 assert(u);
1175
87f0e418 1176 state = unit_active_state(u);
fdf20a31 1177 if (UNIT_IS_INACTIVE_OR_FAILED(state))
87f0e418
LP
1178 return -EALREADY;
1179
92ab323c 1180 if ((following = unit_following(u))) {
c1b6628d
ZJS
1181 log_debug_unit(u->id, "Redirecting stop request from %s to %s.",
1182 u->id, following->id);
92ab323c
LP
1183 return unit_stop(following);
1184 }
1185
877d54e9
LP
1186 unit_status_log_starting_stopping_reloading(u, JOB_STOP);
1187 unit_status_print_starting_stopping(u, JOB_STOP);
c6918296 1188
7898b0cf
LP
1189 if (!UNIT_VTABLE(u)->stop)
1190 return -EBADR;
1191
c1e1601e 1192 unit_add_to_dbus_queue(u);
9e58ff9c 1193
87f0e418
LP
1194 return UNIT_VTABLE(u)->stop(u);
1195}
1196
1197/* Errors:
1198 * -EBADR: This unit type does not support reloading.
1199 * -ENOEXEC: Unit is not started.
1200 * -EAGAIN: An operation is already in progress. Retry later.
1201 */
1202int unit_reload(Unit *u) {
1203 UnitActiveState state;
92ab323c 1204 Unit *following;
87f0e418
LP
1205
1206 assert(u);
1207
ac155bb8 1208 if (u->load_state != UNIT_LOADED)
6124958c
LP
1209 return -EINVAL;
1210
87f0e418
LP
1211 if (!unit_can_reload(u))
1212 return -EBADR;
1213
1214 state = unit_active_state(u);
e364ad06 1215 if (state == UNIT_RELOADING)
87f0e418
LP
1216 return -EALREADY;
1217
e364ad06 1218 if (state != UNIT_ACTIVE)
87f0e418
LP
1219 return -ENOEXEC;
1220
92ab323c 1221 if ((following = unit_following(u))) {
c1b6628d
ZJS
1222 log_debug_unit(u->id, "Redirecting reload request from %s to %s.",
1223 u->id, following->id);
92ab323c
LP
1224 return unit_reload(following);
1225 }
1226
877d54e9
LP
1227 unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
1228
c1e1601e 1229 unit_add_to_dbus_queue(u);
87f0e418
LP
1230 return UNIT_VTABLE(u)->reload(u);
1231}
1232
1233bool unit_can_reload(Unit *u) {
1234 assert(u);
1235
1236 if (!UNIT_VTABLE(u)->reload)
1237 return false;
1238
1239 if (!UNIT_VTABLE(u)->can_reload)
1240 return true;
1241
1242 return UNIT_VTABLE(u)->can_reload(u);
1243}
1244
b4a16b7b 1245static void unit_check_unneeded(Unit *u) {
f3bff0eb
LP
1246 Iterator i;
1247 Unit *other;
1248
1249 assert(u);
1250
1251 /* If this service shall be shut down when unneeded then do
1252 * so. */
1253
ac155bb8 1254 if (!u->stop_when_unneeded)
f3bff0eb
LP
1255 return;
1256
1257 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1258 return;
1259
ac155bb8 1260 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
31afa0a4 1261 if (unit_active_or_pending(other))
f3bff0eb
LP
1262 return;
1263
ac155bb8 1264 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
31afa0a4 1265 if (unit_active_or_pending(other))
f3bff0eb
LP
1266 return;
1267
ac155bb8 1268 SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
31afa0a4 1269 if (unit_active_or_pending(other))
f3bff0eb
LP
1270 return;
1271
ac155bb8 1272 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
31afa0a4 1273 if (unit_active_or_pending(other))
b81884e7
LP
1274 return;
1275
c1b6628d 1276 log_info_unit(u->id, "Service %s is not needed anymore. Stopping.", u->id);
f3bff0eb
LP
1277
1278 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
ac155bb8 1279 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
f3bff0eb
LP
1280}
1281
87f0e418
LP
1282static void retroactively_start_dependencies(Unit *u) {
1283 Iterator i;
1284 Unit *other;
1285
1286 assert(u);
1287 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1288
ac155bb8
MS
1289 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1290 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1291 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1292 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
b81884e7 1293
7f2cddae 1294 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
ac155bb8 1295 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1296 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1297 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
87f0e418 1298
ac155bb8
MS
1299 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1300 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1301 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1302 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
87f0e418 1303
ac155bb8
MS
1304 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1305 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1306 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1307 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
87f0e418 1308
ac155bb8 1309 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
b81884e7 1310 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1311 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
69dd2852 1312
ac155bb8 1313 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
b81884e7 1314 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1315 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
87f0e418
LP
1316}
1317
1318static void retroactively_stop_dependencies(Unit *u) {
1319 Iterator i;
1320 Unit *other;
1321
1322 assert(u);
1323 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1324
b81884e7 1325 /* Pull down units which are bound to us recursively if enabled */
ac155bb8 1326 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
b81884e7 1327 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1328 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
cd0504d0
MS
1329}
1330
1331static void check_unneeded_dependencies(Unit *u) {
1332 Iterator i;
1333 Unit *other;
1334
1335 assert(u);
1336 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
f3bff0eb
LP
1337
1338 /* Garbage collect services that might not be needed anymore, if enabled */
ac155bb8 1339 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
87f0e418 1340 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1341 unit_check_unneeded(other);
ac155bb8 1342 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
f3bff0eb 1343 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1344 unit_check_unneeded(other);
ac155bb8 1345 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
f3bff0eb 1346 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1347 unit_check_unneeded(other);
ac155bb8 1348 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
f3bff0eb 1349 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1350 unit_check_unneeded(other);
ac155bb8 1351 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
f3bff0eb 1352 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1353 unit_check_unneeded(other);
7f2cddae 1354 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
b81884e7
LP
1355 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1356 unit_check_unneeded(other);
87f0e418
LP
1357}
1358
3ecaa09b 1359void unit_start_on_failure(Unit *u) {
c0daa706
LP
1360 Unit *other;
1361 Iterator i;
1362
1363 assert(u);
1364
ac155bb8 1365 if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
222ae6a8
LP
1366 return;
1367
c1b6628d 1368 log_info_unit(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
222ae6a8 1369
ac155bb8 1370 SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
222ae6a8
LP
1371 int r;
1372
c1b6628d
ZJS
1373 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL);
1374 if (r < 0)
1375 log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
222ae6a8 1376 }
c0daa706
LP
1377}
1378
3ecaa09b
LP
1379void unit_trigger_notify(Unit *u) {
1380 Unit *other;
1381 Iterator i;
1382
1383 assert(u);
1384
1385 SET_FOREACH(other, u->dependencies[UNIT_TRIGGERED_BY], i)
1386 if (UNIT_VTABLE(other)->trigger_notify)
1387 UNIT_VTABLE(other)->trigger_notify(other, u);
1388}
1389
e2f3b44c 1390void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
546ac4f0 1391 Manager *m;
7e6e7b06 1392 bool unexpected;
a096ed36 1393
87f0e418
LP
1394 assert(u);
1395 assert(os < _UNIT_ACTIVE_STATE_MAX);
1396 assert(ns < _UNIT_ACTIVE_STATE_MAX);
87f0e418 1397
8e471ccd
LP
1398 /* Note that this is called for all low-level state changes,
1399 * even if they might map to the same high-level
1400 * UnitActiveState! That means that ns == os is OK an expected
c5315881 1401 * behavior here. For example: if a mount point is remounted
cd6d0a45 1402 * this function will be called too! */
87f0e418 1403
546ac4f0
MS
1404 m = u->manager;
1405
1406 if (m->n_reloading <= 0) {
bdbf9951 1407 dual_timestamp ts;
173e3821 1408
bdbf9951 1409 dual_timestamp_get(&ts);
173e3821 1410
bdbf9951 1411 if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
ac155bb8 1412 u->inactive_exit_timestamp = ts;
bdbf9951 1413 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
ac155bb8 1414 u->inactive_enter_timestamp = ts;
bdbf9951
LP
1415
1416 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
ac155bb8 1417 u->active_enter_timestamp = ts;
bdbf9951 1418 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
ac155bb8 1419 u->active_exit_timestamp = ts;
bdbf9951 1420 }
87f0e418 1421
fdf20a31 1422 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
4ad49000 1423 unit_destroy_cgroup(u);
fb385181 1424
7ed9f6cd
MS
1425 if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1426 ExecContext *ec = unit_get_exec_context(u);
1427 if (ec && exec_context_may_touch_console(ec)) {
31a7eb86
ZJS
1428 if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1429 m->n_on_console --;
1430
1431 if (m->n_on_console == 0)
1432 /* unset no_console_output flag, since the console is free */
1433 m->no_console_output = 0;
1434 } else
1435 m->n_on_console ++;
7ed9f6cd
MS
1436 }
1437 }
1438
ac155bb8 1439 if (u->job) {
7e6e7b06 1440 unexpected = false;
87f0e418 1441
ac155bb8 1442 if (u->job->state == JOB_WAITING)
87f0e418
LP
1443
1444 /* So we reached a different state for this
1445 * job. Let's see if we can run it now if it
1446 * failed previously due to EAGAIN. */
ac155bb8 1447 job_add_to_run_queue(u->job);
87f0e418 1448
b410e6b9 1449 /* Let's check whether this state change constitutes a
35b8ca3a 1450 * finished job, or maybe contradicts a running job and
b410e6b9 1451 * hence needs to invalidate jobs. */
87f0e418 1452
ac155bb8 1453 switch (u->job->type) {
87f0e418 1454
b410e6b9
LP
1455 case JOB_START:
1456 case JOB_VERIFY_ACTIVE:
87f0e418 1457
b410e6b9 1458 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
5273510e 1459 job_finish_and_invalidate(u->job, JOB_DONE, true);
ac155bb8 1460 else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
b410e6b9 1461 unexpected = true;
41b02ec7 1462
fdf20a31 1463 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1464 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
b410e6b9 1465 }
87f0e418 1466
b410e6b9 1467 break;
87f0e418 1468
b410e6b9
LP
1469 case JOB_RELOAD:
1470 case JOB_RELOAD_OR_START:
87f0e418 1471
ac155bb8 1472 if (u->job->state == JOB_RUNNING) {
a096ed36 1473 if (ns == UNIT_ACTIVE)
5273510e 1474 job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
032ff4af 1475 else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
a096ed36 1476 unexpected = true;
41b02ec7 1477
fdf20a31 1478 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1479 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
a096ed36 1480 }
b410e6b9 1481 }
87f0e418 1482
b410e6b9 1483 break;
87f0e418 1484
b410e6b9
LP
1485 case JOB_STOP:
1486 case JOB_RESTART:
1487 case JOB_TRY_RESTART:
87f0e418 1488
fdf20a31 1489 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1490 job_finish_and_invalidate(u->job, JOB_DONE, true);
ac155bb8 1491 else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
b410e6b9 1492 unexpected = true;
5273510e 1493 job_finish_and_invalidate(u->job, JOB_FAILED, true);
b410e6b9 1494 }
87f0e418 1495
b410e6b9 1496 break;
87f0e418 1497
b410e6b9
LP
1498 default:
1499 assert_not_reached("Job type unknown");
87f0e418 1500 }
87f0e418 1501
7e6e7b06
LP
1502 } else
1503 unexpected = true;
1504
546ac4f0 1505 if (m->n_reloading <= 0) {
f3bff0eb 1506
bdbf9951
LP
1507 /* If this state change happened without being
1508 * requested by a job, then let's retroactively start
1509 * or stop dependencies. We skip that step when
1510 * deserializing, since we don't want to create any
1511 * additional jobs just because something is already
1512 * activated. */
1513
1514 if (unexpected) {
1515 if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1516 retroactively_start_dependencies(u);
1517 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1518 retroactively_stop_dependencies(u);
1519 }
5de9682c 1520
cd0504d0
MS
1521 /* stop unneeded units regardless if going down was expected or not */
1522 if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1523 check_unneeded_dependencies(u);
1524
bdbf9951 1525 if (ns != os && ns == UNIT_FAILED) {
c1b6628d 1526 log_notice_unit(u->id,
fcf8c440 1527 "Unit %s entered failed state.", u->id);
3ecaa09b 1528 unit_start_on_failure(u);
cd6d0a45 1529 }
3b2775c5 1530 }
e537352b 1531
3b2775c5
LP
1532 /* Some names are special */
1533 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
1534
1535 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
1536 /* The bus just might have become available,
1537 * hence try to connect to it, if we aren't
1538 * yet connected. */
546ac4f0 1539 bus_init(m, true);
3b2775c5 1540
ac155bb8 1541 if (u->type == UNIT_SERVICE &&
3b2775c5 1542 !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
546ac4f0 1543 m->n_reloading <= 0) {
3b2775c5 1544 /* Write audit record if we have just finished starting up */
546ac4f0 1545 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
ac155bb8 1546 u->in_audit = true;
3b2775c5 1547 }
e983b760 1548
3b2775c5 1549 if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
546ac4f0 1550 manager_send_unit_plymouth(m, u);
bdbf9951 1551
3b2775c5 1552 } else {
bdbf9951 1553
3b2775c5
LP
1554 /* We don't care about D-Bus here, since we'll get an
1555 * asynchronous notification for it anyway. */
cd6d0a45 1556
ac155bb8 1557 if (u->type == UNIT_SERVICE &&
3b2775c5
LP
1558 UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1559 !UNIT_IS_INACTIVE_OR_FAILED(os) &&
546ac4f0 1560 m->n_reloading <= 0) {
4927fcae 1561
3b2775c5
LP
1562 /* Hmm, if there was no start record written
1563 * write it now, so that we always have a nice
1564 * pair */
ac155bb8 1565 if (!u->in_audit) {
546ac4f0 1566 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
cd6d0a45 1567
3b2775c5 1568 if (ns == UNIT_INACTIVE)
546ac4f0 1569 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
3b2775c5
LP
1570 } else
1571 /* Write audit record if we have just finished shutting down */
546ac4f0 1572 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
bdbf9951 1573
ac155bb8 1574 u->in_audit = false;
cd6d0a45 1575 }
f278026d
LP
1576 }
1577
546ac4f0 1578 manager_recheck_journal(m);
3ecaa09b 1579 unit_trigger_notify(u);
3b2775c5 1580
f3bff0eb
LP
1581 /* Maybe we finished startup and are now ready for being
1582 * stopped because unneeded? */
bf6dcfa6
OS
1583 if (u->manager->n_reloading <= 0)
1584 unit_check_unneeded(u);
c1e1601e
LP
1585
1586 unit_add_to_dbus_queue(u);
701cc384 1587 unit_add_to_gc_queue(u);
87f0e418
LP
1588}
1589
acbb0225 1590int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) {
b92bea5d
ZJS
1591 struct epoll_event ev = {
1592 .data.ptr = w,
1593 .events = events,
1594 };
87f0e418
LP
1595
1596 assert(u);
1597 assert(fd >= 0);
acbb0225 1598 assert(w);
ea430986 1599 assert(w->type == WATCH_INVALID || (w->type == WATCH_FD && w->fd == fd && w->data.unit == u));
87f0e418 1600
ac155bb8 1601 if (epoll_ctl(u->manager->epoll_fd,
acbb0225
LP
1602 w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD,
1603 fd,
1604 &ev) < 0)
1605 return -errno;
87f0e418 1606
acbb0225
LP
1607 w->fd = fd;
1608 w->type = WATCH_FD;
ea430986 1609 w->data.unit = u;
87f0e418 1610
acbb0225 1611 return 0;
87f0e418
LP
1612}
1613
acbb0225 1614void unit_unwatch_fd(Unit *u, Watch *w) {
87f0e418 1615 assert(u);
acbb0225 1616 assert(w);
87f0e418 1617
acbb0225
LP
1618 if (w->type == WATCH_INVALID)
1619 return;
1620
ea430986
LP
1621 assert(w->type == WATCH_FD);
1622 assert(w->data.unit == u);
ac155bb8 1623 assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
acbb0225
LP
1624
1625 w->fd = -1;
1626 w->type = WATCH_INVALID;
ea430986 1627 w->data.unit = NULL;
87f0e418
LP
1628}
1629
1630int unit_watch_pid(Unit *u, pid_t pid) {
1631 assert(u);
1632 assert(pid >= 1);
1633
05e343b7
LP
1634 /* Watch a specific PID. We only support one unit watching
1635 * each PID for now. */
1636
ac155bb8 1637 return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u);
87f0e418
LP
1638}
1639
1640void unit_unwatch_pid(Unit *u, pid_t pid) {
1641 assert(u);
1642 assert(pid >= 1);
1643
ac155bb8 1644 hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u);
87f0e418
LP
1645}
1646
36697dc0 1647int unit_watch_timer(Unit *u, clockid_t clock_id, bool relative, usec_t usec, Watch *w) {
b92bea5d 1648 struct itimerspec its = {};
acbb0225 1649 int flags, fd;
87f0e418
LP
1650 bool ours;
1651
1652 assert(u);
acbb0225 1653 assert(w);
faf919f1 1654 assert(w->type == WATCH_INVALID || (w->type == WATCH_UNIT_TIMER && w->data.unit == u));
87f0e418
LP
1655
1656 /* This will try to reuse the old timer if there is one */
1657
faf919f1
LP
1658 if (w->type == WATCH_UNIT_TIMER) {
1659 assert(w->data.unit == u);
1660 assert(w->fd >= 0);
1661
87f0e418 1662 ours = false;
acbb0225 1663 fd = w->fd;
faf919f1
LP
1664 } else if (w->type == WATCH_INVALID) {
1665
87f0e418 1666 ours = true;
36697dc0 1667 fd = timerfd_create(clock_id, TFD_NONBLOCK|TFD_CLOEXEC);
68b29a9f 1668 if (fd < 0)
87f0e418 1669 return -errno;
faf919f1
LP
1670 } else
1671 assert_not_reached("Invalid watch type");
87f0e418 1672
36697dc0 1673 if (usec <= 0) {
87f0e418
LP
1674 /* Set absolute time in the past, but not 0, since we
1675 * don't want to disarm the timer */
1676 its.it_value.tv_sec = 0;
1677 its.it_value.tv_nsec = 1;
1678
1679 flags = TFD_TIMER_ABSTIME;
1680 } else {
36697dc0
LP
1681 timespec_store(&its.it_value, usec);
1682 flags = relative ? 0 : TFD_TIMER_ABSTIME;
87f0e418
LP
1683 }
1684
1685 /* This will also flush the elapse counter */
1686 if (timerfd_settime(fd, flags, &its, NULL) < 0)
1687 goto fail;
1688
acbb0225 1689 if (w->type == WATCH_INVALID) {
b92bea5d
ZJS
1690 struct epoll_event ev = {
1691 .data.ptr = w,
1692 .events = EPOLLIN,
1693 };
acbb0225 1694
ac155bb8 1695 if (epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
acbb0225
LP
1696 goto fail;
1697 }
1698
faf919f1 1699 w->type = WATCH_UNIT_TIMER;
acbb0225 1700 w->fd = fd;
ea430986 1701 w->data.unit = u;
87f0e418 1702
87f0e418
LP
1703 return 0;
1704
1705fail:
1706 if (ours)
ea430986 1707 close_nointr_nofail(fd);
87f0e418
LP
1708
1709 return -errno;
1710}
1711
acbb0225 1712void unit_unwatch_timer(Unit *u, Watch *w) {
87f0e418 1713 assert(u);
acbb0225 1714 assert(w);
87f0e418 1715
acbb0225 1716 if (w->type == WATCH_INVALID)
87f0e418
LP
1717 return;
1718
faf919f1
LP
1719 assert(w->type == WATCH_UNIT_TIMER);
1720 assert(w->data.unit == u);
1721 assert(w->fd >= 0);
acbb0225 1722
ac155bb8 1723 assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
a16e1123 1724 close_nointr_nofail(w->fd);
acbb0225
LP
1725
1726 w->fd = -1;
1727 w->type = WATCH_INVALID;
ea430986 1728 w->data.unit = NULL;
87f0e418
LP
1729}
1730
1731bool unit_job_is_applicable(Unit *u, JobType j) {
1732 assert(u);
1733 assert(j >= 0 && j < _JOB_TYPE_MAX);
1734
1735 switch (j) {
1736
1737 case JOB_VERIFY_ACTIVE:
1738 case JOB_START:
57339f47 1739 case JOB_STOP:
e0209d83 1740 case JOB_NOP:
87f0e418
LP
1741 return true;
1742
87f0e418
LP
1743 case JOB_RESTART:
1744 case JOB_TRY_RESTART:
1745 return unit_can_start(u);
1746
1747 case JOB_RELOAD:
1748 return unit_can_reload(u);
1749
1750 case JOB_RELOAD_OR_START:
1751 return unit_can_reload(u) && unit_can_start(u);
1752
1753 default:
1754 assert_not_reached("Invalid job type");
1755 }
1756}
1757
701cc384 1758int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
87f0e418
LP
1759
1760 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
1761 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
9e2f7c11 1762 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
87f0e418
LP
1763 [UNIT_WANTS] = UNIT_WANTED_BY,
1764 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
9e2f7c11 1765 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
7f2cddae 1766 [UNIT_BINDS_TO] = UNIT_BOUND_BY,
60649f17 1767 [UNIT_PART_OF] = UNIT_CONSISTS_OF,
87f0e418 1768 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
9e2f7c11 1769 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
87f0e418 1770 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
7f2cddae 1771 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
60649f17 1772 [UNIT_CONSISTS_OF] = UNIT_PART_OF,
69dd2852
LP
1773 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
1774 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
87f0e418 1775 [UNIT_BEFORE] = UNIT_AFTER,
701cc384 1776 [UNIT_AFTER] = UNIT_BEFORE,
5de9682c 1777 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
701cc384 1778 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
57020a3a
LP
1779 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
1780 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
4dcc1cb4 1781 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
7f2cddae 1782 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
85e9a101 1783 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
87f0e418 1784 };
701cc384 1785 int r, q = 0, v = 0, w = 0;
87f0e418
LP
1786
1787 assert(u);
1788 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
87f0e418
LP
1789 assert(other);
1790
9f151f29
LP
1791 u = unit_follow_merge(u);
1792 other = unit_follow_merge(other);
1793
87f0e418
LP
1794 /* We won't allow dependencies on ourselves. We will not
1795 * consider them an error however. */
1796 if (u == other)
1797 return 0;
1798
ac155bb8 1799 if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
87f0e418
LP
1800 return r;
1801
5de9682c 1802 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
ac155bb8 1803 if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
5de9682c
LP
1804 return r;
1805
701cc384 1806 if (add_reference)
ac155bb8
MS
1807 if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
1808 (r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
701cc384 1809 return r;
87f0e418 1810
ac155bb8 1811 if ((q = set_put(u->dependencies[d], other)) < 0)
701cc384 1812 return q;
87f0e418 1813
5de9682c 1814 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
ac155bb8 1815 if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) {
5de9682c
LP
1816 r = v;
1817 goto fail;
1818 }
701cc384
LP
1819
1820 if (add_reference) {
ac155bb8 1821 if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) {
701cc384
LP
1822 r = w;
1823 goto fail;
1824 }
1825
ac155bb8 1826 if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0)
701cc384 1827 goto fail;
87f0e418
LP
1828 }
1829
c1e1601e 1830 unit_add_to_dbus_queue(u);
87f0e418 1831 return 0;
701cc384
LP
1832
1833fail:
1834 if (q > 0)
ac155bb8 1835 set_remove(u->dependencies[d], other);
701cc384
LP
1836
1837 if (v > 0)
ac155bb8 1838 set_remove(other->dependencies[inverse_table[d]], u);
701cc384
LP
1839
1840 if (w > 0)
ac155bb8 1841 set_remove(u->dependencies[UNIT_REFERENCES], other);
701cc384
LP
1842
1843 return r;
87f0e418 1844}
0301abf4 1845
2c966c03
LP
1846int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
1847 int r;
1848
1849 assert(u);
1850
1851 if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
1852 return r;
1853
1854 if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
1855 return r;
1856
1857 return 0;
1858}
1859
9e2f7c11
LP
1860static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
1861 char *s;
1862
1863 assert(u);
1864 assert(name || path);
8afbb8e1 1865 assert(p);
9e2f7c11
LP
1866
1867 if (!name)
9eb977db 1868 name = path_get_file_name(path);
9e2f7c11
LP
1869
1870 if (!unit_name_is_template(name)) {
1871 *p = NULL;
1872 return name;
1873 }
1874
ac155bb8
MS
1875 if (u->instance)
1876 s = unit_name_replace_instance(name, u->instance);
9e2f7c11 1877 else {
ae018d9b 1878 _cleanup_free_ char *i = NULL;
9e2f7c11 1879
8afbb8e1
LP
1880 i = unit_name_to_prefix(u->id);
1881 if (!i)
9e2f7c11
LP
1882 return NULL;
1883
1884 s = unit_name_replace_instance(name, i);
9e2f7c11
LP
1885 }
1886
1887 if (!s)
1888 return NULL;
1889
1890 *p = s;
1891 return s;
1892}
1893
701cc384 1894int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
09b6b09f
LP
1895 Unit *other;
1896 int r;
8afbb8e1 1897 _cleanup_free_ char *s = NULL;
09b6b09f 1898
9e2f7c11
LP
1899 assert(u);
1900 assert(name || path);
09b6b09f 1901
8afbb8e1
LP
1902 name = resolve_template(u, name, path, &s);
1903 if (!name)
9e2f7c11 1904 return -ENOMEM;
09b6b09f 1905
8afbb8e1
LP
1906 r = manager_load_unit(u->manager, name, path, NULL, &other);
1907 if (r < 0)
1908 return r;
9e2f7c11 1909
8afbb8e1 1910 return unit_add_dependency(u, d, other, add_reference);
09b6b09f
LP
1911}
1912
2c966c03
LP
1913int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1914 Unit *other;
1915 int r;
1916 char *s;
1917
1918 assert(u);
1919 assert(name || path);
1920
1921 if (!(name = resolve_template(u, name, path, &s)))
1922 return -ENOMEM;
1923
ac155bb8 1924 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
2c966c03
LP
1925 goto finish;
1926
1927 r = unit_add_two_dependencies(u, d, e, other, add_reference);
1928
1929finish:
1930 free(s);
1931 return r;
1932}
1933
701cc384 1934int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
bd77d0fc
LP
1935 Unit *other;
1936 int r;
9e2f7c11 1937 char *s;
bd77d0fc 1938
9e2f7c11
LP
1939 assert(u);
1940 assert(name || path);
bd77d0fc 1941
9e2f7c11
LP
1942 if (!(name = resolve_template(u, name, path, &s)))
1943 return -ENOMEM;
bd77d0fc 1944
ac155bb8 1945 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
9e2f7c11
LP
1946 goto finish;
1947
701cc384 1948 r = unit_add_dependency(other, d, u, add_reference);
9e2f7c11
LP
1949
1950finish:
1951 free(s);
1952 return r;
bd77d0fc
LP
1953}
1954
2c966c03
LP
1955int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1956 Unit *other;
1957 int r;
1958 char *s;
1959
1960 assert(u);
1961 assert(name || path);
1962
1963 if (!(name = resolve_template(u, name, path, &s)))
1964 return -ENOMEM;
1965
ac155bb8 1966 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
2c966c03
LP
1967 goto finish;
1968
1969 if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
1970 goto finish;
1971
1972finish:
1973 free(s);
1974 return r;
1975}
1976
0301abf4 1977int set_unit_path(const char *p) {
26d04f86 1978 _cleanup_free_ char *c = NULL;
0301abf4
LP
1979
1980 /* This is mostly for debug purposes */
26d04f86
LP
1981 c = path_make_absolute_cwd(p);
1982 if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0)
1983 return -errno;
0301abf4
LP
1984
1985 return 0;
1986}
88066b3a 1987
ea430986 1988char *unit_dbus_path(Unit *u) {
ea430986
LP
1989 assert(u);
1990
ac155bb8 1991 if (!u->id)
04ade7d2
LP
1992 return NULL;
1993
48899192 1994 return unit_dbus_path_from_name(u->id);
ea430986
LP
1995}
1996
41f9172f 1997char *unit_default_cgroup_path(Unit *u) {
d7bd3de0 1998 _cleanup_free_ char *escaped = NULL, *slice = NULL;
a016b922 1999 int r;
5954c074 2000
013b87c0
LP
2001 assert(u);
2002
4ad49000
LP
2003 if (unit_has_name(u, SPECIAL_ROOT_SLICE))
2004 return strdup(u->manager->cgroup_root);
2005
2006 if (UNIT_ISSET(u->slice) && !unit_has_name(UNIT_DEREF(u->slice), SPECIAL_ROOT_SLICE)) {
a016b922
LP
2007 r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice);
2008 if (r < 0)
2009 return NULL;
2010 }
2011
d7bd3de0
LP
2012 escaped = cg_escape(u->id);
2013 if (!escaped)
5954c074
LP
2014 return NULL;
2015
d7bd3de0
LP
2016 if (slice)
2017 return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL);
2018 else
2019 return strjoin(u->manager->cgroup_root, "/", escaped, NULL);
013b87c0
LP
2020}
2021
a016b922 2022int unit_add_default_slice(Unit *u) {
a8833944
LP
2023 _cleanup_free_ char *b = NULL;
2024 const char *slice_name;
a016b922
LP
2025 Unit *slice;
2026 int r;
2027
2028 assert(u);
2029
9444b1f2 2030 if (UNIT_ISSET(u->slice))
a016b922
LP
2031 return 0;
2032
4ad49000 2033 if (!unit_get_cgroup_context(u))
a016b922
LP
2034 return 0;
2035
a8833944
LP
2036 if (u->instance) {
2037 _cleanup_free_ char *prefix = NULL, *escaped = NULL;
2038 ;
2039 /* Implicitly place all instantiated units in their
2040 * own per-template slice */
2041
2042 prefix = unit_name_to_prefix(u->id);
2043 if (!prefix)
2044 return -ENOMEM;
2045
2046 /* The prefix is already escaped, but it might include
2047 * "-" which has a special meaning for slice units,
2048 * hence escape it here extra. */
2049 escaped = strreplace(prefix, "-", "\\x2d");
2050 if (!escaped)
2051 return -ENOMEM;
2052
2053 if (u->manager->running_as == SYSTEMD_SYSTEM)
2054 b = strjoin("system-", escaped, ".slice", NULL);
2055 else
2056 b = strappend(escaped, ".slice");
2057 if (!b)
2058 return -ENOMEM;
2059
2060 slice_name = b;
2061 } else
2062 slice_name =
2063 u->manager->running_as == SYSTEMD_SYSTEM
2064 ? SPECIAL_SYSTEM_SLICE
2065 : SPECIAL_ROOT_SLICE;
2066
2067 r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
a016b922
LP
2068 if (r < 0)
2069 return r;
2070
2071 unit_ref_set(&u->slice, slice);
2072 return 0;
2073}
2074
9444b1f2
LP
2075const char *unit_slice_name(Unit *u) {
2076 assert(u);
2077
2078 if (!UNIT_ISSET(u->slice))
2079 return NULL;
2080
2081 return UNIT_DEREF(u->slice)->id;
2082}
2083
f6ff8c29 2084int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
78edb35a 2085 _cleanup_free_ char *t = NULL;
f6ff8c29
LP
2086 int r;
2087
2088 assert(u);
2089 assert(type);
2090 assert(_found);
2091
78edb35a
LP
2092 t = unit_name_change_suffix(u->id, type);
2093 if (!t)
f6ff8c29
LP
2094 return -ENOMEM;
2095
2096 assert(!unit_has_name(u, t));
2097
ac155bb8 2098 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
9e2f7c11 2099 assert(r < 0 || *_found != u);
f6ff8c29
LP
2100 return r;
2101}
2102
a16e1123 2103int unit_get_related_unit(Unit *u, const char *type, Unit **_found) {
78edb35a 2104 _cleanup_free_ char *t = NULL;
a16e1123 2105 Unit *found;
a16e1123
LP
2106
2107 assert(u);
2108 assert(type);
2109 assert(_found);
2110
78edb35a
LP
2111 t = unit_name_change_suffix(u->id, type);
2112 if (!t)
a16e1123
LP
2113 return -ENOMEM;
2114
2115 assert(!unit_has_name(u, t));
2116
ac155bb8 2117 found = manager_get_unit(u->manager, t);
a16e1123
LP
2118 if (!found)
2119 return -ENOENT;
2120
2121 *_found = found;
2122 return 0;
2123}
2124
05e343b7
LP
2125int unit_watch_bus_name(Unit *u, const char *name) {
2126 assert(u);
2127 assert(name);
2128
2129 /* Watch a specific name on the bus. We only support one unit
2130 * watching each name for now. */
2131
ac155bb8 2132 return hashmap_put(u->manager->watch_bus, name, u);
05e343b7
LP
2133}
2134
2135void unit_unwatch_bus_name(Unit *u, const char *name) {
2136 assert(u);
2137 assert(name);
2138
ac155bb8 2139 hashmap_remove_value(u->manager->watch_bus, name, u);
05e343b7
LP
2140}
2141
a16e1123
LP
2142bool unit_can_serialize(Unit *u) {
2143 assert(u);
2144
2145 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2146}
2147
6b78f9b4 2148int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
a16e1123
LP
2149 int r;
2150
2151 assert(u);
2152 assert(f);
2153 assert(fds);
2154
2155 if (!unit_can_serialize(u))
2156 return 0;
2157
6fa48533
LP
2158 r = UNIT_VTABLE(u)->serialize(u, f, fds);
2159 if (r < 0)
a16e1123
LP
2160 return r;
2161
cca098b0 2162
6b78f9b4
LP
2163 if (serialize_jobs) {
2164 if (u->job) {
2165 fprintf(f, "job\n");
2166 job_serialize(u->job, f, fds);
2167 }
2168
2169 if (u->nop_job) {
2170 fprintf(f, "job\n");
2171 job_serialize(u->nop_job, f, fds);
2172 }
e0209d83
MS
2173 }
2174
ac155bb8
MS
2175 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2176 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2177 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2178 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2179 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
2791a8f8 2180
ac155bb8
MS
2181 if (dual_timestamp_is_set(&u->condition_timestamp))
2182 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
10717a1a 2183
c2756a68
LP
2184 unit_serialize_item(u, f, "transient", yes_no(u->transient));
2185
2186 if (u->cgroup_path)
2187 unit_serialize_item(u, f, "cgroup", u->cgroup_path);
2188
a16e1123
LP
2189 /* End marker */
2190 fputc('\n', f);
2191 return 0;
2192}
2193
2194void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2195 va_list ap;
2196
2197 assert(u);
2198 assert(f);
2199 assert(key);
2200 assert(format);
2201
2202 fputs(key, f);
2203 fputc('=', f);
2204
2205 va_start(ap, format);
2206 vfprintf(f, format, ap);
2207 va_end(ap);
2208
2209 fputc('\n', f);
2210}
2211
2212void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2213 assert(u);
2214 assert(f);
2215 assert(key);
2216 assert(value);
2217
2218 fprintf(f, "%s=%s\n", key, value);
2219}
2220
2221int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
2222 int r;
2223
2224 assert(u);
2225 assert(f);
2226 assert(fds);
2227
2228 if (!unit_can_serialize(u))
2229 return 0;
2230
2231 for (;;) {
20c03b7b 2232 char line[LINE_MAX], *l, *v;
a16e1123
LP
2233 size_t k;
2234
2235 if (!fgets(line, sizeof(line), f)) {
2236 if (feof(f))
2237 return 0;
2238 return -errno;
2239 }
2240
10f8e83c 2241 char_array_0(line);
a16e1123
LP
2242 l = strstrip(line);
2243
2244 /* End marker */
2245 if (l[0] == 0)
2246 return 0;
2247
2248 k = strcspn(l, "=");
2249
2250 if (l[k] == '=') {
2251 l[k] = 0;
2252 v = l+k+1;
2253 } else
2254 v = l+k;
2255
cca098b0 2256 if (streq(l, "job")) {
39a18c60
MS
2257 if (v[0] == '\0') {
2258 /* new-style serialized job */
2259 Job *j = job_new_raw(u);
2260 if (!j)
2261 return -ENOMEM;
2262
2263 r = job_deserialize(j, f, fds);
2264 if (r < 0) {
2265 job_free(j);
2266 return r;
2267 }
cca098b0 2268
39a18c60
MS
2269 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2270 if (r < 0) {
2271 job_free(j);
2272 return r;
2273 }
e0209d83
MS
2274
2275 r = job_install_deserialized(j);
2276 if (r < 0) {
2277 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2278 job_free(j);
2279 return r;
2280 }
6b19ad24
MS
2281
2282 if (j->state == JOB_RUNNING)
2283 u->manager->n_running_jobs++;
39a18c60
MS
2284 } else {
2285 /* legacy */
2286 JobType type = job_type_from_string(v);
2287 if (type < 0)
2288 log_debug("Failed to parse job type value %s", v);
2289 else
2290 u->deserialized_job = type;
2291 }
cca098b0 2292 continue;
8aaf019b 2293 } else if (streq(l, "inactive-exit-timestamp")) {
ac155bb8 2294 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
8aaf019b
LP
2295 continue;
2296 } else if (streq(l, "active-enter-timestamp")) {
ac155bb8 2297 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
8aaf019b
LP
2298 continue;
2299 } else if (streq(l, "active-exit-timestamp")) {
ac155bb8 2300 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
8aaf019b
LP
2301 continue;
2302 } else if (streq(l, "inactive-enter-timestamp")) {
ac155bb8 2303 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
8aaf019b 2304 continue;
2791a8f8 2305 } else if (streq(l, "condition-timestamp")) {
ac155bb8 2306 dual_timestamp_deserialize(v, &u->condition_timestamp);
2791a8f8
LP
2307 continue;
2308 } else if (streq(l, "condition-result")) {
2309 int b;
2310
c2756a68
LP
2311 b = parse_boolean(v);
2312 if (b < 0)
2791a8f8
LP
2313 log_debug("Failed to parse condition result value %s", v);
2314 else
ac155bb8 2315 u->condition_result = b;
efbac6d2
LP
2316
2317 continue;
c2756a68
LP
2318
2319 } else if (streq(l, "transient")) {
2320 int b;
2321
2322 b = parse_boolean(v);
2323 if (b < 0)
2324 log_debug("Failed to parse transient bool %s", v);
2325 else
2326 u->transient = b;
2327
2328 continue;
2329 } else if (streq(l, "cgroup")) {
2330 char *s;
2331
2332 s = strdup(v);
f440e1bb 2333 if (!s)
c2756a68
LP
2334 return -ENOMEM;
2335
2336 free(u->cgroup_path);
2337 u->cgroup_path = s;
72673e86
LP
2338
2339 hashmap_put(u->manager->cgroup_unit, s, u);
c2756a68 2340 continue;
8aaf019b 2341 }
cca098b0 2342
c2756a68
LP
2343 r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds);
2344 if (r < 0)
a16e1123
LP
2345 return r;
2346 }
2347}
2348
6e2ef85b
LP
2349int unit_add_node_link(Unit *u, const char *what, bool wants) {
2350 Unit *device;
2351 char *e;
2352 int r;
2353
2354 assert(u);
2355
2356 if (!what)
2357 return 0;
2358
2359 /* Adds in links to the device node that this unit is based on */
2360
8407a5d0 2361 if (!is_device_path(what))
6e2ef85b
LP
2362 return 0;
2363
35eb6b12
LP
2364 e = unit_name_from_path(what, ".device");
2365 if (!e)
6e2ef85b
LP
2366 return -ENOMEM;
2367
ac155bb8 2368 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
6e2ef85b 2369 free(e);
6e2ef85b
LP
2370 if (r < 0)
2371 return r;
2372
faa368e3
LP
2373 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
2374 if (r < 0)
6e2ef85b
LP
2375 return r;
2376
faa368e3
LP
2377 if (wants) {
2378 r = unit_add_dependency(device, UNIT_WANTS, u, false);
2379 if (r < 0)
6e2ef85b 2380 return r;
faa368e3 2381 }
6e2ef85b
LP
2382
2383 return 0;
2384}
a16e1123 2385
cca098b0
LP
2386int unit_coldplug(Unit *u) {
2387 int r;
2388
2389 assert(u);
2390
2391 if (UNIT_VTABLE(u)->coldplug)
2392 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2393 return r;
2394
39a18c60
MS
2395 if (u->job) {
2396 r = job_coldplug(u->job);
2397 if (r < 0)
2398 return r;
2399 } else if (u->deserialized_job >= 0) {
2400 /* legacy */
2401 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2402 if (r < 0)
cca098b0
LP
2403 return r;
2404
ac155bb8 2405 u->deserialized_job = _JOB_TYPE_INVALID;
cca098b0
LP
2406 }
2407
2408 return 0;
2409}
2410
b1e2b33c
CR
2411#pragma GCC diagnostic push
2412#pragma GCC diagnostic ignored "-Wformat-nonliteral"
49b1d377
MS
2413void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) {
2414 manager_status_printf(u->manager, false, status, unit_status_msg_format, unit_description(u));
2415}
b1e2b33c 2416#pragma GCC diagnostic pop
49b1d377 2417
45fb0699 2418bool unit_need_daemon_reload(Unit *u) {
ae7a7182
OS
2419 _cleanup_strv_free_ char **t = NULL;
2420 char **path;
1b64d026 2421 struct stat st;
ae7a7182 2422 unsigned loaded_cnt, current_cnt;
1b64d026 2423
45fb0699
LP
2424 assert(u);
2425
ac155bb8 2426 if (u->fragment_path) {
5f4b19f4 2427 zero(st);
ac155bb8 2428 if (stat(u->fragment_path, &st) < 0)
5f4b19f4
LP
2429 /* What, cannot access this anymore? */
2430 return true;
45fb0699 2431
ac155bb8
MS
2432 if (u->fragment_mtime > 0 &&
2433 timespec_load(&st.st_mtim) != u->fragment_mtime)
5f4b19f4
LP
2434 return true;
2435 }
2436
1b64d026
LP
2437 if (u->source_path) {
2438 zero(st);
2439 if (stat(u->source_path, &st) < 0)
2440 return true;
2441
2442 if (u->source_mtime > 0 &&
2443 timespec_load(&st.st_mtim) != u->source_mtime)
2444 return true;
2445 }
5f4b19f4 2446
ae7a7182
OS
2447 t = unit_find_dropin_paths(u);
2448 loaded_cnt = strv_length(t);
2449 current_cnt = strv_length(u->dropin_paths);
2450
2451 if (loaded_cnt == current_cnt) {
2452 if (loaded_cnt == 0)
2453 return false;
2454
2455 if (strv_overlap(u->dropin_paths, t)) {
2456 STRV_FOREACH(path, u->dropin_paths) {
2457 zero(st);
2458 if (stat(*path, &st) < 0)
2459 return true;
2460
2461 if (u->dropin_mtime > 0 &&
2462 timespec_load(&st.st_mtim) > u->dropin_mtime)
2463 return true;
2464 }
2465
2466 return false;
2467 } else
2468 return true;
2469 } else
2470 return true;
45fb0699
LP
2471}
2472
fdf20a31 2473void unit_reset_failed(Unit *u) {
5632e374
LP
2474 assert(u);
2475
fdf20a31
MM
2476 if (UNIT_VTABLE(u)->reset_failed)
2477 UNIT_VTABLE(u)->reset_failed(u);
5632e374
LP
2478}
2479
a7f241db
LP
2480Unit *unit_following(Unit *u) {
2481 assert(u);
2482
2483 if (UNIT_VTABLE(u)->following)
2484 return UNIT_VTABLE(u)->following(u);
2485
2486 return NULL;
2487}
2488
31afa0a4 2489bool unit_stop_pending(Unit *u) {
18ffdfda
LP
2490 assert(u);
2491
31afa0a4
LP
2492 /* This call does check the current state of the unit. It's
2493 * hence useful to be called from state change calls of the
2494 * unit itself, where the state isn't updated yet. This is
2495 * different from unit_inactive_or_pending() which checks both
2496 * the current state and for a queued job. */
18ffdfda 2497
31afa0a4
LP
2498 return u->job && u->job->type == JOB_STOP;
2499}
2500
2501bool unit_inactive_or_pending(Unit *u) {
2502 assert(u);
2503
2504 /* Returns true if the unit is inactive or going down */
18ffdfda 2505
d956ac29
LP
2506 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2507 return true;
2508
31afa0a4 2509 if (unit_stop_pending(u))
18ffdfda
LP
2510 return true;
2511
2512 return false;
2513}
2514
31afa0a4 2515bool unit_active_or_pending(Unit *u) {
f976f3f6
LP
2516 assert(u);
2517
f60c2665 2518 /* Returns true if the unit is active or going up */
f976f3f6
LP
2519
2520 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2521 return true;
2522
ac155bb8
MS
2523 if (u->job &&
2524 (u->job->type == JOB_START ||
2525 u->job->type == JOB_RELOAD_OR_START ||
2526 u->job->type == JOB_RESTART))
f976f3f6
LP
2527 return true;
2528
2529 return false;
2530}
2531
c74f17d9 2532int unit_kill(Unit *u, KillWho w, int signo, DBusError *error) {
8a0867d6
LP
2533 assert(u);
2534 assert(w >= 0 && w < _KILL_WHO_MAX);
8a0867d6
LP
2535 assert(signo > 0);
2536 assert(signo < _NSIG);
2537
8a0867d6
LP
2538 if (!UNIT_VTABLE(u)->kill)
2539 return -ENOTSUP;
2540
c74f17d9 2541 return UNIT_VTABLE(u)->kill(u, w, signo, error);
8a0867d6
LP
2542}
2543
d91c34f2
LP
2544int unit_kill_common(
2545 Unit *u,
2546 KillWho who,
2547 int signo,
2548 pid_t main_pid,
2549 pid_t control_pid,
2550 DBusError *error) {
2551
814cc562
MS
2552 int r = 0;
2553
2554 if (who == KILL_MAIN && main_pid <= 0) {
2555 if (main_pid < 0)
2556 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
2557 else
2558 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
2559 return -ESRCH;
2560 }
2561
2562 if (who == KILL_CONTROL && control_pid <= 0) {
2563 if (control_pid < 0)
2564 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
2565 else
2566 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
2567 return -ESRCH;
2568 }
2569
2570 if (who == KILL_CONTROL || who == KILL_ALL)
2571 if (control_pid > 0)
2572 if (kill(control_pid, signo) < 0)
2573 r = -errno;
2574
2575 if (who == KILL_MAIN || who == KILL_ALL)
2576 if (main_pid > 0)
2577 if (kill(main_pid, signo) < 0)
2578 r = -errno;
2579
4ad49000 2580 if (who == KILL_ALL && u->cgroup_path) {
814cc562
MS
2581 _cleanup_set_free_ Set *pid_set = NULL;
2582 int q;
2583
2584 pid_set = set_new(trivial_hash_func, trivial_compare_func);
2585 if (!pid_set)
2586 return -ENOMEM;
2587
2588 /* Exclude the control/main pid from being killed via the cgroup */
2589 if (control_pid > 0) {
2590 q = set_put(pid_set, LONG_TO_PTR(control_pid));
2591 if (q < 0)
2592 return q;
2593 }
2594
2595 if (main_pid > 0) {
2596 q = set_put(pid_set, LONG_TO_PTR(main_pid));
2597 if (q < 0)
2598 return q;
2599 }
2600
4ad49000 2601 q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
814cc562
MS
2602 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
2603 r = q;
2604 }
2605
2606 return r;
2607}
2608
6210e7fc
LP
2609int unit_following_set(Unit *u, Set **s) {
2610 assert(u);
2611 assert(s);
2612
2613 if (UNIT_VTABLE(u)->following_set)
2614 return UNIT_VTABLE(u)->following_set(u, s);
2615
2616 *s = NULL;
2617 return 0;
2618}
2619
a4375746
LP
2620UnitFileState unit_get_unit_file_state(Unit *u) {
2621 assert(u);
2622
ac155bb8
MS
2623 if (u->unit_file_state < 0 && u->fragment_path)
2624 u->unit_file_state = unit_file_get_state(
67445f4e 2625 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
9eb977db 2626 NULL, path_get_file_name(u->fragment_path));
a4375746 2627
ac155bb8 2628 return u->unit_file_state;
a4375746
LP
2629}
2630
57020a3a
LP
2631Unit* unit_ref_set(UnitRef *ref, Unit *u) {
2632 assert(ref);
2633 assert(u);
2634
2635 if (ref->unit)
2636 unit_ref_unset(ref);
2637
2638 ref->unit = u;
ac155bb8 2639 LIST_PREPEND(UnitRef, refs, u->refs, ref);
57020a3a
LP
2640 return u;
2641}
2642
2643void unit_ref_unset(UnitRef *ref) {
2644 assert(ref);
2645
2646 if (!ref->unit)
2647 return;
2648
ac155bb8 2649 LIST_REMOVE(UnitRef, refs, ref->unit->refs, ref);
57020a3a
LP
2650 ref->unit = NULL;
2651}
2652
7c8fa05c
LP
2653int unit_add_one_mount_link(Unit *u, Mount *m) {
2654 char **i;
2655
2656 assert(u);
2657 assert(m);
2658
2659 if (u->load_state != UNIT_LOADED ||
2660 UNIT(m)->load_state != UNIT_LOADED)
2661 return 0;
2662
2663 STRV_FOREACH(i, u->requires_mounts_for) {
2664
2665 if (UNIT(m) == u)
2666 continue;
2667
2668 if (!path_startswith(*i, m->where))
2669 continue;
2670
2671 return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
2672 }
2673
2674 return 0;
2675}
2676
2677int unit_add_mount_links(Unit *u) {
2678 Unit *other;
2679 int r;
2680
2681 assert(u);
2682
2683 LIST_FOREACH(units_by_type, other, u->manager->units_by_type[UNIT_MOUNT]) {
2684 r = unit_add_one_mount_link(u, MOUNT(other));
2685 if (r < 0)
2686 return r;
2687 }
2688
2689 return 0;
2690}
2691
cba6e062
LP
2692int unit_exec_context_defaults(Unit *u, ExecContext *c) {
2693 unsigned i;
2694 int r;
2695
e06c73cc
LP
2696 assert(u);
2697 assert(c);
2698
cba6e062 2699 /* This only copies in the ones that need memory */
cba6e062
LP
2700 for (i = 0; i < RLIMIT_NLIMITS; i++)
2701 if (u->manager->rlimit[i] && !c->rlimit[i]) {
2702 c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
2703 if (!c->rlimit[i])
2704 return -ENOMEM;
2705 }
2706
67445f4e 2707 if (u->manager->running_as == SYSTEMD_USER &&
cba6e062 2708 !c->working_directory) {
e06c73cc 2709
cba6e062
LP
2710 r = get_home_dir(&c->working_directory);
2711 if (r < 0)
2712 return r;
2713 }
2714
2715 return 0;
e06c73cc
LP
2716}
2717
3ef63c31
LP
2718ExecContext *unit_get_exec_context(Unit *u) {
2719 size_t offset;
2720 assert(u);
2721
2722 offset = UNIT_VTABLE(u)->exec_context_offset;
2723 if (offset <= 0)
2724 return NULL;
2725
2726 return (ExecContext*) ((uint8_t*) u + offset);
2727}
2728
4ad49000
LP
2729CGroupContext *unit_get_cgroup_context(Unit *u) {
2730 size_t offset;
2731
2732 offset = UNIT_VTABLE(u)->cgroup_context_offset;
2733 if (offset <= 0)
2734 return NULL;
2735
2736 return (CGroupContext*) ((uint8_t*) u + offset);
2737}
2738
8e2af478 2739static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) {
b9ec9359 2740 _cleanup_free_ char *b = NULL;
26d04f86
LP
2741 char *p, *q;
2742 int r;
2743
71645aca 2744 assert(u);
26d04f86
LP
2745 assert(name);
2746 assert(_p);
2747 assert(_q);
8e2af478 2748 assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME));
71645aca 2749
b9ec9359
LP
2750 b = xescape(name, "/.");
2751 if (!b)
2752 return -ENOMEM;
2753
2754 if (!filename_is_safe(b))
71645aca
LP
2755 return -EINVAL;
2756
26d04f86
LP
2757 if (u->manager->running_as == SYSTEMD_USER) {
2758 _cleanup_free_ char *c = NULL;
2759
2760 r = user_config_home(&c);
2761 if (r < 0)
2762 return r;
2763 if (r == 0)
2764 return -ENOENT;
2765
2766 p = strjoin(c, "/", u->id, ".d", NULL);
c2756a68 2767 } else if (mode & UNIT_PERSISTENT)
26d04f86 2768 p = strjoin("/etc/systemd/system/", u->id, ".d", NULL);
8e2af478
LP
2769 else
2770 p = strjoin("/run/systemd/system/", u->id, ".d", NULL);
71645aca
LP
2771 if (!p)
2772 return -ENOMEM;
2773
b9ec9359 2774 q = strjoin(p, "/90-", b, ".conf", NULL);
26d04f86
LP
2775 if (!q) {
2776 free(p);
71645aca 2777 return -ENOMEM;
26d04f86 2778 }
71645aca 2779
26d04f86
LP
2780 *_p = p;
2781 *_q = q;
2782 return 0;
71645aca
LP
2783}
2784
8e2af478 2785int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
71645aca 2786 _cleanup_free_ char *p = NULL, *q = NULL;
26d04f86 2787 int r;
71645aca
LP
2788
2789 assert(u);
b42defe3
LP
2790 assert(name);
2791 assert(data);
71645aca 2792
8e2af478
LP
2793 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2794 return 0;
2795
2796 r = drop_in_file(u, mode, name, &p, &q);
26d04f86
LP
2797 if (r < 0)
2798 return r;
71645aca 2799
26d04f86 2800 mkdir_p(p, 0755);
574d5f2d 2801 return write_string_file_atomic_label(q, data);
26d04f86 2802}
71645aca 2803
b9ec9359
LP
2804int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2805 _cleanup_free_ char *p = NULL;
2806 va_list ap;
2807 int r;
2808
2809 assert(u);
2810 assert(name);
2811 assert(format);
2812
2813 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2814 return 0;
2815
2816 va_start(ap, format);
2817 r = vasprintf(&p, format, ap);
2818 va_end(ap);
2819
2820 if (r < 0)
2821 return -ENOMEM;
2822
2823 return unit_write_drop_in(u, mode, name, p);
2824}
2825
2826int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
b42defe3
LP
2827 _cleanup_free_ char *ndata = NULL;
2828
2829 assert(u);
2830 assert(name);
2831 assert(data);
2832
2833 if (!UNIT_VTABLE(u)->private_section)
2834 return -EINVAL;
2835
b9ec9359
LP
2836 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2837 return 0;
2838
b42defe3
LP
2839 ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
2840 if (!ndata)
2841 return -ENOMEM;
2842
2843 return unit_write_drop_in(u, mode, name, ndata);
2844}
2845
b9ec9359
LP
2846int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2847 _cleanup_free_ char *p = NULL;
2848 va_list ap;
2849 int r;
2850
2851 assert(u);
2852 assert(name);
2853 assert(format);
2854
2855 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2856 return 0;
2857
2858 va_start(ap, format);
2859 r = vasprintf(&p, format, ap);
2860 va_end(ap);
2861
2862 if (r < 0)
2863 return -ENOMEM;
2864
2865 return unit_write_drop_in_private(u, mode, name, p);
2866}
2867
8e2af478 2868int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
26d04f86
LP
2869 _cleanup_free_ char *p = NULL, *q = NULL;
2870 int r;
71645aca 2871
26d04f86 2872 assert(u);
71645aca 2873
8e2af478
LP
2874 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2875 return 0;
2876
2877 r = drop_in_file(u, mode, name, &p, &q);
71645aca 2878 if (unlink(q) < 0)
241da328 2879 r = errno == ENOENT ? 0 : -errno;
26d04f86 2880 else
241da328 2881 r = 1;
71645aca
LP
2882
2883 rmdir(p);
26d04f86 2884 return r;
71645aca
LP
2885}
2886
c2756a68
LP
2887int unit_make_transient(Unit *u) {
2888 int r;
2889
2890 assert(u);
2891
2892 u->load_state = UNIT_STUB;
2893 u->load_error = 0;
2894 u->transient = true;
2895
2896 free(u->fragment_path);
2897 u->fragment_path = NULL;
2898
2899 if (u->manager->running_as == SYSTEMD_USER) {
2900 _cleanup_free_ char *c = NULL;
2901
2902 r = user_config_home(&c);
2903 if (r < 0)
2904 return r;
2905 if (r == 0)
2906 return -ENOENT;
2907
2908 u->fragment_path = strjoin(c, "/", u->id, NULL);
2909 if (!u->fragment_path)
2910 return -ENOMEM;
2911
2912 mkdir_p(c, 0755);
2913 } else {
2914 u->fragment_path = strappend("/run/systemd/system/", u->id);
2915 if (!u->fragment_path)
2916 return -ENOMEM;
2917
2918 mkdir_p("/run/systemd/system", 0755);
2919 }
2920
2921 return write_string_file_atomic_label(u->fragment_path, "# Transient stub");
2922}
2923
cd2086fe
LP
2924int unit_kill_context(
2925 Unit *u,
2926 KillContext *c,
2927 bool sigkill,
2928 pid_t main_pid,
2929 pid_t control_pid,
2930 bool main_pid_alien) {
2931
2932 int sig, wait_for_exit = 0, r;
2933
2934 assert(u);
2935 assert(c);
2936
2937 if (c->kill_mode == KILL_NONE)
2938 return 0;
2939
2940 sig = sigkill ? SIGKILL : c->kill_signal;
2941
2942 if (main_pid > 0) {
2943 r = kill_and_sigcont(main_pid, sig);
2944
2945 if (r < 0 && r != -ESRCH) {
2946 _cleanup_free_ char *comm = NULL;
2947 get_process_comm(main_pid, &comm);
2948
2949 log_warning_unit(u->id, "Failed to kill main process %li (%s): %s",
2950 (long) main_pid, strna(comm), strerror(-r));
2951 } else
2952 wait_for_exit = !main_pid_alien;
2953 }
2954
2955 if (control_pid > 0) {
2956 r = kill_and_sigcont(control_pid, sig);
2957
2958 if (r < 0 && r != -ESRCH) {
2959 _cleanup_free_ char *comm = NULL;
2960 get_process_comm(control_pid, &comm);
2961
2962 log_warning_unit(u->id,
2963 "Failed to kill control process %li (%s): %s",
2964 (long) control_pid, strna(comm), strerror(-r));
2965 } else
2966 wait_for_exit = true;
2967 }
2968
4ad49000 2969 if (c->kill_mode == KILL_CONTROL_GROUP && u->cgroup_path) {
cd2086fe
LP
2970 _cleanup_set_free_ Set *pid_set = NULL;
2971
2972 pid_set = set_new(trivial_hash_func, trivial_compare_func);
2973 if (!pid_set)
2974 return -ENOMEM;
2975
2976 /* Exclude the main/control pids from being killed via the cgroup */
2977 if (main_pid > 0) {
2978 r = set_put(pid_set, LONG_TO_PTR(main_pid));
2979 if (r < 0)
2980 return r;
2981 }
2982
2983 if (control_pid > 0) {
2984 r = set_put(pid_set, LONG_TO_PTR(control_pid));
2985 if (r < 0)
2986 return r;
2987 }
2988
4ad49000 2989 r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set);
cd2086fe
LP
2990 if (r < 0) {
2991 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
2992 log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
2993 } else if (r > 0)
2994 wait_for_exit = true;
2995 }
2996
2997 return wait_for_exit;
2998}
2999
94f04347
LP
3000static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
3001 [UNIT_ACTIVE] = "active",
032ff4af 3002 [UNIT_RELOADING] = "reloading",
94f04347 3003 [UNIT_INACTIVE] = "inactive",
fdf20a31 3004 [UNIT_FAILED] = "failed",
94f04347
LP
3005 [UNIT_ACTIVATING] = "activating",
3006 [UNIT_DEACTIVATING] = "deactivating"
3007};
3008
3009DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
3010
3011static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
3012 [UNIT_REQUIRES] = "Requires",
9e2f7c11 3013 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
94f04347 3014 [UNIT_REQUISITE] = "Requisite",
9e2f7c11 3015 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
ac6a4abe
MS
3016 [UNIT_WANTS] = "Wants",
3017 [UNIT_BINDS_TO] = "BindsTo",
3018 [UNIT_PART_OF] = "PartOf",
94f04347 3019 [UNIT_REQUIRED_BY] = "RequiredBy",
9e2f7c11 3020 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
94f04347 3021 [UNIT_WANTED_BY] = "WantedBy",
ac6a4abe
MS
3022 [UNIT_BOUND_BY] = "BoundBy",
3023 [UNIT_CONSISTS_OF] = "ConsistsOf",
94f04347 3024 [UNIT_CONFLICTS] = "Conflicts",
69dd2852 3025 [UNIT_CONFLICTED_BY] = "ConflictedBy",
94f04347
LP
3026 [UNIT_BEFORE] = "Before",
3027 [UNIT_AFTER] = "After",
57020a3a
LP
3028 [UNIT_ON_FAILURE] = "OnFailure",
3029 [UNIT_TRIGGERS] = "Triggers",
4dcc1cb4 3030 [UNIT_TRIGGERED_BY] = "TriggeredBy",
7f2cddae 3031 [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
ac6a4abe
MS
3032 [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
3033 [UNIT_REFERENCES] = "References",
3034 [UNIT_REFERENCED_BY] = "ReferencedBy",
94f04347
LP
3035};
3036
3037DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);