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