]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/unit.c
journal: suppress structured messages if they'd go to the console
[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
81270860
LP
1007 if (log_on_console())
1008 return;
1009
877d54e9
LP
1010 /* We log status messages for all units and all operations. */
1011
1012 format = unit_get_status_message_format_try_harder(u, t);
1013 if (!format)
1014 return;
1015
1016 snprintf(buf, sizeof(buf), format, unit_description(u));
1017 char_array_0(buf);
1018
1019 mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
1020 t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
1021 SD_MESSAGE_UNIT_RELOADING;
1022
1023 log_struct(LOG_INFO,
1024 "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(mid),
1025 "UNIT=%s", u->id,
1026 "MESSAGE=%s", buf,
1027 NULL);
1028}
1029#pragma GCC diagnostic pop
1030
87f0e418 1031/* Errors:
d5159713
LP
1032 * -EBADR: This unit type does not support starting.
1033 * -EALREADY: Unit is already started.
1034 * -EAGAIN: An operation is already in progress. Retry later.
1035 * -ECANCELED: Too many requests for now.
87f0e418
LP
1036 */
1037int unit_start(Unit *u) {
1038 UnitActiveState state;
92ab323c 1039 Unit *following;
87f0e418
LP
1040
1041 assert(u);
1042
ac155bb8 1043 if (u->load_state != UNIT_LOADED)
6124958c
LP
1044 return -EINVAL;
1045
a82e5507
LP
1046 /* If this is already started, then this will succeed. Note
1047 * that this will even succeed if this unit is not startable
1048 * by the user. This is relied on to detect when we need to
1049 * wait for units and when waiting is finished. */
87f0e418
LP
1050 state = unit_active_state(u);
1051 if (UNIT_IS_ACTIVE_OR_RELOADING(state))
1052 return -EALREADY;
1053
a82e5507
LP
1054 /* If the conditions failed, don't do anything at all. If we
1055 * already are activating this call might still be useful to
1056 * speed up activation in case there is some hold-off time,
1057 * but we don't want to recheck the condition in that case. */
1058 if (state != UNIT_ACTIVATING &&
1059 !unit_condition_test(u)) {
ac155bb8 1060 log_debug("Starting of %s requested but condition failed. Ignoring.", u->id);
52661efd
LP
1061 return -EALREADY;
1062 }
1063
92ab323c
LP
1064 /* Forward to the main object, if we aren't it. */
1065 if ((following = unit_following(u))) {
ac155bb8 1066 log_debug("Redirecting start request from %s to %s.", u->id, following->id);
92ab323c
LP
1067 return unit_start(following);
1068 }
1069
877d54e9
LP
1070 unit_status_log_starting_stopping_reloading(u, JOB_START);
1071 unit_status_print_starting_stopping(u, JOB_START);
c6918296 1072
92ab323c
LP
1073 /* If it is stopped, but we cannot start it, then fail */
1074 if (!UNIT_VTABLE(u)->start)
1075 return -EBADR;
1076
87f0e418
LP
1077 /* We don't suppress calls to ->start() here when we are
1078 * already starting, to allow this request to be used as a
1079 * "hurry up" call, for example when the unit is in some "auto
1080 * restart" state where it waits for a holdoff timer to elapse
1081 * before it will start again. */
1082
c1e1601e 1083 unit_add_to_dbus_queue(u);
9e58ff9c 1084
87f0e418
LP
1085 return UNIT_VTABLE(u)->start(u);
1086}
1087
1088bool unit_can_start(Unit *u) {
1089 assert(u);
1090
1091 return !!UNIT_VTABLE(u)->start;
1092}
1093
2528a7a6
LP
1094bool unit_can_isolate(Unit *u) {
1095 assert(u);
1096
1097 return unit_can_start(u) &&
ac155bb8 1098 u->allow_isolate;
2528a7a6
LP
1099}
1100
87f0e418
LP
1101/* Errors:
1102 * -EBADR: This unit type does not support stopping.
1103 * -EALREADY: Unit is already stopped.
1104 * -EAGAIN: An operation is already in progress. Retry later.
1105 */
1106int unit_stop(Unit *u) {
1107 UnitActiveState state;
92ab323c 1108 Unit *following;
87f0e418
LP
1109
1110 assert(u);
1111
87f0e418 1112 state = unit_active_state(u);
fdf20a31 1113 if (UNIT_IS_INACTIVE_OR_FAILED(state))
87f0e418
LP
1114 return -EALREADY;
1115
92ab323c 1116 if ((following = unit_following(u))) {
ac155bb8 1117 log_debug("Redirecting stop request from %s to %s.", u->id, following->id);
92ab323c
LP
1118 return unit_stop(following);
1119 }
1120
877d54e9
LP
1121 unit_status_log_starting_stopping_reloading(u, JOB_STOP);
1122 unit_status_print_starting_stopping(u, JOB_STOP);
c6918296 1123
7898b0cf
LP
1124 if (!UNIT_VTABLE(u)->stop)
1125 return -EBADR;
1126
c1e1601e 1127 unit_add_to_dbus_queue(u);
9e58ff9c 1128
87f0e418
LP
1129 return UNIT_VTABLE(u)->stop(u);
1130}
1131
1132/* Errors:
1133 * -EBADR: This unit type does not support reloading.
1134 * -ENOEXEC: Unit is not started.
1135 * -EAGAIN: An operation is already in progress. Retry later.
1136 */
1137int unit_reload(Unit *u) {
1138 UnitActiveState state;
92ab323c 1139 Unit *following;
87f0e418
LP
1140
1141 assert(u);
1142
ac155bb8 1143 if (u->load_state != UNIT_LOADED)
6124958c
LP
1144 return -EINVAL;
1145
87f0e418
LP
1146 if (!unit_can_reload(u))
1147 return -EBADR;
1148
1149 state = unit_active_state(u);
e364ad06 1150 if (state == UNIT_RELOADING)
87f0e418
LP
1151 return -EALREADY;
1152
e364ad06 1153 if (state != UNIT_ACTIVE)
87f0e418
LP
1154 return -ENOEXEC;
1155
92ab323c 1156 if ((following = unit_following(u))) {
ac155bb8 1157 log_debug("Redirecting reload request from %s to %s.", u->id, following->id);
92ab323c
LP
1158 return unit_reload(following);
1159 }
1160
877d54e9
LP
1161 unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
1162
c1e1601e 1163 unit_add_to_dbus_queue(u);
87f0e418
LP
1164 return UNIT_VTABLE(u)->reload(u);
1165}
1166
1167bool unit_can_reload(Unit *u) {
1168 assert(u);
1169
1170 if (!UNIT_VTABLE(u)->reload)
1171 return false;
1172
1173 if (!UNIT_VTABLE(u)->can_reload)
1174 return true;
1175
1176 return UNIT_VTABLE(u)->can_reload(u);
1177}
1178
b4a16b7b 1179static void unit_check_unneeded(Unit *u) {
f3bff0eb
LP
1180 Iterator i;
1181 Unit *other;
1182
1183 assert(u);
1184
1185 /* If this service shall be shut down when unneeded then do
1186 * so. */
1187
ac155bb8 1188 if (!u->stop_when_unneeded)
f3bff0eb
LP
1189 return;
1190
1191 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1192 return;
1193
ac155bb8 1194 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
f60c2665 1195 if (unit_pending_active(other))
f3bff0eb
LP
1196 return;
1197
ac155bb8 1198 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
f60c2665 1199 if (unit_pending_active(other))
f3bff0eb
LP
1200 return;
1201
ac155bb8 1202 SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
f60c2665 1203 if (unit_pending_active(other))
f3bff0eb
LP
1204 return;
1205
ac155bb8 1206 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
f60c2665 1207 if (unit_pending_active(other))
b81884e7
LP
1208 return;
1209
ac155bb8 1210 log_info("Service %s is not needed anymore. Stopping.", u->id);
f3bff0eb
LP
1211
1212 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
ac155bb8 1213 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
f3bff0eb
LP
1214}
1215
87f0e418
LP
1216static void retroactively_start_dependencies(Unit *u) {
1217 Iterator i;
1218 Unit *other;
1219
1220 assert(u);
1221 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1222
ac155bb8
MS
1223 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1224 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1225 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1226 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
b81884e7 1227
7f2cddae 1228 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
ac155bb8 1229 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1230 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1231 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
87f0e418 1232
ac155bb8
MS
1233 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1234 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1235 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1236 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
87f0e418 1237
ac155bb8
MS
1238 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
1239 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1240 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1241 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
87f0e418 1242
ac155bb8
MS
1243 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1244 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
b81884e7 1245 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
ac155bb8 1246 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
87f0e418 1247
ac155bb8 1248 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
b81884e7 1249 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1250 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
69dd2852 1251
ac155bb8 1252 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
b81884e7 1253 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1254 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
87f0e418
LP
1255}
1256
1257static void retroactively_stop_dependencies(Unit *u) {
1258 Iterator i;
1259 Unit *other;
1260
1261 assert(u);
1262 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1263
b81884e7 1264 /* Pull down units which are bound to us recursively if enabled */
ac155bb8 1265 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
b81884e7 1266 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
ac155bb8 1267 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
cd0504d0
MS
1268}
1269
1270static void check_unneeded_dependencies(Unit *u) {
1271 Iterator i;
1272 Unit *other;
1273
1274 assert(u);
1275 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
f3bff0eb
LP
1276
1277 /* Garbage collect services that might not be needed anymore, if enabled */
ac155bb8 1278 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
87f0e418 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_REQUIRES_OVERRIDABLE], 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_WANTS], 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], 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_OVERRIDABLE], i)
f3bff0eb 1291 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
b4a16b7b 1292 unit_check_unneeded(other);
7f2cddae 1293 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
b81884e7
LP
1294 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1295 unit_check_unneeded(other);
87f0e418
LP
1296}
1297
c0daa706
LP
1298void unit_trigger_on_failure(Unit *u) {
1299 Unit *other;
1300 Iterator i;
1301
1302 assert(u);
1303
ac155bb8 1304 if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
222ae6a8
LP
1305 return;
1306
ac155bb8 1307 log_info("Triggering OnFailure= dependencies of %s.", u->id);
222ae6a8 1308
ac155bb8 1309 SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
222ae6a8
LP
1310 int r;
1311
ac155bb8 1312 if ((r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL)) < 0)
222ae6a8
LP
1313 log_error("Failed to enqueue OnFailure= job: %s", strerror(-r));
1314 }
c0daa706
LP
1315}
1316
e2f3b44c 1317void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
7e6e7b06 1318 bool unexpected;
a096ed36 1319
87f0e418
LP
1320 assert(u);
1321 assert(os < _UNIT_ACTIVE_STATE_MAX);
1322 assert(ns < _UNIT_ACTIVE_STATE_MAX);
87f0e418 1323
8e471ccd
LP
1324 /* Note that this is called for all low-level state changes,
1325 * even if they might map to the same high-level
1326 * UnitActiveState! That means that ns == os is OK an expected
1327 * behaviour here. For example: if a mount point is remounted
cd6d0a45 1328 * this function will be called too! */
87f0e418 1329
ac155bb8 1330 if (u->manager->n_reloading <= 0) {
bdbf9951 1331 dual_timestamp ts;
173e3821 1332
bdbf9951 1333 dual_timestamp_get(&ts);
173e3821 1334
bdbf9951 1335 if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
ac155bb8 1336 u->inactive_exit_timestamp = ts;
bdbf9951 1337 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
ac155bb8 1338 u->inactive_enter_timestamp = ts;
bdbf9951
LP
1339
1340 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
ac155bb8 1341 u->active_enter_timestamp = ts;
bdbf9951 1342 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
ac155bb8 1343 u->active_exit_timestamp = ts;
bdbf9951
LP
1344
1345 timer_unit_notify(u, ns);
1346 path_unit_notify(u, ns);
1347 }
87f0e418 1348
fdf20a31 1349 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
ac155bb8 1350 cgroup_bonding_trim_list(u->cgroup_bondings, true);
fb385181 1351
ac155bb8 1352 if (u->job) {
7e6e7b06 1353 unexpected = false;
87f0e418 1354
ac155bb8 1355 if (u->job->state == JOB_WAITING)
87f0e418
LP
1356
1357 /* So we reached a different state for this
1358 * job. Let's see if we can run it now if it
1359 * failed previously due to EAGAIN. */
ac155bb8 1360 job_add_to_run_queue(u->job);
87f0e418 1361
b410e6b9 1362 /* Let's check whether this state change constitutes a
35b8ca3a 1363 * finished job, or maybe contradicts a running job and
b410e6b9 1364 * hence needs to invalidate jobs. */
87f0e418 1365
ac155bb8 1366 switch (u->job->type) {
87f0e418 1367
b410e6b9
LP
1368 case JOB_START:
1369 case JOB_VERIFY_ACTIVE:
87f0e418 1370
b410e6b9 1371 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
5273510e 1372 job_finish_and_invalidate(u->job, JOB_DONE, true);
ac155bb8 1373 else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
b410e6b9 1374 unexpected = true;
41b02ec7 1375
fdf20a31 1376 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1377 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
b410e6b9 1378 }
87f0e418 1379
b410e6b9 1380 break;
87f0e418 1381
b410e6b9
LP
1382 case JOB_RELOAD:
1383 case JOB_RELOAD_OR_START:
87f0e418 1384
ac155bb8 1385 if (u->job->state == JOB_RUNNING) {
a096ed36 1386 if (ns == UNIT_ACTIVE)
5273510e 1387 job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
032ff4af 1388 else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
a096ed36 1389 unexpected = true;
41b02ec7 1390
fdf20a31 1391 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1392 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
a096ed36 1393 }
b410e6b9 1394 }
87f0e418 1395
b410e6b9 1396 break;
87f0e418 1397
b410e6b9
LP
1398 case JOB_STOP:
1399 case JOB_RESTART:
1400 case JOB_TRY_RESTART:
87f0e418 1401
fdf20a31 1402 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
5273510e 1403 job_finish_and_invalidate(u->job, JOB_DONE, true);
ac155bb8 1404 else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
b410e6b9 1405 unexpected = true;
5273510e 1406 job_finish_and_invalidate(u->job, JOB_FAILED, true);
b410e6b9 1407 }
87f0e418 1408
b410e6b9 1409 break;
87f0e418 1410
b410e6b9
LP
1411 default:
1412 assert_not_reached("Job type unknown");
87f0e418 1413 }
87f0e418 1414
7e6e7b06
LP
1415 } else
1416 unexpected = true;
1417
ac155bb8 1418 if (u->manager->n_reloading <= 0) {
f3bff0eb 1419
bdbf9951
LP
1420 /* If this state change happened without being
1421 * requested by a job, then let's retroactively start
1422 * or stop dependencies. We skip that step when
1423 * deserializing, since we don't want to create any
1424 * additional jobs just because something is already
1425 * activated. */
1426
1427 if (unexpected) {
1428 if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1429 retroactively_start_dependencies(u);
1430 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1431 retroactively_stop_dependencies(u);
1432 }
5de9682c 1433
cd0504d0
MS
1434 /* stop unneeded units regardless if going down was expected or not */
1435 if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1436 check_unneeded_dependencies(u);
1437
bdbf9951 1438 if (ns != os && ns == UNIT_FAILED) {
ac155bb8 1439 log_notice("Unit %s entered failed state.", u->id);
bdbf9951 1440 unit_trigger_on_failure(u);
cd6d0a45 1441 }
3b2775c5 1442 }
e537352b 1443
3b2775c5
LP
1444 /* Some names are special */
1445 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
1446
1447 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
1448 /* The bus just might have become available,
1449 * hence try to connect to it, if we aren't
1450 * yet connected. */
ac155bb8 1451 bus_init(u->manager, true);
3b2775c5 1452
ac155bb8 1453 if (u->type == UNIT_SERVICE &&
3b2775c5 1454 !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
ac155bb8 1455 u->manager->n_reloading <= 0) {
3b2775c5 1456 /* Write audit record if we have just finished starting up */
ac155bb8
MS
1457 manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_START, true);
1458 u->in_audit = true;
3b2775c5 1459 }
e983b760 1460
3b2775c5 1461 if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
ac155bb8 1462 manager_send_unit_plymouth(u->manager, u);
bdbf9951 1463
3b2775c5 1464 } else {
bdbf9951 1465
3b2775c5
LP
1466 /* We don't care about D-Bus here, since we'll get an
1467 * asynchronous notification for it anyway. */
cd6d0a45 1468
ac155bb8 1469 if (u->type == UNIT_SERVICE &&
3b2775c5
LP
1470 UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1471 !UNIT_IS_INACTIVE_OR_FAILED(os) &&
ac155bb8 1472 u->manager->n_reloading <= 0) {
4927fcae 1473
3b2775c5
LP
1474 /* Hmm, if there was no start record written
1475 * write it now, so that we always have a nice
1476 * pair */
ac155bb8
MS
1477 if (!u->in_audit) {
1478 manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
cd6d0a45 1479
3b2775c5 1480 if (ns == UNIT_INACTIVE)
ac155bb8 1481 manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_STOP, true);
3b2775c5
LP
1482 } else
1483 /* Write audit record if we have just finished shutting down */
ac155bb8 1484 manager_send_unit_audit(u->manager, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
bdbf9951 1485
ac155bb8 1486 u->in_audit = false;
cd6d0a45 1487 }
f278026d
LP
1488 }
1489
ac155bb8 1490 manager_recheck_journal(u->manager);
3b2775c5 1491
f3bff0eb
LP
1492 /* Maybe we finished startup and are now ready for being
1493 * stopped because unneeded? */
b4a16b7b 1494 unit_check_unneeded(u);
c1e1601e
LP
1495
1496 unit_add_to_dbus_queue(u);
701cc384 1497 unit_add_to_gc_queue(u);
87f0e418
LP
1498}
1499
acbb0225 1500int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) {
87f0e418
LP
1501 struct epoll_event ev;
1502
1503 assert(u);
1504 assert(fd >= 0);
acbb0225 1505 assert(w);
ea430986 1506 assert(w->type == WATCH_INVALID || (w->type == WATCH_FD && w->fd == fd && w->data.unit == u));
87f0e418
LP
1507
1508 zero(ev);
acbb0225 1509 ev.data.ptr = w;
87f0e418
LP
1510 ev.events = events;
1511
ac155bb8 1512 if (epoll_ctl(u->manager->epoll_fd,
acbb0225
LP
1513 w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD,
1514 fd,
1515 &ev) < 0)
1516 return -errno;
87f0e418 1517
acbb0225
LP
1518 w->fd = fd;
1519 w->type = WATCH_FD;
ea430986 1520 w->data.unit = u;
87f0e418 1521
acbb0225 1522 return 0;
87f0e418
LP
1523}
1524
acbb0225 1525void unit_unwatch_fd(Unit *u, Watch *w) {
87f0e418 1526 assert(u);
acbb0225 1527 assert(w);
87f0e418 1528
acbb0225
LP
1529 if (w->type == WATCH_INVALID)
1530 return;
1531
ea430986
LP
1532 assert(w->type == WATCH_FD);
1533 assert(w->data.unit == u);
ac155bb8 1534 assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
acbb0225
LP
1535
1536 w->fd = -1;
1537 w->type = WATCH_INVALID;
ea430986 1538 w->data.unit = NULL;
87f0e418
LP
1539}
1540
1541int unit_watch_pid(Unit *u, pid_t pid) {
1542 assert(u);
1543 assert(pid >= 1);
1544
05e343b7
LP
1545 /* Watch a specific PID. We only support one unit watching
1546 * each PID for now. */
1547
ac155bb8 1548 return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u);
87f0e418
LP
1549}
1550
1551void unit_unwatch_pid(Unit *u, pid_t pid) {
1552 assert(u);
1553 assert(pid >= 1);
1554
ac155bb8 1555 hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u);
87f0e418
LP
1556}
1557
acbb0225 1558int unit_watch_timer(Unit *u, usec_t delay, Watch *w) {
87f0e418 1559 struct itimerspec its;
acbb0225 1560 int flags, fd;
87f0e418
LP
1561 bool ours;
1562
1563 assert(u);
acbb0225 1564 assert(w);
faf919f1 1565 assert(w->type == WATCH_INVALID || (w->type == WATCH_UNIT_TIMER && w->data.unit == u));
87f0e418
LP
1566
1567 /* This will try to reuse the old timer if there is one */
1568
faf919f1
LP
1569 if (w->type == WATCH_UNIT_TIMER) {
1570 assert(w->data.unit == u);
1571 assert(w->fd >= 0);
1572
87f0e418 1573 ours = false;
acbb0225 1574 fd = w->fd;
faf919f1
LP
1575 } else if (w->type == WATCH_INVALID) {
1576
87f0e418 1577 ours = true;
87f0e418
LP
1578 if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0)
1579 return -errno;
faf919f1
LP
1580 } else
1581 assert_not_reached("Invalid watch type");
87f0e418
LP
1582
1583 zero(its);
1584
1585 if (delay <= 0) {
1586 /* Set absolute time in the past, but not 0, since we
1587 * don't want to disarm the timer */
1588 its.it_value.tv_sec = 0;
1589 its.it_value.tv_nsec = 1;
1590
1591 flags = TFD_TIMER_ABSTIME;
1592 } else {
1593 timespec_store(&its.it_value, delay);
1594 flags = 0;
1595 }
1596
1597 /* This will also flush the elapse counter */
1598 if (timerfd_settime(fd, flags, &its, NULL) < 0)
1599 goto fail;
1600
acbb0225
LP
1601 if (w->type == WATCH_INVALID) {
1602 struct epoll_event ev;
87f0e418 1603
acbb0225
LP
1604 zero(ev);
1605 ev.data.ptr = w;
f94ea366 1606 ev.events = EPOLLIN;
acbb0225 1607
ac155bb8 1608 if (epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
acbb0225
LP
1609 goto fail;
1610 }
1611
faf919f1 1612 w->type = WATCH_UNIT_TIMER;
acbb0225 1613 w->fd = fd;
ea430986 1614 w->data.unit = u;
87f0e418 1615
87f0e418
LP
1616 return 0;
1617
1618fail:
1619 if (ours)
ea430986 1620 close_nointr_nofail(fd);
87f0e418
LP
1621
1622 return -errno;
1623}
1624
acbb0225 1625void unit_unwatch_timer(Unit *u, Watch *w) {
87f0e418 1626 assert(u);
acbb0225 1627 assert(w);
87f0e418 1628
acbb0225 1629 if (w->type == WATCH_INVALID)
87f0e418
LP
1630 return;
1631
faf919f1
LP
1632 assert(w->type == WATCH_UNIT_TIMER);
1633 assert(w->data.unit == u);
1634 assert(w->fd >= 0);
acbb0225 1635
ac155bb8 1636 assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
a16e1123 1637 close_nointr_nofail(w->fd);
acbb0225
LP
1638
1639 w->fd = -1;
1640 w->type = WATCH_INVALID;
ea430986 1641 w->data.unit = NULL;
87f0e418
LP
1642}
1643
1644bool unit_job_is_applicable(Unit *u, JobType j) {
1645 assert(u);
1646 assert(j >= 0 && j < _JOB_TYPE_MAX);
1647
1648 switch (j) {
1649
1650 case JOB_VERIFY_ACTIVE:
1651 case JOB_START:
57339f47 1652 case JOB_STOP:
e0209d83 1653 case JOB_NOP:
87f0e418
LP
1654 return true;
1655
87f0e418
LP
1656 case JOB_RESTART:
1657 case JOB_TRY_RESTART:
1658 return unit_can_start(u);
1659
1660 case JOB_RELOAD:
1661 return unit_can_reload(u);
1662
1663 case JOB_RELOAD_OR_START:
1664 return unit_can_reload(u) && unit_can_start(u);
1665
1666 default:
1667 assert_not_reached("Invalid job type");
1668 }
1669}
1670
701cc384 1671int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
87f0e418
LP
1672
1673 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
1674 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
9e2f7c11 1675 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
87f0e418
LP
1676 [UNIT_WANTS] = UNIT_WANTED_BY,
1677 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
9e2f7c11 1678 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
7f2cddae 1679 [UNIT_BINDS_TO] = UNIT_BOUND_BY,
60649f17 1680 [UNIT_PART_OF] = UNIT_CONSISTS_OF,
87f0e418 1681 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
9e2f7c11 1682 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
87f0e418 1683 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
7f2cddae 1684 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
60649f17 1685 [UNIT_CONSISTS_OF] = UNIT_PART_OF,
69dd2852
LP
1686 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
1687 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
87f0e418 1688 [UNIT_BEFORE] = UNIT_AFTER,
701cc384 1689 [UNIT_AFTER] = UNIT_BEFORE,
5de9682c 1690 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
701cc384 1691 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
57020a3a
LP
1692 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
1693 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
4dcc1cb4 1694 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
7f2cddae 1695 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
85e9a101 1696 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
87f0e418 1697 };
701cc384 1698 int r, q = 0, v = 0, w = 0;
87f0e418
LP
1699
1700 assert(u);
1701 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
87f0e418
LP
1702 assert(other);
1703
9f151f29
LP
1704 u = unit_follow_merge(u);
1705 other = unit_follow_merge(other);
1706
87f0e418
LP
1707 /* We won't allow dependencies on ourselves. We will not
1708 * consider them an error however. */
1709 if (u == other)
1710 return 0;
1711
ac155bb8 1712 if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
87f0e418
LP
1713 return r;
1714
5de9682c 1715 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
ac155bb8 1716 if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
5de9682c
LP
1717 return r;
1718
701cc384 1719 if (add_reference)
ac155bb8
MS
1720 if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
1721 (r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
701cc384 1722 return r;
87f0e418 1723
ac155bb8 1724 if ((q = set_put(u->dependencies[d], other)) < 0)
701cc384 1725 return q;
87f0e418 1726
5de9682c 1727 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
ac155bb8 1728 if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) {
5de9682c
LP
1729 r = v;
1730 goto fail;
1731 }
701cc384
LP
1732
1733 if (add_reference) {
ac155bb8 1734 if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) {
701cc384
LP
1735 r = w;
1736 goto fail;
1737 }
1738
ac155bb8 1739 if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0)
701cc384 1740 goto fail;
87f0e418
LP
1741 }
1742
c1e1601e 1743 unit_add_to_dbus_queue(u);
87f0e418 1744 return 0;
701cc384
LP
1745
1746fail:
1747 if (q > 0)
ac155bb8 1748 set_remove(u->dependencies[d], other);
701cc384
LP
1749
1750 if (v > 0)
ac155bb8 1751 set_remove(other->dependencies[inverse_table[d]], u);
701cc384
LP
1752
1753 if (w > 0)
ac155bb8 1754 set_remove(u->dependencies[UNIT_REFERENCES], other);
701cc384
LP
1755
1756 return r;
87f0e418 1757}
0301abf4 1758
2c966c03
LP
1759int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
1760 int r;
1761
1762 assert(u);
1763
1764 if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
1765 return r;
1766
1767 if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
1768 return r;
1769
1770 return 0;
1771}
1772
9e2f7c11
LP
1773static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
1774 char *s;
1775
1776 assert(u);
1777 assert(name || path);
1778
1779 if (!name)
9eb977db 1780 name = path_get_file_name(path);
9e2f7c11
LP
1781
1782 if (!unit_name_is_template(name)) {
1783 *p = NULL;
1784 return name;
1785 }
1786
ac155bb8
MS
1787 if (u->instance)
1788 s = unit_name_replace_instance(name, u->instance);
9e2f7c11
LP
1789 else {
1790 char *i;
1791
ac155bb8 1792 if (!(i = unit_name_to_prefix(u->id)))
9e2f7c11
LP
1793 return NULL;
1794
1795 s = unit_name_replace_instance(name, i);
1796 free(i);
1797 }
1798
1799 if (!s)
1800 return NULL;
1801
1802 *p = s;
1803 return s;
1804}
1805
701cc384 1806int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
09b6b09f
LP
1807 Unit *other;
1808 int r;
9e2f7c11 1809 char *s;
09b6b09f 1810
9e2f7c11
LP
1811 assert(u);
1812 assert(name || path);
09b6b09f 1813
9e2f7c11
LP
1814 if (!(name = resolve_template(u, name, path, &s)))
1815 return -ENOMEM;
09b6b09f 1816
ac155bb8 1817 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
9e2f7c11
LP
1818 goto finish;
1819
701cc384 1820 r = unit_add_dependency(u, d, other, add_reference);
9e2f7c11
LP
1821
1822finish:
1823 free(s);
1824 return r;
09b6b09f
LP
1825}
1826
2c966c03
LP
1827int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1828 Unit *other;
1829 int r;
1830 char *s;
1831
1832 assert(u);
1833 assert(name || path);
1834
1835 if (!(name = resolve_template(u, name, path, &s)))
1836 return -ENOMEM;
1837
ac155bb8 1838 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
2c966c03
LP
1839 goto finish;
1840
1841 r = unit_add_two_dependencies(u, d, e, other, add_reference);
1842
1843finish:
1844 free(s);
1845 return r;
1846}
1847
701cc384 1848int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
bd77d0fc
LP
1849 Unit *other;
1850 int r;
9e2f7c11 1851 char *s;
bd77d0fc 1852
9e2f7c11
LP
1853 assert(u);
1854 assert(name || path);
bd77d0fc 1855
9e2f7c11
LP
1856 if (!(name = resolve_template(u, name, path, &s)))
1857 return -ENOMEM;
bd77d0fc 1858
ac155bb8 1859 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
9e2f7c11
LP
1860 goto finish;
1861
701cc384 1862 r = unit_add_dependency(other, d, u, add_reference);
9e2f7c11
LP
1863
1864finish:
1865 free(s);
1866 return r;
bd77d0fc
LP
1867}
1868
2c966c03
LP
1869int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1870 Unit *other;
1871 int r;
1872 char *s;
1873
1874 assert(u);
1875 assert(name || path);
1876
1877 if (!(name = resolve_template(u, name, path, &s)))
1878 return -ENOMEM;
1879
ac155bb8 1880 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
2c966c03
LP
1881 goto finish;
1882
1883 if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
1884 goto finish;
1885
1886finish:
1887 free(s);
1888 return r;
1889}
1890
0301abf4
LP
1891int set_unit_path(const char *p) {
1892 char *cwd, *c;
1893 int r;
1894
1895 /* This is mostly for debug purposes */
1896
1897 if (path_is_absolute(p)) {
1898 if (!(c = strdup(p)))
1899 return -ENOMEM;
1900 } else {
1901 if (!(cwd = get_current_dir_name()))
1902 return -errno;
1903
1904 r = asprintf(&c, "%s/%s", cwd, p);
1905 free(cwd);
1906
1907 if (r < 0)
1908 return -ENOMEM;
1909 }
1910
036643a2 1911 if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0) {
0301abf4
LP
1912 r = -errno;
1913 free(c);
1914 return r;
1915 }
1916
1917 return 0;
1918}
88066b3a 1919
ea430986 1920char *unit_dbus_path(Unit *u) {
ea430986
LP
1921 assert(u);
1922
ac155bb8 1923 if (!u->id)
04ade7d2
LP
1924 return NULL;
1925
48899192 1926 return unit_dbus_path_from_name(u->id);
ea430986
LP
1927}
1928
8e274523 1929int unit_add_cgroup(Unit *u, CGroupBonding *b) {
8e274523
LP
1930 int r;
1931
1932 assert(u);
1933 assert(b);
35d2e7ec 1934
8e274523
LP
1935 assert(b->path);
1936
e025b4c3 1937 if (!b->controller) {
35d2e7ec
LP
1938 if (!(b->controller = strdup(SYSTEMD_CGROUP_CONTROLLER)))
1939 return -ENOMEM;
1940
e025b4c3
LP
1941 b->ours = true;
1942 }
1943
8e274523
LP
1944 /* Ensure this hasn't been added yet */
1945 assert(!b->unit);
1946
d686d8a9
LP
1947 if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) {
1948 CGroupBonding *l;
8e274523 1949
ac155bb8 1950 l = hashmap_get(u->manager->cgroup_bondings, b->path);
d686d8a9
LP
1951 LIST_PREPEND(CGroupBonding, by_path, l, b);
1952
ac155bb8 1953 if ((r = hashmap_replace(u->manager->cgroup_bondings, b->path, l)) < 0) {
d686d8a9
LP
1954 LIST_REMOVE(CGroupBonding, by_path, l, b);
1955 return r;
1956 }
8e274523
LP
1957 }
1958
ac155bb8 1959 LIST_PREPEND(CGroupBonding, by_unit, u->cgroup_bondings, b);
8e274523
LP
1960 b->unit = u;
1961
1962 return 0;
1963}
1964
013b87c0
LP
1965static char *default_cgroup_path(Unit *u) {
1966 char *p;
1967
1968 assert(u);
1969
ac155bb8 1970 if (u->instance) {
4f2d528d 1971 char *t;
013b87c0 1972
ac155bb8 1973 t = unit_name_template(u->id);
cd0ed1db 1974 if (!t)
4f2d528d
LP
1975 return NULL;
1976
b7def684 1977 p = strjoin(u->manager->cgroup_hierarchy, "/", t, "/", u->instance, NULL);
4f2d528d
LP
1978 free(t);
1979 } else
b7def684 1980 p = strjoin(u->manager->cgroup_hierarchy, "/", u->id, NULL);
4f2d528d 1981
cd0ed1db 1982 return p;
013b87c0
LP
1983}
1984
8e274523 1985int unit_add_cgroup_from_text(Unit *u, const char *name) {
013b87c0
LP
1986 char *controller = NULL, *path = NULL;
1987 CGroupBonding *b = NULL;
e025b4c3 1988 bool ours = false;
8e274523
LP
1989 int r;
1990
1991 assert(u);
1992 assert(name);
1993
35d2e7ec
LP
1994 if ((r = cg_split_spec(name, &controller, &path)) < 0)
1995 return r;
8e274523 1996
e025b4c3 1997 if (!path) {
35d2e7ec 1998 path = default_cgroup_path(u);
e025b4c3
LP
1999 ours = true;
2000 }
013b87c0 2001
e025b4c3 2002 if (!controller) {
55096547 2003 controller = strdup(SYSTEMD_CGROUP_CONTROLLER);
e025b4c3
LP
2004 ours = true;
2005 }
013b87c0 2006
35d2e7ec
LP
2007 if (!path || !controller) {
2008 free(path);
2009 free(controller);
2010
2011 return -ENOMEM;
8e274523
LP
2012 }
2013
ac155bb8 2014 if (cgroup_bonding_find_list(u->cgroup_bondings, controller)) {
013b87c0
LP
2015 r = -EEXIST;
2016 goto fail;
2017 }
8e274523 2018
013b87c0 2019 if (!(b = new0(CGroupBonding, 1))) {
8e274523
LP
2020 r = -ENOMEM;
2021 goto fail;
2022 }
2023
013b87c0
LP
2024 b->controller = controller;
2025 b->path = path;
e025b4c3
LP
2026 b->ours = ours;
2027 b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER);
8e274523
LP
2028
2029 if ((r = unit_add_cgroup(u, b)) < 0)
2030 goto fail;
2031
2032 return 0;
2033
2034fail:
013b87c0
LP
2035 free(path);
2036 free(controller);
8e274523
LP
2037 free(b);
2038
2039 return r;
2040}
2041
06d4c99a 2042static int unit_add_one_default_cgroup(Unit *u, const char *controller) {
d686d8a9 2043 CGroupBonding *b = NULL;
8e274523
LP
2044 int r = -ENOMEM;
2045
2046 assert(u);
2047
06d4c99a
LP
2048 if (!controller)
2049 controller = SYSTEMD_CGROUP_CONTROLLER;
8e274523 2050
ac155bb8 2051 if (cgroup_bonding_find_list(u->cgroup_bondings, controller))
06d4c99a 2052 return 0;
8e274523 2053
06d4c99a
LP
2054 if (!(b = new0(CGroupBonding, 1)))
2055 return -ENOMEM;
8e274523 2056
06d4c99a
LP
2057 if (!(b->controller = strdup(controller)))
2058 goto fail;
d686d8a9 2059
06d4c99a
LP
2060 if (!(b->path = default_cgroup_path(u)))
2061 goto fail;
d686d8a9 2062
06d4c99a
LP
2063 b->ours = true;
2064 b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER);
d686d8a9 2065
06d4c99a
LP
2066 if ((r = unit_add_cgroup(u, b)) < 0)
2067 goto fail;
8e274523
LP
2068
2069 return 0;
2070
2071fail:
06d4c99a
LP
2072 free(b->path);
2073 free(b->controller);
2074 free(b);
8e274523
LP
2075
2076 return r;
2077}
2078
06d4c99a 2079int unit_add_default_cgroups(Unit *u) {
ab1f0633 2080 CGroupAttribute *a;
06d4c99a
LP
2081 char **c;
2082 int r;
ab1f0633 2083
06d4c99a
LP
2084 assert(u);
2085
2086 /* Adds in the default cgroups, if they weren't specified
2087 * otherwise. */
2088
ac155bb8 2089 if (!u->manager->cgroup_hierarchy)
df18d8c8
LP
2090 return 0;
2091
06d4c99a
LP
2092 if ((r = unit_add_one_default_cgroup(u, NULL)) < 0)
2093 return r;
2094
ac155bb8 2095 STRV_FOREACH(c, u->manager->default_controllers)
ab1f0633
LP
2096 unit_add_one_default_cgroup(u, *c);
2097
ac155bb8 2098 LIST_FOREACH(by_unit, a, u->cgroup_attributes)
ab1f0633 2099 unit_add_one_default_cgroup(u, a->controller);
06d4c99a
LP
2100
2101 return 0;
2102}
2103
8e274523
LP
2104CGroupBonding* unit_get_default_cgroup(Unit *u) {
2105 assert(u);
2106
ac155bb8 2107 return cgroup_bonding_find_list(u->cgroup_bondings, SYSTEMD_CGROUP_CONTROLLER);
8e274523
LP
2108}
2109
ab1f0633
LP
2110int unit_add_cgroup_attribute(Unit *u, const char *controller, const char *name, const char *value, CGroupAttributeMapCallback map_callback) {
2111 int r;
2112 char *c = NULL;
2113 CGroupAttribute *a;
2114
2115 assert(u);
2116 assert(name);
2117 assert(value);
2118
2119 if (!controller) {
2120 const char *dot;
2121
2122 dot = strchr(name, '.');
2123 if (!dot)
2124 return -EINVAL;
2125
2126 c = strndup(name, dot - name);
2127 if (!c)
2128 return -ENOMEM;
2129
2130 controller = c;
2131 }
2132
2133 if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
2134 r = -EINVAL;
2135 goto finish;
2136 }
2137
2138 a = new0(CGroupAttribute, 1);
2139 if (!a) {
2140 r = -ENOMEM;
2141 goto finish;
2142 }
2143
2144 if (c) {
2145 a->controller = c;
2146 c = NULL;
2147 } else
2148 a->controller = strdup(controller);
2149
2150 a->name = strdup(name);
2151 a->value = strdup(value);
2152
2153 if (!a->controller || !a->name || !a->value) {
2154 free(a->controller);
2155 free(a->name);
2156 free(a->value);
2157 free(a);
2158
2159 return -ENOMEM;
2160 }
2161
2162 a->map_callback = map_callback;
2163
ac155bb8 2164 LIST_PREPEND(CGroupAttribute, by_unit, u->cgroup_attributes, a);
ab1f0633
LP
2165
2166 r = 0;
2167
2168finish:
2169 free(c);
2170 return r;
2171}
2172
f6ff8c29
LP
2173int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
2174 char *t;
2175 int r;
2176
2177 assert(u);
2178 assert(type);
2179 assert(_found);
2180
ac155bb8 2181 if (!(t = unit_name_change_suffix(u->id, type)))
f6ff8c29
LP
2182 return -ENOMEM;
2183
2184 assert(!unit_has_name(u, t));
2185
ac155bb8 2186 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
f6ff8c29
LP
2187 free(t);
2188
9e2f7c11 2189 assert(r < 0 || *_found != u);
f6ff8c29
LP
2190
2191 return r;
2192}
2193
a16e1123
LP
2194int unit_get_related_unit(Unit *u, const char *type, Unit **_found) {
2195 Unit *found;
2196 char *t;
2197
2198 assert(u);
2199 assert(type);
2200 assert(_found);
2201
ac155bb8 2202 if (!(t = unit_name_change_suffix(u->id, type)))
a16e1123
LP
2203 return -ENOMEM;
2204
2205 assert(!unit_has_name(u, t));
2206
ac155bb8 2207 found = manager_get_unit(u->manager, t);
a16e1123
LP
2208 free(t);
2209
2210 if (!found)
2211 return -ENOENT;
2212
2213 *_found = found;
2214 return 0;
2215}
2216
9e2f7c11
LP
2217static char *specifier_prefix_and_instance(char specifier, void *data, void *userdata) {
2218 Unit *u = userdata;
2219 assert(u);
2220
ac155bb8 2221 return unit_name_to_prefix_and_instance(u->id);
9e2f7c11
LP
2222}
2223
2224static char *specifier_prefix(char specifier, void *data, void *userdata) {
2225 Unit *u = userdata;
2226 assert(u);
2227
ac155bb8 2228 return unit_name_to_prefix(u->id);
9e2f7c11
LP
2229}
2230
2231static char *specifier_prefix_unescaped(char specifier, void *data, void *userdata) {
2232 Unit *u = userdata;
2233 char *p, *r;
2234
2235 assert(u);
2236
ac155bb8 2237 if (!(p = unit_name_to_prefix(u->id)))
9e2f7c11
LP
2238 return NULL;
2239
2240 r = unit_name_unescape(p);
2241 free(p);
2242
2243 return r;
2244}
2245
2246static char *specifier_instance_unescaped(char specifier, void *data, void *userdata) {
2247 Unit *u = userdata;
2248 assert(u);
2249
ac155bb8
MS
2250 if (u->instance)
2251 return unit_name_unescape(u->instance);
9e2f7c11
LP
2252
2253 return strdup("");
2254}
2255
9fc50704
LP
2256static char *specifier_filename(char specifier, void *data, void *userdata) {
2257 Unit *u = userdata;
2258 assert(u);
2259
ac155bb8
MS
2260 if (u->instance)
2261 return unit_name_path_unescape(u->instance);
9fc50704 2262
ac155bb8 2263 return unit_name_to_path(u->instance);
9fc50704
LP
2264}
2265
0aef4345
LP
2266static char *specifier_cgroup(char specifier, void *data, void *userdata) {
2267 Unit *u = userdata;
2268 assert(u);
2269
2270 return default_cgroup_path(u);
2271}
2272
2273static char *specifier_cgroup_root(char specifier, void *data, void *userdata) {
2274 Unit *u = userdata;
2275 char *p;
2276 assert(u);
2277
2278 if (specifier == 'r')
ac155bb8 2279 return strdup(u->manager->cgroup_hierarchy);
0aef4345 2280
9eb977db 2281 if (path_get_parent(u->manager->cgroup_hierarchy, &p) < 0)
0aef4345
LP
2282 return strdup("");
2283
2284 if (streq(p, "/")) {
2285 free(p);
2286 return strdup("");
2287 }
2288
2289 return p;
2290}
2291
2292static char *specifier_runtime(char specifier, void *data, void *userdata) {
2293 Unit *u = userdata;
2294 assert(u);
2295
ac155bb8 2296 if (u->manager->running_as == MANAGER_USER) {
0aef4345
LP
2297 const char *e;
2298
2299 e = getenv("XDG_RUNTIME_DIR");
2300 if (e)
2301 return strdup(e);
2302 }
2303
2304 return strdup("/run");
2305}
2306
b2896c90
AK
2307static char *specifier_user_name(char specifier, void *data, void *userdata) {
2308 Service *s = userdata;
2309 int r;
2310 const char *username;
2311
2312 /* get USER env from our own env if set */
2313 if (!s->exec_context.user)
2314 return getusername_malloc();
2315
2316 /* fish username from passwd */
2317 username = s->exec_context.user;
d05c5031 2318 r = get_user_creds(&username, NULL, NULL, NULL, NULL);
b2896c90
AK
2319 if (r < 0)
2320 return NULL;
2321
2322 return strdup(username);
2323}
2324
2325static char *specifier_user_home(char specifier, void *data, void *userdata) {
2326 Service *s = userdata;
2327 int r;
2328 const char *username, *home;
2329
2330 /* return HOME if set, otherwise from passwd */
2331 if (!s->exec_context.user) {
2332 char *h;
2333
2334 r = get_home_dir(&h);
2335 if (r < 0)
2336 return NULL;
2337
2338 return h;
2339 }
2340
2341 username = s->exec_context.user;
d05c5031 2342 r = get_user_creds(&username, NULL, NULL, &home, NULL);
b2896c90
AK
2343 if (r < 0)
2344 return NULL;
2345
2346 return strdup(home);
2347}
2348
d05c5031
LP
2349static char *specifier_user_shell(char specifier, void *data, void *userdata) {
2350 Service *s = userdata;
2351 int r;
2352 const char *username, *shell;
2353
2354 /* return HOME if set, otherwise from passwd */
2355 if (!s->exec_context.user) {
2356 char *sh;
2357
2358 r = get_shell(&sh);
2359 if (r < 0)
2360 return strdup("/bin/sh");
2361
2362 return sh;
2363 }
2364
2365 username = s->exec_context.user;
2366 r = get_user_creds(&username, NULL, NULL, NULL, &shell);
2367 if (r < 0)
2368 return strdup("/bin/sh");
2369
2370 return strdup(shell);
2371}
2372
9e2f7c11
LP
2373char *unit_name_printf(Unit *u, const char* format) {
2374
2375 /*
2376 * This will use the passed string as format string and
2377 * replace the following specifiers:
2378 *
2379 * %n: the full id of the unit (foo@bar.waldo)
2380 * %N: the id of the unit without the suffix (foo@bar)
2381 * %p: the prefix (foo)
2382 * %i: the instance (bar)
2383 */
2384
2385 const Specifier table[] = {
ac155bb8 2386 { 'n', specifier_string, u->id },
9e2f7c11
LP
2387 { 'N', specifier_prefix_and_instance, NULL },
2388 { 'p', specifier_prefix, NULL },
ac155bb8 2389 { 'i', specifier_string, u->instance },
9e2f7c11
LP
2390 { 0, NULL, NULL }
2391 };
2392
2393 assert(u);
2394 assert(format);
2395
2396 return specifier_printf(format, table, u);
2397}
2398
2399char *unit_full_printf(Unit *u, const char *format) {
2400
2401 /* This is similar to unit_name_printf() but also supports
0aef4345
LP
2402 * unescaping. Also, adds a couple of additional codes:
2403 *
2404 * %c cgroup path of unit
2405 * %r root cgroup path of this systemd instance (e.g. "/user/lennart/shared/systemd-4711")
2406 * %R parent of root cgroup path (e.g. "/usr/lennart/shared")
2407 * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
b2896c90
AK
2408 * %u the username of the configured User or running user
2409 * %h the homedir of the configured User or running user
0aef4345 2410 */
9e2f7c11
LP
2411
2412 const Specifier table[] = {
ac155bb8 2413 { 'n', specifier_string, u->id },
9e2f7c11
LP
2414 { 'N', specifier_prefix_and_instance, NULL },
2415 { 'p', specifier_prefix, NULL },
2416 { 'P', specifier_prefix_unescaped, NULL },
ac155bb8 2417 { 'i', specifier_string, u->instance },
9e2f7c11 2418 { 'I', specifier_instance_unescaped, NULL },
9fc50704 2419 { 'f', specifier_filename, NULL },
0aef4345
LP
2420 { 'c', specifier_cgroup, NULL },
2421 { 'r', specifier_cgroup_root, NULL },
2422 { 'R', specifier_cgroup_root, NULL },
2423 { 't', specifier_runtime, NULL },
b2896c90
AK
2424 { 'u', specifier_user_name, NULL },
2425 { 'h', specifier_user_home, NULL },
d05c5031 2426 { 's', specifier_user_shell, NULL },
9e2f7c11
LP
2427 { 0, NULL, NULL }
2428 };
2429
2430 assert(u);
2431 assert(format);
2432
2433 return specifier_printf(format, table, u);
2434}
2435
2436char **unit_full_printf_strv(Unit *u, char **l) {
2437 size_t n;
2438 char **r, **i, **j;
2439
2440 /* Applies unit_full_printf to every entry in l */
2441
2442 assert(u);
2443
2444 n = strv_length(l);
2445 if (!(r = new(char*, n+1)))
2446 return NULL;
2447
2448 for (i = l, j = r; *i; i++, j++)
2449 if (!(*j = unit_full_printf(u, *i)))
2450 goto fail;
2451
2452 *j = NULL;
2453 return r;
2454
2455fail:
da19d5c1 2456 for (j--; j >= r; j--)
9e2f7c11
LP
2457 free(*j);
2458
2459 free(r);
2460
2461 return NULL;
2462}
2463
05e343b7
LP
2464int unit_watch_bus_name(Unit *u, const char *name) {
2465 assert(u);
2466 assert(name);
2467
2468 /* Watch a specific name on the bus. We only support one unit
2469 * watching each name for now. */
2470
ac155bb8 2471 return hashmap_put(u->manager->watch_bus, name, u);
05e343b7
LP
2472}
2473
2474void unit_unwatch_bus_name(Unit *u, const char *name) {
2475 assert(u);
2476 assert(name);
2477
ac155bb8 2478 hashmap_remove_value(u->manager->watch_bus, name, u);
05e343b7
LP
2479}
2480
a16e1123
LP
2481bool unit_can_serialize(Unit *u) {
2482 assert(u);
2483
2484 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2485}
2486
6b78f9b4 2487int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
a16e1123
LP
2488 int r;
2489
2490 assert(u);
2491 assert(f);
2492 assert(fds);
2493
2494 if (!unit_can_serialize(u))
2495 return 0;
2496
2497 if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
2498 return r;
2499
cca098b0 2500
6b78f9b4
LP
2501 if (serialize_jobs) {
2502 if (u->job) {
2503 fprintf(f, "job\n");
2504 job_serialize(u->job, f, fds);
2505 }
2506
2507 if (u->nop_job) {
2508 fprintf(f, "job\n");
2509 job_serialize(u->nop_job, f, fds);
2510 }
e0209d83
MS
2511 }
2512
ac155bb8
MS
2513 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2514 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2515 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2516 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2517 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
2791a8f8 2518
ac155bb8
MS
2519 if (dual_timestamp_is_set(&u->condition_timestamp))
2520 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
10717a1a 2521
a16e1123
LP
2522 /* End marker */
2523 fputc('\n', f);
2524 return 0;
2525}
2526
2527void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2528 va_list ap;
2529
2530 assert(u);
2531 assert(f);
2532 assert(key);
2533 assert(format);
2534
2535 fputs(key, f);
2536 fputc('=', f);
2537
2538 va_start(ap, format);
2539 vfprintf(f, format, ap);
2540 va_end(ap);
2541
2542 fputc('\n', f);
2543}
2544
2545void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2546 assert(u);
2547 assert(f);
2548 assert(key);
2549 assert(value);
2550
2551 fprintf(f, "%s=%s\n", key, value);
2552}
2553
2554int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
2555 int r;
2556
2557 assert(u);
2558 assert(f);
2559 assert(fds);
2560
2561 if (!unit_can_serialize(u))
2562 return 0;
2563
2564 for (;;) {
20c03b7b 2565 char line[LINE_MAX], *l, *v;
a16e1123
LP
2566 size_t k;
2567
2568 if (!fgets(line, sizeof(line), f)) {
2569 if (feof(f))
2570 return 0;
2571 return -errno;
2572 }
2573
10f8e83c 2574 char_array_0(line);
a16e1123
LP
2575 l = strstrip(line);
2576
2577 /* End marker */
2578 if (l[0] == 0)
2579 return 0;
2580
2581 k = strcspn(l, "=");
2582
2583 if (l[k] == '=') {
2584 l[k] = 0;
2585 v = l+k+1;
2586 } else
2587 v = l+k;
2588
cca098b0 2589 if (streq(l, "job")) {
39a18c60
MS
2590 if (v[0] == '\0') {
2591 /* new-style serialized job */
2592 Job *j = job_new_raw(u);
2593 if (!j)
2594 return -ENOMEM;
2595
2596 r = job_deserialize(j, f, fds);
2597 if (r < 0) {
2598 job_free(j);
2599 return r;
2600 }
cca098b0 2601
39a18c60
MS
2602 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2603 if (r < 0) {
2604 job_free(j);
2605 return r;
2606 }
e0209d83
MS
2607
2608 r = job_install_deserialized(j);
2609 if (r < 0) {
2610 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2611 job_free(j);
2612 return r;
2613 }
39a18c60
MS
2614 } else {
2615 /* legacy */
2616 JobType type = job_type_from_string(v);
2617 if (type < 0)
2618 log_debug("Failed to parse job type value %s", v);
2619 else
2620 u->deserialized_job = type;
2621 }
cca098b0 2622 continue;
8aaf019b 2623 } else if (streq(l, "inactive-exit-timestamp")) {
ac155bb8 2624 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
8aaf019b
LP
2625 continue;
2626 } else if (streq(l, "active-enter-timestamp")) {
ac155bb8 2627 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
8aaf019b
LP
2628 continue;
2629 } else if (streq(l, "active-exit-timestamp")) {
ac155bb8 2630 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
8aaf019b
LP
2631 continue;
2632 } else if (streq(l, "inactive-enter-timestamp")) {
ac155bb8 2633 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
8aaf019b 2634 continue;
2791a8f8 2635 } else if (streq(l, "condition-timestamp")) {
ac155bb8 2636 dual_timestamp_deserialize(v, &u->condition_timestamp);
2791a8f8
LP
2637 continue;
2638 } else if (streq(l, "condition-result")) {
2639 int b;
2640
2641 if ((b = parse_boolean(v)) < 0)
2642 log_debug("Failed to parse condition result value %s", v);
2643 else
ac155bb8 2644 u->condition_result = b;
efbac6d2
LP
2645
2646 continue;
8aaf019b 2647 }
cca098b0 2648
a16e1123
LP
2649 if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0)
2650 return r;
2651 }
2652}
2653
6e2ef85b
LP
2654int unit_add_node_link(Unit *u, const char *what, bool wants) {
2655 Unit *device;
2656 char *e;
2657 int r;
2658
2659 assert(u);
2660
2661 if (!what)
2662 return 0;
2663
2664 /* Adds in links to the device node that this unit is based on */
2665
8407a5d0 2666 if (!is_device_path(what))
6e2ef85b
LP
2667 return 0;
2668
35eb6b12
LP
2669 e = unit_name_from_path(what, ".device");
2670 if (!e)
6e2ef85b
LP
2671 return -ENOMEM;
2672
ac155bb8 2673 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
6e2ef85b
LP
2674 free(e);
2675
2676 if (r < 0)
2677 return r;
2678
7f2cddae 2679 if ((r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true)) < 0)
6e2ef85b
LP
2680 return r;
2681
2682 if (wants)
2683 if ((r = unit_add_dependency(device, UNIT_WANTS, u, false)) < 0)
2684 return r;
2685
2686 return 0;
2687}
a16e1123 2688
cca098b0
LP
2689int unit_coldplug(Unit *u) {
2690 int r;
2691
2692 assert(u);
2693
2694 if (UNIT_VTABLE(u)->coldplug)
2695 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2696 return r;
2697
39a18c60
MS
2698 if (u->job) {
2699 r = job_coldplug(u->job);
2700 if (r < 0)
2701 return r;
2702 } else if (u->deserialized_job >= 0) {
2703 /* legacy */
2704 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2705 if (r < 0)
cca098b0
LP
2706 return r;
2707
ac155bb8 2708 u->deserialized_job = _JOB_TYPE_INVALID;
cca098b0
LP
2709 }
2710
2711 return 0;
2712}
2713
5831e9b7 2714void unit_status_printf(Unit *u, const char *status, const char *format, ...) {
9e58ff9c
LP
2715 va_list ap;
2716
2717 assert(u);
2718 assert(format);
2719
ac155bb8 2720 if (!manager_get_show_status(u->manager))
9e58ff9c
LP
2721 return;
2722
ac155bb8 2723 if (!manager_is_booting_or_shutting_down(u->manager))
9e58ff9c
LP
2724 return;
2725
2726 va_start(ap, format);
67e5cc4f 2727 status_vprintf(status, true, format, ap);
9e58ff9c
LP
2728 va_end(ap);
2729}
2730
45fb0699 2731bool unit_need_daemon_reload(Unit *u) {
1b64d026
LP
2732 struct stat st;
2733
45fb0699
LP
2734 assert(u);
2735
ac155bb8 2736 if (u->fragment_path) {
5f4b19f4 2737 zero(st);
ac155bb8 2738 if (stat(u->fragment_path, &st) < 0)
5f4b19f4
LP
2739 /* What, cannot access this anymore? */
2740 return true;
45fb0699 2741
ac155bb8
MS
2742 if (u->fragment_mtime > 0 &&
2743 timespec_load(&st.st_mtim) != u->fragment_mtime)
5f4b19f4
LP
2744 return true;
2745 }
2746
1b64d026
LP
2747 if (u->source_path) {
2748 zero(st);
2749 if (stat(u->source_path, &st) < 0)
2750 return true;
2751
2752 if (u->source_mtime > 0 &&
2753 timespec_load(&st.st_mtim) != u->source_mtime)
2754 return true;
2755 }
5f4b19f4
LP
2756
2757 return false;
45fb0699
LP
2758}
2759
fdf20a31 2760void unit_reset_failed(Unit *u) {
5632e374
LP
2761 assert(u);
2762
fdf20a31
MM
2763 if (UNIT_VTABLE(u)->reset_failed)
2764 UNIT_VTABLE(u)->reset_failed(u);
5632e374
LP
2765}
2766
a7f241db
LP
2767Unit *unit_following(Unit *u) {
2768 assert(u);
2769
2770 if (UNIT_VTABLE(u)->following)
2771 return UNIT_VTABLE(u)->following(u);
2772
2773 return NULL;
2774}
2775
18ffdfda
LP
2776bool unit_pending_inactive(Unit *u) {
2777 assert(u);
2778
2779 /* Returns true if the unit is inactive or going down */
2780
2781 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2782 return true;
2783
ac155bb8 2784 if (u->job && u->job->type == JOB_STOP)
18ffdfda
LP
2785 return true;
2786
2787 return false;
2788}
2789
f976f3f6
LP
2790bool unit_pending_active(Unit *u) {
2791 assert(u);
2792
f60c2665 2793 /* Returns true if the unit is active or going up */
f976f3f6
LP
2794
2795 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2796 return true;
2797
ac155bb8
MS
2798 if (u->job &&
2799 (u->job->type == JOB_START ||
2800 u->job->type == JOB_RELOAD_OR_START ||
2801 u->job->type == JOB_RESTART))
f976f3f6
LP
2802 return true;
2803
2804 return false;
2805}
2806
c74f17d9 2807int unit_kill(Unit *u, KillWho w, int signo, DBusError *error) {
8a0867d6
LP
2808 assert(u);
2809 assert(w >= 0 && w < _KILL_WHO_MAX);
8a0867d6
LP
2810 assert(signo > 0);
2811 assert(signo < _NSIG);
2812
8a0867d6
LP
2813 if (!UNIT_VTABLE(u)->kill)
2814 return -ENOTSUP;
2815
c74f17d9 2816 return UNIT_VTABLE(u)->kill(u, w, signo, error);
8a0867d6
LP
2817}
2818
6210e7fc
LP
2819int unit_following_set(Unit *u, Set **s) {
2820 assert(u);
2821 assert(s);
2822
2823 if (UNIT_VTABLE(u)->following_set)
2824 return UNIT_VTABLE(u)->following_set(u, s);
2825
2826 *s = NULL;
2827 return 0;
2828}
2829
a4375746
LP
2830UnitFileState unit_get_unit_file_state(Unit *u) {
2831 assert(u);
2832
ac155bb8
MS
2833 if (u->unit_file_state < 0 && u->fragment_path)
2834 u->unit_file_state = unit_file_get_state(
2835 u->manager->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
9eb977db 2836 NULL, path_get_file_name(u->fragment_path));
a4375746 2837
ac155bb8 2838 return u->unit_file_state;
a4375746
LP
2839}
2840
57020a3a
LP
2841Unit* unit_ref_set(UnitRef *ref, Unit *u) {
2842 assert(ref);
2843 assert(u);
2844
2845 if (ref->unit)
2846 unit_ref_unset(ref);
2847
2848 ref->unit = u;
ac155bb8 2849 LIST_PREPEND(UnitRef, refs, u->refs, ref);
57020a3a
LP
2850 return u;
2851}
2852
2853void unit_ref_unset(UnitRef *ref) {
2854 assert(ref);
2855
2856 if (!ref->unit)
2857 return;
2858
ac155bb8 2859 LIST_REMOVE(UnitRef, refs, ref->unit->refs, ref);
57020a3a
LP
2860 ref->unit = NULL;
2861}
2862
7c8fa05c
LP
2863int unit_add_one_mount_link(Unit *u, Mount *m) {
2864 char **i;
2865
2866 assert(u);
2867 assert(m);
2868
2869 if (u->load_state != UNIT_LOADED ||
2870 UNIT(m)->load_state != UNIT_LOADED)
2871 return 0;
2872
2873 STRV_FOREACH(i, u->requires_mounts_for) {
2874
2875 if (UNIT(m) == u)
2876 continue;
2877
2878 if (!path_startswith(*i, m->where))
2879 continue;
2880
2881 return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
2882 }
2883
2884 return 0;
2885}
2886
2887int unit_add_mount_links(Unit *u) {
2888 Unit *other;
2889 int r;
2890
2891 assert(u);
2892
2893 LIST_FOREACH(units_by_type, other, u->manager->units_by_type[UNIT_MOUNT]) {
2894 r = unit_add_one_mount_link(u, MOUNT(other));
2895 if (r < 0)
2896 return r;
2897 }
2898
2899 return 0;
2900}
2901
cba6e062
LP
2902int unit_exec_context_defaults(Unit *u, ExecContext *c) {
2903 unsigned i;
2904 int r;
2905
e06c73cc
LP
2906 assert(u);
2907 assert(c);
2908
cba6e062 2909 /* This only copies in the ones that need memory */
e06c73cc 2910
cba6e062
LP
2911 for (i = 0; i < RLIMIT_NLIMITS; i++)
2912 if (u->manager->rlimit[i] && !c->rlimit[i]) {
2913 c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
2914 if (!c->rlimit[i])
2915 return -ENOMEM;
2916 }
2917
2918 if (u->manager->running_as == MANAGER_USER &&
2919 !c->working_directory) {
e06c73cc 2920
cba6e062
LP
2921 r = get_home_dir(&c->working_directory);
2922 if (r < 0)
2923 return r;
2924 }
2925
2926 return 0;
e06c73cc
LP
2927}
2928
94f04347
LP
2929static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
2930 [UNIT_ACTIVE] = "active",
032ff4af 2931 [UNIT_RELOADING] = "reloading",
94f04347 2932 [UNIT_INACTIVE] = "inactive",
fdf20a31 2933 [UNIT_FAILED] = "failed",
94f04347
LP
2934 [UNIT_ACTIVATING] = "activating",
2935 [UNIT_DEACTIVATING] = "deactivating"
2936};
2937
2938DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
2939
2940static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
2941 [UNIT_REQUIRES] = "Requires",
9e2f7c11 2942 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
94f04347 2943 [UNIT_REQUISITE] = "Requisite",
9e2f7c11 2944 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
ac6a4abe
MS
2945 [UNIT_WANTS] = "Wants",
2946 [UNIT_BINDS_TO] = "BindsTo",
2947 [UNIT_PART_OF] = "PartOf",
94f04347 2948 [UNIT_REQUIRED_BY] = "RequiredBy",
9e2f7c11 2949 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
94f04347 2950 [UNIT_WANTED_BY] = "WantedBy",
ac6a4abe
MS
2951 [UNIT_BOUND_BY] = "BoundBy",
2952 [UNIT_CONSISTS_OF] = "ConsistsOf",
94f04347 2953 [UNIT_CONFLICTS] = "Conflicts",
69dd2852 2954 [UNIT_CONFLICTED_BY] = "ConflictedBy",
94f04347
LP
2955 [UNIT_BEFORE] = "Before",
2956 [UNIT_AFTER] = "After",
57020a3a
LP
2957 [UNIT_ON_FAILURE] = "OnFailure",
2958 [UNIT_TRIGGERS] = "Triggers",
4dcc1cb4 2959 [UNIT_TRIGGERED_BY] = "TriggeredBy",
7f2cddae 2960 [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
ac6a4abe
MS
2961 [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
2962 [UNIT_REFERENCES] = "References",
2963 [UNIT_REFERENCED_BY] = "ReferencedBy",
94f04347
LP
2964};
2965
2966DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);