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