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