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