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;
93 bool unit_has_name(Unit *u, const char *name) {
97 return !!set_get(u->names, (char*) name);
100 int unit_add_name(Unit *u, const char *text) {
108 if (unit_name_is_template(text)) {
112 s = unit_name_replace_instance(text, u->instance);
119 if (!unit_name_is_valid(s, false)) {
124 assert_se((t = unit_name_to_type(s)) >= 0);
126 if (u->type != _UNIT_TYPE_INVALID && t != u->type) {
131 r = unit_name_to_instance(s, &i);
135 if (i && unit_vtable[t]->no_instances) {
140 /* Ensure that this unit is either instanced or not instanced,
142 if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) {
147 if (unit_vtable[t]->no_alias &&
148 !set_isempty(u->names) &&
149 !set_get(u->names, s)) {
154 if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) {
159 r = set_put(u->names, s);
166 r = hashmap_put(u->manager->units, s, u);
168 set_remove(u->names, s);
172 if (u->type == _UNIT_TYPE_INVALID) {
178 LIST_PREPEND(units_by_type, u->manager->units_by_type[t], u);
180 if (UNIT_VTABLE(u)->init)
181 UNIT_VTABLE(u)->init(u);
185 unit_add_to_dbus_queue(u);
195 int unit_choose_id(Unit *u, const char *name) {
197 _cleanup_free_ char *t = NULL;
203 if (unit_name_is_template(name)) {
208 t = unit_name_replace_instance(name, u->instance);
215 /* Selects one of the names of this unit as the id */
216 s = set_get(u->names, (char*) name);
221 r = unit_name_to_instance(s, &i);
230 unit_add_to_dbus_queue(u);
235 int unit_set_description(Unit *u, const char *description) {
240 if (isempty(description))
243 s = strdup(description);
248 free(u->description);
251 unit_add_to_dbus_queue(u);
255 bool unit_check_gc(Unit *u) {
258 if (u->load_state == UNIT_STUB)
261 if (UNIT_VTABLE(u)->no_gc)
273 if (unit_active_state(u) != UNIT_INACTIVE)
279 if (UNIT_VTABLE(u)->check_gc)
280 if (UNIT_VTABLE(u)->check_gc(u))
286 void unit_add_to_load_queue(Unit *u) {
288 assert(u->type != _UNIT_TYPE_INVALID);
290 if (u->load_state != UNIT_STUB || u->in_load_queue)
293 LIST_PREPEND(load_queue, u->manager->load_queue, u);
294 u->in_load_queue = true;
297 void unit_add_to_cleanup_queue(Unit *u) {
300 if (u->in_cleanup_queue)
303 LIST_PREPEND(cleanup_queue, u->manager->cleanup_queue, u);
304 u->in_cleanup_queue = true;
307 void unit_add_to_gc_queue(Unit *u) {
310 if (u->in_gc_queue || u->in_cleanup_queue)
313 if (unit_check_gc(u))
316 LIST_PREPEND(gc_queue, u->manager->gc_queue, u);
317 u->in_gc_queue = true;
319 u->manager->n_in_gc_queue ++;
322 void unit_add_to_dbus_queue(Unit *u) {
324 assert(u->type != _UNIT_TYPE_INVALID);
326 if (u->load_state == UNIT_STUB || u->in_dbus_queue)
329 /* Shortcut things if nobody cares */
330 if (set_isempty(u->manager->subscribed)) {
331 u->sent_dbus_new_signal = true;
335 LIST_PREPEND(dbus_queue, u->manager->dbus_unit_queue, u);
336 u->in_dbus_queue = true;
339 static void bidi_set_free(Unit *u, Set *s) {
345 /* Frees the set and makes sure we are dropped from the
346 * inverse pointers */
348 SET_FOREACH(other, s, i) {
351 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
352 set_remove(other->dependencies[d], u);
354 unit_add_to_gc_queue(other);
360 static void unit_remove_transient(Unit *u) {
368 if (u->fragment_path)
369 unlink(u->fragment_path);
371 STRV_FOREACH(i, u->dropin_paths) {
372 _cleanup_free_ char *p = NULL;
377 r = path_get_parent(*i, &p);
383 static void unit_free_requires_mounts_for(Unit *u) {
386 STRV_FOREACH(j, u->requires_mounts_for) {
387 char s[strlen(*j) + 1];
389 PATH_FOREACH_PREFIX_MORE(s, *j) {
393 x = hashmap_get2(u->manager->units_requiring_mounts_for, s, (void**) &y);
399 if (set_isempty(x)) {
400 hashmap_remove(u->manager->units_requiring_mounts_for, y);
407 strv_free(u->requires_mounts_for);
408 u->requires_mounts_for = NULL;
411 void unit_free(Unit *u) {
418 if (u->manager->n_reloading <= 0)
419 unit_remove_transient(u);
421 bus_unit_send_removed_signal(u);
423 if (u->load_state != UNIT_STUB)
424 if (UNIT_VTABLE(u)->done)
425 UNIT_VTABLE(u)->done(u);
427 unit_free_requires_mounts_for(u);
429 SET_FOREACH(t, u->names, i)
430 hashmap_remove_value(u->manager->units, t, u);
444 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
445 bidi_set_free(u, u->dependencies[d]);
447 if (u->type != _UNIT_TYPE_INVALID)
448 LIST_REMOVE(units_by_type, u->manager->units_by_type[u->type], u);
450 if (u->in_load_queue)
451 LIST_REMOVE(load_queue, u->manager->load_queue, u);
453 if (u->in_dbus_queue)
454 LIST_REMOVE(dbus_queue, u->manager->dbus_unit_queue, u);
456 if (u->in_cleanup_queue)
457 LIST_REMOVE(cleanup_queue, u->manager->cleanup_queue, u);
459 if (u->in_gc_queue) {
460 LIST_REMOVE(gc_queue, u->manager->gc_queue, u);
461 u->manager->n_in_gc_queue--;
464 if (u->in_cgroup_queue)
465 LIST_REMOVE(cgroup_queue, u->manager->cgroup_queue, u);
467 if (u->cgroup_path) {
468 hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
469 free(u->cgroup_path);
472 free(u->description);
473 strv_free(u->documentation);
474 free(u->fragment_path);
475 free(u->source_path);
476 strv_free(u->dropin_paths);
479 set_free_free(u->names);
481 condition_free_list(u->conditions);
483 unit_ref_unset(&u->slice);
486 unit_ref_unset(u->refs);
491 UnitActiveState unit_active_state(Unit *u) {
494 if (u->load_state == UNIT_MERGED)
495 return unit_active_state(unit_follow_merge(u));
497 /* After a reload it might happen that a unit is not correctly
498 * loaded but still has a process around. That's why we won't
499 * shortcut failed loading to UNIT_INACTIVE_FAILED. */
501 return UNIT_VTABLE(u)->active_state(u);
504 const char* unit_sub_state_to_string(Unit *u) {
507 return UNIT_VTABLE(u)->sub_state_to_string(u);
510 static void complete_move(Set **s, Set **other) {
518 set_move(*s, *other);
525 static void merge_names(Unit *u, Unit *other) {
532 complete_move(&u->names, &other->names);
534 set_free_free(other->names);
538 SET_FOREACH(t, u->names, i)
539 assert_se(hashmap_replace(u->manager->units, t, u) == 0);
542 static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
549 assert(d < _UNIT_DEPENDENCY_MAX);
551 /* Fix backwards pointers */
552 SET_FOREACH(back, other->dependencies[d], i) {
555 for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++) {
556 r = set_remove_and_put(back->dependencies[k], other, u);
558 set_remove(back->dependencies[k], other);
560 assert(r >= 0 || r == -ENOENT);
564 complete_move(&u->dependencies[d], &other->dependencies[d]);
566 set_free(other->dependencies[d]);
567 other->dependencies[d] = NULL;
570 int unit_merge(Unit *u, Unit *other) {
575 assert(u->manager == other->manager);
576 assert(u->type != _UNIT_TYPE_INVALID);
578 other = unit_follow_merge(other);
583 if (u->type != other->type)
586 if (!u->instance != !other->instance)
589 if (other->load_state != UNIT_STUB &&
590 other->load_state != UNIT_NOT_FOUND)
599 if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
603 merge_names(u, other);
605 /* Redirect all references */
607 unit_ref_set(other->refs, u);
609 /* Merge dependencies */
610 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
611 merge_dependencies(u, other, d);
613 other->load_state = UNIT_MERGED;
614 other->merged_into = u;
616 /* If there is still some data attached to the other node, we
617 * don't need it anymore, and can free it. */
618 if (other->load_state != UNIT_STUB)
619 if (UNIT_VTABLE(other)->done)
620 UNIT_VTABLE(other)->done(other);
622 unit_add_to_dbus_queue(u);
623 unit_add_to_cleanup_queue(other);
628 int unit_merge_by_name(Unit *u, const char *name) {
631 _cleanup_free_ char *s = NULL;
636 if (unit_name_is_template(name)) {
640 s = unit_name_replace_instance(name, u->instance);
647 other = manager_get_unit(u->manager, name);
649 r = unit_add_name(u, name);
651 r = unit_merge(u, other);
656 Unit* unit_follow_merge(Unit *u) {
659 while (u->load_state == UNIT_MERGED)
660 assert_se(u = u->merged_into);
665 int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
671 if (c->std_output != EXEC_OUTPUT_KMSG &&
672 c->std_output != EXEC_OUTPUT_SYSLOG &&
673 c->std_output != EXEC_OUTPUT_JOURNAL &&
674 c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
675 c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
676 c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
677 c->std_error != EXEC_OUTPUT_KMSG &&
678 c->std_error != EXEC_OUTPUT_SYSLOG &&
679 c->std_error != EXEC_OUTPUT_JOURNAL &&
680 c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
681 c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
682 c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE)
685 /* If syslog or kernel logging is requested, make sure our own
686 * logging daemon is run first. */
688 if (u->manager->running_as == SYSTEMD_SYSTEM) {
689 r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true);
697 const char *unit_description(Unit *u) {
701 return u->description;
706 void unit_dump(Unit *u, FILE *f, const char *prefix) {
710 _cleanup_free_ char *p2 = NULL;
713 timestamp1[FORMAT_TIMESTAMP_MAX],
714 timestamp2[FORMAT_TIMESTAMP_MAX],
715 timestamp3[FORMAT_TIMESTAMP_MAX],
716 timestamp4[FORMAT_TIMESTAMP_MAX],
717 timespan[FORMAT_TIMESPAN_MAX];
719 _cleanup_set_free_ Set *following_set = NULL;
723 assert(u->type >= 0);
727 p2 = strappend(prefix, "\t");
728 prefix2 = p2 ? p2 : prefix;
732 "%s\tDescription: %s\n"
734 "%s\tUnit Load State: %s\n"
735 "%s\tUnit Active State: %s\n"
736 "%s\tInactive Exit Timestamp: %s\n"
737 "%s\tActive Enter Timestamp: %s\n"
738 "%s\tActive Exit Timestamp: %s\n"
739 "%s\tInactive Enter Timestamp: %s\n"
740 "%s\tGC Check Good: %s\n"
741 "%s\tNeed Daemon Reload: %s\n"
742 "%s\tTransient: %s\n"
745 "%s\tCGroup realized: %s\n"
746 "%s\tCGroup mask: 0x%x\n"
747 "%s\tCGroup members mask: 0x%x\n",
749 prefix, unit_description(u),
750 prefix, strna(u->instance),
751 prefix, unit_load_state_to_string(u->load_state),
752 prefix, unit_active_state_to_string(unit_active_state(u)),
753 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->inactive_exit_timestamp.realtime)),
754 prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->active_enter_timestamp.realtime)),
755 prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)),
756 prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)),
757 prefix, yes_no(unit_check_gc(u)),
758 prefix, yes_no(unit_need_daemon_reload(u)),
759 prefix, yes_no(u->transient),
760 prefix, strna(unit_slice_name(u)),
761 prefix, strna(u->cgroup_path),
762 prefix, yes_no(u->cgroup_realized),
763 prefix, u->cgroup_mask,
764 prefix, u->cgroup_members_mask);
766 SET_FOREACH(t, u->names, i)
767 fprintf(f, "%s\tName: %s\n", prefix, t);
769 STRV_FOREACH(j, u->documentation)
770 fprintf(f, "%s\tDocumentation: %s\n", prefix, *j);
772 following = unit_following(u);
774 fprintf(f, "%s\tFollowing: %s\n", prefix, following->id);
776 r = unit_following_set(u, &following_set);
780 SET_FOREACH(other, following_set, i)
781 fprintf(f, "%s\tFollowing Set Member: %s\n", prefix, other->id);
784 if (u->fragment_path)
785 fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path);
788 fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path);
790 STRV_FOREACH(j, u->dropin_paths)
791 fprintf(f, "%s\tDropIn Path: %s\n", prefix, *j);
793 if (u->job_timeout > 0)
794 fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
796 condition_dump_list(u->conditions, f, prefix);
798 if (dual_timestamp_is_set(&u->condition_timestamp))
800 "%s\tCondition Timestamp: %s\n"
801 "%s\tCondition Result: %s\n",
802 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->condition_timestamp.realtime)),
803 prefix, yes_no(u->condition_result));
805 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
808 SET_FOREACH(other, u->dependencies[d], i)
809 fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
812 if (!strv_isempty(u->requires_mounts_for)) {
814 "%s\tRequiresMountsFor:", prefix);
816 STRV_FOREACH(j, u->requires_mounts_for)
817 fprintf(f, " %s", *j);
822 if (u->load_state == UNIT_LOADED) {
825 "%s\tStopWhenUnneeded: %s\n"
826 "%s\tRefuseManualStart: %s\n"
827 "%s\tRefuseManualStop: %s\n"
828 "%s\tDefaultDependencies: %s\n"
829 "%s\tOnFailureIsolate: %s\n"
830 "%s\tIgnoreOnIsolate: %s\n"
831 "%s\tIgnoreOnSnapshot: %s\n",
832 prefix, yes_no(u->stop_when_unneeded),
833 prefix, yes_no(u->refuse_manual_start),
834 prefix, yes_no(u->refuse_manual_stop),
835 prefix, yes_no(u->default_dependencies),
836 prefix, yes_no(u->on_failure_isolate),
837 prefix, yes_no(u->ignore_on_isolate),
838 prefix, yes_no(u->ignore_on_snapshot));
840 if (UNIT_VTABLE(u)->dump)
841 UNIT_VTABLE(u)->dump(u, f, prefix2);
843 } else if (u->load_state == UNIT_MERGED)
845 "%s\tMerged into: %s\n",
846 prefix, u->merged_into->id);
847 else if (u->load_state == UNIT_ERROR)
848 fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->load_error));
852 job_dump(u->job, f, prefix2);
855 job_dump(u->nop_job, f, prefix2);
859 /* Common implementation for multiple backends */
860 int unit_load_fragment_and_dropin(Unit *u) {
865 /* Load a .{service,socket,...} file */
866 r = unit_load_fragment(u);
870 if (u->load_state == UNIT_STUB)
873 /* Load drop-in directory data */
874 r = unit_load_dropin(unit_follow_merge(u));
881 /* Common implementation for multiple backends */
882 int unit_load_fragment_and_dropin_optional(Unit *u) {
887 /* Same as unit_load_fragment_and_dropin(), but whether
888 * something can be loaded or not doesn't matter. */
890 /* Load a .service file */
891 r = unit_load_fragment(u);
895 if (u->load_state == UNIT_STUB)
896 u->load_state = UNIT_LOADED;
898 /* Load drop-in directory data */
899 r = unit_load_dropin(unit_follow_merge(u));
906 int unit_add_default_target_dependency(Unit *u, Unit *target) {
910 if (target->type != UNIT_TARGET)
913 /* Only add the dependency if both units are loaded, so that
914 * that loop check below is reliable */
915 if (u->load_state != UNIT_LOADED ||
916 target->load_state != UNIT_LOADED)
919 /* If either side wants no automatic dependencies, then let's
921 if (!u->default_dependencies ||
922 !target->default_dependencies)
925 /* Don't create loops */
926 if (set_get(target->dependencies[UNIT_BEFORE], u))
929 return unit_add_dependency(target, UNIT_AFTER, u, true);
932 static int unit_add_default_dependencies(Unit *u) {
934 static const UnitDependency deps[] = {
936 UNIT_REQUIRED_BY_OVERRIDABLE,
948 for (k = 0; k < ELEMENTSOF(deps); k++)
949 SET_FOREACH(target, u->dependencies[deps[k]], i) {
950 r = unit_add_default_target_dependency(u, target);
955 if (u->default_dependencies && unit_get_cgroup_context(u)) {
956 if (UNIT_ISSET(u->slice))
957 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true);
959 r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, SPECIAL_ROOT_SLICE, NULL, true);
968 static int unit_add_mount_links(Unit *u) {
974 STRV_FOREACH(i, u->requires_mounts_for) {
975 char prefix[strlen(*i) + 1];
977 PATH_FOREACH_PREFIX_MORE(prefix, *i) {
980 r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m);
988 if (m->load_state != UNIT_LOADED)
991 r = unit_add_dependency(u, UNIT_AFTER, m, true);
995 if (m->fragment_path) {
996 r = unit_add_dependency(u, UNIT_REQUIRES, m, true);
1006 int unit_load(Unit *u) {
1011 if (u->in_load_queue) {
1012 LIST_REMOVE(load_queue, u->manager->load_queue, u);
1013 u->in_load_queue = false;
1016 if (u->type == _UNIT_TYPE_INVALID)
1019 if (u->load_state != UNIT_STUB)
1022 if (UNIT_VTABLE(u)->load) {
1023 r = UNIT_VTABLE(u)->load(u);
1028 if (u->load_state == UNIT_STUB) {
1033 if (u->load_state == UNIT_LOADED) {
1035 if (u->default_dependencies) {
1036 r = unit_add_default_dependencies(u);
1041 unit_update_member_masks(u);
1043 r = unit_add_mount_links(u);
1047 if (u->on_failure_isolate &&
1048 set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
1050 log_error_unit(u->id,
1051 "More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.", u->id);
1058 assert((u->load_state != UNIT_MERGED) == !u->merged_into);
1060 unit_add_to_dbus_queue(unit_follow_merge(u));
1061 unit_add_to_gc_queue(u);
1066 u->load_state = u->load_state == UNIT_STUB ? UNIT_NOT_FOUND : UNIT_ERROR;
1068 unit_add_to_dbus_queue(u);
1069 unit_add_to_gc_queue(u);
1071 log_debug_unit(u->id, "Failed to load configuration for %s: %s",
1072 u->id, strerror(-r));
1077 static bool unit_condition_test(Unit *u) {
1080 dual_timestamp_get(&u->condition_timestamp);
1081 u->condition_result = condition_test_list(u->id, u->conditions);
1083 return u->condition_result;
1086 _pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
1087 const UnitStatusMessageFormats *format_table;
1091 assert(t < _JOB_TYPE_MAX);
1093 if (t != JOB_START && t != JOB_STOP)
1096 format_table = &UNIT_VTABLE(u)->status_message_formats;
1100 return format_table->starting_stopping[t == JOB_STOP];
1103 _pure_ static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) {
1108 assert(t < _JOB_TYPE_MAX);
1110 format = unit_get_status_message_format(u, t);
1114 /* Return generic strings */
1116 return "Starting %s.";
1117 else if (t == JOB_STOP)
1118 return "Stopping %s.";
1119 else if (t == JOB_RELOAD)
1120 return "Reloading %s.";
1125 static void unit_status_print_starting_stopping(Unit *u, JobType t) {
1130 /* We only print status messages for selected units on
1131 * selected operations. */
1133 format = unit_get_status_message_format(u, t);
1137 unit_status_printf(u, "", format);
1140 #pragma GCC diagnostic push
1141 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
1142 static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
1149 if (t != JOB_START && t != JOB_STOP && t != JOB_RELOAD)
1152 if (log_on_console())
1155 /* We log status messages for all units and all operations. */
1157 format = unit_get_status_message_format_try_harder(u, t);
1161 snprintf(buf, sizeof(buf), format, unit_description(u));
1164 mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
1165 t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
1166 SD_MESSAGE_UNIT_RELOADING;
1168 log_struct_unit(LOG_INFO,
1174 #pragma GCC diagnostic pop
1177 * -EBADR: This unit type does not support starting.
1178 * -EALREADY: Unit is already started.
1179 * -EAGAIN: An operation is already in progress. Retry later.
1180 * -ECANCELED: Too many requests for now.
1182 int unit_start(Unit *u) {
1183 UnitActiveState state;
1188 if (u->load_state != UNIT_LOADED)
1191 /* If this is already started, then this will succeed. Note
1192 * that this will even succeed if this unit is not startable
1193 * by the user. This is relied on to detect when we need to
1194 * wait for units and when waiting is finished. */
1195 state = unit_active_state(u);
1196 if (UNIT_IS_ACTIVE_OR_RELOADING(state))
1199 /* If the conditions failed, don't do anything at all. If we
1200 * already are activating this call might still be useful to
1201 * speed up activation in case there is some hold-off time,
1202 * but we don't want to recheck the condition in that case. */
1203 if (state != UNIT_ACTIVATING &&
1204 !unit_condition_test(u)) {
1205 log_debug_unit(u->id, "Starting of %s requested but condition failed. Ignoring.", u->id);
1209 /* Forward to the main object, if we aren't it. */
1210 following = unit_following(u);
1212 log_debug_unit(u->id, "Redirecting start request from %s to %s.",
1213 u->id, following->id);
1214 return unit_start(following);
1217 unit_status_log_starting_stopping_reloading(u, JOB_START);
1218 unit_status_print_starting_stopping(u, JOB_START);
1220 /* If it is stopped, but we cannot start it, then fail */
1221 if (!UNIT_VTABLE(u)->start)
1224 /* We don't suppress calls to ->start() here when we are
1225 * already starting, to allow this request to be used as a
1226 * "hurry up" call, for example when the unit is in some "auto
1227 * restart" state where it waits for a holdoff timer to elapse
1228 * before it will start again. */
1230 unit_add_to_dbus_queue(u);
1232 return UNIT_VTABLE(u)->start(u);
1235 bool unit_can_start(Unit *u) {
1238 return !!UNIT_VTABLE(u)->start;
1241 bool unit_can_isolate(Unit *u) {
1244 return unit_can_start(u) &&
1249 * -EBADR: This unit type does not support stopping.
1250 * -EALREADY: Unit is already stopped.
1251 * -EAGAIN: An operation is already in progress. Retry later.
1253 int unit_stop(Unit *u) {
1254 UnitActiveState state;
1259 state = unit_active_state(u);
1260 if (UNIT_IS_INACTIVE_OR_FAILED(state))
1263 if ((following = unit_following(u))) {
1264 log_debug_unit(u->id, "Redirecting stop request from %s to %s.",
1265 u->id, following->id);
1266 return unit_stop(following);
1269 unit_status_log_starting_stopping_reloading(u, JOB_STOP);
1270 unit_status_print_starting_stopping(u, JOB_STOP);
1272 if (!UNIT_VTABLE(u)->stop)
1275 unit_add_to_dbus_queue(u);
1277 return UNIT_VTABLE(u)->stop(u);
1281 * -EBADR: This unit type does not support reloading.
1282 * -ENOEXEC: Unit is not started.
1283 * -EAGAIN: An operation is already in progress. Retry later.
1285 int unit_reload(Unit *u) {
1286 UnitActiveState state;
1291 if (u->load_state != UNIT_LOADED)
1294 if (!unit_can_reload(u))
1297 state = unit_active_state(u);
1298 if (state == UNIT_RELOADING)
1301 if (state != UNIT_ACTIVE)
1304 following = unit_following(u);
1306 log_debug_unit(u->id, "Redirecting reload request from %s to %s.",
1307 u->id, following->id);
1308 return unit_reload(following);
1311 unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
1313 unit_add_to_dbus_queue(u);
1314 return UNIT_VTABLE(u)->reload(u);
1317 bool unit_can_reload(Unit *u) {
1320 if (!UNIT_VTABLE(u)->reload)
1323 if (!UNIT_VTABLE(u)->can_reload)
1326 return UNIT_VTABLE(u)->can_reload(u);
1329 static void unit_check_unneeded(Unit *u) {
1335 /* If this service shall be shut down when unneeded then do
1338 if (!u->stop_when_unneeded)
1341 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1344 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
1345 if (unit_active_or_pending(other))
1348 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
1349 if (unit_active_or_pending(other))
1352 SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
1353 if (unit_active_or_pending(other))
1356 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1357 if (unit_active_or_pending(other))
1360 log_info_unit(u->id, "Service %s is not needed anymore. Stopping.", u->id);
1362 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
1363 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
1366 static void retroactively_start_dependencies(Unit *u) {
1371 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1373 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1374 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1375 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1376 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1378 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1379 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1380 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1381 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1383 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1384 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1385 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1386 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1388 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1389 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1390 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1391 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1393 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
1394 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1395 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1397 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
1398 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1399 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1402 static void retroactively_stop_dependencies(Unit *u) {
1407 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1409 /* Pull down units which are bound to us recursively if enabled */
1410 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1411 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1412 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1415 static void check_unneeded_dependencies(Unit *u) {
1420 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1422 /* Garbage collect services that might not be needed anymore, if enabled */
1423 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1424 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1425 unit_check_unneeded(other);
1426 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1427 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1428 unit_check_unneeded(other);
1429 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1430 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1431 unit_check_unneeded(other);
1432 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
1433 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1434 unit_check_unneeded(other);
1435 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
1436 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1437 unit_check_unneeded(other);
1438 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1439 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1440 unit_check_unneeded(other);
1443 void unit_start_on_failure(Unit *u) {
1449 if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
1452 log_info_unit(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
1454 SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
1457 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL);
1459 log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
1463 void unit_trigger_notify(Unit *u) {
1469 SET_FOREACH(other, u->dependencies[UNIT_TRIGGERED_BY], i)
1470 if (UNIT_VTABLE(other)->trigger_notify)
1471 UNIT_VTABLE(other)->trigger_notify(other, u);
1474 void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
1479 assert(os < _UNIT_ACTIVE_STATE_MAX);
1480 assert(ns < _UNIT_ACTIVE_STATE_MAX);
1482 /* Note that this is called for all low-level state changes,
1483 * even if they might map to the same high-level
1484 * UnitActiveState! That means that ns == os is OK an expected
1485 * behavior here. For example: if a mount point is remounted
1486 * this function will be called too! */
1490 if (m->n_reloading <= 0) {
1493 dual_timestamp_get(&ts);
1495 if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
1496 u->inactive_exit_timestamp = ts;
1497 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
1498 u->inactive_enter_timestamp = ts;
1500 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
1501 u->active_enter_timestamp = ts;
1502 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
1503 u->active_exit_timestamp = ts;
1506 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1507 unit_destroy_cgroup(u);
1509 /* Note that this doesn't apply to RemainAfterExit services exiting
1510 * sucessfully, since there's no change of state in that case. Which is
1511 * why it is handled in service_set_state() */
1512 if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1513 ExecContext *ec = unit_get_exec_context(u);
1514 if (ec && exec_context_may_touch_console(ec)) {
1515 if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1518 if (m->n_on_console == 0)
1519 /* unset no_console_output flag, since the console is free */
1520 m->no_console_output = false;
1529 if (u->job->state == JOB_WAITING)
1531 /* So we reached a different state for this
1532 * job. Let's see if we can run it now if it
1533 * failed previously due to EAGAIN. */
1534 job_add_to_run_queue(u->job);
1536 /* Let's check whether this state change constitutes a
1537 * finished job, or maybe contradicts a running job and
1538 * hence needs to invalidate jobs. */
1540 switch (u->job->type) {
1543 case JOB_VERIFY_ACTIVE:
1545 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
1546 job_finish_and_invalidate(u->job, JOB_DONE, true);
1547 else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
1550 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1551 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1557 case JOB_RELOAD_OR_START:
1559 if (u->job->state == JOB_RUNNING) {
1560 if (ns == UNIT_ACTIVE)
1561 job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
1562 else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
1565 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1566 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1574 case JOB_TRY_RESTART:
1576 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1577 job_finish_and_invalidate(u->job, JOB_DONE, true);
1578 else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
1580 job_finish_and_invalidate(u->job, JOB_FAILED, true);
1586 assert_not_reached("Job type unknown");
1592 if (m->n_reloading <= 0) {
1594 /* If this state change happened without being
1595 * requested by a job, then let's retroactively start
1596 * or stop dependencies. We skip that step when
1597 * deserializing, since we don't want to create any
1598 * additional jobs just because something is already
1602 if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1603 retroactively_start_dependencies(u);
1604 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1605 retroactively_stop_dependencies(u);
1608 /* stop unneeded units regardless if going down was expected or not */
1609 if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1610 check_unneeded_dependencies(u);
1612 if (ns != os && ns == UNIT_FAILED) {
1613 log_notice_unit(u->id,
1614 "Unit %s entered failed state.", u->id);
1615 unit_start_on_failure(u);
1619 /* Some names are special */
1620 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
1622 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
1623 /* The bus just might have become available,
1624 * hence try to connect to it, if we aren't
1628 if (u->type == UNIT_SERVICE &&
1629 !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
1630 m->n_reloading <= 0) {
1631 /* Write audit record if we have just finished starting up */
1632 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
1636 if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
1637 manager_send_unit_plymouth(m, u);
1641 /* We don't care about D-Bus here, since we'll get an
1642 * asynchronous notification for it anyway. */
1644 if (u->type == UNIT_SERVICE &&
1645 UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1646 !UNIT_IS_INACTIVE_OR_FAILED(os) &&
1647 m->n_reloading <= 0) {
1649 /* Hmm, if there was no start record written
1650 * write it now, so that we always have a nice
1653 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
1655 if (ns == UNIT_INACTIVE)
1656 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
1658 /* Write audit record if we have just finished shutting down */
1659 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
1661 u->in_audit = false;
1665 manager_recheck_journal(m);
1666 unit_trigger_notify(u);
1668 /* Maybe we finished startup and are now ready for being
1669 * stopped because unneeded? */
1670 if (u->manager->n_reloading <= 0)
1671 unit_check_unneeded(u);
1673 unit_add_to_dbus_queue(u);
1674 unit_add_to_gc_queue(u);
1677 int unit_watch_pid(Unit *u, pid_t pid) {
1681 /* Watch a specific PID. We only support one unit watching
1682 * each PID for now. */
1684 return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1687 void unit_unwatch_pid(Unit *u, pid_t pid) {
1691 hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1694 bool unit_job_is_applicable(Unit *u, JobType j) {
1696 assert(j >= 0 && j < _JOB_TYPE_MAX);
1700 case JOB_VERIFY_ACTIVE:
1707 case JOB_TRY_RESTART:
1708 return unit_can_start(u);
1711 return unit_can_reload(u);
1713 case JOB_RELOAD_OR_START:
1714 return unit_can_reload(u) && unit_can_start(u);
1717 assert_not_reached("Invalid job type");
1721 int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
1723 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
1724 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
1725 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1726 [UNIT_WANTS] = UNIT_WANTED_BY,
1727 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
1728 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1729 [UNIT_BINDS_TO] = UNIT_BOUND_BY,
1730 [UNIT_PART_OF] = UNIT_CONSISTS_OF,
1731 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
1732 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
1733 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
1734 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
1735 [UNIT_CONSISTS_OF] = UNIT_PART_OF,
1736 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
1737 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
1738 [UNIT_BEFORE] = UNIT_AFTER,
1739 [UNIT_AFTER] = UNIT_BEFORE,
1740 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
1741 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
1742 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
1743 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
1744 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
1745 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
1746 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
1748 int r, q = 0, v = 0, w = 0;
1751 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
1754 u = unit_follow_merge(u);
1755 other = unit_follow_merge(other);
1757 /* We won't allow dependencies on ourselves. We will not
1758 * consider them an error however. */
1762 if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
1765 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
1766 if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
1770 if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
1771 (r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
1774 if ((q = set_put(u->dependencies[d], other)) < 0)
1777 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
1778 if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) {
1783 if (add_reference) {
1784 if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) {
1789 if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0)
1793 unit_add_to_dbus_queue(u);
1798 set_remove(u->dependencies[d], other);
1801 set_remove(other->dependencies[inverse_table[d]], u);
1804 set_remove(u->dependencies[UNIT_REFERENCES], other);
1809 int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
1814 if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
1817 if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
1823 static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
1827 assert(name || path);
1831 name = path_get_file_name(path);
1833 if (!unit_name_is_template(name)) {
1839 s = unit_name_replace_instance(name, u->instance);
1841 _cleanup_free_ char *i = NULL;
1843 i = unit_name_to_prefix(u->id);
1847 s = unit_name_replace_instance(name, i);
1857 int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1860 _cleanup_free_ char *s = NULL;
1863 assert(name || path);
1865 name = resolve_template(u, name, path, &s);
1869 r = manager_load_unit(u->manager, name, path, NULL, &other);
1873 return unit_add_dependency(u, d, other, add_reference);
1876 int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1879 _cleanup_free_ char *s = NULL;
1882 assert(name || path);
1884 if (!(name = resolve_template(u, name, path, &s)))
1887 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1890 r = unit_add_two_dependencies(u, d, e, other, add_reference);
1895 int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1898 _cleanup_free_ char *s = NULL;
1901 assert(name || path);
1903 if (!(name = resolve_template(u, name, path, &s)))
1906 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1909 r = unit_add_dependency(other, d, u, add_reference);
1914 int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1917 _cleanup_free_ char *s = NULL;
1920 assert(name || path);
1922 if (!(name = resolve_template(u, name, path, &s)))
1925 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1928 if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
1934 int set_unit_path(const char *p) {
1935 _cleanup_free_ char *c = NULL;
1937 /* This is mostly for debug purposes */
1938 c = path_make_absolute_cwd(p);
1939 if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0)
1945 char *unit_dbus_path(Unit *u) {
1951 return unit_dbus_path_from_name(u->id);
1954 char *unit_default_cgroup_path(Unit *u) {
1955 _cleanup_free_ char *escaped = NULL, *slice = NULL;
1960 if (unit_has_name(u, SPECIAL_ROOT_SLICE))
1961 return strdup(u->manager->cgroup_root);
1963 if (UNIT_ISSET(u->slice) && !unit_has_name(UNIT_DEREF(u->slice), SPECIAL_ROOT_SLICE)) {
1964 r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice);
1969 escaped = cg_escape(u->id);
1974 return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL);
1976 return strjoin(u->manager->cgroup_root, "/", escaped, NULL);
1979 int unit_add_default_slice(Unit *u) {
1980 _cleanup_free_ char *b = NULL;
1981 const char *slice_name;
1987 if (UNIT_ISSET(u->slice))
1990 if (!unit_get_cgroup_context(u))
1994 _cleanup_free_ char *prefix = NULL, *escaped = NULL;
1996 /* Implicitly place all instantiated units in their
1997 * own per-template slice */
1999 prefix = unit_name_to_prefix(u->id);
2003 /* The prefix is already escaped, but it might include
2004 * "-" which has a special meaning for slice units,
2005 * hence escape it here extra. */
2006 escaped = strreplace(prefix, "-", "\\x2d");
2010 if (u->manager->running_as == SYSTEMD_SYSTEM)
2011 b = strjoin("system-", escaped, ".slice", NULL);
2013 b = strappend(escaped, ".slice");
2020 u->manager->running_as == SYSTEMD_SYSTEM
2021 ? SPECIAL_SYSTEM_SLICE
2022 : SPECIAL_ROOT_SLICE;
2024 r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
2028 unit_ref_set(&u->slice, slice);
2032 const char *unit_slice_name(Unit *u) {
2035 if (!UNIT_ISSET(u->slice))
2038 return UNIT_DEREF(u->slice)->id;
2041 int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
2042 _cleanup_free_ char *t = NULL;
2049 t = unit_name_change_suffix(u->id, type);
2053 assert(!unit_has_name(u, t));
2055 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
2056 assert(r < 0 || *_found != u);
2060 int unit_watch_bus_name(Unit *u, const char *name) {
2064 /* Watch a specific name on the bus. We only support one unit
2065 * watching each name for now. */
2067 return hashmap_put(u->manager->watch_bus, name, u);
2070 void unit_unwatch_bus_name(Unit *u, const char *name) {
2074 hashmap_remove_value(u->manager->watch_bus, name, u);
2077 bool unit_can_serialize(Unit *u) {
2080 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2083 int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
2090 if (!unit_can_serialize(u))
2093 r = UNIT_VTABLE(u)->serialize(u, f, fds);
2098 if (serialize_jobs) {
2100 fprintf(f, "job\n");
2101 job_serialize(u->job, f, fds);
2105 fprintf(f, "job\n");
2106 job_serialize(u->nop_job, f, fds);
2110 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2111 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2112 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2113 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2114 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
2116 if (dual_timestamp_is_set(&u->condition_timestamp))
2117 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
2119 unit_serialize_item(u, f, "transient", yes_no(u->transient));
2122 unit_serialize_item(u, f, "cgroup", u->cgroup_path);
2129 void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2140 va_start(ap, format);
2141 vfprintf(f, format, ap);
2147 void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2153 fprintf(f, "%s=%s\n", key, value);
2156 int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
2163 if (!unit_can_serialize(u))
2167 char line[LINE_MAX], *l, *v;
2170 if (!fgets(line, sizeof(line), f)) {
2183 k = strcspn(l, "=");
2191 if (streq(l, "job")) {
2193 /* new-style serialized job */
2194 Job *j = job_new_raw(u);
2198 r = job_deserialize(j, f, fds);
2204 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2210 r = job_install_deserialized(j);
2212 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2217 if (j->state == JOB_RUNNING)
2218 u->manager->n_running_jobs++;
2221 JobType type = job_type_from_string(v);
2223 log_debug("Failed to parse job type value %s", v);
2225 u->deserialized_job = type;
2228 } else if (streq(l, "inactive-exit-timestamp")) {
2229 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
2231 } else if (streq(l, "active-enter-timestamp")) {
2232 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
2234 } else if (streq(l, "active-exit-timestamp")) {
2235 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
2237 } else if (streq(l, "inactive-enter-timestamp")) {
2238 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
2240 } else if (streq(l, "condition-timestamp")) {
2241 dual_timestamp_deserialize(v, &u->condition_timestamp);
2243 } else if (streq(l, "condition-result")) {
2246 b = parse_boolean(v);
2248 log_debug("Failed to parse condition result value %s", v);
2250 u->condition_result = b;
2254 } else if (streq(l, "transient")) {
2257 b = parse_boolean(v);
2259 log_debug("Failed to parse transient bool %s", v);
2264 } else if (streq(l, "cgroup")) {
2271 free(u->cgroup_path);
2274 assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1);
2278 r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds);
2284 int unit_add_node_link(Unit *u, const char *what, bool wants) {
2286 _cleanup_free_ char *e = NULL;
2294 /* Adds in links to the device node that this unit is based on */
2296 if (!is_device_path(what))
2299 e = unit_name_from_path(what, ".device");
2303 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
2308 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
2313 r = unit_add_dependency(device, UNIT_WANTS, u, false);
2321 int unit_coldplug(Unit *u) {
2326 if (UNIT_VTABLE(u)->coldplug)
2327 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2331 r = job_coldplug(u->job);
2334 } else if (u->deserialized_job >= 0) {
2336 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2340 u->deserialized_job = _JOB_TYPE_INVALID;
2346 #pragma GCC diagnostic push
2347 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
2348 void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) {
2349 manager_status_printf(u->manager, false, status, unit_status_msg_format, unit_description(u));
2351 #pragma GCC diagnostic pop
2353 bool unit_need_daemon_reload(Unit *u) {
2354 _cleanup_strv_free_ char **t = NULL;
2357 unsigned loaded_cnt, current_cnt;
2361 if (u->fragment_path) {
2363 if (stat(u->fragment_path, &st) < 0)
2364 /* What, cannot access this anymore? */
2367 if (u->fragment_mtime > 0 &&
2368 timespec_load(&st.st_mtim) != u->fragment_mtime)
2372 if (u->source_path) {
2374 if (stat(u->source_path, &st) < 0)
2377 if (u->source_mtime > 0 &&
2378 timespec_load(&st.st_mtim) != u->source_mtime)
2382 t = unit_find_dropin_paths(u);
2383 loaded_cnt = strv_length(t);
2384 current_cnt = strv_length(u->dropin_paths);
2386 if (loaded_cnt == current_cnt) {
2387 if (loaded_cnt == 0)
2390 if (strv_overlap(u->dropin_paths, t)) {
2391 STRV_FOREACH(path, u->dropin_paths) {
2393 if (stat(*path, &st) < 0)
2396 if (u->dropin_mtime > 0 &&
2397 timespec_load(&st.st_mtim) > u->dropin_mtime)
2408 void unit_reset_failed(Unit *u) {
2411 if (UNIT_VTABLE(u)->reset_failed)
2412 UNIT_VTABLE(u)->reset_failed(u);
2415 Unit *unit_following(Unit *u) {
2418 if (UNIT_VTABLE(u)->following)
2419 return UNIT_VTABLE(u)->following(u);
2424 bool unit_stop_pending(Unit *u) {
2427 /* This call does check the current state of the unit. It's
2428 * hence useful to be called from state change calls of the
2429 * unit itself, where the state isn't updated yet. This is
2430 * different from unit_inactive_or_pending() which checks both
2431 * the current state and for a queued job. */
2433 return u->job && u->job->type == JOB_STOP;
2436 bool unit_inactive_or_pending(Unit *u) {
2439 /* Returns true if the unit is inactive or going down */
2441 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2444 if (unit_stop_pending(u))
2450 bool unit_active_or_pending(Unit *u) {
2453 /* Returns true if the unit is active or going up */
2455 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2459 (u->job->type == JOB_START ||
2460 u->job->type == JOB_RELOAD_OR_START ||
2461 u->job->type == JOB_RESTART))
2467 int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error) {
2469 assert(w >= 0 && w < _KILL_WHO_MAX);
2471 assert(signo < _NSIG);
2473 if (!UNIT_VTABLE(u)->kill)
2476 return UNIT_VTABLE(u)->kill(u, w, signo, error);
2479 static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
2483 pid_set = set_new(trivial_hash_func, trivial_compare_func);
2487 /* Exclude the main/control pids from being killed via the cgroup */
2489 r = set_put(pid_set, LONG_TO_PTR(main_pid));
2494 if (control_pid > 0) {
2495 r = set_put(pid_set, LONG_TO_PTR(control_pid));
2507 int unit_kill_common(
2513 sd_bus_error *error) {
2517 if (who == KILL_MAIN && main_pid <= 0) {
2519 sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
2521 sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
2525 if (who == KILL_CONTROL && control_pid <= 0) {
2526 if (control_pid < 0)
2527 sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
2529 sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
2533 if (who == KILL_CONTROL || who == KILL_ALL)
2534 if (control_pid > 0)
2535 if (kill(control_pid, signo) < 0)
2538 if (who == KILL_MAIN || who == KILL_ALL)
2540 if (kill(main_pid, signo) < 0)
2543 if (who == KILL_ALL && u->cgroup_path) {
2544 _cleanup_set_free_ Set *pid_set = NULL;
2547 /* Exclude the main/control pids from being killed via the cgroup */
2548 pid_set = unit_pid_set(main_pid, control_pid);
2552 q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
2553 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
2560 int unit_following_set(Unit *u, Set **s) {
2564 if (UNIT_VTABLE(u)->following_set)
2565 return UNIT_VTABLE(u)->following_set(u, s);
2571 UnitFileState unit_get_unit_file_state(Unit *u) {
2574 if (u->unit_file_state < 0 && u->fragment_path)
2575 u->unit_file_state = unit_file_get_state(
2576 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
2577 NULL, path_get_file_name(u->fragment_path));
2579 return u->unit_file_state;
2582 Unit* unit_ref_set(UnitRef *ref, Unit *u) {
2587 unit_ref_unset(ref);
2590 LIST_PREPEND(refs, u->refs, ref);
2594 void unit_ref_unset(UnitRef *ref) {
2600 LIST_REMOVE(refs, ref->unit->refs, ref);
2604 int unit_exec_context_defaults(Unit *u, ExecContext *c) {
2611 /* This only copies in the ones that need memory */
2612 for (i = 0; i < RLIMIT_NLIMITS; i++)
2613 if (u->manager->rlimit[i] && !c->rlimit[i]) {
2614 c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
2619 if (u->manager->running_as == SYSTEMD_USER &&
2620 !c->working_directory) {
2622 r = get_home_dir(&c->working_directory);
2630 ExecContext *unit_get_exec_context(Unit *u) {
2634 offset = UNIT_VTABLE(u)->exec_context_offset;
2638 return (ExecContext*) ((uint8_t*) u + offset);
2641 KillContext *unit_get_kill_context(Unit *u) {
2645 offset = UNIT_VTABLE(u)->kill_context_offset;
2649 return (KillContext*) ((uint8_t*) u + offset);
2652 CGroupContext *unit_get_cgroup_context(Unit *u) {
2655 offset = UNIT_VTABLE(u)->cgroup_context_offset;
2659 return (CGroupContext*) ((uint8_t*) u + offset);
2662 static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) {
2663 _cleanup_free_ char *b = NULL;
2671 assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME));
2673 b = xescape(name, "/.");
2677 if (!filename_is_safe(b))
2680 if (u->manager->running_as == SYSTEMD_USER) {
2681 _cleanup_free_ char *c = NULL;
2683 r = user_config_home(&c);
2689 p = strjoin(c, "/", u->id, ".d", NULL);
2690 } else if (mode & UNIT_PERSISTENT)
2691 p = strjoin("/etc/systemd/system/", u->id, ".d", NULL);
2693 p = strjoin("/run/systemd/system/", u->id, ".d", NULL);
2697 q = strjoin(p, "/90-", b, ".conf", NULL);
2708 int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2709 _cleanup_free_ char *p = NULL, *q = NULL;
2716 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2719 r = drop_in_file(u, mode, name, &p, &q);
2724 return write_string_file_atomic_label(q, data);
2727 int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2728 _cleanup_free_ char *p = NULL;
2736 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2739 va_start(ap, format);
2740 r = vasprintf(&p, format, ap);
2746 return unit_write_drop_in(u, mode, name, p);
2749 int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2750 _cleanup_free_ char *ndata = NULL;
2756 if (!UNIT_VTABLE(u)->private_section)
2759 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2762 ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
2766 return unit_write_drop_in(u, mode, name, ndata);
2769 int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2770 _cleanup_free_ char *p = NULL;
2778 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2781 va_start(ap, format);
2782 r = vasprintf(&p, format, ap);
2788 return unit_write_drop_in_private(u, mode, name, p);
2791 int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
2792 _cleanup_free_ char *p = NULL, *q = NULL;
2797 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2800 r = drop_in_file(u, mode, name, &p, &q);
2805 r = errno == ENOENT ? 0 : -errno;
2813 int unit_make_transient(Unit *u) {
2818 u->load_state = UNIT_STUB;
2820 u->transient = true;
2822 free(u->fragment_path);
2823 u->fragment_path = NULL;
2825 if (u->manager->running_as == SYSTEMD_USER) {
2826 _cleanup_free_ char *c = NULL;
2828 r = user_config_home(&c);
2834 u->fragment_path = strjoin(c, "/", u->id, NULL);
2835 if (!u->fragment_path)
2840 u->fragment_path = strappend("/run/systemd/system/", u->id);
2841 if (!u->fragment_path)
2844 mkdir_p("/run/systemd/system", 0755);
2847 return write_string_file_atomic_label(u->fragment_path, "# Transient stub");
2850 int unit_kill_context(
2856 bool main_pid_alien) {
2858 int sig, wait_for_exit = 0, r;
2863 if (c->kill_mode == KILL_NONE)
2866 sig = sigkill ? SIGKILL : c->kill_signal;
2869 r = kill_and_sigcont(main_pid, sig);
2871 if (r < 0 && r != -ESRCH) {
2872 _cleanup_free_ char *comm = NULL;
2873 get_process_comm(main_pid, &comm);
2875 log_warning_unit(u->id, "Failed to kill main process %li (%s): %s",
2876 (long) main_pid, strna(comm), strerror(-r));
2878 wait_for_exit = !main_pid_alien;
2881 kill(main_pid, SIGHUP);
2885 if (control_pid > 0) {
2886 r = kill_and_sigcont(control_pid, sig);
2888 if (r < 0 && r != -ESRCH) {
2889 _cleanup_free_ char *comm = NULL;
2890 get_process_comm(control_pid, &comm);
2892 log_warning_unit(u->id,
2893 "Failed to kill control process %li (%s): %s",
2894 (long) control_pid, strna(comm), strerror(-r));
2896 wait_for_exit = true;
2899 kill(control_pid, SIGHUP);
2903 if (c->kill_mode == KILL_CONTROL_GROUP && u->cgroup_path) {
2904 _cleanup_set_free_ Set *pid_set = NULL;
2906 /* Exclude the main/control pids from being killed via the cgroup */
2907 pid_set = unit_pid_set(main_pid, control_pid);
2911 r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set);
2913 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
2914 log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
2916 wait_for_exit = true;
2917 if (c->send_sighup) {
2920 pid_set = unit_pid_set(main_pid, control_pid);
2924 cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, SIGHUP, true, true, false, pid_set);
2929 return wait_for_exit;
2932 int unit_require_mounts_for(Unit *u, const char *path) {
2933 char prefix[strlen(path) + 1], *p;
2939 /* Registers a unit for requiring a certain path and all its
2940 * prefixes. We keep a simple array of these paths in the
2941 * unit, since its usually short. However, we build a prefix
2942 * table for all possible prefixes so that new appearing mount
2943 * units can easily determine which units to make themselves a
2950 path_kill_slashes(p);
2952 if (!path_is_absolute(p)) {
2957 if (!path_is_safe(p)) {
2962 if (strv_contains(u->requires_mounts_for, p)) {
2967 r = strv_push(&u->requires_mounts_for, p);
2973 PATH_FOREACH_PREFIX_MORE(prefix, p) {
2976 x = hashmap_get(u->manager->units_requiring_mounts_for, prefix);
2980 if (!u->manager->units_requiring_mounts_for) {
2981 u->manager->units_requiring_mounts_for = hashmap_new(string_hash_func, string_compare_func);
2982 if (!u->manager->units_requiring_mounts_for)
2990 x = set_new(NULL, NULL);
2996 r = hashmap_put(u->manager->units_requiring_mounts_for, q, x);
3012 static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
3013 [UNIT_ACTIVE] = "active",
3014 [UNIT_RELOADING] = "reloading",
3015 [UNIT_INACTIVE] = "inactive",
3016 [UNIT_FAILED] = "failed",
3017 [UNIT_ACTIVATING] = "activating",
3018 [UNIT_DEACTIVATING] = "deactivating"
3021 DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
3023 static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
3024 [UNIT_REQUIRES] = "Requires",
3025 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
3026 [UNIT_REQUISITE] = "Requisite",
3027 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
3028 [UNIT_WANTS] = "Wants",
3029 [UNIT_BINDS_TO] = "BindsTo",
3030 [UNIT_PART_OF] = "PartOf",
3031 [UNIT_REQUIRED_BY] = "RequiredBy",
3032 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
3033 [UNIT_WANTED_BY] = "WantedBy",
3034 [UNIT_BOUND_BY] = "BoundBy",
3035 [UNIT_CONSISTS_OF] = "ConsistsOf",
3036 [UNIT_CONFLICTS] = "Conflicts",
3037 [UNIT_CONFLICTED_BY] = "ConflictedBy",
3038 [UNIT_BEFORE] = "Before",
3039 [UNIT_AFTER] = "After",
3040 [UNIT_ON_FAILURE] = "OnFailure",
3041 [UNIT_TRIGGERS] = "Triggers",
3042 [UNIT_TRIGGERED_BY] = "TriggeredBy",
3043 [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
3044 [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
3045 [UNIT_REFERENCES] = "References",
3046 [UNIT_REFERENCED_BY] = "ReferencedBy",
3049 DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);