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