]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/unit.c
core: there's no point to complain so loudly about non-isolatable boot targets
[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 916
c1b6628d
ZJS
917 log_error_unit(u->id,
918 "More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.", 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
c1b6628d
ZJS
937 log_debug_unit(u->id, "Failed to load configuration for %s: %s",
938 u->id, strerror(-r));
23a177ef 939
87f0e418
LP
940 return r;
941}
942
90bbc946
LP
943bool unit_condition_test(Unit *u) {
944 assert(u);
945
ac155bb8
MS
946 dual_timestamp_get(&u->condition_timestamp);
947 u->condition_result = condition_test_list(u->conditions);
90bbc946 948
ac155bb8 949 return u->condition_result;
90bbc946
LP
950}
951
877d54e9 952static const char* unit_get_status_message_format(Unit *u, JobType t) {
c6918296 953 const UnitStatusMessageFormats *format_table;
877d54e9
LP
954
955 assert(u);
956 assert(t >= 0);
957 assert(t < _JOB_TYPE_MAX);
958
959 if (t != JOB_START && t != JOB_STOP)
960 return NULL;
c6918296
MS
961
962 format_table = &UNIT_VTABLE(u)->status_message_formats;
963 if (!format_table)
877d54e9
LP
964 return NULL;
965
966 return format_table->starting_stopping[t == JOB_STOP];
967}
968
969static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) {
970 const char *format;
971
972 assert(u);
973 assert(t >= 0);
974 assert(t < _JOB_TYPE_MAX);
975
976 format = unit_get_status_message_format(u, t);
977 if (format)
978 return format;
979
980 /* Return generic strings */
981 if (t == JOB_START)
982 return "Starting %s.";
983 else if (t == JOB_STOP)
984 return "Stopping %s.";
985 else if (t == JOB_RELOAD)
986 return "Reloading %s.";
987
988 return NULL;
989}
990
991static void unit_status_print_starting_stopping(Unit *u, JobType t) {
992 const char *format;
993
994 assert(u);
995
996 /* We only print status messages for selected units on
997 * selected operations. */
c6918296 998
877d54e9 999 format = unit_get_status_message_format(u, t);
c6918296
MS
1000 if (!format)
1001 return;
1002
49b1d377 1003 unit_status_printf(u, "", format);
c6918296
MS
1004}
1005
877d54e9
LP
1006#pragma GCC diagnostic push
1007#pragma GCC diagnostic ignored "-Wformat-nonliteral"
1008static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
1009 const char *format;
1010 char buf[LINE_MAX];
1011 sd_id128_t mid;
1012
1013 assert(u);
1014
1015 if (t != JOB_START && t != JOB_STOP && t != JOB_RELOAD)
1016 return;
1017
81270860
LP
1018 if (log_on_console())
1019 return;
1020
877d54e9
LP
1021 /* We log status messages for all units and all operations. */
1022
1023 format = unit_get_status_message_format_try_harder(u, t);
1024 if (!format)
1025 return;
1026
1027 snprintf(buf, sizeof(buf), format, unit_description(u));
1028 char_array_0(buf);
1029
1030 mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
1031 t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
1032 SD_MESSAGE_UNIT_RELOADING;
1033
bbc9006e 1034 log_struct_unit(LOG_INFO,
c1b6628d
ZJS
1035 u->id,
1036 MESSAGE_ID(mid),
1037 "MESSAGE=%s", buf,
1038 NULL);
877d54e9
LP
1039}
1040#pragma GCC diagnostic pop
1041
87f0e418 1042/* Errors:
d5159713
LP
1043 * -EBADR: This unit type does not support starting.
1044 * -EALREADY: Unit is already started.
1045 * -EAGAIN: An operation is already in progress. Retry later.
1046 * -ECANCELED: Too many requests for now.
87f0e418
LP
1047 */
1048int unit_start(Unit *u) {
1049 UnitActiveState state;
92ab323c 1050 Unit *following;
87f0e418
LP
1051
1052 assert(u);
1053
ac155bb8 1054 if (u->load_state != UNIT_LOADED)
6124958c
LP
1055 return -EINVAL;
1056
a82e5507
LP
1057 /* If this is already started, then this will succeed. Note
1058 * that this will even succeed if this unit is not startable
1059 * by the user. This is relied on to detect when we need to
1060 * wait for units and when waiting is finished. */
87f0e418
LP
1061 state = unit_active_state(u);
1062 if (UNIT_IS_ACTIVE_OR_RELOADING(state))
1063 return -EALREADY;
1064
a82e5507
LP
1065 /* If the conditions failed, don't do anything at all. If we
1066 * already are activating this call might still be useful to
1067 * speed up activation in case there is some hold-off time,
1068 * but we don't want to recheck the condition in that case. */
1069 if (state != UNIT_ACTIVATING &&
1070 !unit_condition_test(u)) {
c1b6628d 1071 log_debug_unit(u->id, "Starting of %s requested but condition failed. Ignoring.", u->id);
52661efd
LP
1072 return -EALREADY;
1073 }
1074
92ab323c
LP
1075 /* Forward to the main object, if we aren't it. */
1076 if ((following = unit_following(u))) {
c1b6628d
ZJS
1077 log_debug_unit(u->id, "Redirecting start request from %s to %s.",
1078 u->id, following->id);
92ab323c
LP
1079 return unit_start(following);
1080 }
1081
877d54e9
LP
1082 unit_status_log_starting_stopping_reloading(u, JOB_START);
1083 unit_status_print_starting_stopping(u, JOB_START);
c6918296 1084
92ab323c
LP
1085 /* If it is stopped, but we cannot start it, then fail */
1086 if (!UNIT_VTABLE(u)->start)
1087 return -EBADR;
1088
87f0e418
LP
1089 /* We don't suppress calls to ->start() here when we are
1090 * already starting, to allow this request to be used as a
1091 * "hurry up" call, for example when the unit is in some "auto
1092 * restart" state where it waits for a holdoff timer to elapse
1093 * before it will start again. */
1094
c1e1601e 1095 unit_add_to_dbus_queue(u);
9e58ff9c 1096
87f0e418
LP
1097 return UNIT_VTABLE(u)->start(u);
1098}
1099
1100bool unit_can_start(Unit *u) {
1101 assert(u);
1102
1103 return !!UNIT_VTABLE(u)->start;
1104}
1105
2528a7a6
LP
1106bool unit_can_isolate(Unit *u) {
1107 assert(u);
1108
1109 return unit_can_start(u) &&
ac155bb8 1110 u->allow_isolate;
2528a7a6
LP
1111}
1112
87f0e418
LP
1113/* Errors:
1114 * -EBADR: This unit type does not support stopping.
1115 * -EALREADY: Unit is already stopped.
1116 * -EAGAIN: An operation is already in progress. Retry later.
1117 */
1118int unit_stop(Unit *u) {
1119 UnitActiveState state;
92ab323c 1120 Unit *following;
87f0e418
LP
1121
1122 assert(u);
1123
87f0e418 1124 state = unit_active_state(u);
fdf20a31 1125 if (UNIT_IS_INACTIVE_OR_FAILED(state))
87f0e418
LP
1126 return -EALREADY;
1127
92ab323c 1128 if ((following = unit_following(u))) {
c1b6628d
ZJS
1129 log_debug_unit(u->id, "Redirecting stop request from %s to %s.",
1130 u->id, following->id);
92ab323c
LP
1131 return unit_stop(following);
1132 }
1133
877d54e9
LP
1134 unit_status_log_starting_stopping_reloading(u, JOB_STOP);
1135 unit_status_print_starting_stopping(u, JOB_STOP);
c6918296 1136
7898b0cf
LP
1137 if (!UNIT_VTABLE(u)->stop)
1138 return -EBADR;
1139
c1e1601e 1140 unit_add_to_dbus_queue(u);
9e58ff9c 1141
87f0e418
LP
1142 return UNIT_VTABLE(u)->stop(u);
1143}
1144
1145/* Errors:
1146 * -EBADR: This unit type does not support reloading.
1147 * -ENOEXEC: Unit is not started.
1148 * -EAGAIN: An operation is already in progress. Retry later.
1149 */
1150int unit_reload(Unit *u) {
1151 UnitActiveState state;
92ab323c 1152 Unit *following;
87f0e418
LP
1153
1154 assert(u);
1155
ac155bb8 1156 if (u->load_state != UNIT_LOADED)
6124958c
LP
1157 return -EINVAL;
1158
87f0e418
LP
1159 if (!unit_can_reload(u))
1160 return -EBADR;
1161
1162 state = unit_active_state(u);
e364ad06 1163 if (state == UNIT_RELOADING)
87f0e418
LP
1164 return -EALREADY;
1165
e364ad06 1166 if (state != UNIT_ACTIVE)
87f0e418
LP
1167 return -ENOEXEC;
1168
92ab323c 1169 if ((following = unit_following(u))) {
c1b6628d
ZJS
1170 log_debug_unit(u->id, "Redirecting reload request from %s to %s.",
1171 u->id, following->id);
92ab323c
LP
1172 return unit_reload(following);
1173 }
1174
877d54e9
LP
1175 unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
1176
c1e1601e 1177 unit_add_to_dbus_queue(u);
87f0e418
LP
1178 return UNIT_VTABLE(u)->reload(u);
1179}
1180
1181bool unit_can_reload(Unit *u) {
1182 assert(u);
1183
1184 if (!UNIT_VTABLE(u)->reload)
1185 return false;
1186
1187 if (!UNIT_VTABLE(u)->can_reload)
1188 return true;
1189
1190 return UNIT_VTABLE(u)->can_reload(u);
1191}
1192
b4a16b7b 1193static void unit_check_unneeded(Unit *u) {
f3bff0eb
LP
1194 Iterator i;
1195 Unit *other;
1196
1197 assert(u);
1198
1199 /* If this service shall be shut down when unneeded then do
1200 * so. */
1201
ac155bb8 1202 if (!u->stop_when_unneeded)
f3bff0eb
LP
1203 return;
1204
1205 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1206 return;
1207
ac155bb8 1208 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
f60c2665 1209 if (unit_pending_active(other))
f3bff0eb
LP
1210 return;
1211
ac155bb8 1212 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
f60c2665 1213 if (unit_pending_active(other))
f3bff0eb
LP
1214 return;
1215
ac155bb8 1216 SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
f60c2665 1217 if (unit_pending_active(other))
f3bff0eb
LP
1218 return;
1219
ac155bb8 1220 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
f60c2665 1221 if (unit_pending_active(other))
b81884e7
LP
1222 return;
1223
c1b6628d 1224 log_info_unit(u->id, "Service %s is not needed anymore. Stopping.", u->id);
f3bff0eb
LP
1225
1226 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
ac155bb8 1227 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
f3bff0eb
LP
1228}
1229
87f0e418
LP
1230static void retroactively_start_dependencies(Unit *u) {
1231 Iterator i;
1232 Unit *other;
1233
1234 assert(u);
1235 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1236
ac155bb8
MS
1237 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1238 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1239 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1240 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
b81884e7 1241
7f2cddae 1242 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
ac155bb8 1243 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1244 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1245 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
87f0e418 1246
ac155bb8
MS
1247 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1248 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1249 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1250 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
87f0e418 1251
ac155bb8
MS
1252 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1253 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1254 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1255 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
87f0e418 1256
ac155bb8 1257 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], 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);
69dd2852 1260
ac155bb8 1261 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
b81884e7 1262 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1263 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
87f0e418
LP
1264}
1265
1266static void retroactively_stop_dependencies(Unit *u) {
1267 Iterator i;
1268 Unit *other;
1269
1270 assert(u);
1271 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1272
b81884e7 1273 /* Pull down units which are bound to us recursively if enabled */
ac155bb8 1274 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
b81884e7 1275 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1276 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
cd0504d0
MS
1277}
1278
1279static void check_unneeded_dependencies(Unit *u) {
1280 Iterator i;
1281 Unit *other;
1282
1283 assert(u);
1284 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
f3bff0eb
LP
1285
1286 /* Garbage collect services that might not be needed anymore, if enabled */
ac155bb8 1287 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
87f0e418 1288 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1289 unit_check_unneeded(other);
ac155bb8 1290 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
f3bff0eb 1291 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1292 unit_check_unneeded(other);
ac155bb8 1293 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
f3bff0eb 1294 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1295 unit_check_unneeded(other);
ac155bb8 1296 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
f3bff0eb 1297 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1298 unit_check_unneeded(other);
ac155bb8 1299 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
f3bff0eb 1300 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1301 unit_check_unneeded(other);
7f2cddae 1302 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
b81884e7
LP
1303 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1304 unit_check_unneeded(other);
87f0e418
LP
1305}
1306
c0daa706
LP
1307void unit_trigger_on_failure(Unit *u) {
1308 Unit *other;
1309 Iterator i;
1310
1311 assert(u);
1312
ac155bb8 1313 if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
222ae6a8
LP
1314 return;
1315
c1b6628d 1316 log_info_unit(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
222ae6a8 1317
ac155bb8 1318 SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
222ae6a8
LP
1319 int r;
1320
c1b6628d
ZJS
1321 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL);
1322 if (r < 0)
1323 log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
222ae6a8 1324 }
c0daa706
LP
1325}
1326
e2f3b44c 1327void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
546ac4f0 1328 Manager *m;
7e6e7b06 1329 bool unexpected;
a096ed36 1330
87f0e418
LP
1331 assert(u);
1332 assert(os < _UNIT_ACTIVE_STATE_MAX);
1333 assert(ns < _UNIT_ACTIVE_STATE_MAX);
87f0e418 1334
8e471ccd
LP
1335 /* Note that this is called for all low-level state changes,
1336 * even if they might map to the same high-level
1337 * UnitActiveState! That means that ns == os is OK an expected
c5315881 1338 * behavior here. For example: if a mount point is remounted
cd6d0a45 1339 * this function will be called too! */
87f0e418 1340
546ac4f0
MS
1341 m = u->manager;
1342
1343 if (m->n_reloading <= 0) {
bdbf9951 1344 dual_timestamp ts;
173e3821 1345
bdbf9951 1346 dual_timestamp_get(&ts);
173e3821 1347
bdbf9951 1348 if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
ac155bb8 1349 u->inactive_exit_timestamp = ts;
bdbf9951 1350 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
ac155bb8 1351 u->inactive_enter_timestamp = ts;
bdbf9951
LP
1352
1353 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
ac155bb8 1354 u->active_enter_timestamp = ts;
bdbf9951 1355 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
ac155bb8 1356 u->active_exit_timestamp = ts;
bdbf9951
LP
1357
1358 timer_unit_notify(u, ns);
1359 path_unit_notify(u, ns);
1360 }
87f0e418 1361
fdf20a31 1362 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
ac155bb8 1363 cgroup_bonding_trim_list(u->cgroup_bondings, true);
fb385181 1364
7ed9f6cd
MS
1365 if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1366 ExecContext *ec = unit_get_exec_context(u);
1367 if (ec && exec_context_may_touch_console(ec)) {
7ed9f6cd
MS
1368 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1369 m->n_on_console--;
1370 else
1371 m->n_on_console++;
1372 }
1373 }
1374
ac155bb8 1375 if (u->job) {
7e6e7b06 1376 unexpected = false;
87f0e418 1377
ac155bb8 1378 if (u->job->state == JOB_WAITING)
87f0e418
LP
1379
1380 /* So we reached a different state for this
1381 * job. Let's see if we can run it now if it
1382 * failed previously due to EAGAIN. */
ac155bb8 1383 job_add_to_run_queue(u->job);
87f0e418 1384
b410e6b9 1385 /* Let's check whether this state change constitutes a
35b8ca3a 1386 * finished job, or maybe contradicts a running job and
b410e6b9 1387 * hence needs to invalidate jobs. */
87f0e418 1388
ac155bb8 1389 switch (u->job->type) {
87f0e418 1390
b410e6b9
LP
1391 case JOB_START:
1392 case JOB_VERIFY_ACTIVE:
87f0e418 1393
b410e6b9 1394 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
5273510e 1395 job_finish_and_invalidate(u->job, JOB_DONE, true);
ac155bb8 1396 else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
b410e6b9 1397 unexpected = true;
41b02ec7 1398
fdf20a31 1399 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1400 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
b410e6b9 1401 }
87f0e418 1402
b410e6b9 1403 break;
87f0e418 1404
b410e6b9
LP
1405 case JOB_RELOAD:
1406 case JOB_RELOAD_OR_START:
87f0e418 1407
ac155bb8 1408 if (u->job->state == JOB_RUNNING) {
a096ed36 1409 if (ns == UNIT_ACTIVE)
5273510e 1410 job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
032ff4af 1411 else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
a096ed36 1412 unexpected = true;
41b02ec7 1413
fdf20a31 1414 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1415 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
a096ed36 1416 }
b410e6b9 1417 }
87f0e418 1418
b410e6b9 1419 break;
87f0e418 1420
b410e6b9
LP
1421 case JOB_STOP:
1422 case JOB_RESTART:
1423 case JOB_TRY_RESTART:
87f0e418 1424
fdf20a31 1425 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1426 job_finish_and_invalidate(u->job, JOB_DONE, true);
ac155bb8 1427 else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
b410e6b9 1428 unexpected = true;
5273510e 1429 job_finish_and_invalidate(u->job, JOB_FAILED, true);
b410e6b9 1430 }
87f0e418 1431
b410e6b9 1432 break;
87f0e418 1433
b410e6b9
LP
1434 default:
1435 assert_not_reached("Job type unknown");
87f0e418 1436 }
87f0e418 1437
7e6e7b06
LP
1438 } else
1439 unexpected = true;
1440
546ac4f0 1441 if (m->n_reloading <= 0) {
f3bff0eb 1442
bdbf9951
LP
1443 /* If this state change happened without being
1444 * requested by a job, then let's retroactively start
1445 * or stop dependencies. We skip that step when
1446 * deserializing, since we don't want to create any
1447 * additional jobs just because something is already
1448 * activated. */
1449
1450 if (unexpected) {
1451 if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1452 retroactively_start_dependencies(u);
1453 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1454 retroactively_stop_dependencies(u);
1455 }
5de9682c 1456
cd0504d0
MS
1457 /* stop unneeded units regardless if going down was expected or not */
1458 if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1459 check_unneeded_dependencies(u);
1460
bdbf9951 1461 if (ns != os && ns == UNIT_FAILED) {
c1b6628d
ZJS
1462 log_notice_unit(u->id,
1463 "MESSAGE=Unit %s entered failed state.", u->id);
bdbf9951 1464 unit_trigger_on_failure(u);
cd6d0a45 1465 }
3b2775c5 1466 }
e537352b 1467
3b2775c5
LP
1468 /* Some names are special */
1469 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
1470
1471 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
1472 /* The bus just might have become available,
1473 * hence try to connect to it, if we aren't
1474 * yet connected. */
546ac4f0 1475 bus_init(m, true);
3b2775c5 1476
ac155bb8 1477 if (u->type == UNIT_SERVICE &&
3b2775c5 1478 !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
546ac4f0 1479 m->n_reloading <= 0) {
3b2775c5 1480 /* Write audit record if we have just finished starting up */
546ac4f0 1481 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
ac155bb8 1482 u->in_audit = true;
3b2775c5 1483 }
e983b760 1484
3b2775c5 1485 if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
546ac4f0 1486 manager_send_unit_plymouth(m, u);
bdbf9951 1487
3b2775c5 1488 } else {
bdbf9951 1489
3b2775c5
LP
1490 /* We don't care about D-Bus here, since we'll get an
1491 * asynchronous notification for it anyway. */
cd6d0a45 1492
ac155bb8 1493 if (u->type == UNIT_SERVICE &&
3b2775c5
LP
1494 UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1495 !UNIT_IS_INACTIVE_OR_FAILED(os) &&
546ac4f0 1496 m->n_reloading <= 0) {
4927fcae 1497
3b2775c5
LP
1498 /* Hmm, if there was no start record written
1499 * write it now, so that we always have a nice
1500 * pair */
ac155bb8 1501 if (!u->in_audit) {
546ac4f0 1502 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
cd6d0a45 1503
3b2775c5 1504 if (ns == UNIT_INACTIVE)
546ac4f0 1505 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
3b2775c5
LP
1506 } else
1507 /* Write audit record if we have just finished shutting down */
546ac4f0 1508 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
bdbf9951 1509
ac155bb8 1510 u->in_audit = false;
cd6d0a45 1511 }
f278026d
LP
1512 }
1513
546ac4f0 1514 manager_recheck_journal(m);
3b2775c5 1515
f3bff0eb
LP
1516 /* Maybe we finished startup and are now ready for being
1517 * stopped because unneeded? */
bf6dcfa6
OS
1518 if (u->manager->n_reloading <= 0)
1519 unit_check_unneeded(u);
c1e1601e
LP
1520
1521 unit_add_to_dbus_queue(u);
701cc384 1522 unit_add_to_gc_queue(u);
87f0e418
LP
1523}
1524
acbb0225 1525int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) {
b92bea5d
ZJS
1526 struct epoll_event ev = {
1527 .data.ptr = w,
1528 .events = events,
1529 };
87f0e418
LP
1530
1531 assert(u);
1532 assert(fd >= 0);
acbb0225 1533 assert(w);
ea430986 1534 assert(w->type == WATCH_INVALID || (w->type == WATCH_FD && w->fd == fd && w->data.unit == u));
87f0e418 1535
ac155bb8 1536 if (epoll_ctl(u->manager->epoll_fd,
acbb0225
LP
1537 w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD,
1538 fd,
1539 &ev) < 0)
1540 return -errno;
87f0e418 1541
acbb0225
LP
1542 w->fd = fd;
1543 w->type = WATCH_FD;
ea430986 1544 w->data.unit = u;
87f0e418 1545
acbb0225 1546 return 0;
87f0e418
LP
1547}
1548
acbb0225 1549void unit_unwatch_fd(Unit *u, Watch *w) {
87f0e418 1550 assert(u);
acbb0225 1551 assert(w);
87f0e418 1552
acbb0225
LP
1553 if (w->type == WATCH_INVALID)
1554 return;
1555
ea430986
LP
1556 assert(w->type == WATCH_FD);
1557 assert(w->data.unit == u);
ac155bb8 1558 assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
acbb0225
LP
1559
1560 w->fd = -1;
1561 w->type = WATCH_INVALID;
ea430986 1562 w->data.unit = NULL;
87f0e418
LP
1563}
1564
1565int unit_watch_pid(Unit *u, pid_t pid) {
1566 assert(u);
1567 assert(pid >= 1);
1568
05e343b7
LP
1569 /* Watch a specific PID. We only support one unit watching
1570 * each PID for now. */
1571
ac155bb8 1572 return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u);
87f0e418
LP
1573}
1574
1575void unit_unwatch_pid(Unit *u, pid_t pid) {
1576 assert(u);
1577 assert(pid >= 1);
1578
ac155bb8 1579 hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u);
87f0e418
LP
1580}
1581
36697dc0 1582int unit_watch_timer(Unit *u, clockid_t clock_id, bool relative, usec_t usec, Watch *w) {
b92bea5d 1583 struct itimerspec its = {};
acbb0225 1584 int flags, fd;
87f0e418
LP
1585 bool ours;
1586
1587 assert(u);
acbb0225 1588 assert(w);
faf919f1 1589 assert(w->type == WATCH_INVALID || (w->type == WATCH_UNIT_TIMER && w->data.unit == u));
87f0e418
LP
1590
1591 /* This will try to reuse the old timer if there is one */
1592
faf919f1
LP
1593 if (w->type == WATCH_UNIT_TIMER) {
1594 assert(w->data.unit == u);
1595 assert(w->fd >= 0);
1596
87f0e418 1597 ours = false;
acbb0225 1598 fd = w->fd;
faf919f1
LP
1599 } else if (w->type == WATCH_INVALID) {
1600
87f0e418 1601 ours = true;
36697dc0 1602 fd = timerfd_create(clock_id, TFD_NONBLOCK|TFD_CLOEXEC);
68b29a9f 1603 if (fd < 0)
87f0e418 1604 return -errno;
faf919f1
LP
1605 } else
1606 assert_not_reached("Invalid watch type");
87f0e418 1607
36697dc0 1608 if (usec <= 0) {
87f0e418
LP
1609 /* Set absolute time in the past, but not 0, since we
1610 * don't want to disarm the timer */
1611 its.it_value.tv_sec = 0;
1612 its.it_value.tv_nsec = 1;
1613
1614 flags = TFD_TIMER_ABSTIME;
1615 } else {
36697dc0
LP
1616 timespec_store(&its.it_value, usec);
1617 flags = relative ? 0 : TFD_TIMER_ABSTIME;
87f0e418
LP
1618 }
1619
1620 /* This will also flush the elapse counter */
1621 if (timerfd_settime(fd, flags, &its, NULL) < 0)
1622 goto fail;
1623
acbb0225 1624 if (w->type == WATCH_INVALID) {
b92bea5d
ZJS
1625 struct epoll_event ev = {
1626 .data.ptr = w,
1627 .events = EPOLLIN,
1628 };
acbb0225 1629
ac155bb8 1630 if (epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
acbb0225
LP
1631 goto fail;
1632 }
1633
faf919f1 1634 w->type = WATCH_UNIT_TIMER;
acbb0225 1635 w->fd = fd;
ea430986 1636 w->data.unit = u;
87f0e418 1637
87f0e418
LP
1638 return 0;
1639
1640fail:
1641 if (ours)
ea430986 1642 close_nointr_nofail(fd);
87f0e418
LP
1643
1644 return -errno;
1645}
1646
acbb0225 1647void unit_unwatch_timer(Unit *u, Watch *w) {
87f0e418 1648 assert(u);
acbb0225 1649 assert(w);
87f0e418 1650
acbb0225 1651 if (w->type == WATCH_INVALID)
87f0e418
LP
1652 return;
1653
faf919f1
LP
1654 assert(w->type == WATCH_UNIT_TIMER);
1655 assert(w->data.unit == u);
1656 assert(w->fd >= 0);
acbb0225 1657
ac155bb8 1658 assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
a16e1123 1659 close_nointr_nofail(w->fd);
acbb0225
LP
1660
1661 w->fd = -1;
1662 w->type = WATCH_INVALID;
ea430986 1663 w->data.unit = NULL;
87f0e418
LP
1664}
1665
1666bool unit_job_is_applicable(Unit *u, JobType j) {
1667 assert(u);
1668 assert(j >= 0 && j < _JOB_TYPE_MAX);
1669
1670 switch (j) {
1671
1672 case JOB_VERIFY_ACTIVE:
1673 case JOB_START:
57339f47 1674 case JOB_STOP:
e0209d83 1675 case JOB_NOP:
87f0e418
LP
1676 return true;
1677
87f0e418
LP
1678 case JOB_RESTART:
1679 case JOB_TRY_RESTART:
1680 return unit_can_start(u);
1681
1682 case JOB_RELOAD:
1683 return unit_can_reload(u);
1684
1685 case JOB_RELOAD_OR_START:
1686 return unit_can_reload(u) && unit_can_start(u);
1687
1688 default:
1689 assert_not_reached("Invalid job type");
1690 }
1691}
1692
701cc384 1693int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
87f0e418
LP
1694
1695 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
1696 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
9e2f7c11 1697 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
87f0e418
LP
1698 [UNIT_WANTS] = UNIT_WANTED_BY,
1699 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
9e2f7c11 1700 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
7f2cddae 1701 [UNIT_BINDS_TO] = UNIT_BOUND_BY,
60649f17 1702 [UNIT_PART_OF] = UNIT_CONSISTS_OF,
87f0e418 1703 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
9e2f7c11 1704 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
87f0e418 1705 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
7f2cddae 1706 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
60649f17 1707 [UNIT_CONSISTS_OF] = UNIT_PART_OF,
69dd2852
LP
1708 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
1709 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
87f0e418 1710 [UNIT_BEFORE] = UNIT_AFTER,
701cc384 1711 [UNIT_AFTER] = UNIT_BEFORE,
5de9682c 1712 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
701cc384 1713 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
57020a3a
LP
1714 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
1715 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
4dcc1cb4 1716 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
7f2cddae 1717 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
85e9a101 1718 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
87f0e418 1719 };
701cc384 1720 int r, q = 0, v = 0, w = 0;
87f0e418
LP
1721
1722 assert(u);
1723 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
87f0e418
LP
1724 assert(other);
1725
9f151f29
LP
1726 u = unit_follow_merge(u);
1727 other = unit_follow_merge(other);
1728
87f0e418
LP
1729 /* We won't allow dependencies on ourselves. We will not
1730 * consider them an error however. */
1731 if (u == other)
1732 return 0;
1733
ac155bb8 1734 if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
87f0e418
LP
1735 return r;
1736
5de9682c 1737 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
ac155bb8 1738 if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
5de9682c
LP
1739 return r;
1740
701cc384 1741 if (add_reference)
ac155bb8
MS
1742 if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
1743 (r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
701cc384 1744 return r;
87f0e418 1745
ac155bb8 1746 if ((q = set_put(u->dependencies[d], other)) < 0)
701cc384 1747 return q;
87f0e418 1748
5de9682c 1749 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
ac155bb8 1750 if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) {
5de9682c
LP
1751 r = v;
1752 goto fail;
1753 }
701cc384
LP
1754
1755 if (add_reference) {
ac155bb8 1756 if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) {
701cc384
LP
1757 r = w;
1758 goto fail;
1759 }
1760
ac155bb8 1761 if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0)
701cc384 1762 goto fail;
87f0e418
LP
1763 }
1764
c1e1601e 1765 unit_add_to_dbus_queue(u);
87f0e418 1766 return 0;
701cc384
LP
1767
1768fail:
1769 if (q > 0)
ac155bb8 1770 set_remove(u->dependencies[d], other);
701cc384
LP
1771
1772 if (v > 0)
ac155bb8 1773 set_remove(other->dependencies[inverse_table[d]], u);
701cc384
LP
1774
1775 if (w > 0)
ac155bb8 1776 set_remove(u->dependencies[UNIT_REFERENCES], other);
701cc384
LP
1777
1778 return r;
87f0e418 1779}
0301abf4 1780
2c966c03
LP
1781int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
1782 int r;
1783
1784 assert(u);
1785
1786 if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
1787 return r;
1788
1789 if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
1790 return r;
1791
1792 return 0;
1793}
1794
9e2f7c11
LP
1795static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
1796 char *s;
1797
1798 assert(u);
1799 assert(name || path);
8afbb8e1 1800 assert(p);
9e2f7c11
LP
1801
1802 if (!name)
9eb977db 1803 name = path_get_file_name(path);
9e2f7c11
LP
1804
1805 if (!unit_name_is_template(name)) {
1806 *p = NULL;
1807 return name;
1808 }
1809
ac155bb8
MS
1810 if (u->instance)
1811 s = unit_name_replace_instance(name, u->instance);
9e2f7c11
LP
1812 else {
1813 char *i;
1814
8afbb8e1
LP
1815 i = unit_name_to_prefix(u->id);
1816 if (!i)
9e2f7c11
LP
1817 return NULL;
1818
1819 s = unit_name_replace_instance(name, i);
1820 free(i);
1821 }
1822
1823 if (!s)
1824 return NULL;
1825
1826 *p = s;
1827 return s;
1828}
1829
701cc384 1830int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
09b6b09f
LP
1831 Unit *other;
1832 int r;
8afbb8e1 1833 _cleanup_free_ char *s = NULL;
09b6b09f 1834
9e2f7c11
LP
1835 assert(u);
1836 assert(name || path);
09b6b09f 1837
8afbb8e1
LP
1838 name = resolve_template(u, name, path, &s);
1839 if (!name)
9e2f7c11 1840 return -ENOMEM;
09b6b09f 1841
8afbb8e1
LP
1842 r = manager_load_unit(u->manager, name, path, NULL, &other);
1843 if (r < 0)
1844 return r;
9e2f7c11 1845
8afbb8e1 1846 return unit_add_dependency(u, d, other, add_reference);
09b6b09f
LP
1847}
1848
2c966c03
LP
1849int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1850 Unit *other;
1851 int r;
1852 char *s;
1853
1854 assert(u);
1855 assert(name || path);
1856
1857 if (!(name = resolve_template(u, name, path, &s)))
1858 return -ENOMEM;
1859
ac155bb8 1860 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
2c966c03
LP
1861 goto finish;
1862
1863 r = unit_add_two_dependencies(u, d, e, other, add_reference);
1864
1865finish:
1866 free(s);
1867 return r;
1868}
1869
701cc384 1870int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
bd77d0fc
LP
1871 Unit *other;
1872 int r;
9e2f7c11 1873 char *s;
bd77d0fc 1874
9e2f7c11
LP
1875 assert(u);
1876 assert(name || path);
bd77d0fc 1877
9e2f7c11
LP
1878 if (!(name = resolve_template(u, name, path, &s)))
1879 return -ENOMEM;
bd77d0fc 1880
ac155bb8 1881 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
9e2f7c11
LP
1882 goto finish;
1883
701cc384 1884 r = unit_add_dependency(other, d, u, add_reference);
9e2f7c11
LP
1885
1886finish:
1887 free(s);
1888 return r;
bd77d0fc
LP
1889}
1890
2c966c03
LP
1891int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1892 Unit *other;
1893 int r;
1894 char *s;
1895
1896 assert(u);
1897 assert(name || path);
1898
1899 if (!(name = resolve_template(u, name, path, &s)))
1900 return -ENOMEM;
1901
ac155bb8 1902 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
2c966c03
LP
1903 goto finish;
1904
1905 if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
1906 goto finish;
1907
1908finish:
1909 free(s);
1910 return r;
1911}
1912
0301abf4 1913int set_unit_path(const char *p) {
26d04f86 1914 _cleanup_free_ char *c = NULL;
0301abf4
LP
1915
1916 /* This is mostly for debug purposes */
26d04f86
LP
1917 c = path_make_absolute_cwd(p);
1918 if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0)
1919 return -errno;
0301abf4
LP
1920
1921 return 0;
1922}
88066b3a 1923
ea430986 1924char *unit_dbus_path(Unit *u) {
ea430986
LP
1925 assert(u);
1926
ac155bb8 1927 if (!u->id)
04ade7d2
LP
1928 return NULL;
1929
48899192 1930 return unit_dbus_path_from_name(u->id);
ea430986
LP
1931}
1932
8e274523 1933int unit_add_cgroup(Unit *u, CGroupBonding *b) {
8e274523
LP
1934 int r;
1935
1936 assert(u);
1937 assert(b);
35d2e7ec 1938
8e274523
LP
1939 assert(b->path);
1940
e025b4c3 1941 if (!b->controller) {
246aa6dd
LP
1942 b->controller = strdup(SYSTEMD_CGROUP_CONTROLLER);
1943 if (!b->controller)
1944 return log_oom();
35d2e7ec 1945
e025b4c3
LP
1946 b->ours = true;
1947 }
1948
8e274523
LP
1949 /* Ensure this hasn't been added yet */
1950 assert(!b->unit);
1951
d686d8a9
LP
1952 if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) {
1953 CGroupBonding *l;
8e274523 1954
ac155bb8 1955 l = hashmap_get(u->manager->cgroup_bondings, b->path);
d686d8a9
LP
1956 LIST_PREPEND(CGroupBonding, by_path, l, b);
1957
246aa6dd
LP
1958 r = hashmap_replace(u->manager->cgroup_bondings, b->path, l);
1959 if (r < 0) {
d686d8a9
LP
1960 LIST_REMOVE(CGroupBonding, by_path, l, b);
1961 return r;
1962 }
8e274523
LP
1963 }
1964
ac155bb8 1965 LIST_PREPEND(CGroupBonding, by_unit, u->cgroup_bondings, b);
8e274523
LP
1966 b->unit = u;
1967
1968 return 0;
1969}
1970
41f9172f 1971char *unit_default_cgroup_path(Unit *u) {
013b87c0
LP
1972 assert(u);
1973
ac155bb8 1974 if (u->instance) {
246aa6dd 1975 _cleanup_free_ char *t = NULL;
013b87c0 1976
ac155bb8 1977 t = unit_name_template(u->id);
cd0ed1db 1978 if (!t)
4f2d528d
LP
1979 return NULL;
1980
246aa6dd 1981 return strjoin(u->manager->cgroup_hierarchy, "/", t, "/", u->instance, NULL);
4f2d528d 1982 } else
246aa6dd 1983 return strjoin(u->manager->cgroup_hierarchy, "/", u->id, NULL);
013b87c0
LP
1984}
1985
246aa6dd 1986int unit_add_cgroup_from_text(Unit *u, const char *name, bool overwrite, CGroupBonding **ret) {
013b87c0
LP
1987 char *controller = NULL, *path = NULL;
1988 CGroupBonding *b = NULL;
e025b4c3 1989 bool ours = false;
8e274523
LP
1990 int r;
1991
1992 assert(u);
1993 assert(name);
1994
246aa6dd
LP
1995 r = cg_split_spec(name, &controller, &path);
1996 if (r < 0)
35d2e7ec 1997 return r;
8e274523 1998
e025b4c3 1999 if (!path) {
41f9172f 2000 path = unit_default_cgroup_path(u);
e025b4c3
LP
2001 ours = true;
2002 }
013b87c0 2003
e025b4c3 2004 if (!controller) {
55096547 2005 controller = strdup(SYSTEMD_CGROUP_CONTROLLER);
e025b4c3
LP
2006 ours = true;
2007 }
013b87c0 2008
35d2e7ec
LP
2009 if (!path || !controller) {
2010 free(path);
2011 free(controller);
246aa6dd 2012 return log_oom();
8e274523
LP
2013 }
2014
246aa6dd
LP
2015 b = cgroup_bonding_find_list(u->cgroup_bondings, controller);
2016 if (b) {
2017 if (streq(path, b->path)) {
2018 free(path);
2019 free(controller);
2020
2021 if (ret)
2022 *ret = b;
2023 return 0;
2024 }
2025
2026 if (overwrite && !b->essential) {
2027 free(controller);
2028
2029 free(b->path);
2030 b->path = path;
2031
2032 b->ours = ours;
2033 b->realized = false;
2034
2035 if (ret)
2036 *ret = b;
2037
2038 return 1;
2039 }
2040
013b87c0 2041 r = -EEXIST;
246aa6dd 2042 b = NULL;
013b87c0
LP
2043 goto fail;
2044 }
8e274523 2045
246aa6dd
LP
2046 b = new0(CGroupBonding, 1);
2047 if (!b) {
8e274523
LP
2048 r = -ENOMEM;
2049 goto fail;
2050 }
2051
013b87c0
LP
2052 b->controller = controller;
2053 b->path = path;
e025b4c3
LP
2054 b->ours = ours;
2055 b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER);
8e274523 2056
246aa6dd
LP
2057 r = unit_add_cgroup(u, b);
2058 if (r < 0)
8e274523
LP
2059 goto fail;
2060
246aa6dd
LP
2061 if (ret)
2062 *ret = b;
2063
2064 return 1;
8e274523
LP
2065
2066fail:
013b87c0
LP
2067 free(path);
2068 free(controller);
8e274523
LP
2069 free(b);
2070
2071 return r;
2072}
2073
06d4c99a 2074static int unit_add_one_default_cgroup(Unit *u, const char *controller) {
d686d8a9 2075 CGroupBonding *b = NULL;
8e274523
LP
2076 int r = -ENOMEM;
2077
2078 assert(u);
2079
06d4c99a
LP
2080 if (!controller)
2081 controller = SYSTEMD_CGROUP_CONTROLLER;
8e274523 2082
ac155bb8 2083 if (cgroup_bonding_find_list(u->cgroup_bondings, controller))
06d4c99a 2084 return 0;
8e274523 2085
246aa6dd
LP
2086 b = new0(CGroupBonding, 1);
2087 if (!b)
06d4c99a 2088 return -ENOMEM;
8e274523 2089
246aa6dd 2090 b->controller = strdup(controller);
8755586e 2091 if (!b->controller)
06d4c99a 2092 goto fail;
d686d8a9 2093
41f9172f
LP
2094 b->path = unit_default_cgroup_path(u);
2095 if (!b->path)
06d4c99a 2096 goto fail;
d686d8a9 2097
06d4c99a
LP
2098 b->ours = true;
2099 b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER);
d686d8a9 2100
246aa6dd
LP
2101 r = unit_add_cgroup(u, b);
2102 if (r < 0)
06d4c99a 2103 goto fail;
8e274523 2104
26d04f86 2105 return 1;
8e274523
LP
2106
2107fail:
06d4c99a
LP
2108 free(b->path);
2109 free(b->controller);
2110 free(b);
8e274523
LP
2111
2112 return r;
2113}
2114
06d4c99a 2115int unit_add_default_cgroups(Unit *u) {
ab1f0633 2116 CGroupAttribute *a;
06d4c99a
LP
2117 char **c;
2118 int r;
ab1f0633 2119
06d4c99a
LP
2120 assert(u);
2121
2122 /* Adds in the default cgroups, if they weren't specified
2123 * otherwise. */
2124
ac155bb8 2125 if (!u->manager->cgroup_hierarchy)
df18d8c8
LP
2126 return 0;
2127
246aa6dd
LP
2128 r = unit_add_one_default_cgroup(u, NULL);
2129 if (r < 0)
06d4c99a
LP
2130 return r;
2131
ac155bb8 2132 STRV_FOREACH(c, u->manager->default_controllers)
ab1f0633
LP
2133 unit_add_one_default_cgroup(u, *c);
2134
ac155bb8 2135 LIST_FOREACH(by_unit, a, u->cgroup_attributes)
ab1f0633 2136 unit_add_one_default_cgroup(u, a->controller);
06d4c99a
LP
2137
2138 return 0;
2139}
2140
8e274523
LP
2141CGroupBonding* unit_get_default_cgroup(Unit *u) {
2142 assert(u);
2143
246aa6dd 2144 return cgroup_bonding_find_list(u->cgroup_bondings, NULL);
8e274523
LP
2145}
2146
246aa6dd
LP
2147int unit_add_cgroup_attribute(
2148 Unit *u,
26d04f86 2149 const CGroupSemantics *semantics,
246aa6dd
LP
2150 const char *controller,
2151 const char *name,
2152 const char *value,
246aa6dd
LP
2153 CGroupAttribute **ret) {
2154
2155 _cleanup_free_ char *c = NULL;
ab1f0633 2156 CGroupAttribute *a;
e884315e 2157 int r;
ab1f0633
LP
2158
2159 assert(u);
ab1f0633
LP
2160 assert(value);
2161
26d04f86
LP
2162 if (semantics) {
2163 /* Semantics always take precedence */
2164 if (semantics->name)
2165 name = semantics->name;
2166
2167 if (semantics->controller)
2168 controller = semantics->controller;
2169 }
2170
2171 if (!name)
2172 return -EINVAL;
2173
ab1f0633 2174 if (!controller) {
e884315e
LP
2175 r = cg_controller_from_attr(name, &c);
2176 if (r < 0)
ab1f0633
LP
2177 return -EINVAL;
2178
ab1f0633
LP
2179 controller = c;
2180 }
2181
e884315e 2182 if (!controller || streq(controller, SYSTEMD_CGROUP_CONTROLLER))
246aa6dd
LP
2183 return -EINVAL;
2184
26d04f86
LP
2185 if (!filename_is_safe(name))
2186 return -EINVAL;
2187
2188 if (!filename_is_safe(controller))
2189 return -EINVAL;
2190
2191 /* Check if this attribute already exists. Note that we will
2192 * explicitly check for the value here too, as there are
2193 * attributes which accept multiple values. */
246aa6dd
LP
2194 a = cgroup_attribute_find_list(u->cgroup_attributes, controller, name);
2195 if (a) {
246aa6dd 2196 if (streq(value, a->value)) {
26d04f86 2197 /* Exactly the same value is always OK, let's ignore this */
246aa6dd
LP
2198 if (ret)
2199 *ret = a;
2200
2201 return 0;
2202 }
2203
26d04f86
LP
2204 if (semantics && !semantics->multiple) {
2205 char *v;
246aa6dd 2206
26d04f86
LP
2207 /* If this is a single-item entry, we can
2208 * simply patch the existing attribute */
2209
2210 v = strdup(value);
2211 if (!v)
2212 return -ENOMEM;
246aa6dd 2213
26d04f86
LP
2214 free(a->value);
2215 a->value = v;
246aa6dd 2216
26d04f86
LP
2217 if (ret)
2218 *ret = a;
2219 return 1;
2220 }
ab1f0633
LP
2221 }
2222
2223 a = new0(CGroupAttribute, 1);
246aa6dd
LP
2224 if (!a)
2225 return -ENOMEM;
ab1f0633
LP
2226
2227 if (c) {
2228 a->controller = c;
2229 c = NULL;
2230 } else
2231 a->controller = strdup(controller);
2232
2233 a->name = strdup(name);
2234 a->value = strdup(value);
2235
2236 if (!a->controller || !a->name || !a->value) {
2237 free(a->controller);
2238 free(a->name);
2239 free(a->value);
2240 free(a);
ab1f0633
LP
2241 return -ENOMEM;
2242 }
2243
26d04f86 2244 a->semantics = semantics;
246aa6dd 2245 a->unit = u;
ab1f0633 2246
ac155bb8 2247 LIST_PREPEND(CGroupAttribute, by_unit, u->cgroup_attributes, a);
ab1f0633 2248
246aa6dd
LP
2249 if (ret)
2250 *ret = a;
ab1f0633 2251
246aa6dd 2252 return 1;
ab1f0633
LP
2253}
2254
f6ff8c29
LP
2255int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
2256 char *t;
2257 int r;
2258
2259 assert(u);
2260 assert(type);
2261 assert(_found);
2262
ac155bb8 2263 if (!(t = unit_name_change_suffix(u->id, type)))
f6ff8c29
LP
2264 return -ENOMEM;
2265
2266 assert(!unit_has_name(u, t));
2267
ac155bb8 2268 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
f6ff8c29
LP
2269 free(t);
2270
9e2f7c11 2271 assert(r < 0 || *_found != u);
f6ff8c29
LP
2272
2273 return r;
2274}
2275
a16e1123
LP
2276int unit_get_related_unit(Unit *u, const char *type, Unit **_found) {
2277 Unit *found;
2278 char *t;
2279
2280 assert(u);
2281 assert(type);
2282 assert(_found);
2283
ac155bb8 2284 if (!(t = unit_name_change_suffix(u->id, type)))
a16e1123
LP
2285 return -ENOMEM;
2286
2287 assert(!unit_has_name(u, t));
2288
ac155bb8 2289 found = manager_get_unit(u->manager, t);
a16e1123
LP
2290 free(t);
2291
2292 if (!found)
2293 return -ENOENT;
2294
2295 *_found = found;
2296 return 0;
2297}
2298
05e343b7
LP
2299int unit_watch_bus_name(Unit *u, const char *name) {
2300 assert(u);
2301 assert(name);
2302
2303 /* Watch a specific name on the bus. We only support one unit
2304 * watching each name for now. */
2305
ac155bb8 2306 return hashmap_put(u->manager->watch_bus, name, u);
05e343b7
LP
2307}
2308
2309void unit_unwatch_bus_name(Unit *u, const char *name) {
2310 assert(u);
2311 assert(name);
2312
ac155bb8 2313 hashmap_remove_value(u->manager->watch_bus, name, u);
05e343b7
LP
2314}
2315
a16e1123
LP
2316bool unit_can_serialize(Unit *u) {
2317 assert(u);
2318
2319 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2320}
2321
6b78f9b4 2322int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
a16e1123
LP
2323 int r;
2324
2325 assert(u);
2326 assert(f);
2327 assert(fds);
2328
2329 if (!unit_can_serialize(u))
2330 return 0;
2331
2332 if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
2333 return r;
2334
cca098b0 2335
6b78f9b4
LP
2336 if (serialize_jobs) {
2337 if (u->job) {
2338 fprintf(f, "job\n");
2339 job_serialize(u->job, f, fds);
2340 }
2341
2342 if (u->nop_job) {
2343 fprintf(f, "job\n");
2344 job_serialize(u->nop_job, f, fds);
2345 }
e0209d83
MS
2346 }
2347
ac155bb8
MS
2348 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2349 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2350 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2351 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2352 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
2791a8f8 2353
ac155bb8
MS
2354 if (dual_timestamp_is_set(&u->condition_timestamp))
2355 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
10717a1a 2356
a16e1123
LP
2357 /* End marker */
2358 fputc('\n', f);
2359 return 0;
2360}
2361
2362void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2363 va_list ap;
2364
2365 assert(u);
2366 assert(f);
2367 assert(key);
2368 assert(format);
2369
2370 fputs(key, f);
2371 fputc('=', f);
2372
2373 va_start(ap, format);
2374 vfprintf(f, format, ap);
2375 va_end(ap);
2376
2377 fputc('\n', f);
2378}
2379
2380void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2381 assert(u);
2382 assert(f);
2383 assert(key);
2384 assert(value);
2385
2386 fprintf(f, "%s=%s\n", key, value);
2387}
2388
2389int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
2390 int r;
2391
2392 assert(u);
2393 assert(f);
2394 assert(fds);
2395
2396 if (!unit_can_serialize(u))
2397 return 0;
2398
2399 for (;;) {
20c03b7b 2400 char line[LINE_MAX], *l, *v;
a16e1123
LP
2401 size_t k;
2402
2403 if (!fgets(line, sizeof(line), f)) {
2404 if (feof(f))
2405 return 0;
2406 return -errno;
2407 }
2408
10f8e83c 2409 char_array_0(line);
a16e1123
LP
2410 l = strstrip(line);
2411
2412 /* End marker */
2413 if (l[0] == 0)
2414 return 0;
2415
2416 k = strcspn(l, "=");
2417
2418 if (l[k] == '=') {
2419 l[k] = 0;
2420 v = l+k+1;
2421 } else
2422 v = l+k;
2423
cca098b0 2424 if (streq(l, "job")) {
39a18c60
MS
2425 if (v[0] == '\0') {
2426 /* new-style serialized job */
2427 Job *j = job_new_raw(u);
2428 if (!j)
2429 return -ENOMEM;
2430
2431 r = job_deserialize(j, f, fds);
2432 if (r < 0) {
2433 job_free(j);
2434 return r;
2435 }
cca098b0 2436
39a18c60
MS
2437 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2438 if (r < 0) {
2439 job_free(j);
2440 return r;
2441 }
e0209d83
MS
2442
2443 r = job_install_deserialized(j);
2444 if (r < 0) {
2445 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2446 job_free(j);
2447 return r;
2448 }
6b19ad24
MS
2449
2450 if (j->state == JOB_RUNNING)
2451 u->manager->n_running_jobs++;
39a18c60
MS
2452 } else {
2453 /* legacy */
2454 JobType type = job_type_from_string(v);
2455 if (type < 0)
2456 log_debug("Failed to parse job type value %s", v);
2457 else
2458 u->deserialized_job = type;
2459 }
cca098b0 2460 continue;
8aaf019b 2461 } else if (streq(l, "inactive-exit-timestamp")) {
ac155bb8 2462 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
8aaf019b
LP
2463 continue;
2464 } else if (streq(l, "active-enter-timestamp")) {
ac155bb8 2465 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
8aaf019b
LP
2466 continue;
2467 } else if (streq(l, "active-exit-timestamp")) {
ac155bb8 2468 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
8aaf019b
LP
2469 continue;
2470 } else if (streq(l, "inactive-enter-timestamp")) {
ac155bb8 2471 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
8aaf019b 2472 continue;
2791a8f8 2473 } else if (streq(l, "condition-timestamp")) {
ac155bb8 2474 dual_timestamp_deserialize(v, &u->condition_timestamp);
2791a8f8
LP
2475 continue;
2476 } else if (streq(l, "condition-result")) {
2477 int b;
2478
2479 if ((b = parse_boolean(v)) < 0)
2480 log_debug("Failed to parse condition result value %s", v);
2481 else
ac155bb8 2482 u->condition_result = b;
efbac6d2
LP
2483
2484 continue;
8aaf019b 2485 }
cca098b0 2486
a16e1123
LP
2487 if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0)
2488 return r;
2489 }
2490}
2491
6e2ef85b
LP
2492int unit_add_node_link(Unit *u, const char *what, bool wants) {
2493 Unit *device;
2494 char *e;
2495 int r;
2496
2497 assert(u);
2498
2499 if (!what)
2500 return 0;
2501
2502 /* Adds in links to the device node that this unit is based on */
2503
8407a5d0 2504 if (!is_device_path(what))
6e2ef85b
LP
2505 return 0;
2506
35eb6b12
LP
2507 e = unit_name_from_path(what, ".device");
2508 if (!e)
6e2ef85b
LP
2509 return -ENOMEM;
2510
ac155bb8 2511 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
6e2ef85b 2512 free(e);
6e2ef85b
LP
2513 if (r < 0)
2514 return r;
2515
faa368e3
LP
2516 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
2517 if (r < 0)
6e2ef85b
LP
2518 return r;
2519
faa368e3
LP
2520 if (wants) {
2521 r = unit_add_dependency(device, UNIT_WANTS, u, false);
2522 if (r < 0)
6e2ef85b 2523 return r;
faa368e3 2524 }
6e2ef85b
LP
2525
2526 return 0;
2527}
a16e1123 2528
cca098b0
LP
2529int unit_coldplug(Unit *u) {
2530 int r;
2531
2532 assert(u);
2533
2534 if (UNIT_VTABLE(u)->coldplug)
2535 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2536 return r;
2537
39a18c60
MS
2538 if (u->job) {
2539 r = job_coldplug(u->job);
2540 if (r < 0)
2541 return r;
2542 } else if (u->deserialized_job >= 0) {
2543 /* legacy */
2544 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2545 if (r < 0)
cca098b0
LP
2546 return r;
2547
ac155bb8 2548 u->deserialized_job = _JOB_TYPE_INVALID;
cca098b0
LP
2549 }
2550
2551 return 0;
2552}
2553
49b1d377
MS
2554void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) {
2555 manager_status_printf(u->manager, false, status, unit_status_msg_format, unit_description(u));
2556}
2557
45fb0699 2558bool unit_need_daemon_reload(Unit *u) {
ae7a7182
OS
2559 _cleanup_strv_free_ char **t = NULL;
2560 char **path;
1b64d026 2561 struct stat st;
ae7a7182 2562 unsigned loaded_cnt, current_cnt;
1b64d026 2563
45fb0699
LP
2564 assert(u);
2565
ac155bb8 2566 if (u->fragment_path) {
5f4b19f4 2567 zero(st);
ac155bb8 2568 if (stat(u->fragment_path, &st) < 0)
5f4b19f4
LP
2569 /* What, cannot access this anymore? */
2570 return true;
45fb0699 2571
ac155bb8
MS
2572 if (u->fragment_mtime > 0 &&
2573 timespec_load(&st.st_mtim) != u->fragment_mtime)
5f4b19f4
LP
2574 return true;
2575 }
2576
1b64d026
LP
2577 if (u->source_path) {
2578 zero(st);
2579 if (stat(u->source_path, &st) < 0)
2580 return true;
2581
2582 if (u->source_mtime > 0 &&
2583 timespec_load(&st.st_mtim) != u->source_mtime)
2584 return true;
2585 }
5f4b19f4 2586
ae7a7182
OS
2587 t = unit_find_dropin_paths(u);
2588 loaded_cnt = strv_length(t);
2589 current_cnt = strv_length(u->dropin_paths);
2590
2591 if (loaded_cnt == current_cnt) {
2592 if (loaded_cnt == 0)
2593 return false;
2594
2595 if (strv_overlap(u->dropin_paths, t)) {
2596 STRV_FOREACH(path, u->dropin_paths) {
2597 zero(st);
2598 if (stat(*path, &st) < 0)
2599 return true;
2600
2601 if (u->dropin_mtime > 0 &&
2602 timespec_load(&st.st_mtim) > u->dropin_mtime)
2603 return true;
2604 }
2605
2606 return false;
2607 } else
2608 return true;
2609 } else
2610 return true;
45fb0699
LP
2611}
2612
fdf20a31 2613void unit_reset_failed(Unit *u) {
5632e374
LP
2614 assert(u);
2615
fdf20a31
MM
2616 if (UNIT_VTABLE(u)->reset_failed)
2617 UNIT_VTABLE(u)->reset_failed(u);
5632e374
LP
2618}
2619
a7f241db
LP
2620Unit *unit_following(Unit *u) {
2621 assert(u);
2622
2623 if (UNIT_VTABLE(u)->following)
2624 return UNIT_VTABLE(u)->following(u);
2625
2626 return NULL;
2627}
2628
18ffdfda
LP
2629bool unit_pending_inactive(Unit *u) {
2630 assert(u);
2631
2632 /* Returns true if the unit is inactive or going down */
2633
2634 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2635 return true;
2636
ac155bb8 2637 if (u->job && u->job->type == JOB_STOP)
18ffdfda
LP
2638 return true;
2639
2640 return false;
2641}
2642
f976f3f6
LP
2643bool unit_pending_active(Unit *u) {
2644 assert(u);
2645
f60c2665 2646 /* Returns true if the unit is active or going up */
f976f3f6
LP
2647
2648 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2649 return true;
2650
ac155bb8
MS
2651 if (u->job &&
2652 (u->job->type == JOB_START ||
2653 u->job->type == JOB_RELOAD_OR_START ||
2654 u->job->type == JOB_RESTART))
f976f3f6
LP
2655 return true;
2656
2657 return false;
2658}
2659
c74f17d9 2660int unit_kill(Unit *u, KillWho w, int signo, DBusError *error) {
8a0867d6
LP
2661 assert(u);
2662 assert(w >= 0 && w < _KILL_WHO_MAX);
8a0867d6
LP
2663 assert(signo > 0);
2664 assert(signo < _NSIG);
2665
8a0867d6
LP
2666 if (!UNIT_VTABLE(u)->kill)
2667 return -ENOTSUP;
2668
c74f17d9 2669 return UNIT_VTABLE(u)->kill(u, w, signo, error);
8a0867d6
LP
2670}
2671
d91c34f2
LP
2672int unit_kill_common(
2673 Unit *u,
2674 KillWho who,
2675 int signo,
2676 pid_t main_pid,
2677 pid_t control_pid,
2678 DBusError *error) {
2679
814cc562
MS
2680 int r = 0;
2681
2682 if (who == KILL_MAIN && main_pid <= 0) {
2683 if (main_pid < 0)
2684 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
2685 else
2686 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
2687 return -ESRCH;
2688 }
2689
2690 if (who == KILL_CONTROL && control_pid <= 0) {
2691 if (control_pid < 0)
2692 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
2693 else
2694 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
2695 return -ESRCH;
2696 }
2697
2698 if (who == KILL_CONTROL || who == KILL_ALL)
2699 if (control_pid > 0)
2700 if (kill(control_pid, signo) < 0)
2701 r = -errno;
2702
2703 if (who == KILL_MAIN || who == KILL_ALL)
2704 if (main_pid > 0)
2705 if (kill(main_pid, signo) < 0)
2706 r = -errno;
2707
2708 if (who == KILL_ALL) {
2709 _cleanup_set_free_ Set *pid_set = NULL;
2710 int q;
2711
2712 pid_set = set_new(trivial_hash_func, trivial_compare_func);
2713 if (!pid_set)
2714 return -ENOMEM;
2715
2716 /* Exclude the control/main pid from being killed via the cgroup */
2717 if (control_pid > 0) {
2718 q = set_put(pid_set, LONG_TO_PTR(control_pid));
2719 if (q < 0)
2720 return q;
2721 }
2722
2723 if (main_pid > 0) {
2724 q = set_put(pid_set, LONG_TO_PTR(main_pid));
2725 if (q < 0)
2726 return q;
2727 }
2728
2729 q = cgroup_bonding_kill_list(u->cgroup_bondings, signo, false, false, pid_set, NULL);
2730 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
2731 r = q;
2732 }
2733
2734 return r;
2735}
2736
6210e7fc
LP
2737int unit_following_set(Unit *u, Set **s) {
2738 assert(u);
2739 assert(s);
2740
2741 if (UNIT_VTABLE(u)->following_set)
2742 return UNIT_VTABLE(u)->following_set(u, s);
2743
2744 *s = NULL;
2745 return 0;
2746}
2747
a4375746
LP
2748UnitFileState unit_get_unit_file_state(Unit *u) {
2749 assert(u);
2750
ac155bb8
MS
2751 if (u->unit_file_state < 0 && u->fragment_path)
2752 u->unit_file_state = unit_file_get_state(
67445f4e 2753 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
9eb977db 2754 NULL, path_get_file_name(u->fragment_path));
a4375746 2755
ac155bb8 2756 return u->unit_file_state;
a4375746
LP
2757}
2758
57020a3a
LP
2759Unit* unit_ref_set(UnitRef *ref, Unit *u) {
2760 assert(ref);
2761 assert(u);
2762
2763 if (ref->unit)
2764 unit_ref_unset(ref);
2765
2766 ref->unit = u;
ac155bb8 2767 LIST_PREPEND(UnitRef, refs, u->refs, ref);
57020a3a
LP
2768 return u;
2769}
2770
2771void unit_ref_unset(UnitRef *ref) {
2772 assert(ref);
2773
2774 if (!ref->unit)
2775 return;
2776
ac155bb8 2777 LIST_REMOVE(UnitRef, refs, ref->unit->refs, ref);
57020a3a
LP
2778 ref->unit = NULL;
2779}
2780
7c8fa05c
LP
2781int unit_add_one_mount_link(Unit *u, Mount *m) {
2782 char **i;
2783
2784 assert(u);
2785 assert(m);
2786
2787 if (u->load_state != UNIT_LOADED ||
2788 UNIT(m)->load_state != UNIT_LOADED)
2789 return 0;
2790
2791 STRV_FOREACH(i, u->requires_mounts_for) {
2792
2793 if (UNIT(m) == u)
2794 continue;
2795
2796 if (!path_startswith(*i, m->where))
2797 continue;
2798
2799 return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
2800 }
2801
2802 return 0;
2803}
2804
2805int unit_add_mount_links(Unit *u) {
2806 Unit *other;
2807 int r;
2808
2809 assert(u);
2810
2811 LIST_FOREACH(units_by_type, other, u->manager->units_by_type[UNIT_MOUNT]) {
2812 r = unit_add_one_mount_link(u, MOUNT(other));
2813 if (r < 0)
2814 return r;
2815 }
2816
2817 return 0;
2818}
2819
cba6e062
LP
2820int unit_exec_context_defaults(Unit *u, ExecContext *c) {
2821 unsigned i;
2822 int r;
2823
e06c73cc
LP
2824 assert(u);
2825 assert(c);
2826
cba6e062 2827 /* This only copies in the ones that need memory */
e06c73cc 2828
cba6e062
LP
2829 for (i = 0; i < RLIMIT_NLIMITS; i++)
2830 if (u->manager->rlimit[i] && !c->rlimit[i]) {
2831 c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
2832 if (!c->rlimit[i])
2833 return -ENOMEM;
2834 }
2835
67445f4e 2836 if (u->manager->running_as == SYSTEMD_USER &&
cba6e062 2837 !c->working_directory) {
e06c73cc 2838
cba6e062
LP
2839 r = get_home_dir(&c->working_directory);
2840 if (r < 0)
2841 return r;
2842 }
2843
2844 return 0;
e06c73cc
LP
2845}
2846
3ef63c31
LP
2847ExecContext *unit_get_exec_context(Unit *u) {
2848 size_t offset;
2849 assert(u);
2850
2851 offset = UNIT_VTABLE(u)->exec_context_offset;
2852 if (offset <= 0)
2853 return NULL;
2854
2855 return (ExecContext*) ((uint8_t*) u + offset);
2856}
2857
26d04f86
LP
2858static int drop_in_file(Unit *u, bool runtime, const char *name, char **_p, char **_q) {
2859 char *p, *q;
2860 int r;
2861
71645aca 2862 assert(u);
26d04f86
LP
2863 assert(name);
2864 assert(_p);
2865 assert(_q);
71645aca 2866
26d04f86 2867 if (u->manager->running_as == SYSTEMD_USER && runtime)
71645aca
LP
2868 return -ENOTSUP;
2869
2870 if (!filename_is_safe(name))
2871 return -EINVAL;
2872
26d04f86
LP
2873 if (u->manager->running_as == SYSTEMD_USER) {
2874 _cleanup_free_ char *c = NULL;
2875
2876 r = user_config_home(&c);
2877 if (r < 0)
2878 return r;
2879 if (r == 0)
2880 return -ENOENT;
2881
2882 p = strjoin(c, "/", u->id, ".d", NULL);
2883 } else if (runtime)
2884 p = strjoin("/run/systemd/system/", u->id, ".d", NULL);
2885 else
2886 p = strjoin("/etc/systemd/system/", u->id, ".d", NULL);
71645aca
LP
2887 if (!p)
2888 return -ENOMEM;
2889
2890 q = strjoin(p, "/50-", name, ".conf", NULL);
26d04f86
LP
2891 if (!q) {
2892 free(p);
71645aca 2893 return -ENOMEM;
26d04f86 2894 }
71645aca 2895
26d04f86
LP
2896 *_p = p;
2897 *_q = q;
2898 return 0;
71645aca
LP
2899}
2900
26d04f86 2901int unit_write_drop_in(Unit *u, bool runtime, const char *name, const char *data) {
71645aca 2902 _cleanup_free_ char *p = NULL, *q = NULL;
26d04f86 2903 int r;
71645aca
LP
2904
2905 assert(u);
2906
26d04f86
LP
2907 r = drop_in_file(u, runtime, name, &p, &q);
2908 if (r < 0)
2909 return r;
71645aca 2910
26d04f86 2911 mkdir_p(p, 0755);
574d5f2d 2912 return write_string_file_atomic_label(q, data);
26d04f86 2913}
71645aca 2914
26d04f86
LP
2915int unit_remove_drop_in(Unit *u, bool runtime, const char *name) {
2916 _cleanup_free_ char *p = NULL, *q = NULL;
2917 int r;
71645aca 2918
26d04f86 2919 assert(u);
71645aca 2920
26d04f86 2921 r = drop_in_file(u, runtime, name, &p, &q);
71645aca 2922 if (unlink(q) < 0)
26d04f86
LP
2923 r = -errno;
2924 else
2925 r = 0;
71645aca
LP
2926
2927 rmdir(p);
26d04f86 2928 return r;
71645aca
LP
2929}
2930
cd2086fe
LP
2931int unit_kill_context(
2932 Unit *u,
2933 KillContext *c,
2934 bool sigkill,
2935 pid_t main_pid,
2936 pid_t control_pid,
2937 bool main_pid_alien) {
2938
2939 int sig, wait_for_exit = 0, r;
2940
2941 assert(u);
2942 assert(c);
2943
2944 if (c->kill_mode == KILL_NONE)
2945 return 0;
2946
2947 sig = sigkill ? SIGKILL : c->kill_signal;
2948
2949 if (main_pid > 0) {
2950 r = kill_and_sigcont(main_pid, sig);
2951
2952 if (r < 0 && r != -ESRCH) {
2953 _cleanup_free_ char *comm = NULL;
2954 get_process_comm(main_pid, &comm);
2955
2956 log_warning_unit(u->id, "Failed to kill main process %li (%s): %s",
2957 (long) main_pid, strna(comm), strerror(-r));
2958 } else
2959 wait_for_exit = !main_pid_alien;
2960 }
2961
2962 if (control_pid > 0) {
2963 r = kill_and_sigcont(control_pid, sig);
2964
2965 if (r < 0 && r != -ESRCH) {
2966 _cleanup_free_ char *comm = NULL;
2967 get_process_comm(control_pid, &comm);
2968
2969 log_warning_unit(u->id,
2970 "Failed to kill control process %li (%s): %s",
2971 (long) control_pid, strna(comm), strerror(-r));
2972 } else
2973 wait_for_exit = true;
2974 }
2975
2976 if (c->kill_mode == KILL_CONTROL_GROUP) {
2977 _cleanup_set_free_ Set *pid_set = NULL;
2978
2979 pid_set = set_new(trivial_hash_func, trivial_compare_func);
2980 if (!pid_set)
2981 return -ENOMEM;
2982
2983 /* Exclude the main/control pids from being killed via the cgroup */
2984 if (main_pid > 0) {
2985 r = set_put(pid_set, LONG_TO_PTR(main_pid));
2986 if (r < 0)
2987 return r;
2988 }
2989
2990 if (control_pid > 0) {
2991 r = set_put(pid_set, LONG_TO_PTR(control_pid));
2992 if (r < 0)
2993 return r;
2994 }
2995
2996 r = cgroup_bonding_kill_list(u->cgroup_bondings, sig, true, false, pid_set, NULL);
2997 if (r < 0) {
2998 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
2999 log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
3000 } else if (r > 0)
3001 wait_for_exit = true;
3002 }
3003
3004 return wait_for_exit;
3005}
3006
94f04347
LP
3007static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
3008 [UNIT_ACTIVE] = "active",
032ff4af 3009 [UNIT_RELOADING] = "reloading",
94f04347 3010 [UNIT_INACTIVE] = "inactive",
fdf20a31 3011 [UNIT_FAILED] = "failed",
94f04347
LP
3012 [UNIT_ACTIVATING] = "activating",
3013 [UNIT_DEACTIVATING] = "deactivating"
3014};
3015
3016DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
3017
3018static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
3019 [UNIT_REQUIRES] = "Requires",
9e2f7c11 3020 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
94f04347 3021 [UNIT_REQUISITE] = "Requisite",
9e2f7c11 3022 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
ac6a4abe
MS
3023 [UNIT_WANTS] = "Wants",
3024 [UNIT_BINDS_TO] = "BindsTo",
3025 [UNIT_PART_OF] = "PartOf",
94f04347 3026 [UNIT_REQUIRED_BY] = "RequiredBy",
9e2f7c11 3027 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
94f04347 3028 [UNIT_WANTED_BY] = "WantedBy",
ac6a4abe
MS
3029 [UNIT_BOUND_BY] = "BoundBy",
3030 [UNIT_CONSISTS_OF] = "ConsistsOf",
94f04347 3031 [UNIT_CONFLICTS] = "Conflicts",
69dd2852 3032 [UNIT_CONFLICTED_BY] = "ConflictedBy",
94f04347
LP
3033 [UNIT_BEFORE] = "Before",
3034 [UNIT_AFTER] = "After",
57020a3a
LP
3035 [UNIT_ON_FAILURE] = "OnFailure",
3036 [UNIT_TRIGGERS] = "Triggers",
4dcc1cb4 3037 [UNIT_TRIGGERED_BY] = "TriggeredBy",
7f2cddae 3038 [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
ac6a4abe
MS
3039 [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
3040 [UNIT_REFERENCES] = "References",
3041 [UNIT_REFERENCED_BY] = "ReferencedBy",
94f04347
LP
3042};
3043
3044DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);