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