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