]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/unit.c
NEWS: correct NTP implementation data
[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,
87f0e418 1599 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
9e2f7c11 1600 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
87f0e418 1601 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
7f2cddae 1602 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
69dd2852
LP
1603 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
1604 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
87f0e418 1605 [UNIT_BEFORE] = UNIT_AFTER,
701cc384 1606 [UNIT_AFTER] = UNIT_BEFORE,
5de9682c 1607 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
701cc384 1608 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
57020a3a
LP
1609 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
1610 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
4dcc1cb4 1611 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
7f2cddae
LP
1612 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
1613 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO
87f0e418 1614 };
701cc384 1615 int r, q = 0, v = 0, w = 0;
87f0e418
LP
1616
1617 assert(u);
1618 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
87f0e418
LP
1619 assert(other);
1620
9f151f29
LP
1621 u = unit_follow_merge(u);
1622 other = unit_follow_merge(other);
1623
87f0e418
LP
1624 /* We won't allow dependencies on ourselves. We will not
1625 * consider them an error however. */
1626 if (u == other)
1627 return 0;
1628
ac155bb8 1629 if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
87f0e418
LP
1630 return r;
1631
5de9682c 1632 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
ac155bb8 1633 if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
5de9682c
LP
1634 return r;
1635
701cc384 1636 if (add_reference)
ac155bb8
MS
1637 if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
1638 (r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
701cc384 1639 return r;
87f0e418 1640
ac155bb8 1641 if ((q = set_put(u->dependencies[d], other)) < 0)
701cc384 1642 return q;
87f0e418 1643
5de9682c 1644 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
ac155bb8 1645 if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) {
5de9682c
LP
1646 r = v;
1647 goto fail;
1648 }
701cc384
LP
1649
1650 if (add_reference) {
ac155bb8 1651 if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) {
701cc384
LP
1652 r = w;
1653 goto fail;
1654 }
1655
ac155bb8 1656 if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0)
701cc384 1657 goto fail;
87f0e418
LP
1658 }
1659
c1e1601e 1660 unit_add_to_dbus_queue(u);
87f0e418 1661 return 0;
701cc384
LP
1662
1663fail:
1664 if (q > 0)
ac155bb8 1665 set_remove(u->dependencies[d], other);
701cc384
LP
1666
1667 if (v > 0)
ac155bb8 1668 set_remove(other->dependencies[inverse_table[d]], u);
701cc384
LP
1669
1670 if (w > 0)
ac155bb8 1671 set_remove(u->dependencies[UNIT_REFERENCES], other);
701cc384
LP
1672
1673 return r;
87f0e418 1674}
0301abf4 1675
2c966c03
LP
1676int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
1677 int r;
1678
1679 assert(u);
1680
1681 if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
1682 return r;
1683
1684 if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
1685 return r;
1686
1687 return 0;
1688}
1689
9e2f7c11
LP
1690static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
1691 char *s;
1692
1693 assert(u);
1694 assert(name || path);
1695
1696 if (!name)
9eb977db 1697 name = path_get_file_name(path);
9e2f7c11
LP
1698
1699 if (!unit_name_is_template(name)) {
1700 *p = NULL;
1701 return name;
1702 }
1703
ac155bb8
MS
1704 if (u->instance)
1705 s = unit_name_replace_instance(name, u->instance);
9e2f7c11
LP
1706 else {
1707 char *i;
1708
ac155bb8 1709 if (!(i = unit_name_to_prefix(u->id)))
9e2f7c11
LP
1710 return NULL;
1711
1712 s = unit_name_replace_instance(name, i);
1713 free(i);
1714 }
1715
1716 if (!s)
1717 return NULL;
1718
1719 *p = s;
1720 return s;
1721}
1722
701cc384 1723int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
09b6b09f
LP
1724 Unit *other;
1725 int r;
9e2f7c11 1726 char *s;
09b6b09f 1727
9e2f7c11
LP
1728 assert(u);
1729 assert(name || path);
09b6b09f 1730
9e2f7c11
LP
1731 if (!(name = resolve_template(u, name, path, &s)))
1732 return -ENOMEM;
09b6b09f 1733
ac155bb8 1734 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
9e2f7c11
LP
1735 goto finish;
1736
701cc384 1737 r = unit_add_dependency(u, d, other, add_reference);
9e2f7c11
LP
1738
1739finish:
1740 free(s);
1741 return r;
09b6b09f
LP
1742}
1743
2c966c03
LP
1744int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1745 Unit *other;
1746 int r;
1747 char *s;
1748
1749 assert(u);
1750 assert(name || path);
1751
1752 if (!(name = resolve_template(u, name, path, &s)))
1753 return -ENOMEM;
1754
ac155bb8 1755 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
2c966c03
LP
1756 goto finish;
1757
1758 r = unit_add_two_dependencies(u, d, e, other, add_reference);
1759
1760finish:
1761 free(s);
1762 return r;
1763}
1764
701cc384 1765int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
bd77d0fc
LP
1766 Unit *other;
1767 int r;
9e2f7c11 1768 char *s;
bd77d0fc 1769
9e2f7c11
LP
1770 assert(u);
1771 assert(name || path);
bd77d0fc 1772
9e2f7c11
LP
1773 if (!(name = resolve_template(u, name, path, &s)))
1774 return -ENOMEM;
bd77d0fc 1775
ac155bb8 1776 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
9e2f7c11
LP
1777 goto finish;
1778
701cc384 1779 r = unit_add_dependency(other, d, u, add_reference);
9e2f7c11
LP
1780
1781finish:
1782 free(s);
1783 return r;
bd77d0fc
LP
1784}
1785
2c966c03
LP
1786int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1787 Unit *other;
1788 int r;
1789 char *s;
1790
1791 assert(u);
1792 assert(name || path);
1793
1794 if (!(name = resolve_template(u, name, path, &s)))
1795 return -ENOMEM;
1796
ac155bb8 1797 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
2c966c03
LP
1798 goto finish;
1799
1800 if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
1801 goto finish;
1802
1803finish:
1804 free(s);
1805 return r;
1806}
1807
0301abf4
LP
1808int set_unit_path(const char *p) {
1809 char *cwd, *c;
1810 int r;
1811
1812 /* This is mostly for debug purposes */
1813
1814 if (path_is_absolute(p)) {
1815 if (!(c = strdup(p)))
1816 return -ENOMEM;
1817 } else {
1818 if (!(cwd = get_current_dir_name()))
1819 return -errno;
1820
1821 r = asprintf(&c, "%s/%s", cwd, p);
1822 free(cwd);
1823
1824 if (r < 0)
1825 return -ENOMEM;
1826 }
1827
036643a2 1828 if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0) {
0301abf4
LP
1829 r = -errno;
1830 free(c);
1831 return r;
1832 }
1833
1834 return 0;
1835}
88066b3a 1836
ea430986 1837char *unit_dbus_path(Unit *u) {
ea430986
LP
1838 assert(u);
1839
ac155bb8 1840 if (!u->id)
04ade7d2
LP
1841 return NULL;
1842
48899192 1843 return unit_dbus_path_from_name(u->id);
ea430986
LP
1844}
1845
8e274523 1846int unit_add_cgroup(Unit *u, CGroupBonding *b) {
8e274523
LP
1847 int r;
1848
1849 assert(u);
1850 assert(b);
35d2e7ec 1851
8e274523
LP
1852 assert(b->path);
1853
e025b4c3 1854 if (!b->controller) {
35d2e7ec
LP
1855 if (!(b->controller = strdup(SYSTEMD_CGROUP_CONTROLLER)))
1856 return -ENOMEM;
1857
e025b4c3
LP
1858 b->ours = true;
1859 }
1860
8e274523
LP
1861 /* Ensure this hasn't been added yet */
1862 assert(!b->unit);
1863
d686d8a9
LP
1864 if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) {
1865 CGroupBonding *l;
8e274523 1866
ac155bb8 1867 l = hashmap_get(u->manager->cgroup_bondings, b->path);
d686d8a9
LP
1868 LIST_PREPEND(CGroupBonding, by_path, l, b);
1869
ac155bb8 1870 if ((r = hashmap_replace(u->manager->cgroup_bondings, b->path, l)) < 0) {
d686d8a9
LP
1871 LIST_REMOVE(CGroupBonding, by_path, l, b);
1872 return r;
1873 }
8e274523
LP
1874 }
1875
ac155bb8 1876 LIST_PREPEND(CGroupBonding, by_unit, u->cgroup_bondings, b);
8e274523
LP
1877 b->unit = u;
1878
1879 return 0;
1880}
1881
013b87c0
LP
1882static char *default_cgroup_path(Unit *u) {
1883 char *p;
1884
1885 assert(u);
1886
ac155bb8 1887 if (u->instance) {
4f2d528d 1888 char *t;
013b87c0 1889
ac155bb8 1890 t = unit_name_template(u->id);
cd0ed1db 1891 if (!t)
4f2d528d
LP
1892 return NULL;
1893
b7def684 1894 p = strjoin(u->manager->cgroup_hierarchy, "/", t, "/", u->instance, NULL);
4f2d528d
LP
1895 free(t);
1896 } else
b7def684 1897 p = strjoin(u->manager->cgroup_hierarchy, "/", u->id, NULL);
4f2d528d 1898
cd0ed1db 1899 return p;
013b87c0
LP
1900}
1901
8e274523 1902int unit_add_cgroup_from_text(Unit *u, const char *name) {
013b87c0
LP
1903 char *controller = NULL, *path = NULL;
1904 CGroupBonding *b = NULL;
e025b4c3 1905 bool ours = false;
8e274523
LP
1906 int r;
1907
1908 assert(u);
1909 assert(name);
1910
35d2e7ec
LP
1911 if ((r = cg_split_spec(name, &controller, &path)) < 0)
1912 return r;
8e274523 1913
e025b4c3 1914 if (!path) {
35d2e7ec 1915 path = default_cgroup_path(u);
e025b4c3
LP
1916 ours = true;
1917 }
013b87c0 1918
e025b4c3 1919 if (!controller) {
55096547 1920 controller = strdup(SYSTEMD_CGROUP_CONTROLLER);
e025b4c3
LP
1921 ours = true;
1922 }
013b87c0 1923
35d2e7ec
LP
1924 if (!path || !controller) {
1925 free(path);
1926 free(controller);
1927
1928 return -ENOMEM;
8e274523
LP
1929 }
1930
ac155bb8 1931 if (cgroup_bonding_find_list(u->cgroup_bondings, controller)) {
013b87c0
LP
1932 r = -EEXIST;
1933 goto fail;
1934 }
8e274523 1935
013b87c0 1936 if (!(b = new0(CGroupBonding, 1))) {
8e274523
LP
1937 r = -ENOMEM;
1938 goto fail;
1939 }
1940
013b87c0
LP
1941 b->controller = controller;
1942 b->path = path;
e025b4c3
LP
1943 b->ours = ours;
1944 b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER);
8e274523
LP
1945
1946 if ((r = unit_add_cgroup(u, b)) < 0)
1947 goto fail;
1948
1949 return 0;
1950
1951fail:
013b87c0
LP
1952 free(path);
1953 free(controller);
8e274523
LP
1954 free(b);
1955
1956 return r;
1957}
1958
06d4c99a 1959static int unit_add_one_default_cgroup(Unit *u, const char *controller) {
d686d8a9 1960 CGroupBonding *b = NULL;
8e274523
LP
1961 int r = -ENOMEM;
1962
1963 assert(u);
1964
06d4c99a
LP
1965 if (!controller)
1966 controller = SYSTEMD_CGROUP_CONTROLLER;
8e274523 1967
ac155bb8 1968 if (cgroup_bonding_find_list(u->cgroup_bondings, controller))
06d4c99a 1969 return 0;
8e274523 1970
06d4c99a
LP
1971 if (!(b = new0(CGroupBonding, 1)))
1972 return -ENOMEM;
8e274523 1973
06d4c99a
LP
1974 if (!(b->controller = strdup(controller)))
1975 goto fail;
d686d8a9 1976
06d4c99a
LP
1977 if (!(b->path = default_cgroup_path(u)))
1978 goto fail;
d686d8a9 1979
06d4c99a
LP
1980 b->ours = true;
1981 b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER);
d686d8a9 1982
06d4c99a
LP
1983 if ((r = unit_add_cgroup(u, b)) < 0)
1984 goto fail;
8e274523
LP
1985
1986 return 0;
1987
1988fail:
06d4c99a
LP
1989 free(b->path);
1990 free(b->controller);
1991 free(b);
8e274523
LP
1992
1993 return r;
1994}
1995
06d4c99a 1996int unit_add_default_cgroups(Unit *u) {
ab1f0633 1997 CGroupAttribute *a;
06d4c99a
LP
1998 char **c;
1999 int r;
ab1f0633 2000
06d4c99a
LP
2001 assert(u);
2002
2003 /* Adds in the default cgroups, if they weren't specified
2004 * otherwise. */
2005
ac155bb8 2006 if (!u->manager->cgroup_hierarchy)
df18d8c8
LP
2007 return 0;
2008
06d4c99a
LP
2009 if ((r = unit_add_one_default_cgroup(u, NULL)) < 0)
2010 return r;
2011
ac155bb8 2012 STRV_FOREACH(c, u->manager->default_controllers)
ab1f0633
LP
2013 unit_add_one_default_cgroup(u, *c);
2014
ac155bb8 2015 LIST_FOREACH(by_unit, a, u->cgroup_attributes)
ab1f0633 2016 unit_add_one_default_cgroup(u, a->controller);
06d4c99a
LP
2017
2018 return 0;
2019}
2020
8e274523
LP
2021CGroupBonding* unit_get_default_cgroup(Unit *u) {
2022 assert(u);
2023
ac155bb8 2024 return cgroup_bonding_find_list(u->cgroup_bondings, SYSTEMD_CGROUP_CONTROLLER);
8e274523
LP
2025}
2026
ab1f0633
LP
2027int unit_add_cgroup_attribute(Unit *u, const char *controller, const char *name, const char *value, CGroupAttributeMapCallback map_callback) {
2028 int r;
2029 char *c = NULL;
2030 CGroupAttribute *a;
2031
2032 assert(u);
2033 assert(name);
2034 assert(value);
2035
2036 if (!controller) {
2037 const char *dot;
2038
2039 dot = strchr(name, '.');
2040 if (!dot)
2041 return -EINVAL;
2042
2043 c = strndup(name, dot - name);
2044 if (!c)
2045 return -ENOMEM;
2046
2047 controller = c;
2048 }
2049
2050 if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
2051 r = -EINVAL;
2052 goto finish;
2053 }
2054
2055 a = new0(CGroupAttribute, 1);
2056 if (!a) {
2057 r = -ENOMEM;
2058 goto finish;
2059 }
2060
2061 if (c) {
2062 a->controller = c;
2063 c = NULL;
2064 } else
2065 a->controller = strdup(controller);
2066
2067 a->name = strdup(name);
2068 a->value = strdup(value);
2069
2070 if (!a->controller || !a->name || !a->value) {
2071 free(a->controller);
2072 free(a->name);
2073 free(a->value);
2074 free(a);
2075
2076 return -ENOMEM;
2077 }
2078
2079 a->map_callback = map_callback;
2080
ac155bb8 2081 LIST_PREPEND(CGroupAttribute, by_unit, u->cgroup_attributes, a);
ab1f0633
LP
2082
2083 r = 0;
2084
2085finish:
2086 free(c);
2087 return r;
2088}
2089
f6ff8c29
LP
2090int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
2091 char *t;
2092 int r;
2093
2094 assert(u);
2095 assert(type);
2096 assert(_found);
2097
ac155bb8 2098 if (!(t = unit_name_change_suffix(u->id, type)))
f6ff8c29
LP
2099 return -ENOMEM;
2100
2101 assert(!unit_has_name(u, t));
2102
ac155bb8 2103 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
f6ff8c29
LP
2104 free(t);
2105
9e2f7c11 2106 assert(r < 0 || *_found != u);
f6ff8c29
LP
2107
2108 return r;
2109}
2110
a16e1123
LP
2111int unit_get_related_unit(Unit *u, const char *type, Unit **_found) {
2112 Unit *found;
2113 char *t;
2114
2115 assert(u);
2116 assert(type);
2117 assert(_found);
2118
ac155bb8 2119 if (!(t = unit_name_change_suffix(u->id, type)))
a16e1123
LP
2120 return -ENOMEM;
2121
2122 assert(!unit_has_name(u, t));
2123
ac155bb8 2124 found = manager_get_unit(u->manager, t);
a16e1123
LP
2125 free(t);
2126
2127 if (!found)
2128 return -ENOENT;
2129
2130 *_found = found;
2131 return 0;
2132}
2133
9e2f7c11
LP
2134static char *specifier_prefix_and_instance(char specifier, void *data, void *userdata) {
2135 Unit *u = userdata;
2136 assert(u);
2137
ac155bb8 2138 return unit_name_to_prefix_and_instance(u->id);
9e2f7c11
LP
2139}
2140
2141static char *specifier_prefix(char specifier, void *data, void *userdata) {
2142 Unit *u = userdata;
2143 assert(u);
2144
ac155bb8 2145 return unit_name_to_prefix(u->id);
9e2f7c11
LP
2146}
2147
2148static char *specifier_prefix_unescaped(char specifier, void *data, void *userdata) {
2149 Unit *u = userdata;
2150 char *p, *r;
2151
2152 assert(u);
2153
ac155bb8 2154 if (!(p = unit_name_to_prefix(u->id)))
9e2f7c11
LP
2155 return NULL;
2156
2157 r = unit_name_unescape(p);
2158 free(p);
2159
2160 return r;
2161}
2162
2163static char *specifier_instance_unescaped(char specifier, void *data, void *userdata) {
2164 Unit *u = userdata;
2165 assert(u);
2166
ac155bb8
MS
2167 if (u->instance)
2168 return unit_name_unescape(u->instance);
9e2f7c11
LP
2169
2170 return strdup("");
2171}
2172
9fc50704
LP
2173static char *specifier_filename(char specifier, void *data, void *userdata) {
2174 Unit *u = userdata;
2175 assert(u);
2176
ac155bb8
MS
2177 if (u->instance)
2178 return unit_name_path_unescape(u->instance);
9fc50704 2179
ac155bb8 2180 return unit_name_to_path(u->instance);
9fc50704
LP
2181}
2182
0aef4345
LP
2183static char *specifier_cgroup(char specifier, void *data, void *userdata) {
2184 Unit *u = userdata;
2185 assert(u);
2186
2187 return default_cgroup_path(u);
2188}
2189
2190static char *specifier_cgroup_root(char specifier, void *data, void *userdata) {
2191 Unit *u = userdata;
2192 char *p;
2193 assert(u);
2194
2195 if (specifier == 'r')
ac155bb8 2196 return strdup(u->manager->cgroup_hierarchy);
0aef4345 2197
9eb977db 2198 if (path_get_parent(u->manager->cgroup_hierarchy, &p) < 0)
0aef4345
LP
2199 return strdup("");
2200
2201 if (streq(p, "/")) {
2202 free(p);
2203 return strdup("");
2204 }
2205
2206 return p;
2207}
2208
2209static char *specifier_runtime(char specifier, void *data, void *userdata) {
2210 Unit *u = userdata;
2211 assert(u);
2212
ac155bb8 2213 if (u->manager->running_as == MANAGER_USER) {
0aef4345
LP
2214 const char *e;
2215
2216 e = getenv("XDG_RUNTIME_DIR");
2217 if (e)
2218 return strdup(e);
2219 }
2220
2221 return strdup("/run");
2222}
2223
b2896c90
AK
2224static char *specifier_user_name(char specifier, void *data, void *userdata) {
2225 Service *s = userdata;
2226 int r;
2227 const char *username;
2228
2229 /* get USER env from our own env if set */
2230 if (!s->exec_context.user)
2231 return getusername_malloc();
2232
2233 /* fish username from passwd */
2234 username = s->exec_context.user;
d05c5031 2235 r = get_user_creds(&username, NULL, NULL, NULL, NULL);
b2896c90
AK
2236 if (r < 0)
2237 return NULL;
2238
2239 return strdup(username);
2240}
2241
2242static char *specifier_user_home(char specifier, void *data, void *userdata) {
2243 Service *s = userdata;
2244 int r;
2245 const char *username, *home;
2246
2247 /* return HOME if set, otherwise from passwd */
2248 if (!s->exec_context.user) {
2249 char *h;
2250
2251 r = get_home_dir(&h);
2252 if (r < 0)
2253 return NULL;
2254
2255 return h;
2256 }
2257
2258 username = s->exec_context.user;
d05c5031 2259 r = get_user_creds(&username, NULL, NULL, &home, NULL);
b2896c90
AK
2260 if (r < 0)
2261 return NULL;
2262
2263 return strdup(home);
2264}
2265
d05c5031
LP
2266static char *specifier_user_shell(char specifier, void *data, void *userdata) {
2267 Service *s = userdata;
2268 int r;
2269 const char *username, *shell;
2270
2271 /* return HOME if set, otherwise from passwd */
2272 if (!s->exec_context.user) {
2273 char *sh;
2274
2275 r = get_shell(&sh);
2276 if (r < 0)
2277 return strdup("/bin/sh");
2278
2279 return sh;
2280 }
2281
2282 username = s->exec_context.user;
2283 r = get_user_creds(&username, NULL, NULL, NULL, &shell);
2284 if (r < 0)
2285 return strdup("/bin/sh");
2286
2287 return strdup(shell);
2288}
2289
9e2f7c11
LP
2290char *unit_name_printf(Unit *u, const char* format) {
2291
2292 /*
2293 * This will use the passed string as format string and
2294 * replace the following specifiers:
2295 *
2296 * %n: the full id of the unit (foo@bar.waldo)
2297 * %N: the id of the unit without the suffix (foo@bar)
2298 * %p: the prefix (foo)
2299 * %i: the instance (bar)
2300 */
2301
2302 const Specifier table[] = {
ac155bb8 2303 { 'n', specifier_string, u->id },
9e2f7c11
LP
2304 { 'N', specifier_prefix_and_instance, NULL },
2305 { 'p', specifier_prefix, NULL },
ac155bb8 2306 { 'i', specifier_string, u->instance },
9e2f7c11
LP
2307 { 0, NULL, NULL }
2308 };
2309
2310 assert(u);
2311 assert(format);
2312
2313 return specifier_printf(format, table, u);
2314}
2315
2316char *unit_full_printf(Unit *u, const char *format) {
2317
2318 /* This is similar to unit_name_printf() but also supports
0aef4345
LP
2319 * unescaping. Also, adds a couple of additional codes:
2320 *
2321 * %c cgroup path of unit
2322 * %r root cgroup path of this systemd instance (e.g. "/user/lennart/shared/systemd-4711")
2323 * %R parent of root cgroup path (e.g. "/usr/lennart/shared")
2324 * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
b2896c90
AK
2325 * %u the username of the configured User or running user
2326 * %h the homedir of the configured User or running user
0aef4345 2327 */
9e2f7c11
LP
2328
2329 const Specifier table[] = {
ac155bb8 2330 { 'n', specifier_string, u->id },
9e2f7c11
LP
2331 { 'N', specifier_prefix_and_instance, NULL },
2332 { 'p', specifier_prefix, NULL },
2333 { 'P', specifier_prefix_unescaped, NULL },
ac155bb8 2334 { 'i', specifier_string, u->instance },
9e2f7c11 2335 { 'I', specifier_instance_unescaped, NULL },
9fc50704 2336 { 'f', specifier_filename, NULL },
0aef4345
LP
2337 { 'c', specifier_cgroup, NULL },
2338 { 'r', specifier_cgroup_root, NULL },
2339 { 'R', specifier_cgroup_root, NULL },
2340 { 't', specifier_runtime, NULL },
b2896c90
AK
2341 { 'u', specifier_user_name, NULL },
2342 { 'h', specifier_user_home, NULL },
d05c5031 2343 { 's', specifier_user_shell, NULL },
9e2f7c11
LP
2344 { 0, NULL, NULL }
2345 };
2346
2347 assert(u);
2348 assert(format);
2349
2350 return specifier_printf(format, table, u);
2351}
2352
2353char **unit_full_printf_strv(Unit *u, char **l) {
2354 size_t n;
2355 char **r, **i, **j;
2356
2357 /* Applies unit_full_printf to every entry in l */
2358
2359 assert(u);
2360
2361 n = strv_length(l);
2362 if (!(r = new(char*, n+1)))
2363 return NULL;
2364
2365 for (i = l, j = r; *i; i++, j++)
2366 if (!(*j = unit_full_printf(u, *i)))
2367 goto fail;
2368
2369 *j = NULL;
2370 return r;
2371
2372fail:
da19d5c1 2373 for (j--; j >= r; j--)
9e2f7c11
LP
2374 free(*j);
2375
2376 free(r);
2377
2378 return NULL;
2379}
2380
05e343b7
LP
2381int unit_watch_bus_name(Unit *u, const char *name) {
2382 assert(u);
2383 assert(name);
2384
2385 /* Watch a specific name on the bus. We only support one unit
2386 * watching each name for now. */
2387
ac155bb8 2388 return hashmap_put(u->manager->watch_bus, name, u);
05e343b7
LP
2389}
2390
2391void unit_unwatch_bus_name(Unit *u, const char *name) {
2392 assert(u);
2393 assert(name);
2394
ac155bb8 2395 hashmap_remove_value(u->manager->watch_bus, name, u);
05e343b7
LP
2396}
2397
a16e1123
LP
2398bool unit_can_serialize(Unit *u) {
2399 assert(u);
2400
2401 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2402}
2403
2404int unit_serialize(Unit *u, FILE *f, FDSet *fds) {
2405 int r;
2406
2407 assert(u);
2408 assert(f);
2409 assert(fds);
2410
2411 if (!unit_can_serialize(u))
2412 return 0;
2413
2414 if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
2415 return r;
2416
39a18c60
MS
2417 if (u->job) {
2418 fprintf(f, "job\n");
2419 job_serialize(u->job, f, fds);
2420 }
cca098b0 2421
e0209d83
MS
2422 if (u->nop_job) {
2423 fprintf(f, "job\n");
2424 job_serialize(u->nop_job, f, fds);
2425 }
2426
ac155bb8
MS
2427 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2428 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2429 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2430 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2431 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
2791a8f8 2432
ac155bb8
MS
2433 if (dual_timestamp_is_set(&u->condition_timestamp))
2434 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
10717a1a 2435
a16e1123
LP
2436 /* End marker */
2437 fputc('\n', f);
2438 return 0;
2439}
2440
2441void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2442 va_list ap;
2443
2444 assert(u);
2445 assert(f);
2446 assert(key);
2447 assert(format);
2448
2449 fputs(key, f);
2450 fputc('=', f);
2451
2452 va_start(ap, format);
2453 vfprintf(f, format, ap);
2454 va_end(ap);
2455
2456 fputc('\n', f);
2457}
2458
2459void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2460 assert(u);
2461 assert(f);
2462 assert(key);
2463 assert(value);
2464
2465 fprintf(f, "%s=%s\n", key, value);
2466}
2467
2468int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
2469 int r;
2470
2471 assert(u);
2472 assert(f);
2473 assert(fds);
2474
2475 if (!unit_can_serialize(u))
2476 return 0;
2477
2478 for (;;) {
20c03b7b 2479 char line[LINE_MAX], *l, *v;
a16e1123
LP
2480 size_t k;
2481
2482 if (!fgets(line, sizeof(line), f)) {
2483 if (feof(f))
2484 return 0;
2485 return -errno;
2486 }
2487
10f8e83c 2488 char_array_0(line);
a16e1123
LP
2489 l = strstrip(line);
2490
2491 /* End marker */
2492 if (l[0] == 0)
2493 return 0;
2494
2495 k = strcspn(l, "=");
2496
2497 if (l[k] == '=') {
2498 l[k] = 0;
2499 v = l+k+1;
2500 } else
2501 v = l+k;
2502
cca098b0 2503 if (streq(l, "job")) {
39a18c60
MS
2504 if (v[0] == '\0') {
2505 /* new-style serialized job */
2506 Job *j = job_new_raw(u);
2507 if (!j)
2508 return -ENOMEM;
2509
2510 r = job_deserialize(j, f, fds);
2511 if (r < 0) {
2512 job_free(j);
2513 return r;
2514 }
cca098b0 2515
39a18c60
MS
2516 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2517 if (r < 0) {
2518 job_free(j);
2519 return r;
2520 }
e0209d83
MS
2521
2522 r = job_install_deserialized(j);
2523 if (r < 0) {
2524 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2525 job_free(j);
2526 return r;
2527 }
39a18c60
MS
2528 } else {
2529 /* legacy */
2530 JobType type = job_type_from_string(v);
2531 if (type < 0)
2532 log_debug("Failed to parse job type value %s", v);
2533 else
2534 u->deserialized_job = type;
2535 }
cca098b0 2536 continue;
8aaf019b 2537 } else if (streq(l, "inactive-exit-timestamp")) {
ac155bb8 2538 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
8aaf019b
LP
2539 continue;
2540 } else if (streq(l, "active-enter-timestamp")) {
ac155bb8 2541 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
8aaf019b
LP
2542 continue;
2543 } else if (streq(l, "active-exit-timestamp")) {
ac155bb8 2544 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
8aaf019b
LP
2545 continue;
2546 } else if (streq(l, "inactive-enter-timestamp")) {
ac155bb8 2547 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
8aaf019b 2548 continue;
2791a8f8 2549 } else if (streq(l, "condition-timestamp")) {
ac155bb8 2550 dual_timestamp_deserialize(v, &u->condition_timestamp);
2791a8f8
LP
2551 continue;
2552 } else if (streq(l, "condition-result")) {
2553 int b;
2554
2555 if ((b = parse_boolean(v)) < 0)
2556 log_debug("Failed to parse condition result value %s", v);
2557 else
ac155bb8 2558 u->condition_result = b;
efbac6d2
LP
2559
2560 continue;
8aaf019b 2561 }
cca098b0 2562
a16e1123
LP
2563 if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0)
2564 return r;
2565 }
2566}
2567
6e2ef85b
LP
2568int unit_add_node_link(Unit *u, const char *what, bool wants) {
2569 Unit *device;
2570 char *e;
2571 int r;
2572
2573 assert(u);
2574
2575 if (!what)
2576 return 0;
2577
2578 /* Adds in links to the device node that this unit is based on */
2579
8407a5d0 2580 if (!is_device_path(what))
6e2ef85b
LP
2581 return 0;
2582
35eb6b12
LP
2583 e = unit_name_from_path(what, ".device");
2584 if (!e)
6e2ef85b
LP
2585 return -ENOMEM;
2586
ac155bb8 2587 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
6e2ef85b
LP
2588 free(e);
2589
2590 if (r < 0)
2591 return r;
2592
7f2cddae 2593 if ((r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true)) < 0)
6e2ef85b
LP
2594 return r;
2595
2596 if (wants)
2597 if ((r = unit_add_dependency(device, UNIT_WANTS, u, false)) < 0)
2598 return r;
2599
2600 return 0;
2601}
a16e1123 2602
cca098b0
LP
2603int unit_coldplug(Unit *u) {
2604 int r;
2605
2606 assert(u);
2607
2608 if (UNIT_VTABLE(u)->coldplug)
2609 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2610 return r;
2611
39a18c60
MS
2612 if (u->job) {
2613 r = job_coldplug(u->job);
2614 if (r < 0)
2615 return r;
2616 } else if (u->deserialized_job >= 0) {
2617 /* legacy */
2618 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2619 if (r < 0)
cca098b0
LP
2620 return r;
2621
ac155bb8 2622 u->deserialized_job = _JOB_TYPE_INVALID;
cca098b0
LP
2623 }
2624
2625 return 0;
2626}
2627
5831e9b7 2628void unit_status_printf(Unit *u, const char *status, const char *format, ...) {
9e58ff9c
LP
2629 va_list ap;
2630
2631 assert(u);
2632 assert(format);
2633
ac155bb8 2634 if (!manager_get_show_status(u->manager))
9e58ff9c
LP
2635 return;
2636
ac155bb8 2637 if (!manager_is_booting_or_shutting_down(u->manager))
9e58ff9c
LP
2638 return;
2639
2640 va_start(ap, format);
67e5cc4f 2641 status_vprintf(status, true, format, ap);
9e58ff9c
LP
2642 va_end(ap);
2643}
2644
45fb0699 2645bool unit_need_daemon_reload(Unit *u) {
1b64d026
LP
2646 struct stat st;
2647
45fb0699
LP
2648 assert(u);
2649
ac155bb8 2650 if (u->fragment_path) {
5f4b19f4 2651 zero(st);
ac155bb8 2652 if (stat(u->fragment_path, &st) < 0)
5f4b19f4
LP
2653 /* What, cannot access this anymore? */
2654 return true;
45fb0699 2655
ac155bb8
MS
2656 if (u->fragment_mtime > 0 &&
2657 timespec_load(&st.st_mtim) != u->fragment_mtime)
5f4b19f4
LP
2658 return true;
2659 }
2660
1b64d026
LP
2661 if (u->source_path) {
2662 zero(st);
2663 if (stat(u->source_path, &st) < 0)
2664 return true;
2665
2666 if (u->source_mtime > 0 &&
2667 timespec_load(&st.st_mtim) != u->source_mtime)
2668 return true;
2669 }
5f4b19f4
LP
2670
2671 return false;
45fb0699
LP
2672}
2673
fdf20a31 2674void unit_reset_failed(Unit *u) {
5632e374
LP
2675 assert(u);
2676
fdf20a31
MM
2677 if (UNIT_VTABLE(u)->reset_failed)
2678 UNIT_VTABLE(u)->reset_failed(u);
5632e374
LP
2679}
2680
a7f241db
LP
2681Unit *unit_following(Unit *u) {
2682 assert(u);
2683
2684 if (UNIT_VTABLE(u)->following)
2685 return UNIT_VTABLE(u)->following(u);
2686
2687 return NULL;
2688}
2689
18ffdfda
LP
2690bool unit_pending_inactive(Unit *u) {
2691 assert(u);
2692
2693 /* Returns true if the unit is inactive or going down */
2694
2695 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2696 return true;
2697
ac155bb8 2698 if (u->job && u->job->type == JOB_STOP)
18ffdfda
LP
2699 return true;
2700
2701 return false;
2702}
2703
f976f3f6
LP
2704bool unit_pending_active(Unit *u) {
2705 assert(u);
2706
f60c2665 2707 /* Returns true if the unit is active or going up */
f976f3f6
LP
2708
2709 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2710 return true;
2711
ac155bb8
MS
2712 if (u->job &&
2713 (u->job->type == JOB_START ||
2714 u->job->type == JOB_RELOAD_OR_START ||
2715 u->job->type == JOB_RESTART))
f976f3f6
LP
2716 return true;
2717
2718 return false;
2719}
2720
8a0867d6
LP
2721int unit_kill(Unit *u, KillWho w, KillMode m, int signo, DBusError *error) {
2722 assert(u);
2723 assert(w >= 0 && w < _KILL_WHO_MAX);
2724 assert(m >= 0 && m < _KILL_MODE_MAX);
2725 assert(signo > 0);
2726 assert(signo < _NSIG);
2727
2728 if (m == KILL_NONE)
2729 return 0;
2730
2731 if (!UNIT_VTABLE(u)->kill)
2732 return -ENOTSUP;
2733
2734 return UNIT_VTABLE(u)->kill(u, w, m, signo, error);
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(
2753 u->manager->running_as == MANAGER_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
e06c73cc
LP
2820int unit_patch_working_directory(Unit *u, ExecContext *c) {
2821 assert(u);
2822 assert(c);
2823
2824 if (u->manager->running_as != MANAGER_USER)
2825 return 0;
2826
2827 if (c->working_directory)
2828 return 0;
2829
2830 return get_home_dir(&c->working_directory);
2831}
2832
94f04347
LP
2833static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
2834 [UNIT_ACTIVE] = "active",
032ff4af 2835 [UNIT_RELOADING] = "reloading",
94f04347 2836 [UNIT_INACTIVE] = "inactive",
fdf20a31 2837 [UNIT_FAILED] = "failed",
94f04347
LP
2838 [UNIT_ACTIVATING] = "activating",
2839 [UNIT_DEACTIVATING] = "deactivating"
2840};
2841
2842DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
2843
2844static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
2845 [UNIT_REQUIRES] = "Requires",
9e2f7c11 2846 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
94f04347
LP
2847 [UNIT_WANTS] = "Wants",
2848 [UNIT_REQUISITE] = "Requisite",
9e2f7c11 2849 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
94f04347 2850 [UNIT_REQUIRED_BY] = "RequiredBy",
9e2f7c11 2851 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
7f2cddae 2852 [UNIT_BINDS_TO] = "BindsTo",
94f04347
LP
2853 [UNIT_WANTED_BY] = "WantedBy",
2854 [UNIT_CONFLICTS] = "Conflicts",
69dd2852 2855 [UNIT_CONFLICTED_BY] = "ConflictedBy",
b81884e7 2856 [UNIT_BOUND_BY] = "BoundBy",
94f04347
LP
2857 [UNIT_BEFORE] = "Before",
2858 [UNIT_AFTER] = "After",
701cc384 2859 [UNIT_REFERENCES] = "References",
5de9682c 2860 [UNIT_REFERENCED_BY] = "ReferencedBy",
57020a3a
LP
2861 [UNIT_ON_FAILURE] = "OnFailure",
2862 [UNIT_TRIGGERS] = "Triggers",
4dcc1cb4 2863 [UNIT_TRIGGERED_BY] = "TriggeredBy",
7f2cddae
LP
2864 [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
2865 [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom"
94f04347
LP
2866};
2867
2868DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);