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>
33 #include "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"
53 const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
54 [UNIT_SERVICE] = &service_vtable,
55 [UNIT_TIMER] = &timer_vtable,
56 [UNIT_SOCKET] = &socket_vtable,
57 [UNIT_TARGET] = &target_vtable,
58 [UNIT_DEVICE] = &device_vtable,
59 [UNIT_MOUNT] = &mount_vtable,
60 [UNIT_AUTOMOUNT] = &automount_vtable,
61 [UNIT_SNAPSHOT] = &snapshot_vtable,
62 [UNIT_SWAP] = &swap_vtable,
63 [UNIT_PATH] = &path_vtable,
64 [UNIT_SLICE] = &slice_vtable,
65 [UNIT_SCOPE] = &scope_vtable
68 Unit *unit_new(Manager *m, size_t size) {
72 assert(size >= sizeof(Unit));
78 u->names = set_new(string_hash_func, string_compare_func);
85 u->type = _UNIT_TYPE_INVALID;
86 u->deserialized_job = _JOB_TYPE_INVALID;
87 u->default_dependencies = true;
88 u->unit_file_state = _UNIT_FILE_STATE_INVALID;
89 u->on_failure_job_mode = JOB_REPLACE;
94 bool unit_has_name(Unit *u, const char *name) {
98 return !!set_get(u->names, (char*) name);
101 int unit_add_name(Unit *u, const char *text) {
109 if (unit_name_is_template(text)) {
113 s = unit_name_replace_instance(text, u->instance);
120 if (!unit_name_is_valid(s, false)) {
125 assert_se((t = unit_name_to_type(s)) >= 0);
127 if (u->type != _UNIT_TYPE_INVALID && t != u->type) {
132 r = unit_name_to_instance(s, &i);
136 if (i && unit_vtable[t]->no_instances) {
141 /* Ensure that this unit is either instanced or not instanced,
143 if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) {
148 if (unit_vtable[t]->no_alias &&
149 !set_isempty(u->names) &&
150 !set_get(u->names, s)) {
155 if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) {
160 r = set_put(u->names, s);
167 r = hashmap_put(u->manager->units, s, u);
169 set_remove(u->names, s);
173 if (u->type == _UNIT_TYPE_INVALID) {
179 LIST_PREPEND(units_by_type, u->manager->units_by_type[t], u);
181 if (UNIT_VTABLE(u)->init)
182 UNIT_VTABLE(u)->init(u);
186 unit_add_to_dbus_queue(u);
196 int unit_choose_id(Unit *u, const char *name) {
198 _cleanup_free_ char *t = NULL;
204 if (unit_name_is_template(name)) {
209 t = unit_name_replace_instance(name, u->instance);
216 /* Selects one of the names of this unit as the id */
217 s = set_get(u->names, (char*) name);
222 r = unit_name_to_instance(s, &i);
231 unit_add_to_dbus_queue(u);
236 int unit_set_description(Unit *u, const char *description) {
241 if (isempty(description))
244 s = strdup(description);
249 free(u->description);
252 unit_add_to_dbus_queue(u);
256 bool unit_check_gc(Unit *u) {
259 if (u->load_state == UNIT_STUB)
262 if (UNIT_VTABLE(u)->no_gc)
274 if (unit_active_state(u) != UNIT_INACTIVE)
280 if (UNIT_VTABLE(u)->check_gc)
281 if (UNIT_VTABLE(u)->check_gc(u))
287 void unit_add_to_load_queue(Unit *u) {
289 assert(u->type != _UNIT_TYPE_INVALID);
291 if (u->load_state != UNIT_STUB || u->in_load_queue)
294 LIST_PREPEND(load_queue, u->manager->load_queue, u);
295 u->in_load_queue = true;
298 void unit_add_to_cleanup_queue(Unit *u) {
301 if (u->in_cleanup_queue)
304 LIST_PREPEND(cleanup_queue, u->manager->cleanup_queue, u);
305 u->in_cleanup_queue = true;
308 void unit_add_to_gc_queue(Unit *u) {
311 if (u->in_gc_queue || u->in_cleanup_queue)
314 if (unit_check_gc(u))
317 LIST_PREPEND(gc_queue, u->manager->gc_queue, u);
318 u->in_gc_queue = true;
320 u->manager->n_in_gc_queue ++;
323 void unit_add_to_dbus_queue(Unit *u) {
325 assert(u->type != _UNIT_TYPE_INVALID);
327 if (u->load_state == UNIT_STUB || u->in_dbus_queue)
330 /* Shortcut things if nobody cares */
331 if (set_isempty(u->manager->subscribed)) {
332 u->sent_dbus_new_signal = true;
336 LIST_PREPEND(dbus_queue, u->manager->dbus_unit_queue, u);
337 u->in_dbus_queue = true;
340 static void bidi_set_free(Unit *u, Set *s) {
346 /* Frees the set and makes sure we are dropped from the
347 * inverse pointers */
349 SET_FOREACH(other, s, i) {
352 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
353 set_remove(other->dependencies[d], u);
355 unit_add_to_gc_queue(other);
361 static void unit_remove_transient(Unit *u) {
369 if (u->fragment_path)
370 unlink(u->fragment_path);
372 STRV_FOREACH(i, u->dropin_paths) {
373 _cleanup_free_ char *p = NULL;
378 r = path_get_parent(*i, &p);
384 static void unit_free_requires_mounts_for(Unit *u) {
387 STRV_FOREACH(j, u->requires_mounts_for) {
388 char s[strlen(*j) + 1];
390 PATH_FOREACH_PREFIX_MORE(s, *j) {
394 x = hashmap_get2(u->manager->units_requiring_mounts_for, s, (void**) &y);
400 if (set_isempty(x)) {
401 hashmap_remove(u->manager->units_requiring_mounts_for, y);
408 strv_free(u->requires_mounts_for);
409 u->requires_mounts_for = NULL;
412 void unit_free(Unit *u) {
419 if (u->manager->n_reloading <= 0)
420 unit_remove_transient(u);
422 bus_unit_send_removed_signal(u);
424 if (u->load_state != UNIT_STUB)
425 if (UNIT_VTABLE(u)->done)
426 UNIT_VTABLE(u)->done(u);
428 unit_free_requires_mounts_for(u);
430 SET_FOREACH(t, u->names, i)
431 hashmap_remove_value(u->manager->units, t, u);
445 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
446 bidi_set_free(u, u->dependencies[d]);
448 if (u->type != _UNIT_TYPE_INVALID)
449 LIST_REMOVE(units_by_type, u->manager->units_by_type[u->type], u);
451 if (u->in_load_queue)
452 LIST_REMOVE(load_queue, u->manager->load_queue, u);
454 if (u->in_dbus_queue)
455 LIST_REMOVE(dbus_queue, u->manager->dbus_unit_queue, u);
457 if (u->in_cleanup_queue)
458 LIST_REMOVE(cleanup_queue, u->manager->cleanup_queue, u);
460 if (u->in_gc_queue) {
461 LIST_REMOVE(gc_queue, u->manager->gc_queue, u);
462 u->manager->n_in_gc_queue--;
465 if (u->in_cgroup_queue)
466 LIST_REMOVE(cgroup_queue, u->manager->cgroup_queue, u);
468 if (u->cgroup_path) {
469 hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
470 free(u->cgroup_path);
473 free(u->description);
474 strv_free(u->documentation);
475 free(u->fragment_path);
476 free(u->source_path);
477 strv_free(u->dropin_paths);
480 set_free_free(u->names);
482 condition_free_list(u->conditions);
484 unit_ref_unset(&u->slice);
487 unit_ref_unset(u->refs);
492 UnitActiveState unit_active_state(Unit *u) {
495 if (u->load_state == UNIT_MERGED)
496 return unit_active_state(unit_follow_merge(u));
498 /* After a reload it might happen that a unit is not correctly
499 * loaded but still has a process around. That's why we won't
500 * shortcut failed loading to UNIT_INACTIVE_FAILED. */
502 return UNIT_VTABLE(u)->active_state(u);
505 const char* unit_sub_state_to_string(Unit *u) {
508 return UNIT_VTABLE(u)->sub_state_to_string(u);
511 static void complete_move(Set **s, Set **other) {
519 set_move(*s, *other);
526 static void merge_names(Unit *u, Unit *other) {
533 complete_move(&u->names, &other->names);
535 set_free_free(other->names);
539 SET_FOREACH(t, u->names, i)
540 assert_se(hashmap_replace(u->manager->units, t, u) == 0);
543 static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
550 assert(d < _UNIT_DEPENDENCY_MAX);
552 /* Fix backwards pointers */
553 SET_FOREACH(back, other->dependencies[d], i) {
556 for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++) {
557 r = set_remove_and_put(back->dependencies[k], other, u);
559 set_remove(back->dependencies[k], other);
561 assert(r >= 0 || r == -ENOENT);
565 complete_move(&u->dependencies[d], &other->dependencies[d]);
567 set_free(other->dependencies[d]);
568 other->dependencies[d] = NULL;
571 int unit_merge(Unit *u, Unit *other) {
576 assert(u->manager == other->manager);
577 assert(u->type != _UNIT_TYPE_INVALID);
579 other = unit_follow_merge(other);
584 if (u->type != other->type)
587 if (!u->instance != !other->instance)
590 if (other->load_state != UNIT_STUB &&
591 other->load_state != UNIT_NOT_FOUND)
600 if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
604 merge_names(u, other);
606 /* Redirect all references */
608 unit_ref_set(other->refs, u);
610 /* Merge dependencies */
611 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
612 merge_dependencies(u, other, d);
614 other->load_state = UNIT_MERGED;
615 other->merged_into = u;
617 /* If there is still some data attached to the other node, we
618 * don't need it anymore, and can free it. */
619 if (other->load_state != UNIT_STUB)
620 if (UNIT_VTABLE(other)->done)
621 UNIT_VTABLE(other)->done(other);
623 unit_add_to_dbus_queue(u);
624 unit_add_to_cleanup_queue(other);
629 int unit_merge_by_name(Unit *u, const char *name) {
632 _cleanup_free_ char *s = NULL;
637 if (unit_name_is_template(name)) {
641 s = unit_name_replace_instance(name, u->instance);
648 other = manager_get_unit(u->manager, name);
650 r = unit_add_name(u, name);
652 r = unit_merge(u, other);
657 Unit* unit_follow_merge(Unit *u) {
660 while (u->load_state == UNIT_MERGED)
661 assert_se(u = u->merged_into);
666 int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
672 if (c->std_output != EXEC_OUTPUT_KMSG &&
673 c->std_output != EXEC_OUTPUT_SYSLOG &&
674 c->std_output != EXEC_OUTPUT_JOURNAL &&
675 c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
676 c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
677 c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
678 c->std_error != EXEC_OUTPUT_KMSG &&
679 c->std_error != EXEC_OUTPUT_SYSLOG &&
680 c->std_error != EXEC_OUTPUT_JOURNAL &&
681 c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
682 c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
683 c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE)
686 /* If syslog or kernel logging is requested, make sure our own
687 * logging daemon is run first. */
689 if (u->manager->running_as == SYSTEMD_SYSTEM) {
690 r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true);
698 const char *unit_description(Unit *u) {
702 return u->description;
707 void unit_dump(Unit *u, FILE *f, const char *prefix) {
711 _cleanup_free_ char *p2 = NULL;
714 timestamp1[FORMAT_TIMESTAMP_MAX],
715 timestamp2[FORMAT_TIMESTAMP_MAX],
716 timestamp3[FORMAT_TIMESTAMP_MAX],
717 timestamp4[FORMAT_TIMESTAMP_MAX],
718 timespan[FORMAT_TIMESPAN_MAX];
720 _cleanup_set_free_ Set *following_set = NULL;
724 assert(u->type >= 0);
728 p2 = strappend(prefix, "\t");
729 prefix2 = p2 ? p2 : prefix;
733 "%s\tDescription: %s\n"
735 "%s\tUnit Load State: %s\n"
736 "%s\tUnit Active State: %s\n"
737 "%s\tInactive Exit Timestamp: %s\n"
738 "%s\tActive Enter Timestamp: %s\n"
739 "%s\tActive Exit Timestamp: %s\n"
740 "%s\tInactive Enter Timestamp: %s\n"
741 "%s\tGC Check Good: %s\n"
742 "%s\tNeed Daemon Reload: %s\n"
743 "%s\tTransient: %s\n"
746 "%s\tCGroup realized: %s\n"
747 "%s\tCGroup mask: 0x%x\n"
748 "%s\tCGroup members mask: 0x%x\n",
750 prefix, unit_description(u),
751 prefix, strna(u->instance),
752 prefix, unit_load_state_to_string(u->load_state),
753 prefix, unit_active_state_to_string(unit_active_state(u)),
754 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->inactive_exit_timestamp.realtime)),
755 prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->active_enter_timestamp.realtime)),
756 prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)),
757 prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)),
758 prefix, yes_no(unit_check_gc(u)),
759 prefix, yes_no(unit_need_daemon_reload(u)),
760 prefix, yes_no(u->transient),
761 prefix, strna(unit_slice_name(u)),
762 prefix, strna(u->cgroup_path),
763 prefix, yes_no(u->cgroup_realized),
764 prefix, u->cgroup_mask,
765 prefix, u->cgroup_members_mask);
767 SET_FOREACH(t, u->names, i)
768 fprintf(f, "%s\tName: %s\n", prefix, t);
770 STRV_FOREACH(j, u->documentation)
771 fprintf(f, "%s\tDocumentation: %s\n", prefix, *j);
773 following = unit_following(u);
775 fprintf(f, "%s\tFollowing: %s\n", prefix, following->id);
777 r = unit_following_set(u, &following_set);
781 SET_FOREACH(other, following_set, i)
782 fprintf(f, "%s\tFollowing Set Member: %s\n", prefix, other->id);
785 if (u->fragment_path)
786 fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path);
789 fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path);
791 STRV_FOREACH(j, u->dropin_paths)
792 fprintf(f, "%s\tDropIn Path: %s\n", prefix, *j);
794 if (u->job_timeout > 0)
795 fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
797 condition_dump_list(u->conditions, f, prefix);
799 if (dual_timestamp_is_set(&u->condition_timestamp))
801 "%s\tCondition Timestamp: %s\n"
802 "%s\tCondition Result: %s\n",
803 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->condition_timestamp.realtime)),
804 prefix, yes_no(u->condition_result));
806 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
809 SET_FOREACH(other, u->dependencies[d], i)
810 fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
813 if (!strv_isempty(u->requires_mounts_for)) {
815 "%s\tRequiresMountsFor:", prefix);
817 STRV_FOREACH(j, u->requires_mounts_for)
818 fprintf(f, " %s", *j);
823 if (u->load_state == UNIT_LOADED) {
826 "%s\tStopWhenUnneeded: %s\n"
827 "%s\tRefuseManualStart: %s\n"
828 "%s\tRefuseManualStop: %s\n"
829 "%s\tDefaultDependencies: %s\n"
830 "%s\tOnFailureJobMode: %s\n"
831 "%s\tIgnoreOnIsolate: %s\n"
832 "%s\tIgnoreOnSnapshot: %s\n",
833 prefix, yes_no(u->stop_when_unneeded),
834 prefix, yes_no(u->refuse_manual_start),
835 prefix, yes_no(u->refuse_manual_stop),
836 prefix, yes_no(u->default_dependencies),
837 prefix, job_mode_to_string(u->on_failure_job_mode),
838 prefix, yes_no(u->ignore_on_isolate),
839 prefix, yes_no(u->ignore_on_snapshot));
841 if (UNIT_VTABLE(u)->dump)
842 UNIT_VTABLE(u)->dump(u, f, prefix2);
844 } else if (u->load_state == UNIT_MERGED)
846 "%s\tMerged into: %s\n",
847 prefix, u->merged_into->id);
848 else if (u->load_state == UNIT_ERROR)
849 fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->load_error));
853 job_dump(u->job, f, prefix2);
856 job_dump(u->nop_job, f, prefix2);
860 /* Common implementation for multiple backends */
861 int unit_load_fragment_and_dropin(Unit *u) {
866 /* Load a .{service,socket,...} file */
867 r = unit_load_fragment(u);
871 if (u->load_state == UNIT_STUB)
874 /* Load drop-in directory data */
875 r = unit_load_dropin(unit_follow_merge(u));
882 /* Common implementation for multiple backends */
883 int unit_load_fragment_and_dropin_optional(Unit *u) {
888 /* Same as unit_load_fragment_and_dropin(), but whether
889 * something can be loaded or not doesn't matter. */
891 /* Load a .service file */
892 r = unit_load_fragment(u);
896 if (u->load_state == UNIT_STUB)
897 u->load_state = UNIT_LOADED;
899 /* Load drop-in directory data */
900 r = unit_load_dropin(unit_follow_merge(u));
907 int unit_add_default_target_dependency(Unit *u, Unit *target) {
911 if (target->type != UNIT_TARGET)
914 /* Only add the dependency if both units are loaded, so that
915 * that loop check below is reliable */
916 if (u->load_state != UNIT_LOADED ||
917 target->load_state != UNIT_LOADED)
920 /* If either side wants no automatic dependencies, then let's
922 if (!u->default_dependencies ||
923 !target->default_dependencies)
926 /* Don't create loops */
927 if (set_get(target->dependencies[UNIT_BEFORE], u))
930 return unit_add_dependency(target, UNIT_AFTER, u, true);
933 static int unit_add_default_dependencies(Unit *u) {
935 static const UnitDependency deps[] = {
937 UNIT_REQUIRED_BY_OVERRIDABLE,
949 for (k = 0; k < ELEMENTSOF(deps); k++)
950 SET_FOREACH(target, u->dependencies[deps[k]], i) {
951 r = unit_add_default_target_dependency(u, target);
956 if (u->default_dependencies && unit_get_cgroup_context(u)) {
957 if (UNIT_ISSET(u->slice))
958 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true);
960 r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, SPECIAL_ROOT_SLICE, NULL, true);
969 static int unit_add_mount_links(Unit *u) {
975 STRV_FOREACH(i, u->requires_mounts_for) {
976 char prefix[strlen(*i) + 1];
978 PATH_FOREACH_PREFIX_MORE(prefix, *i) {
981 r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m);
989 if (m->load_state != UNIT_LOADED)
992 r = unit_add_dependency(u, UNIT_AFTER, m, true);
996 if (m->fragment_path) {
997 r = unit_add_dependency(u, UNIT_REQUIRES, m, true);
1007 int unit_load(Unit *u) {
1012 if (u->in_load_queue) {
1013 LIST_REMOVE(load_queue, u->manager->load_queue, u);
1014 u->in_load_queue = false;
1017 if (u->type == _UNIT_TYPE_INVALID)
1020 if (u->load_state != UNIT_STUB)
1023 if (UNIT_VTABLE(u)->load) {
1024 r = UNIT_VTABLE(u)->load(u);
1029 if (u->load_state == UNIT_STUB) {
1034 if (u->load_state == UNIT_LOADED) {
1036 if (u->default_dependencies) {
1037 r = unit_add_default_dependencies(u);
1042 unit_update_member_masks(u);
1044 r = unit_add_mount_links(u);
1048 if (u->on_failure_job_mode == JOB_ISOLATE &&
1049 set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
1051 log_error_unit(u->id,
1052 "More than one OnFailure= dependencies specified for %s but OnFailureJobMode=isolate set. Refusing.", u->id);
1059 assert((u->load_state != UNIT_MERGED) == !u->merged_into);
1061 unit_add_to_dbus_queue(unit_follow_merge(u));
1062 unit_add_to_gc_queue(u);
1067 u->load_state = u->load_state == UNIT_STUB ? UNIT_NOT_FOUND : UNIT_ERROR;
1069 unit_add_to_dbus_queue(u);
1070 unit_add_to_gc_queue(u);
1072 log_debug_unit(u->id, "Failed to load configuration for %s: %s",
1073 u->id, strerror(-r));
1078 static bool unit_condition_test(Unit *u) {
1081 dual_timestamp_get(&u->condition_timestamp);
1082 u->condition_result = condition_test_list(u->id, u->conditions);
1084 return u->condition_result;
1087 _pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
1088 const UnitStatusMessageFormats *format_table;
1092 assert(t < _JOB_TYPE_MAX);
1094 if (t != JOB_START && t != JOB_STOP)
1097 format_table = &UNIT_VTABLE(u)->status_message_formats;
1101 return format_table->starting_stopping[t == JOB_STOP];
1104 _pure_ static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) {
1109 assert(t < _JOB_TYPE_MAX);
1111 format = unit_get_status_message_format(u, t);
1115 /* Return generic strings */
1117 return "Starting %s.";
1118 else if (t == JOB_STOP)
1119 return "Stopping %s.";
1120 else if (t == JOB_RELOAD)
1121 return "Reloading %s.";
1126 static void unit_status_print_starting_stopping(Unit *u, JobType t) {
1131 /* We only print status messages for selected units on
1132 * selected operations. */
1134 format = unit_get_status_message_format(u, t);
1138 unit_status_printf(u, "", format);
1141 #pragma GCC diagnostic push
1142 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
1143 static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
1150 if (t != JOB_START && t != JOB_STOP && t != JOB_RELOAD)
1153 if (log_on_console())
1156 /* We log status messages for all units and all operations. */
1158 format = unit_get_status_message_format_try_harder(u, t);
1162 snprintf(buf, sizeof(buf), format, unit_description(u));
1165 mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
1166 t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
1167 SD_MESSAGE_UNIT_RELOADING;
1169 log_struct_unit(LOG_INFO,
1175 #pragma GCC diagnostic pop
1178 * -EBADR: This unit type does not support starting.
1179 * -EALREADY: Unit is already started.
1180 * -EAGAIN: An operation is already in progress. Retry later.
1181 * -ECANCELED: Too many requests for now.
1183 int unit_start(Unit *u) {
1184 UnitActiveState state;
1189 if (u->load_state != UNIT_LOADED)
1192 /* If this is already started, then this will succeed. Note
1193 * that this will even succeed if this unit is not startable
1194 * by the user. This is relied on to detect when we need to
1195 * wait for units and when waiting is finished. */
1196 state = unit_active_state(u);
1197 if (UNIT_IS_ACTIVE_OR_RELOADING(state))
1200 /* If the conditions failed, don't do anything at all. If we
1201 * already are activating this call might still be useful to
1202 * speed up activation in case there is some hold-off time,
1203 * but we don't want to recheck the condition in that case. */
1204 if (state != UNIT_ACTIVATING &&
1205 !unit_condition_test(u)) {
1206 log_debug_unit(u->id, "Starting of %s requested but condition failed. Ignoring.", u->id);
1210 /* Forward to the main object, if we aren't it. */
1211 following = unit_following(u);
1213 log_debug_unit(u->id, "Redirecting start request from %s to %s.",
1214 u->id, following->id);
1215 return unit_start(following);
1218 unit_status_log_starting_stopping_reloading(u, JOB_START);
1219 unit_status_print_starting_stopping(u, JOB_START);
1221 /* If it is stopped, but we cannot start it, then fail */
1222 if (!UNIT_VTABLE(u)->start)
1225 /* We don't suppress calls to ->start() here when we are
1226 * already starting, to allow this request to be used as a
1227 * "hurry up" call, for example when the unit is in some "auto
1228 * restart" state where it waits for a holdoff timer to elapse
1229 * before it will start again. */
1231 unit_add_to_dbus_queue(u);
1233 return UNIT_VTABLE(u)->start(u);
1236 bool unit_can_start(Unit *u) {
1239 return !!UNIT_VTABLE(u)->start;
1242 bool unit_can_isolate(Unit *u) {
1245 return unit_can_start(u) &&
1250 * -EBADR: This unit type does not support stopping.
1251 * -EALREADY: Unit is already stopped.
1252 * -EAGAIN: An operation is already in progress. Retry later.
1254 int unit_stop(Unit *u) {
1255 UnitActiveState state;
1260 state = unit_active_state(u);
1261 if (UNIT_IS_INACTIVE_OR_FAILED(state))
1264 if ((following = unit_following(u))) {
1265 log_debug_unit(u->id, "Redirecting stop request from %s to %s.",
1266 u->id, following->id);
1267 return unit_stop(following);
1270 unit_status_log_starting_stopping_reloading(u, JOB_STOP);
1271 unit_status_print_starting_stopping(u, JOB_STOP);
1273 if (!UNIT_VTABLE(u)->stop)
1276 unit_add_to_dbus_queue(u);
1278 return UNIT_VTABLE(u)->stop(u);
1282 * -EBADR: This unit type does not support reloading.
1283 * -ENOEXEC: Unit is not started.
1284 * -EAGAIN: An operation is already in progress. Retry later.
1286 int unit_reload(Unit *u) {
1287 UnitActiveState state;
1292 if (u->load_state != UNIT_LOADED)
1295 if (!unit_can_reload(u))
1298 state = unit_active_state(u);
1299 if (state == UNIT_RELOADING)
1302 if (state != UNIT_ACTIVE)
1305 following = unit_following(u);
1307 log_debug_unit(u->id, "Redirecting reload request from %s to %s.",
1308 u->id, following->id);
1309 return unit_reload(following);
1312 unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
1314 unit_add_to_dbus_queue(u);
1315 return UNIT_VTABLE(u)->reload(u);
1318 bool unit_can_reload(Unit *u) {
1321 if (!UNIT_VTABLE(u)->reload)
1324 if (!UNIT_VTABLE(u)->can_reload)
1327 return UNIT_VTABLE(u)->can_reload(u);
1330 static void unit_check_unneeded(Unit *u) {
1336 /* If this service shall be shut down when unneeded then do
1339 if (!u->stop_when_unneeded)
1342 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1345 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
1346 if (unit_active_or_pending(other))
1349 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
1350 if (unit_active_or_pending(other))
1353 SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
1354 if (unit_active_or_pending(other))
1357 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1358 if (unit_active_or_pending(other))
1361 log_info_unit(u->id, "Service %s is not needed anymore. Stopping.", u->id);
1363 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
1364 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
1367 static void retroactively_start_dependencies(Unit *u) {
1372 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1374 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1375 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1376 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1377 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1379 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1380 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1381 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1382 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1384 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1385 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1386 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1387 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1389 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1390 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1391 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1392 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1394 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
1395 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1396 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1398 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
1399 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1400 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1403 static void retroactively_stop_dependencies(Unit *u) {
1408 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1410 /* Pull down units which are bound to us recursively if enabled */
1411 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1412 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1413 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1416 static void check_unneeded_dependencies(Unit *u) {
1421 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1423 /* Garbage collect services that might not be needed anymore, if enabled */
1424 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1425 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1426 unit_check_unneeded(other);
1427 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1428 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1429 unit_check_unneeded(other);
1430 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1431 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1432 unit_check_unneeded(other);
1433 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
1434 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1435 unit_check_unneeded(other);
1436 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
1437 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1438 unit_check_unneeded(other);
1439 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1440 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1441 unit_check_unneeded(other);
1444 void unit_start_on_failure(Unit *u) {
1450 if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
1453 log_info_unit(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
1455 SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
1458 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_job_mode, true, NULL, NULL);
1460 log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
1464 void unit_trigger_notify(Unit *u) {
1470 SET_FOREACH(other, u->dependencies[UNIT_TRIGGERED_BY], i)
1471 if (UNIT_VTABLE(other)->trigger_notify)
1472 UNIT_VTABLE(other)->trigger_notify(other, u);
1475 void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
1480 assert(os < _UNIT_ACTIVE_STATE_MAX);
1481 assert(ns < _UNIT_ACTIVE_STATE_MAX);
1483 /* Note that this is called for all low-level state changes,
1484 * even if they might map to the same high-level
1485 * UnitActiveState! That means that ns == os is OK an expected
1486 * behavior here. For example: if a mount point is remounted
1487 * this function will be called too! */
1491 if (m->n_reloading <= 0) {
1494 dual_timestamp_get(&ts);
1496 if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
1497 u->inactive_exit_timestamp = ts;
1498 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
1499 u->inactive_enter_timestamp = ts;
1501 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
1502 u->active_enter_timestamp = ts;
1503 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
1504 u->active_exit_timestamp = ts;
1507 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1508 unit_destroy_cgroup(u);
1510 /* Note that this doesn't apply to RemainAfterExit services exiting
1511 * sucessfully, since there's no change of state in that case. Which is
1512 * why it is handled in service_set_state() */
1513 if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1514 ExecContext *ec = unit_get_exec_context(u);
1515 if (ec && exec_context_may_touch_console(ec)) {
1516 if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1519 if (m->n_on_console == 0)
1520 /* unset no_console_output flag, since the console is free */
1521 m->no_console_output = false;
1530 if (u->job->state == JOB_WAITING)
1532 /* So we reached a different state for this
1533 * job. Let's see if we can run it now if it
1534 * failed previously due to EAGAIN. */
1535 job_add_to_run_queue(u->job);
1537 /* Let's check whether this state change constitutes a
1538 * finished job, or maybe contradicts a running job and
1539 * hence needs to invalidate jobs. */
1541 switch (u->job->type) {
1544 case JOB_VERIFY_ACTIVE:
1546 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
1547 job_finish_and_invalidate(u->job, JOB_DONE, true);
1548 else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
1551 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1552 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1558 case JOB_RELOAD_OR_START:
1560 if (u->job->state == JOB_RUNNING) {
1561 if (ns == UNIT_ACTIVE)
1562 job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
1563 else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
1566 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1567 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1575 case JOB_TRY_RESTART:
1577 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1578 job_finish_and_invalidate(u->job, JOB_DONE, true);
1579 else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
1581 job_finish_and_invalidate(u->job, JOB_FAILED, true);
1587 assert_not_reached("Job type unknown");
1593 if (m->n_reloading <= 0) {
1595 /* If this state change happened without being
1596 * requested by a job, then let's retroactively start
1597 * or stop dependencies. We skip that step when
1598 * deserializing, since we don't want to create any
1599 * additional jobs just because something is already
1603 if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1604 retroactively_start_dependencies(u);
1605 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1606 retroactively_stop_dependencies(u);
1609 /* stop unneeded units regardless if going down was expected or not */
1610 if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1611 check_unneeded_dependencies(u);
1613 if (ns != os && ns == UNIT_FAILED) {
1614 log_notice_unit(u->id,
1615 "Unit %s entered failed state.", u->id);
1616 unit_start_on_failure(u);
1620 /* Some names are special */
1621 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
1623 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
1624 /* The bus just might have become available,
1625 * hence try to connect to it, if we aren't
1629 if (u->type == UNIT_SERVICE &&
1630 !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
1631 m->n_reloading <= 0) {
1632 /* Write audit record if we have just finished starting up */
1633 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
1637 if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
1638 manager_send_unit_plymouth(m, u);
1642 /* We don't care about D-Bus here, since we'll get an
1643 * asynchronous notification for it anyway. */
1645 if (u->type == UNIT_SERVICE &&
1646 UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1647 !UNIT_IS_INACTIVE_OR_FAILED(os) &&
1648 m->n_reloading <= 0) {
1650 /* Hmm, if there was no start record written
1651 * write it now, so that we always have a nice
1654 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
1656 if (ns == UNIT_INACTIVE)
1657 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
1659 /* Write audit record if we have just finished shutting down */
1660 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
1662 u->in_audit = false;
1666 manager_recheck_journal(m);
1667 unit_trigger_notify(u);
1669 /* Maybe we finished startup and are now ready for being
1670 * stopped because unneeded? */
1671 if (u->manager->n_reloading <= 0)
1672 unit_check_unneeded(u);
1674 unit_add_to_dbus_queue(u);
1675 unit_add_to_gc_queue(u);
1678 int unit_watch_pid(Unit *u, pid_t pid) {
1682 /* Watch a specific PID. We only support one unit watching
1683 * each PID for now. */
1685 return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1688 void unit_unwatch_pid(Unit *u, pid_t pid) {
1692 hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1695 bool unit_job_is_applicable(Unit *u, JobType j) {
1697 assert(j >= 0 && j < _JOB_TYPE_MAX);
1701 case JOB_VERIFY_ACTIVE:
1708 case JOB_TRY_RESTART:
1709 return unit_can_start(u);
1712 return unit_can_reload(u);
1714 case JOB_RELOAD_OR_START:
1715 return unit_can_reload(u) && unit_can_start(u);
1718 assert_not_reached("Invalid job type");
1722 int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
1724 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
1725 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
1726 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1727 [UNIT_WANTS] = UNIT_WANTED_BY,
1728 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
1729 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1730 [UNIT_BINDS_TO] = UNIT_BOUND_BY,
1731 [UNIT_PART_OF] = UNIT_CONSISTS_OF,
1732 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
1733 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
1734 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
1735 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
1736 [UNIT_CONSISTS_OF] = UNIT_PART_OF,
1737 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
1738 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
1739 [UNIT_BEFORE] = UNIT_AFTER,
1740 [UNIT_AFTER] = UNIT_BEFORE,
1741 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
1742 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
1743 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
1744 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
1745 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
1746 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
1747 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
1749 int r, q = 0, v = 0, w = 0;
1752 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
1755 u = unit_follow_merge(u);
1756 other = unit_follow_merge(other);
1758 /* We won't allow dependencies on ourselves. We will not
1759 * consider them an error however. */
1763 if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
1766 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
1767 if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
1771 if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
1772 (r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
1775 if ((q = set_put(u->dependencies[d], other)) < 0)
1778 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
1779 if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) {
1784 if (add_reference) {
1785 if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) {
1790 if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0)
1794 unit_add_to_dbus_queue(u);
1799 set_remove(u->dependencies[d], other);
1802 set_remove(other->dependencies[inverse_table[d]], u);
1805 set_remove(u->dependencies[UNIT_REFERENCES], other);
1810 int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
1815 if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
1818 if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
1824 static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
1828 assert(name || path);
1832 name = path_get_file_name(path);
1834 if (!unit_name_is_template(name)) {
1840 s = unit_name_replace_instance(name, u->instance);
1842 _cleanup_free_ char *i = NULL;
1844 i = unit_name_to_prefix(u->id);
1848 s = unit_name_replace_instance(name, i);
1858 int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1861 _cleanup_free_ char *s = NULL;
1864 assert(name || path);
1866 name = resolve_template(u, name, path, &s);
1870 r = manager_load_unit(u->manager, name, path, NULL, &other);
1874 return unit_add_dependency(u, d, other, add_reference);
1877 int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1880 _cleanup_free_ char *s = NULL;
1883 assert(name || path);
1885 if (!(name = resolve_template(u, name, path, &s)))
1888 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1891 r = unit_add_two_dependencies(u, d, e, other, add_reference);
1896 int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1899 _cleanup_free_ char *s = NULL;
1902 assert(name || path);
1904 if (!(name = resolve_template(u, name, path, &s)))
1907 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1910 r = unit_add_dependency(other, d, u, add_reference);
1915 int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1918 _cleanup_free_ char *s = NULL;
1921 assert(name || path);
1923 if (!(name = resolve_template(u, name, path, &s)))
1926 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1929 if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
1935 int set_unit_path(const char *p) {
1936 _cleanup_free_ char *c = NULL;
1938 /* This is mostly for debug purposes */
1939 c = path_make_absolute_cwd(p);
1940 if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0)
1946 char *unit_dbus_path(Unit *u) {
1952 return unit_dbus_path_from_name(u->id);
1955 char *unit_default_cgroup_path(Unit *u) {
1956 _cleanup_free_ char *escaped = NULL, *slice = NULL;
1961 if (unit_has_name(u, SPECIAL_ROOT_SLICE))
1962 return strdup(u->manager->cgroup_root);
1964 if (UNIT_ISSET(u->slice) && !unit_has_name(UNIT_DEREF(u->slice), SPECIAL_ROOT_SLICE)) {
1965 r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice);
1970 escaped = cg_escape(u->id);
1975 return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL);
1977 return strjoin(u->manager->cgroup_root, "/", escaped, NULL);
1980 int unit_add_default_slice(Unit *u) {
1981 _cleanup_free_ char *b = NULL;
1982 const char *slice_name;
1988 if (UNIT_ISSET(u->slice))
1991 if (!unit_get_cgroup_context(u))
1995 _cleanup_free_ char *prefix = NULL, *escaped = NULL;
1997 /* Implicitly place all instantiated units in their
1998 * own per-template slice */
2000 prefix = unit_name_to_prefix(u->id);
2004 /* The prefix is already escaped, but it might include
2005 * "-" which has a special meaning for slice units,
2006 * hence escape it here extra. */
2007 escaped = strreplace(prefix, "-", "\\x2d");
2011 if (u->manager->running_as == SYSTEMD_SYSTEM)
2012 b = strjoin("system-", escaped, ".slice", NULL);
2014 b = strappend(escaped, ".slice");
2021 u->manager->running_as == SYSTEMD_SYSTEM
2022 ? SPECIAL_SYSTEM_SLICE
2023 : SPECIAL_ROOT_SLICE;
2025 r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
2029 unit_ref_set(&u->slice, slice);
2033 const char *unit_slice_name(Unit *u) {
2036 if (!UNIT_ISSET(u->slice))
2039 return UNIT_DEREF(u->slice)->id;
2042 int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
2043 _cleanup_free_ char *t = NULL;
2050 t = unit_name_change_suffix(u->id, type);
2054 assert(!unit_has_name(u, t));
2056 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
2057 assert(r < 0 || *_found != u);
2061 int unit_watch_bus_name(Unit *u, const char *name) {
2065 /* Watch a specific name on the bus. We only support one unit
2066 * watching each name for now. */
2068 return hashmap_put(u->manager->watch_bus, name, u);
2071 void unit_unwatch_bus_name(Unit *u, const char *name) {
2075 hashmap_remove_value(u->manager->watch_bus, name, u);
2078 bool unit_can_serialize(Unit *u) {
2081 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2084 int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
2091 if (!unit_can_serialize(u))
2094 r = UNIT_VTABLE(u)->serialize(u, f, fds);
2099 if (serialize_jobs) {
2101 fprintf(f, "job\n");
2102 job_serialize(u->job, f, fds);
2106 fprintf(f, "job\n");
2107 job_serialize(u->nop_job, f, fds);
2111 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2112 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2113 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2114 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2115 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
2117 if (dual_timestamp_is_set(&u->condition_timestamp))
2118 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
2120 unit_serialize_item(u, f, "transient", yes_no(u->transient));
2123 unit_serialize_item(u, f, "cgroup", u->cgroup_path);
2130 void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2141 va_start(ap, format);
2142 vfprintf(f, format, ap);
2148 void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2154 fprintf(f, "%s=%s\n", key, value);
2157 int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
2164 if (!unit_can_serialize(u))
2168 char line[LINE_MAX], *l, *v;
2171 if (!fgets(line, sizeof(line), f)) {
2184 k = strcspn(l, "=");
2192 if (streq(l, "job")) {
2194 /* new-style serialized job */
2195 Job *j = job_new_raw(u);
2199 r = job_deserialize(j, f, fds);
2205 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2211 r = job_install_deserialized(j);
2213 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2218 if (j->state == JOB_RUNNING)
2219 u->manager->n_running_jobs++;
2222 JobType type = job_type_from_string(v);
2224 log_debug("Failed to parse job type value %s", v);
2226 u->deserialized_job = type;
2229 } else if (streq(l, "inactive-exit-timestamp")) {
2230 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
2232 } else if (streq(l, "active-enter-timestamp")) {
2233 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
2235 } else if (streq(l, "active-exit-timestamp")) {
2236 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
2238 } else if (streq(l, "inactive-enter-timestamp")) {
2239 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
2241 } else if (streq(l, "condition-timestamp")) {
2242 dual_timestamp_deserialize(v, &u->condition_timestamp);
2244 } else if (streq(l, "condition-result")) {
2247 b = parse_boolean(v);
2249 log_debug("Failed to parse condition result value %s", v);
2251 u->condition_result = b;
2255 } else if (streq(l, "transient")) {
2258 b = parse_boolean(v);
2260 log_debug("Failed to parse transient bool %s", v);
2265 } else if (streq(l, "cgroup")) {
2272 free(u->cgroup_path);
2275 assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1);
2279 r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds);
2285 int unit_add_node_link(Unit *u, const char *what, bool wants) {
2287 _cleanup_free_ char *e = NULL;
2295 /* Adds in links to the device node that this unit is based on */
2297 if (!is_device_path(what))
2300 e = unit_name_from_path(what, ".device");
2304 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
2309 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
2314 r = unit_add_dependency(device, UNIT_WANTS, u, false);
2322 int unit_coldplug(Unit *u) {
2327 if (UNIT_VTABLE(u)->coldplug)
2328 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2332 r = job_coldplug(u->job);
2335 } else if (u->deserialized_job >= 0) {
2337 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2341 u->deserialized_job = _JOB_TYPE_INVALID;
2347 #pragma GCC diagnostic push
2348 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
2349 void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) {
2350 manager_status_printf(u->manager, false, status, unit_status_msg_format, unit_description(u));
2352 #pragma GCC diagnostic pop
2354 bool unit_need_daemon_reload(Unit *u) {
2355 _cleanup_strv_free_ char **t = NULL;
2358 unsigned loaded_cnt, current_cnt;
2362 if (u->fragment_path) {
2364 if (stat(u->fragment_path, &st) < 0)
2365 /* What, cannot access this anymore? */
2368 if (u->fragment_mtime > 0 &&
2369 timespec_load(&st.st_mtim) != u->fragment_mtime)
2373 if (u->source_path) {
2375 if (stat(u->source_path, &st) < 0)
2378 if (u->source_mtime > 0 &&
2379 timespec_load(&st.st_mtim) != u->source_mtime)
2383 t = unit_find_dropin_paths(u);
2384 loaded_cnt = strv_length(t);
2385 current_cnt = strv_length(u->dropin_paths);
2387 if (loaded_cnt == current_cnt) {
2388 if (loaded_cnt == 0)
2391 if (strv_overlap(u->dropin_paths, t)) {
2392 STRV_FOREACH(path, u->dropin_paths) {
2394 if (stat(*path, &st) < 0)
2397 if (u->dropin_mtime > 0 &&
2398 timespec_load(&st.st_mtim) > u->dropin_mtime)
2409 void unit_reset_failed(Unit *u) {
2412 if (UNIT_VTABLE(u)->reset_failed)
2413 UNIT_VTABLE(u)->reset_failed(u);
2416 Unit *unit_following(Unit *u) {
2419 if (UNIT_VTABLE(u)->following)
2420 return UNIT_VTABLE(u)->following(u);
2425 bool unit_stop_pending(Unit *u) {
2428 /* This call does check the current state of the unit. It's
2429 * hence useful to be called from state change calls of the
2430 * unit itself, where the state isn't updated yet. This is
2431 * different from unit_inactive_or_pending() which checks both
2432 * the current state and for a queued job. */
2434 return u->job && u->job->type == JOB_STOP;
2437 bool unit_inactive_or_pending(Unit *u) {
2440 /* Returns true if the unit is inactive or going down */
2442 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2445 if (unit_stop_pending(u))
2451 bool unit_active_or_pending(Unit *u) {
2454 /* Returns true if the unit is active or going up */
2456 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2460 (u->job->type == JOB_START ||
2461 u->job->type == JOB_RELOAD_OR_START ||
2462 u->job->type == JOB_RESTART))
2468 int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error) {
2470 assert(w >= 0 && w < _KILL_WHO_MAX);
2472 assert(signo < _NSIG);
2474 if (!UNIT_VTABLE(u)->kill)
2477 return UNIT_VTABLE(u)->kill(u, w, signo, error);
2480 static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
2484 pid_set = set_new(trivial_hash_func, trivial_compare_func);
2488 /* Exclude the main/control pids from being killed via the cgroup */
2490 r = set_put(pid_set, LONG_TO_PTR(main_pid));
2495 if (control_pid > 0) {
2496 r = set_put(pid_set, LONG_TO_PTR(control_pid));
2508 int unit_kill_common(
2514 sd_bus_error *error) {
2518 if (who == KILL_MAIN && main_pid <= 0) {
2520 sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
2522 sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
2526 if (who == KILL_CONTROL && control_pid <= 0) {
2527 if (control_pid < 0)
2528 sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
2530 sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
2534 if (who == KILL_CONTROL || who == KILL_ALL)
2535 if (control_pid > 0)
2536 if (kill(control_pid, signo) < 0)
2539 if (who == KILL_MAIN || who == KILL_ALL)
2541 if (kill(main_pid, signo) < 0)
2544 if (who == KILL_ALL && u->cgroup_path) {
2545 _cleanup_set_free_ Set *pid_set = NULL;
2548 /* Exclude the main/control pids from being killed via the cgroup */
2549 pid_set = unit_pid_set(main_pid, control_pid);
2553 q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
2554 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
2561 int unit_following_set(Unit *u, Set **s) {
2565 if (UNIT_VTABLE(u)->following_set)
2566 return UNIT_VTABLE(u)->following_set(u, s);
2572 UnitFileState unit_get_unit_file_state(Unit *u) {
2575 if (u->unit_file_state < 0 && u->fragment_path)
2576 u->unit_file_state = unit_file_get_state(
2577 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
2578 NULL, path_get_file_name(u->fragment_path));
2580 return u->unit_file_state;
2583 Unit* unit_ref_set(UnitRef *ref, Unit *u) {
2588 unit_ref_unset(ref);
2591 LIST_PREPEND(refs, u->refs, ref);
2595 void unit_ref_unset(UnitRef *ref) {
2601 LIST_REMOVE(refs, ref->unit->refs, ref);
2605 int unit_exec_context_defaults(Unit *u, ExecContext *c) {
2612 /* This only copies in the ones that need memory */
2613 for (i = 0; i < RLIMIT_NLIMITS; i++)
2614 if (u->manager->rlimit[i] && !c->rlimit[i]) {
2615 c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
2620 if (u->manager->running_as == SYSTEMD_USER &&
2621 !c->working_directory) {
2623 r = get_home_dir(&c->working_directory);
2631 ExecContext *unit_get_exec_context(Unit *u) {
2635 offset = UNIT_VTABLE(u)->exec_context_offset;
2639 return (ExecContext*) ((uint8_t*) u + offset);
2642 KillContext *unit_get_kill_context(Unit *u) {
2646 offset = UNIT_VTABLE(u)->kill_context_offset;
2650 return (KillContext*) ((uint8_t*) u + offset);
2653 CGroupContext *unit_get_cgroup_context(Unit *u) {
2656 offset = UNIT_VTABLE(u)->cgroup_context_offset;
2660 return (CGroupContext*) ((uint8_t*) u + offset);
2663 static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) {
2664 _cleanup_free_ char *b = NULL;
2672 assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME));
2674 b = xescape(name, "/.");
2678 if (!filename_is_safe(b))
2681 if (u->manager->running_as == SYSTEMD_USER) {
2682 _cleanup_free_ char *c = NULL;
2684 r = user_config_home(&c);
2690 p = strjoin(c, "/", u->id, ".d", NULL);
2691 } else if (mode & UNIT_PERSISTENT)
2692 p = strjoin("/etc/systemd/system/", u->id, ".d", NULL);
2694 p = strjoin("/run/systemd/system/", u->id, ".d", NULL);
2698 q = strjoin(p, "/90-", b, ".conf", NULL);
2709 int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2710 _cleanup_free_ char *p = NULL, *q = NULL;
2717 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2720 r = drop_in_file(u, mode, name, &p, &q);
2725 return write_string_file_atomic_label(q, data);
2728 int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2729 _cleanup_free_ char *p = NULL;
2737 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2740 va_start(ap, format);
2741 r = vasprintf(&p, format, ap);
2747 return unit_write_drop_in(u, mode, name, p);
2750 int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2751 _cleanup_free_ char *ndata = NULL;
2757 if (!UNIT_VTABLE(u)->private_section)
2760 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2763 ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
2767 return unit_write_drop_in(u, mode, name, ndata);
2770 int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2771 _cleanup_free_ char *p = NULL;
2779 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2782 va_start(ap, format);
2783 r = vasprintf(&p, format, ap);
2789 return unit_write_drop_in_private(u, mode, name, p);
2792 int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
2793 _cleanup_free_ char *p = NULL, *q = NULL;
2798 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2801 r = drop_in_file(u, mode, name, &p, &q);
2806 r = errno == ENOENT ? 0 : -errno;
2814 int unit_make_transient(Unit *u) {
2819 u->load_state = UNIT_STUB;
2821 u->transient = true;
2823 free(u->fragment_path);
2824 u->fragment_path = NULL;
2826 if (u->manager->running_as == SYSTEMD_USER) {
2827 _cleanup_free_ char *c = NULL;
2829 r = user_config_home(&c);
2835 u->fragment_path = strjoin(c, "/", u->id, NULL);
2836 if (!u->fragment_path)
2841 u->fragment_path = strappend("/run/systemd/system/", u->id);
2842 if (!u->fragment_path)
2845 mkdir_p("/run/systemd/system", 0755);
2848 return write_string_file_atomic_label(u->fragment_path, "# Transient stub");
2851 int unit_kill_context(
2857 bool main_pid_alien) {
2859 int sig, wait_for_exit = 0, r;
2864 if (c->kill_mode == KILL_NONE)
2867 sig = sigkill ? SIGKILL : c->kill_signal;
2870 r = kill_and_sigcont(main_pid, sig);
2872 if (r < 0 && r != -ESRCH) {
2873 _cleanup_free_ char *comm = NULL;
2874 get_process_comm(main_pid, &comm);
2876 log_warning_unit(u->id, "Failed to kill main process %li (%s): %s",
2877 (long) main_pid, strna(comm), strerror(-r));
2879 wait_for_exit = !main_pid_alien;
2882 kill(main_pid, SIGHUP);
2886 if (control_pid > 0) {
2887 r = kill_and_sigcont(control_pid, sig);
2889 if (r < 0 && r != -ESRCH) {
2890 _cleanup_free_ char *comm = NULL;
2891 get_process_comm(control_pid, &comm);
2893 log_warning_unit(u->id,
2894 "Failed to kill control process %li (%s): %s",
2895 (long) control_pid, strna(comm), strerror(-r));
2897 wait_for_exit = true;
2900 kill(control_pid, SIGHUP);
2904 if (c->kill_mode == KILL_CONTROL_GROUP && u->cgroup_path) {
2905 _cleanup_set_free_ Set *pid_set = NULL;
2907 /* Exclude the main/control pids from being killed via the cgroup */
2908 pid_set = unit_pid_set(main_pid, control_pid);
2912 r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set);
2914 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
2915 log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
2917 wait_for_exit = true;
2918 if (c->send_sighup) {
2921 pid_set = unit_pid_set(main_pid, control_pid);
2925 cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, SIGHUP, true, true, false, pid_set);
2930 return wait_for_exit;
2933 int unit_require_mounts_for(Unit *u, const char *path) {
2934 char prefix[strlen(path) + 1], *p;
2940 /* Registers a unit for requiring a certain path and all its
2941 * prefixes. We keep a simple array of these paths in the
2942 * unit, since its usually short. However, we build a prefix
2943 * table for all possible prefixes so that new appearing mount
2944 * units can easily determine which units to make themselves a
2951 path_kill_slashes(p);
2953 if (!path_is_absolute(p)) {
2958 if (!path_is_safe(p)) {
2963 if (strv_contains(u->requires_mounts_for, p)) {
2968 r = strv_push(&u->requires_mounts_for, p);
2974 PATH_FOREACH_PREFIX_MORE(prefix, p) {
2977 x = hashmap_get(u->manager->units_requiring_mounts_for, prefix);
2981 if (!u->manager->units_requiring_mounts_for) {
2982 u->manager->units_requiring_mounts_for = hashmap_new(string_hash_func, string_compare_func);
2983 if (!u->manager->units_requiring_mounts_for)
2991 x = set_new(NULL, NULL);
2997 r = hashmap_put(u->manager->units_requiring_mounts_for, q, x);
3013 static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
3014 [UNIT_ACTIVE] = "active",
3015 [UNIT_RELOADING] = "reloading",
3016 [UNIT_INACTIVE] = "inactive",
3017 [UNIT_FAILED] = "failed",
3018 [UNIT_ACTIVATING] = "activating",
3019 [UNIT_DEACTIVATING] = "deactivating"
3022 DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
3024 static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
3025 [UNIT_REQUIRES] = "Requires",
3026 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
3027 [UNIT_REQUISITE] = "Requisite",
3028 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
3029 [UNIT_WANTS] = "Wants",
3030 [UNIT_BINDS_TO] = "BindsTo",
3031 [UNIT_PART_OF] = "PartOf",
3032 [UNIT_REQUIRED_BY] = "RequiredBy",
3033 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
3034 [UNIT_WANTED_BY] = "WantedBy",
3035 [UNIT_BOUND_BY] = "BoundBy",
3036 [UNIT_CONSISTS_OF] = "ConsistsOf",
3037 [UNIT_CONFLICTS] = "Conflicts",
3038 [UNIT_CONFLICTED_BY] = "ConflictedBy",
3039 [UNIT_BEFORE] = "Before",
3040 [UNIT_AFTER] = "After",
3041 [UNIT_ON_FAILURE] = "OnFailure",
3042 [UNIT_TRIGGERS] = "Triggers",
3043 [UNIT_TRIGGERED_BY] = "TriggeredBy",
3044 [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
3045 [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
3046 [UNIT_REFERENCES] = "References",
3047 [UNIT_REFERENCED_BY] = "ReferencedBy",
3050 DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);