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