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