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