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