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