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