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