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