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