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