1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
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
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include <sys/epoll.h>
26 #include <sys/timerfd.h>
32 #include "systemd/sd-id128.h"
33 #include "systemd/sd-messages.h"
38 #include "path-util.h"
39 #include "load-fragment.h"
40 #include "load-dropin.h"
42 #include "unit-name.h"
43 #include "dbus-unit.h"
45 #include "cgroup-util.h"
49 #include "fileio-label.h"
50 #include "bus-errors.h"
52 const 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,
60 [UNIT_SNAPSHOT] = &snapshot_vtable,
61 [UNIT_SWAP] = &swap_vtable,
62 [UNIT_PATH] = &path_vtable,
63 [UNIT_SLICE] = &slice_vtable,
64 [UNIT_SCOPE] = &scope_vtable
67 Unit *unit_new(Manager *m, size_t size) {
71 assert(size >= sizeof(Unit));
77 u->names = set_new(string_hash_func, string_compare_func);
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;
92 bool unit_has_name(Unit *u, const char *name) {
96 return !!set_get(u->names, (char*) name);
99 int unit_add_name(Unit *u, const char *text) {
107 if (unit_name_is_template(text)) {
111 s = unit_name_replace_instance(text, u->instance);
118 if (!unit_name_is_valid(s, false)) {
123 assert_se((t = unit_name_to_type(s)) >= 0);
125 if (u->type != _UNIT_TYPE_INVALID && t != u->type) {
130 if ((r = unit_name_to_instance(s, &i)) < 0)
133 if (i && unit_vtable[t]->no_instances) {
138 /* Ensure that this unit is either instanced or not instanced,
140 if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) {
145 if (unit_vtable[t]->no_alias &&
146 !set_isempty(u->names) &&
147 !set_get(u->names, s)) {
152 if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) {
157 if ((r = set_put(u->names, s)) < 0) {
163 if ((r = hashmap_put(u->manager->units, s, u)) < 0) {
164 set_remove(u->names, s);
168 if (u->type == _UNIT_TYPE_INVALID) {
174 LIST_PREPEND(Unit, units_by_type, u->manager->units_by_type[t], u);
176 if (UNIT_VTABLE(u)->init)
177 UNIT_VTABLE(u)->init(u);
181 unit_add_to_dbus_queue(u);
191 int unit_choose_id(Unit *u, const char *name) {
192 char *s, *t = NULL, *i;
198 if (unit_name_is_template(name)) {
203 if (!(t = unit_name_replace_instance(name, u->instance)))
209 /* Selects one of the names of this unit as the id */
210 s = set_get(u->names, (char*) name);
216 if ((r = unit_name_to_instance(s, &i)) < 0)
224 unit_add_to_dbus_queue(u);
229 int unit_set_description(Unit *u, const char *description) {
234 if (isempty(description))
237 s = strdup(description);
242 free(u->description);
245 unit_add_to_dbus_queue(u);
249 bool unit_check_gc(Unit *u) {
252 if (u->load_state == UNIT_STUB)
255 if (UNIT_VTABLE(u)->no_gc)
267 if (unit_active_state(u) != UNIT_INACTIVE)
273 if (UNIT_VTABLE(u)->check_gc)
274 if (UNIT_VTABLE(u)->check_gc(u))
280 void unit_add_to_load_queue(Unit *u) {
282 assert(u->type != _UNIT_TYPE_INVALID);
284 if (u->load_state != UNIT_STUB || u->in_load_queue)
287 LIST_PREPEND(Unit, load_queue, u->manager->load_queue, u);
288 u->in_load_queue = true;
291 void unit_add_to_cleanup_queue(Unit *u) {
294 if (u->in_cleanup_queue)
297 LIST_PREPEND(Unit, cleanup_queue, u->manager->cleanup_queue, u);
298 u->in_cleanup_queue = true;
301 void unit_add_to_gc_queue(Unit *u) {
304 if (u->in_gc_queue || u->in_cleanup_queue)
307 if (unit_check_gc(u))
310 LIST_PREPEND(Unit, gc_queue, u->manager->gc_queue, u);
311 u->in_gc_queue = true;
313 u->manager->n_in_gc_queue ++;
316 void unit_add_to_dbus_queue(Unit *u) {
318 assert(u->type != _UNIT_TYPE_INVALID);
320 if (u->load_state == UNIT_STUB || u->in_dbus_queue)
323 /* Shortcut things if nobody cares */
324 if (!bus_has_subscriber(u->manager)) {
325 u->sent_dbus_new_signal = true;
329 LIST_PREPEND(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
330 u->in_dbus_queue = true;
333 static void bidi_set_free(Unit *u, Set *s) {
339 /* Frees the set and makes sure we are dropped from the
340 * inverse pointers */
342 SET_FOREACH(other, s, i) {
345 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
346 set_remove(other->dependencies[d], u);
348 unit_add_to_gc_queue(other);
354 static void unit_remove_transient(Unit *u) {
362 if (u->fragment_path)
363 unlink(u->fragment_path);
365 STRV_FOREACH(i, u->dropin_paths) {
366 _cleanup_free_ char *p = NULL;
371 r = path_get_parent(*i, &p);
377 void unit_free(Unit *u) {
384 if (u->manager->n_reloading <= 0)
385 unit_remove_transient(u);
387 bus_unit_send_removed_signal(u);
389 if (u->load_state != UNIT_STUB)
390 if (UNIT_VTABLE(u)->done)
391 UNIT_VTABLE(u)->done(u);
393 SET_FOREACH(t, u->names, i)
394 hashmap_remove_value(u->manager->units, t, u);
408 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
409 bidi_set_free(u, u->dependencies[d]);
411 if (u->requires_mounts_for) {
412 LIST_REMOVE(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u);
413 strv_free(u->requires_mounts_for);
416 if (u->type != _UNIT_TYPE_INVALID)
417 LIST_REMOVE(Unit, units_by_type, u->manager->units_by_type[u->type], u);
419 if (u->in_load_queue)
420 LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u);
422 if (u->in_dbus_queue)
423 LIST_REMOVE(Unit, dbus_queue, u->manager->dbus_unit_queue, u);
425 if (u->in_cleanup_queue)
426 LIST_REMOVE(Unit, cleanup_queue, u->manager->cleanup_queue, u);
428 if (u->in_gc_queue) {
429 LIST_REMOVE(Unit, gc_queue, u->manager->gc_queue, u);
430 u->manager->n_in_gc_queue--;
433 if (u->in_cgroup_queue)
434 LIST_REMOVE(Unit, cgroup_queue, u->manager->cgroup_queue, u);
436 if (u->cgroup_path) {
437 hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
438 free(u->cgroup_path);
441 free(u->description);
442 strv_free(u->documentation);
443 free(u->fragment_path);
444 free(u->source_path);
445 strv_free(u->dropin_paths);
448 set_free_free(u->names);
450 condition_free_list(u->conditions);
452 unit_ref_unset(&u->slice);
455 unit_ref_unset(u->refs);
460 UnitActiveState unit_active_state(Unit *u) {
463 if (u->load_state == UNIT_MERGED)
464 return unit_active_state(unit_follow_merge(u));
466 /* After a reload it might happen that a unit is not correctly
467 * loaded but still has a process around. That's why we won't
468 * shortcut failed loading to UNIT_INACTIVE_FAILED. */
470 return UNIT_VTABLE(u)->active_state(u);
473 const char* unit_sub_state_to_string(Unit *u) {
476 return UNIT_VTABLE(u)->sub_state_to_string(u);
479 static void complete_move(Set **s, Set **other) {
487 set_move(*s, *other);
494 static void merge_names(Unit *u, Unit *other) {
501 complete_move(&u->names, &other->names);
503 set_free_free(other->names);
507 SET_FOREACH(t, u->names, i)
508 assert_se(hashmap_replace(u->manager->units, t, u) == 0);
511 static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
518 assert(d < _UNIT_DEPENDENCY_MAX);
520 /* Fix backwards pointers */
521 SET_FOREACH(back, other->dependencies[d], i) {
524 for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++)
525 if ((r = set_remove_and_put(back->dependencies[k], other, u)) < 0) {
528 set_remove(back->dependencies[k], other);
530 assert(r == -ENOENT);
534 complete_move(&u->dependencies[d], &other->dependencies[d]);
536 set_free(other->dependencies[d]);
537 other->dependencies[d] = NULL;
540 int unit_merge(Unit *u, Unit *other) {
545 assert(u->manager == other->manager);
546 assert(u->type != _UNIT_TYPE_INVALID);
548 other = unit_follow_merge(other);
553 if (u->type != other->type)
556 if (!u->instance != !other->instance)
559 if (other->load_state != UNIT_STUB &&
560 other->load_state != UNIT_NOT_FOUND)
569 if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
573 merge_names(u, other);
575 /* Redirect all references */
577 unit_ref_set(other->refs, u);
579 /* Merge dependencies */
580 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
581 merge_dependencies(u, other, d);
583 other->load_state = UNIT_MERGED;
584 other->merged_into = u;
586 /* If there is still some data attached to the other node, we
587 * don't need it anymore, and can free it. */
588 if (other->load_state != UNIT_STUB)
589 if (UNIT_VTABLE(other)->done)
590 UNIT_VTABLE(other)->done(other);
592 unit_add_to_dbus_queue(u);
593 unit_add_to_cleanup_queue(other);
598 int unit_merge_by_name(Unit *u, const char *name) {
606 if (unit_name_is_template(name)) {
610 if (!(s = unit_name_replace_instance(name, u->instance)))
616 other = manager_get_unit(u->manager, name);
618 r = unit_add_name(u, name);
620 r = unit_merge(u, other);
626 Unit* unit_follow_merge(Unit *u) {
629 while (u->load_state == UNIT_MERGED)
630 assert_se(u = u->merged_into);
635 int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
641 if (c->std_output != EXEC_OUTPUT_KMSG &&
642 c->std_output != EXEC_OUTPUT_SYSLOG &&
643 c->std_output != EXEC_OUTPUT_JOURNAL &&
644 c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
645 c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
646 c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
647 c->std_error != EXEC_OUTPUT_KMSG &&
648 c->std_error != EXEC_OUTPUT_SYSLOG &&
649 c->std_error != EXEC_OUTPUT_JOURNAL &&
650 c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
651 c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
652 c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE)
655 /* If syslog or kernel logging is requested, make sure our own
656 * logging daemon is run first. */
658 if (u->manager->running_as == SYSTEMD_SYSTEM) {
659 r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true);
667 const char *unit_description(Unit *u) {
671 return u->description;
676 void unit_dump(Unit *u, FILE *f, const char *prefix) {
683 timestamp1[FORMAT_TIMESTAMP_MAX],
684 timestamp2[FORMAT_TIMESTAMP_MAX],
685 timestamp3[FORMAT_TIMESTAMP_MAX],
686 timestamp4[FORMAT_TIMESTAMP_MAX],
687 timespan[FORMAT_TIMESPAN_MAX];
691 assert(u->type >= 0);
695 p2 = strappend(prefix, "\t");
696 prefix2 = p2 ? p2 : prefix;
700 "%s\tDescription: %s\n"
702 "%s\tUnit Load State: %s\n"
703 "%s\tUnit Active State: %s\n"
704 "%s\tInactive Exit Timestamp: %s\n"
705 "%s\tActive Enter Timestamp: %s\n"
706 "%s\tActive Exit Timestamp: %s\n"
707 "%s\tInactive Enter Timestamp: %s\n"
708 "%s\tGC Check Good: %s\n"
709 "%s\tNeed Daemon Reload: %s\n"
710 "%s\tTransient: %s\n"
713 "%s\tCGroup realized: %s\n"
714 "%s\tCGroup mask: 0x%x\n",
716 prefix, unit_description(u),
717 prefix, strna(u->instance),
718 prefix, unit_load_state_to_string(u->load_state),
719 prefix, unit_active_state_to_string(unit_active_state(u)),
720 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->inactive_exit_timestamp.realtime)),
721 prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->active_enter_timestamp.realtime)),
722 prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)),
723 prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)),
724 prefix, yes_no(unit_check_gc(u)),
725 prefix, yes_no(unit_need_daemon_reload(u)),
726 prefix, yes_no(u->transient),
727 prefix, strna(unit_slice_name(u)),
728 prefix, strna(u->cgroup_path),
729 prefix, yes_no(u->cgroup_realized),
730 prefix, u->cgroup_mask);
732 SET_FOREACH(t, u->names, i)
733 fprintf(f, "%s\tName: %s\n", prefix, t);
735 STRV_FOREACH(j, u->documentation)
736 fprintf(f, "%s\tDocumentation: %s\n", prefix, *j);
738 if ((following = unit_following(u)))
739 fprintf(f, "%s\tFollowing: %s\n", prefix, following->id);
741 if (u->fragment_path)
742 fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path);
745 fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path);
747 STRV_FOREACH(j, u->dropin_paths)
748 fprintf(f, "%s\tDropIn Path: %s\n", prefix, *j);
750 if (u->job_timeout > 0)
751 fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
753 condition_dump_list(u->conditions, f, prefix);
755 if (dual_timestamp_is_set(&u->condition_timestamp))
757 "%s\tCondition Timestamp: %s\n"
758 "%s\tCondition Result: %s\n",
759 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->condition_timestamp.realtime)),
760 prefix, yes_no(u->condition_result));
762 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
765 SET_FOREACH(other, u->dependencies[d], i)
766 fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
769 if (!strv_isempty(u->requires_mounts_for)) {
771 "%s\tRequiresMountsFor:", prefix);
773 STRV_FOREACH(j, u->requires_mounts_for)
774 fprintf(f, " %s", *j);
779 if (u->load_state == UNIT_LOADED) {
782 "%s\tStopWhenUnneeded: %s\n"
783 "%s\tRefuseManualStart: %s\n"
784 "%s\tRefuseManualStop: %s\n"
785 "%s\tDefaultDependencies: %s\n"
786 "%s\tOnFailureIsolate: %s\n"
787 "%s\tIgnoreOnIsolate: %s\n"
788 "%s\tIgnoreOnSnapshot: %s\n",
789 prefix, yes_no(u->stop_when_unneeded),
790 prefix, yes_no(u->refuse_manual_start),
791 prefix, yes_no(u->refuse_manual_stop),
792 prefix, yes_no(u->default_dependencies),
793 prefix, yes_no(u->on_failure_isolate),
794 prefix, yes_no(u->ignore_on_isolate),
795 prefix, yes_no(u->ignore_on_snapshot));
797 if (UNIT_VTABLE(u)->dump)
798 UNIT_VTABLE(u)->dump(u, f, prefix2);
800 } else if (u->load_state == UNIT_MERGED)
802 "%s\tMerged into: %s\n",
803 prefix, u->merged_into->id);
804 else if (u->load_state == UNIT_ERROR)
805 fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->load_error));
809 job_dump(u->job, f, prefix2);
812 job_dump(u->nop_job, f, prefix2);
817 /* Common implementation for multiple backends */
818 int unit_load_fragment_and_dropin(Unit *u) {
823 /* Load a .service file */
824 r = unit_load_fragment(u);
828 if (u->load_state == UNIT_STUB)
831 /* Load drop-in directory data */
832 r = unit_load_dropin(unit_follow_merge(u));
839 /* Common implementation for multiple backends */
840 int unit_load_fragment_and_dropin_optional(Unit *u) {
845 /* Same as unit_load_fragment_and_dropin(), but whether
846 * something can be loaded or not doesn't matter. */
848 /* Load a .service file */
849 r = unit_load_fragment(u);
853 if (u->load_state == UNIT_STUB)
854 u->load_state = UNIT_LOADED;
856 /* Load drop-in directory data */
857 r = unit_load_dropin(unit_follow_merge(u));
864 int unit_add_default_target_dependency(Unit *u, Unit *target) {
868 if (target->type != UNIT_TARGET)
871 /* Only add the dependency if both units are loaded, so that
872 * that loop check below is reliable */
873 if (u->load_state != UNIT_LOADED ||
874 target->load_state != UNIT_LOADED)
877 /* If either side wants no automatic dependencies, then let's
879 if (!u->default_dependencies ||
880 !target->default_dependencies)
883 /* Don't create loops */
884 if (set_get(target->dependencies[UNIT_BEFORE], u))
887 return unit_add_dependency(target, UNIT_AFTER, u, true);
890 static int unit_add_default_dependencies(Unit *u) {
892 static const UnitDependency deps[] = {
894 UNIT_REQUIRED_BY_OVERRIDABLE,
906 for (k = 0; k < ELEMENTSOF(deps); k++)
907 SET_FOREACH(target, u->dependencies[deps[k]], i) {
908 r = unit_add_default_target_dependency(u, target);
913 if (u->default_dependencies && unit_get_cgroup_context(u)) {
914 if (UNIT_ISSET(u->slice))
915 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true);
917 r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, SPECIAL_ROOT_SLICE, NULL, true);
926 int unit_load(Unit *u) {
931 if (u->in_load_queue) {
932 LIST_REMOVE(Unit, load_queue, u->manager->load_queue, u);
933 u->in_load_queue = false;
936 if (u->type == _UNIT_TYPE_INVALID)
939 if (u->load_state != UNIT_STUB)
942 if (UNIT_VTABLE(u)->load) {
943 r = UNIT_VTABLE(u)->load(u);
948 if (u->load_state == UNIT_STUB) {
953 if (u->load_state == UNIT_LOADED) {
955 if (u->default_dependencies) {
956 r = unit_add_default_dependencies(u);
961 r = unit_add_mount_links(u);
965 if (u->on_failure_isolate &&
966 set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
968 log_error_unit(u->id,
969 "More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.", u->id);
976 assert((u->load_state != UNIT_MERGED) == !u->merged_into);
978 unit_add_to_dbus_queue(unit_follow_merge(u));
979 unit_add_to_gc_queue(u);
984 u->load_state = u->load_state == UNIT_STUB ? UNIT_NOT_FOUND : UNIT_ERROR;
986 unit_add_to_dbus_queue(u);
987 unit_add_to_gc_queue(u);
989 log_debug_unit(u->id, "Failed to load configuration for %s: %s",
990 u->id, strerror(-r));
995 bool unit_condition_test(Unit *u) {
998 dual_timestamp_get(&u->condition_timestamp);
999 u->condition_result = condition_test_list(u->conditions);
1001 return u->condition_result;
1004 _pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
1005 const UnitStatusMessageFormats *format_table;
1009 assert(t < _JOB_TYPE_MAX);
1011 if (t != JOB_START && t != JOB_STOP)
1014 format_table = &UNIT_VTABLE(u)->status_message_formats;
1018 return format_table->starting_stopping[t == JOB_STOP];
1021 _pure_ static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) {
1026 assert(t < _JOB_TYPE_MAX);
1028 format = unit_get_status_message_format(u, t);
1032 /* Return generic strings */
1034 return "Starting %s.";
1035 else if (t == JOB_STOP)
1036 return "Stopping %s.";
1037 else if (t == JOB_RELOAD)
1038 return "Reloading %s.";
1043 static void unit_status_print_starting_stopping(Unit *u, JobType t) {
1048 /* We only print status messages for selected units on
1049 * selected operations. */
1051 format = unit_get_status_message_format(u, t);
1055 unit_status_printf(u, "", format);
1058 #pragma GCC diagnostic push
1059 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
1060 static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
1067 if (t != JOB_START && t != JOB_STOP && t != JOB_RELOAD)
1070 if (log_on_console())
1073 /* We log status messages for all units and all operations. */
1075 format = unit_get_status_message_format_try_harder(u, t);
1079 snprintf(buf, sizeof(buf), format, unit_description(u));
1082 mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
1083 t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
1084 SD_MESSAGE_UNIT_RELOADING;
1086 log_struct_unit(LOG_INFO,
1092 #pragma GCC diagnostic pop
1095 * -EBADR: This unit type does not support starting.
1096 * -EALREADY: Unit is already started.
1097 * -EAGAIN: An operation is already in progress. Retry later.
1098 * -ECANCELED: Too many requests for now.
1100 int unit_start(Unit *u) {
1101 UnitActiveState state;
1106 if (u->load_state != UNIT_LOADED)
1109 /* If this is already started, then this will succeed. Note
1110 * that this will even succeed if this unit is not startable
1111 * by the user. This is relied on to detect when we need to
1112 * wait for units and when waiting is finished. */
1113 state = unit_active_state(u);
1114 if (UNIT_IS_ACTIVE_OR_RELOADING(state))
1117 /* If the conditions failed, don't do anything at all. If we
1118 * already are activating this call might still be useful to
1119 * speed up activation in case there is some hold-off time,
1120 * but we don't want to recheck the condition in that case. */
1121 if (state != UNIT_ACTIVATING &&
1122 !unit_condition_test(u)) {
1123 log_debug_unit(u->id, "Starting of %s requested but condition failed. Ignoring.", u->id);
1127 /* Forward to the main object, if we aren't it. */
1128 if ((following = unit_following(u))) {
1129 log_debug_unit(u->id, "Redirecting start request from %s to %s.",
1130 u->id, following->id);
1131 return unit_start(following);
1134 unit_status_log_starting_stopping_reloading(u, JOB_START);
1135 unit_status_print_starting_stopping(u, JOB_START);
1137 /* If it is stopped, but we cannot start it, then fail */
1138 if (!UNIT_VTABLE(u)->start)
1141 /* We don't suppress calls to ->start() here when we are
1142 * already starting, to allow this request to be used as a
1143 * "hurry up" call, for example when the unit is in some "auto
1144 * restart" state where it waits for a holdoff timer to elapse
1145 * before it will start again. */
1147 unit_add_to_dbus_queue(u);
1149 return UNIT_VTABLE(u)->start(u);
1152 bool unit_can_start(Unit *u) {
1155 return !!UNIT_VTABLE(u)->start;
1158 bool unit_can_isolate(Unit *u) {
1161 return unit_can_start(u) &&
1166 * -EBADR: This unit type does not support stopping.
1167 * -EALREADY: Unit is already stopped.
1168 * -EAGAIN: An operation is already in progress. Retry later.
1170 int unit_stop(Unit *u) {
1171 UnitActiveState state;
1176 state = unit_active_state(u);
1177 if (UNIT_IS_INACTIVE_OR_FAILED(state))
1180 if ((following = unit_following(u))) {
1181 log_debug_unit(u->id, "Redirecting stop request from %s to %s.",
1182 u->id, following->id);
1183 return unit_stop(following);
1186 unit_status_log_starting_stopping_reloading(u, JOB_STOP);
1187 unit_status_print_starting_stopping(u, JOB_STOP);
1189 if (!UNIT_VTABLE(u)->stop)
1192 unit_add_to_dbus_queue(u);
1194 return UNIT_VTABLE(u)->stop(u);
1198 * -EBADR: This unit type does not support reloading.
1199 * -ENOEXEC: Unit is not started.
1200 * -EAGAIN: An operation is already in progress. Retry later.
1202 int unit_reload(Unit *u) {
1203 UnitActiveState state;
1208 if (u->load_state != UNIT_LOADED)
1211 if (!unit_can_reload(u))
1214 state = unit_active_state(u);
1215 if (state == UNIT_RELOADING)
1218 if (state != UNIT_ACTIVE)
1221 if ((following = unit_following(u))) {
1222 log_debug_unit(u->id, "Redirecting reload request from %s to %s.",
1223 u->id, following->id);
1224 return unit_reload(following);
1227 unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
1229 unit_add_to_dbus_queue(u);
1230 return UNIT_VTABLE(u)->reload(u);
1233 bool unit_can_reload(Unit *u) {
1236 if (!UNIT_VTABLE(u)->reload)
1239 if (!UNIT_VTABLE(u)->can_reload)
1242 return UNIT_VTABLE(u)->can_reload(u);
1245 static void unit_check_unneeded(Unit *u) {
1251 /* If this service shall be shut down when unneeded then do
1254 if (!u->stop_when_unneeded)
1257 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1260 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
1261 if (unit_active_or_pending(other))
1264 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
1265 if (unit_active_or_pending(other))
1268 SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
1269 if (unit_active_or_pending(other))
1272 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1273 if (unit_active_or_pending(other))
1276 log_info_unit(u->id, "Service %s is not needed anymore. Stopping.", u->id);
1278 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
1279 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
1282 static void retroactively_start_dependencies(Unit *u) {
1287 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1289 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1290 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1291 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1292 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1294 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1295 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1296 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1297 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1299 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1300 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1301 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1302 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1304 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1305 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1306 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1307 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1309 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
1310 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1311 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1313 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
1314 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1315 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1318 static void retroactively_stop_dependencies(Unit *u) {
1323 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1325 /* Pull down units which are bound to us recursively if enabled */
1326 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1327 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1328 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1331 static void check_unneeded_dependencies(Unit *u) {
1336 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1338 /* Garbage collect services that might not be needed anymore, if enabled */
1339 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1340 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1341 unit_check_unneeded(other);
1342 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1343 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1344 unit_check_unneeded(other);
1345 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1346 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1347 unit_check_unneeded(other);
1348 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
1349 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1350 unit_check_unneeded(other);
1351 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
1352 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1353 unit_check_unneeded(other);
1354 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1355 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1356 unit_check_unneeded(other);
1359 void unit_start_on_failure(Unit *u) {
1365 if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
1368 log_info_unit(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
1370 SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
1373 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL);
1375 log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
1379 void unit_trigger_notify(Unit *u) {
1385 SET_FOREACH(other, u->dependencies[UNIT_TRIGGERED_BY], i)
1386 if (UNIT_VTABLE(other)->trigger_notify)
1387 UNIT_VTABLE(other)->trigger_notify(other, u);
1390 void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
1395 assert(os < _UNIT_ACTIVE_STATE_MAX);
1396 assert(ns < _UNIT_ACTIVE_STATE_MAX);
1398 /* Note that this is called for all low-level state changes,
1399 * even if they might map to the same high-level
1400 * UnitActiveState! That means that ns == os is OK an expected
1401 * behavior here. For example: if a mount point is remounted
1402 * this function will be called too! */
1406 if (m->n_reloading <= 0) {
1409 dual_timestamp_get(&ts);
1411 if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
1412 u->inactive_exit_timestamp = ts;
1413 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
1414 u->inactive_enter_timestamp = ts;
1416 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
1417 u->active_enter_timestamp = ts;
1418 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
1419 u->active_exit_timestamp = ts;
1422 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1423 unit_destroy_cgroup(u);
1425 if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1426 ExecContext *ec = unit_get_exec_context(u);
1427 if (ec && exec_context_may_touch_console(ec)) {
1428 if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1431 if (m->n_on_console == 0)
1432 /* unset no_console_output flag, since the console is free */
1433 m->no_console_output = 0;
1442 if (u->job->state == JOB_WAITING)
1444 /* So we reached a different state for this
1445 * job. Let's see if we can run it now if it
1446 * failed previously due to EAGAIN. */
1447 job_add_to_run_queue(u->job);
1449 /* Let's check whether this state change constitutes a
1450 * finished job, or maybe contradicts a running job and
1451 * hence needs to invalidate jobs. */
1453 switch (u->job->type) {
1456 case JOB_VERIFY_ACTIVE:
1458 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
1459 job_finish_and_invalidate(u->job, JOB_DONE, true);
1460 else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
1463 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1464 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1470 case JOB_RELOAD_OR_START:
1472 if (u->job->state == JOB_RUNNING) {
1473 if (ns == UNIT_ACTIVE)
1474 job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
1475 else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
1478 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1479 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1487 case JOB_TRY_RESTART:
1489 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1490 job_finish_and_invalidate(u->job, JOB_DONE, true);
1491 else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
1493 job_finish_and_invalidate(u->job, JOB_FAILED, true);
1499 assert_not_reached("Job type unknown");
1505 if (m->n_reloading <= 0) {
1507 /* If this state change happened without being
1508 * requested by a job, then let's retroactively start
1509 * or stop dependencies. We skip that step when
1510 * deserializing, since we don't want to create any
1511 * additional jobs just because something is already
1515 if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1516 retroactively_start_dependencies(u);
1517 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1518 retroactively_stop_dependencies(u);
1521 /* stop unneeded units regardless if going down was expected or not */
1522 if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1523 check_unneeded_dependencies(u);
1525 if (ns != os && ns == UNIT_FAILED) {
1526 log_notice_unit(u->id,
1527 "Unit %s entered failed state.", u->id);
1528 unit_start_on_failure(u);
1532 /* Some names are special */
1533 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
1535 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
1536 /* The bus just might have become available,
1537 * hence try to connect to it, if we aren't
1541 if (u->type == UNIT_SERVICE &&
1542 !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
1543 m->n_reloading <= 0) {
1544 /* Write audit record if we have just finished starting up */
1545 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
1549 if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
1550 manager_send_unit_plymouth(m, u);
1554 /* We don't care about D-Bus here, since we'll get an
1555 * asynchronous notification for it anyway. */
1557 if (u->type == UNIT_SERVICE &&
1558 UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1559 !UNIT_IS_INACTIVE_OR_FAILED(os) &&
1560 m->n_reloading <= 0) {
1562 /* Hmm, if there was no start record written
1563 * write it now, so that we always have a nice
1566 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
1568 if (ns == UNIT_INACTIVE)
1569 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
1571 /* Write audit record if we have just finished shutting down */
1572 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
1574 u->in_audit = false;
1578 manager_recheck_journal(m);
1579 unit_trigger_notify(u);
1581 /* Maybe we finished startup and are now ready for being
1582 * stopped because unneeded? */
1583 if (u->manager->n_reloading <= 0)
1584 unit_check_unneeded(u);
1586 unit_add_to_dbus_queue(u);
1587 unit_add_to_gc_queue(u);
1590 int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) {
1591 struct epoll_event ev = {
1599 assert(w->type == WATCH_INVALID || (w->type == WATCH_FD && w->fd == fd && w->data.unit == u));
1601 if (epoll_ctl(u->manager->epoll_fd,
1602 w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD,
1614 void unit_unwatch_fd(Unit *u, Watch *w) {
1618 if (w->type == WATCH_INVALID)
1621 assert(w->type == WATCH_FD);
1622 assert(w->data.unit == u);
1623 assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
1626 w->type = WATCH_INVALID;
1627 w->data.unit = NULL;
1630 int unit_watch_pid(Unit *u, pid_t pid) {
1634 /* Watch a specific PID. We only support one unit watching
1635 * each PID for now. */
1637 return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1640 void unit_unwatch_pid(Unit *u, pid_t pid) {
1644 hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1647 int unit_watch_timer(Unit *u, clockid_t clock_id, bool relative, usec_t usec, Watch *w) {
1648 struct itimerspec its = {};
1654 assert(w->type == WATCH_INVALID || (w->type == WATCH_UNIT_TIMER && w->data.unit == u));
1656 /* This will try to reuse the old timer if there is one */
1658 if (w->type == WATCH_UNIT_TIMER) {
1659 assert(w->data.unit == u);
1664 } else if (w->type == WATCH_INVALID) {
1667 fd = timerfd_create(clock_id, TFD_NONBLOCK|TFD_CLOEXEC);
1671 assert_not_reached("Invalid watch type");
1674 /* Set absolute time in the past, but not 0, since we
1675 * don't want to disarm the timer */
1676 its.it_value.tv_sec = 0;
1677 its.it_value.tv_nsec = 1;
1679 flags = TFD_TIMER_ABSTIME;
1681 timespec_store(&its.it_value, usec);
1682 flags = relative ? 0 : TFD_TIMER_ABSTIME;
1685 /* This will also flush the elapse counter */
1686 if (timerfd_settime(fd, flags, &its, NULL) < 0)
1689 if (w->type == WATCH_INVALID) {
1690 struct epoll_event ev = {
1695 if (epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
1699 w->type = WATCH_UNIT_TIMER;
1707 close_nointr_nofail(fd);
1712 void unit_unwatch_timer(Unit *u, Watch *w) {
1716 if (w->type == WATCH_INVALID)
1719 assert(w->type == WATCH_UNIT_TIMER);
1720 assert(w->data.unit == u);
1723 assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
1724 close_nointr_nofail(w->fd);
1727 w->type = WATCH_INVALID;
1728 w->data.unit = NULL;
1731 bool unit_job_is_applicable(Unit *u, JobType j) {
1733 assert(j >= 0 && j < _JOB_TYPE_MAX);
1737 case JOB_VERIFY_ACTIVE:
1744 case JOB_TRY_RESTART:
1745 return unit_can_start(u);
1748 return unit_can_reload(u);
1750 case JOB_RELOAD_OR_START:
1751 return unit_can_reload(u) && unit_can_start(u);
1754 assert_not_reached("Invalid job type");
1758 int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
1760 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
1761 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
1762 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1763 [UNIT_WANTS] = UNIT_WANTED_BY,
1764 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
1765 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1766 [UNIT_BINDS_TO] = UNIT_BOUND_BY,
1767 [UNIT_PART_OF] = UNIT_CONSISTS_OF,
1768 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
1769 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
1770 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
1771 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
1772 [UNIT_CONSISTS_OF] = UNIT_PART_OF,
1773 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
1774 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
1775 [UNIT_BEFORE] = UNIT_AFTER,
1776 [UNIT_AFTER] = UNIT_BEFORE,
1777 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
1778 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
1779 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
1780 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
1781 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
1782 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
1783 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
1785 int r, q = 0, v = 0, w = 0;
1788 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
1791 u = unit_follow_merge(u);
1792 other = unit_follow_merge(other);
1794 /* We won't allow dependencies on ourselves. We will not
1795 * consider them an error however. */
1799 if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
1802 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
1803 if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
1807 if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
1808 (r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
1811 if ((q = set_put(u->dependencies[d], other)) < 0)
1814 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
1815 if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) {
1820 if (add_reference) {
1821 if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) {
1826 if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0)
1830 unit_add_to_dbus_queue(u);
1835 set_remove(u->dependencies[d], other);
1838 set_remove(other->dependencies[inverse_table[d]], u);
1841 set_remove(u->dependencies[UNIT_REFERENCES], other);
1846 int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
1851 if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
1854 if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
1860 static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
1864 assert(name || path);
1868 name = path_get_file_name(path);
1870 if (!unit_name_is_template(name)) {
1876 s = unit_name_replace_instance(name, u->instance);
1878 _cleanup_free_ char *i = NULL;
1880 i = unit_name_to_prefix(u->id);
1884 s = unit_name_replace_instance(name, i);
1894 int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1897 _cleanup_free_ char *s = NULL;
1900 assert(name || path);
1902 name = resolve_template(u, name, path, &s);
1906 r = manager_load_unit(u->manager, name, path, NULL, &other);
1910 return unit_add_dependency(u, d, other, add_reference);
1913 int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1919 assert(name || path);
1921 if (!(name = resolve_template(u, name, path, &s)))
1924 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1927 r = unit_add_two_dependencies(u, d, e, other, add_reference);
1934 int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1940 assert(name || path);
1942 if (!(name = resolve_template(u, name, path, &s)))
1945 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1948 r = unit_add_dependency(other, d, u, add_reference);
1955 int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1961 assert(name || path);
1963 if (!(name = resolve_template(u, name, path, &s)))
1966 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1969 if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
1977 int set_unit_path(const char *p) {
1978 _cleanup_free_ char *c = NULL;
1980 /* This is mostly for debug purposes */
1981 c = path_make_absolute_cwd(p);
1982 if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0)
1988 char *unit_dbus_path(Unit *u) {
1994 return unit_dbus_path_from_name(u->id);
1997 char *unit_default_cgroup_path(Unit *u) {
1998 _cleanup_free_ char *escaped = NULL, *slice = NULL;
2003 if (unit_has_name(u, SPECIAL_ROOT_SLICE))
2004 return strdup(u->manager->cgroup_root);
2006 if (UNIT_ISSET(u->slice) && !unit_has_name(UNIT_DEREF(u->slice), SPECIAL_ROOT_SLICE)) {
2007 r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice);
2012 escaped = cg_escape(u->id);
2017 return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL);
2019 return strjoin(u->manager->cgroup_root, "/", escaped, NULL);
2022 int unit_add_default_slice(Unit *u) {
2023 _cleanup_free_ char *b = NULL;
2024 const char *slice_name;
2030 if (UNIT_ISSET(u->slice))
2033 if (!unit_get_cgroup_context(u))
2037 _cleanup_free_ char *prefix = NULL, *escaped = NULL;
2039 /* Implicitly place all instantiated units in their
2040 * own per-template slice */
2042 prefix = unit_name_to_prefix(u->id);
2046 /* The prefix is already escaped, but it might include
2047 * "-" which has a special meaning for slice units,
2048 * hence escape it here extra. */
2049 escaped = strreplace(prefix, "-", "\\x2d");
2053 if (u->manager->running_as == SYSTEMD_SYSTEM)
2054 b = strjoin("system-", escaped, ".slice", NULL);
2056 b = strappend(escaped, ".slice");
2063 u->manager->running_as == SYSTEMD_SYSTEM
2064 ? SPECIAL_SYSTEM_SLICE
2065 : SPECIAL_ROOT_SLICE;
2067 r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
2071 unit_ref_set(&u->slice, slice);
2075 const char *unit_slice_name(Unit *u) {
2078 if (!UNIT_ISSET(u->slice))
2081 return UNIT_DEREF(u->slice)->id;
2084 int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
2085 _cleanup_free_ char *t = NULL;
2092 t = unit_name_change_suffix(u->id, type);
2096 assert(!unit_has_name(u, t));
2098 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
2099 assert(r < 0 || *_found != u);
2103 int unit_get_related_unit(Unit *u, const char *type, Unit **_found) {
2104 _cleanup_free_ char *t = NULL;
2111 t = unit_name_change_suffix(u->id, type);
2115 assert(!unit_has_name(u, t));
2117 found = manager_get_unit(u->manager, t);
2125 int unit_watch_bus_name(Unit *u, const char *name) {
2129 /* Watch a specific name on the bus. We only support one unit
2130 * watching each name for now. */
2132 return hashmap_put(u->manager->watch_bus, name, u);
2135 void unit_unwatch_bus_name(Unit *u, const char *name) {
2139 hashmap_remove_value(u->manager->watch_bus, name, u);
2142 bool unit_can_serialize(Unit *u) {
2145 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2148 int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
2155 if (!unit_can_serialize(u))
2158 r = UNIT_VTABLE(u)->serialize(u, f, fds);
2163 if (serialize_jobs) {
2165 fprintf(f, "job\n");
2166 job_serialize(u->job, f, fds);
2170 fprintf(f, "job\n");
2171 job_serialize(u->nop_job, f, fds);
2175 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2176 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2177 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2178 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2179 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
2181 if (dual_timestamp_is_set(&u->condition_timestamp))
2182 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
2184 unit_serialize_item(u, f, "transient", yes_no(u->transient));
2187 unit_serialize_item(u, f, "cgroup", u->cgroup_path);
2194 void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2205 va_start(ap, format);
2206 vfprintf(f, format, ap);
2212 void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2218 fprintf(f, "%s=%s\n", key, value);
2221 int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
2228 if (!unit_can_serialize(u))
2232 char line[LINE_MAX], *l, *v;
2235 if (!fgets(line, sizeof(line), f)) {
2248 k = strcspn(l, "=");
2256 if (streq(l, "job")) {
2258 /* new-style serialized job */
2259 Job *j = job_new_raw(u);
2263 r = job_deserialize(j, f, fds);
2269 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2275 r = job_install_deserialized(j);
2277 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2282 if (j->state == JOB_RUNNING)
2283 u->manager->n_running_jobs++;
2286 JobType type = job_type_from_string(v);
2288 log_debug("Failed to parse job type value %s", v);
2290 u->deserialized_job = type;
2293 } else if (streq(l, "inactive-exit-timestamp")) {
2294 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
2296 } else if (streq(l, "active-enter-timestamp")) {
2297 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
2299 } else if (streq(l, "active-exit-timestamp")) {
2300 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
2302 } else if (streq(l, "inactive-enter-timestamp")) {
2303 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
2305 } else if (streq(l, "condition-timestamp")) {
2306 dual_timestamp_deserialize(v, &u->condition_timestamp);
2308 } else if (streq(l, "condition-result")) {
2311 b = parse_boolean(v);
2313 log_debug("Failed to parse condition result value %s", v);
2315 u->condition_result = b;
2319 } else if (streq(l, "transient")) {
2322 b = parse_boolean(v);
2324 log_debug("Failed to parse transient bool %s", v);
2329 } else if (streq(l, "cgroup")) {
2336 free(u->cgroup_path);
2339 hashmap_put(u->manager->cgroup_unit, s, u);
2343 r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds);
2349 int unit_add_node_link(Unit *u, const char *what, bool wants) {
2359 /* Adds in links to the device node that this unit is based on */
2361 if (!is_device_path(what))
2364 e = unit_name_from_path(what, ".device");
2368 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
2373 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
2378 r = unit_add_dependency(device, UNIT_WANTS, u, false);
2386 int unit_coldplug(Unit *u) {
2391 if (UNIT_VTABLE(u)->coldplug)
2392 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2396 r = job_coldplug(u->job);
2399 } else if (u->deserialized_job >= 0) {
2401 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2405 u->deserialized_job = _JOB_TYPE_INVALID;
2411 #pragma GCC diagnostic push
2412 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
2413 void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) {
2414 manager_status_printf(u->manager, false, status, unit_status_msg_format, unit_description(u));
2416 #pragma GCC diagnostic pop
2418 bool unit_need_daemon_reload(Unit *u) {
2419 _cleanup_strv_free_ char **t = NULL;
2422 unsigned loaded_cnt, current_cnt;
2426 if (u->fragment_path) {
2428 if (stat(u->fragment_path, &st) < 0)
2429 /* What, cannot access this anymore? */
2432 if (u->fragment_mtime > 0 &&
2433 timespec_load(&st.st_mtim) != u->fragment_mtime)
2437 if (u->source_path) {
2439 if (stat(u->source_path, &st) < 0)
2442 if (u->source_mtime > 0 &&
2443 timespec_load(&st.st_mtim) != u->source_mtime)
2447 t = unit_find_dropin_paths(u);
2448 loaded_cnt = strv_length(t);
2449 current_cnt = strv_length(u->dropin_paths);
2451 if (loaded_cnt == current_cnt) {
2452 if (loaded_cnt == 0)
2455 if (strv_overlap(u->dropin_paths, t)) {
2456 STRV_FOREACH(path, u->dropin_paths) {
2458 if (stat(*path, &st) < 0)
2461 if (u->dropin_mtime > 0 &&
2462 timespec_load(&st.st_mtim) > u->dropin_mtime)
2473 void unit_reset_failed(Unit *u) {
2476 if (UNIT_VTABLE(u)->reset_failed)
2477 UNIT_VTABLE(u)->reset_failed(u);
2480 Unit *unit_following(Unit *u) {
2483 if (UNIT_VTABLE(u)->following)
2484 return UNIT_VTABLE(u)->following(u);
2489 bool unit_stop_pending(Unit *u) {
2492 /* This call does check the current state of the unit. It's
2493 * hence useful to be called from state change calls of the
2494 * unit itself, where the state isn't updated yet. This is
2495 * different from unit_inactive_or_pending() which checks both
2496 * the current state and for a queued job. */
2498 return u->job && u->job->type == JOB_STOP;
2501 bool unit_inactive_or_pending(Unit *u) {
2504 /* Returns true if the unit is inactive or going down */
2506 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2509 if (unit_stop_pending(u))
2515 bool unit_active_or_pending(Unit *u) {
2518 /* Returns true if the unit is active or going up */
2520 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2524 (u->job->type == JOB_START ||
2525 u->job->type == JOB_RELOAD_OR_START ||
2526 u->job->type == JOB_RESTART))
2532 int unit_kill(Unit *u, KillWho w, int signo, DBusError *error) {
2534 assert(w >= 0 && w < _KILL_WHO_MAX);
2536 assert(signo < _NSIG);
2538 if (!UNIT_VTABLE(u)->kill)
2541 return UNIT_VTABLE(u)->kill(u, w, signo, error);
2544 int unit_kill_common(
2554 if (who == KILL_MAIN && main_pid <= 0) {
2556 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
2558 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
2562 if (who == KILL_CONTROL && control_pid <= 0) {
2563 if (control_pid < 0)
2564 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
2566 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
2570 if (who == KILL_CONTROL || who == KILL_ALL)
2571 if (control_pid > 0)
2572 if (kill(control_pid, signo) < 0)
2575 if (who == KILL_MAIN || who == KILL_ALL)
2577 if (kill(main_pid, signo) < 0)
2580 if (who == KILL_ALL && u->cgroup_path) {
2581 _cleanup_set_free_ Set *pid_set = NULL;
2584 pid_set = set_new(trivial_hash_func, trivial_compare_func);
2588 /* Exclude the control/main pid from being killed via the cgroup */
2589 if (control_pid > 0) {
2590 q = set_put(pid_set, LONG_TO_PTR(control_pid));
2596 q = set_put(pid_set, LONG_TO_PTR(main_pid));
2601 q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
2602 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
2609 int unit_following_set(Unit *u, Set **s) {
2613 if (UNIT_VTABLE(u)->following_set)
2614 return UNIT_VTABLE(u)->following_set(u, s);
2620 UnitFileState unit_get_unit_file_state(Unit *u) {
2623 if (u->unit_file_state < 0 && u->fragment_path)
2624 u->unit_file_state = unit_file_get_state(
2625 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
2626 NULL, path_get_file_name(u->fragment_path));
2628 return u->unit_file_state;
2631 Unit* unit_ref_set(UnitRef *ref, Unit *u) {
2636 unit_ref_unset(ref);
2639 LIST_PREPEND(UnitRef, refs, u->refs, ref);
2643 void unit_ref_unset(UnitRef *ref) {
2649 LIST_REMOVE(UnitRef, refs, ref->unit->refs, ref);
2653 int unit_add_one_mount_link(Unit *u, Mount *m) {
2659 if (u->load_state != UNIT_LOADED ||
2660 UNIT(m)->load_state != UNIT_LOADED)
2663 STRV_FOREACH(i, u->requires_mounts_for) {
2668 if (!path_startswith(*i, m->where))
2671 return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
2677 int unit_add_mount_links(Unit *u) {
2683 LIST_FOREACH(units_by_type, other, u->manager->units_by_type[UNIT_MOUNT]) {
2684 r = unit_add_one_mount_link(u, MOUNT(other));
2692 int unit_exec_context_defaults(Unit *u, ExecContext *c) {
2699 /* This only copies in the ones that need memory */
2700 for (i = 0; i < RLIMIT_NLIMITS; i++)
2701 if (u->manager->rlimit[i] && !c->rlimit[i]) {
2702 c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
2707 if (u->manager->running_as == SYSTEMD_USER &&
2708 !c->working_directory) {
2710 r = get_home_dir(&c->working_directory);
2718 ExecContext *unit_get_exec_context(Unit *u) {
2722 offset = UNIT_VTABLE(u)->exec_context_offset;
2726 return (ExecContext*) ((uint8_t*) u + offset);
2729 CGroupContext *unit_get_cgroup_context(Unit *u) {
2732 offset = UNIT_VTABLE(u)->cgroup_context_offset;
2736 return (CGroupContext*) ((uint8_t*) u + offset);
2739 static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) {
2740 _cleanup_free_ char *b = NULL;
2748 assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME));
2750 b = xescape(name, "/.");
2754 if (!filename_is_safe(b))
2757 if (u->manager->running_as == SYSTEMD_USER) {
2758 _cleanup_free_ char *c = NULL;
2760 r = user_config_home(&c);
2766 p = strjoin(c, "/", u->id, ".d", NULL);
2767 } else if (mode & UNIT_PERSISTENT)
2768 p = strjoin("/etc/systemd/system/", u->id, ".d", NULL);
2770 p = strjoin("/run/systemd/system/", u->id, ".d", NULL);
2774 q = strjoin(p, "/90-", b, ".conf", NULL);
2785 int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2786 _cleanup_free_ char *p = NULL, *q = NULL;
2793 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2796 r = drop_in_file(u, mode, name, &p, &q);
2801 return write_string_file_atomic_label(q, data);
2804 int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2805 _cleanup_free_ char *p = NULL;
2813 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2816 va_start(ap, format);
2817 r = vasprintf(&p, format, ap);
2823 return unit_write_drop_in(u, mode, name, p);
2826 int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2827 _cleanup_free_ char *ndata = NULL;
2833 if (!UNIT_VTABLE(u)->private_section)
2836 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2839 ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
2843 return unit_write_drop_in(u, mode, name, ndata);
2846 int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2847 _cleanup_free_ char *p = NULL;
2855 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2858 va_start(ap, format);
2859 r = vasprintf(&p, format, ap);
2865 return unit_write_drop_in_private(u, mode, name, p);
2868 int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
2869 _cleanup_free_ char *p = NULL, *q = NULL;
2874 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2877 r = drop_in_file(u, mode, name, &p, &q);
2879 r = errno == ENOENT ? 0 : -errno;
2887 int unit_make_transient(Unit *u) {
2892 u->load_state = UNIT_STUB;
2894 u->transient = true;
2896 free(u->fragment_path);
2897 u->fragment_path = NULL;
2899 if (u->manager->running_as == SYSTEMD_USER) {
2900 _cleanup_free_ char *c = NULL;
2902 r = user_config_home(&c);
2908 u->fragment_path = strjoin(c, "/", u->id, NULL);
2909 if (!u->fragment_path)
2914 u->fragment_path = strappend("/run/systemd/system/", u->id);
2915 if (!u->fragment_path)
2918 mkdir_p("/run/systemd/system", 0755);
2921 return write_string_file_atomic_label(u->fragment_path, "# Transient stub");
2924 int unit_kill_context(
2930 bool main_pid_alien) {
2932 int sig, wait_for_exit = 0, r;
2937 if (c->kill_mode == KILL_NONE)
2940 sig = sigkill ? SIGKILL : c->kill_signal;
2943 r = kill_and_sigcont(main_pid, sig);
2945 if (r < 0 && r != -ESRCH) {
2946 _cleanup_free_ char *comm = NULL;
2947 get_process_comm(main_pid, &comm);
2949 log_warning_unit(u->id, "Failed to kill main process %li (%s): %s",
2950 (long) main_pid, strna(comm), strerror(-r));
2952 wait_for_exit = !main_pid_alien;
2955 if (control_pid > 0) {
2956 r = kill_and_sigcont(control_pid, sig);
2958 if (r < 0 && r != -ESRCH) {
2959 _cleanup_free_ char *comm = NULL;
2960 get_process_comm(control_pid, &comm);
2962 log_warning_unit(u->id,
2963 "Failed to kill control process %li (%s): %s",
2964 (long) control_pid, strna(comm), strerror(-r));
2966 wait_for_exit = true;
2969 if (c->kill_mode == KILL_CONTROL_GROUP && u->cgroup_path) {
2970 _cleanup_set_free_ Set *pid_set = NULL;
2972 pid_set = set_new(trivial_hash_func, trivial_compare_func);
2976 /* Exclude the main/control pids from being killed via the cgroup */
2978 r = set_put(pid_set, LONG_TO_PTR(main_pid));
2983 if (control_pid > 0) {
2984 r = set_put(pid_set, LONG_TO_PTR(control_pid));
2989 r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set);
2991 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
2992 log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
2994 wait_for_exit = true;
2997 return wait_for_exit;
3000 static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
3001 [UNIT_ACTIVE] = "active",
3002 [UNIT_RELOADING] = "reloading",
3003 [UNIT_INACTIVE] = "inactive",
3004 [UNIT_FAILED] = "failed",
3005 [UNIT_ACTIVATING] = "activating",
3006 [UNIT_DEACTIVATING] = "deactivating"
3009 DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
3011 static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
3012 [UNIT_REQUIRES] = "Requires",
3013 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
3014 [UNIT_REQUISITE] = "Requisite",
3015 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
3016 [UNIT_WANTS] = "Wants",
3017 [UNIT_BINDS_TO] = "BindsTo",
3018 [UNIT_PART_OF] = "PartOf",
3019 [UNIT_REQUIRED_BY] = "RequiredBy",
3020 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
3021 [UNIT_WANTED_BY] = "WantedBy",
3022 [UNIT_BOUND_BY] = "BoundBy",
3023 [UNIT_CONSISTS_OF] = "ConsistsOf",
3024 [UNIT_CONFLICTS] = "Conflicts",
3025 [UNIT_CONFLICTED_BY] = "ConflictedBy",
3026 [UNIT_BEFORE] = "Before",
3027 [UNIT_AFTER] = "After",
3028 [UNIT_ON_FAILURE] = "OnFailure",
3029 [UNIT_TRIGGERS] = "Triggers",
3030 [UNIT_TRIGGERED_BY] = "TriggeredBy",
3031 [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
3032 [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
3033 [UNIT_REFERENCES] = "References",
3034 [UNIT_REFERENCED_BY] = "ReferencedBy",
3037 DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);