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"
54 const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
55 [UNIT_SERVICE] = &service_vtable,
56 [UNIT_SOCKET] = &socket_vtable,
57 [UNIT_BUSNAME] = &busname_vtable,
58 [UNIT_TARGET] = &target_vtable,
59 [UNIT_SNAPSHOT] = &snapshot_vtable,
60 [UNIT_DEVICE] = &device_vtable,
61 [UNIT_MOUNT] = &mount_vtable,
62 [UNIT_AUTOMOUNT] = &automount_vtable,
63 [UNIT_SWAP] = &swap_vtable,
64 [UNIT_TIMER] = &timer_vtable,
65 [UNIT_PATH] = &path_vtable,
66 [UNIT_SLICE] = &slice_vtable,
67 [UNIT_SCOPE] = &scope_vtable
70 Unit *unit_new(Manager *m, size_t size) {
74 assert(size >= sizeof(Unit));
80 u->names = set_new(string_hash_func, string_compare_func);
87 u->type = _UNIT_TYPE_INVALID;
88 u->deserialized_job = _JOB_TYPE_INVALID;
89 u->default_dependencies = true;
90 u->unit_file_state = _UNIT_FILE_STATE_INVALID;
91 u->on_failure_job_mode = JOB_REPLACE;
96 bool unit_has_name(Unit *u, const char *name) {
100 return !!set_get(u->names, (char*) name);
103 int unit_add_name(Unit *u, const char *text) {
111 if (unit_name_is_template(text)) {
115 s = unit_name_replace_instance(text, u->instance);
122 if (!unit_name_is_valid(s, false)) {
127 assert_se((t = unit_name_to_type(s)) >= 0);
129 if (u->type != _UNIT_TYPE_INVALID && t != u->type) {
134 r = unit_name_to_instance(s, &i);
138 if (i && unit_vtable[t]->no_instances) {
143 /* Ensure that this unit is either instanced or not instanced,
145 if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) {
150 if (unit_vtable[t]->no_alias &&
151 !set_isempty(u->names) &&
152 !set_get(u->names, s)) {
157 if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) {
162 r = set_put(u->names, s);
169 r = hashmap_put(u->manager->units, s, u);
171 set_remove(u->names, s);
175 if (u->type == _UNIT_TYPE_INVALID) {
181 LIST_PREPEND(units_by_type, u->manager->units_by_type[t], u);
183 if (UNIT_VTABLE(u)->init)
184 UNIT_VTABLE(u)->init(u);
188 unit_add_to_dbus_queue(u);
198 int unit_choose_id(Unit *u, const char *name) {
200 _cleanup_free_ char *t = NULL;
206 if (unit_name_is_template(name)) {
211 t = unit_name_replace_instance(name, u->instance);
218 /* Selects one of the names of this unit as the id */
219 s = set_get(u->names, (char*) name);
224 r = unit_name_to_instance(s, &i);
233 unit_add_to_dbus_queue(u);
238 int unit_set_description(Unit *u, const char *description) {
243 if (isempty(description))
246 s = strdup(description);
251 free(u->description);
254 unit_add_to_dbus_queue(u);
258 bool unit_check_gc(Unit *u) {
261 if (u->load_state == UNIT_STUB)
264 if (UNIT_VTABLE(u)->no_gc)
276 if (unit_active_state(u) != UNIT_INACTIVE)
282 if (UNIT_VTABLE(u)->check_gc)
283 if (UNIT_VTABLE(u)->check_gc(u))
289 void unit_add_to_load_queue(Unit *u) {
291 assert(u->type != _UNIT_TYPE_INVALID);
293 if (u->load_state != UNIT_STUB || u->in_load_queue)
296 LIST_PREPEND(load_queue, u->manager->load_queue, u);
297 u->in_load_queue = true;
300 void unit_add_to_cleanup_queue(Unit *u) {
303 if (u->in_cleanup_queue)
306 LIST_PREPEND(cleanup_queue, u->manager->cleanup_queue, u);
307 u->in_cleanup_queue = true;
310 void unit_add_to_gc_queue(Unit *u) {
313 if (u->in_gc_queue || u->in_cleanup_queue)
316 if (unit_check_gc(u))
319 LIST_PREPEND(gc_queue, u->manager->gc_queue, u);
320 u->in_gc_queue = true;
322 u->manager->n_in_gc_queue ++;
325 void unit_add_to_dbus_queue(Unit *u) {
327 assert(u->type != _UNIT_TYPE_INVALID);
329 if (u->load_state == UNIT_STUB || u->in_dbus_queue)
332 /* Shortcut things if nobody cares */
333 if (set_isempty(u->manager->subscribed)) {
334 u->sent_dbus_new_signal = true;
338 LIST_PREPEND(dbus_queue, u->manager->dbus_unit_queue, u);
339 u->in_dbus_queue = true;
342 static void bidi_set_free(Unit *u, Set *s) {
348 /* Frees the set and makes sure we are dropped from the
349 * inverse pointers */
351 SET_FOREACH(other, s, i) {
354 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
355 set_remove(other->dependencies[d], u);
357 unit_add_to_gc_queue(other);
363 static void unit_remove_transient(Unit *u) {
371 if (u->fragment_path)
372 unlink(u->fragment_path);
374 STRV_FOREACH(i, u->dropin_paths) {
375 _cleanup_free_ char *p = NULL;
380 r = path_get_parent(*i, &p);
386 static void unit_free_requires_mounts_for(Unit *u) {
389 STRV_FOREACH(j, u->requires_mounts_for) {
390 char s[strlen(*j) + 1];
392 PATH_FOREACH_PREFIX_MORE(s, *j) {
396 x = hashmap_get2(u->manager->units_requiring_mounts_for, s, (void**) &y);
402 if (set_isempty(x)) {
403 hashmap_remove(u->manager->units_requiring_mounts_for, y);
410 strv_free(u->requires_mounts_for);
411 u->requires_mounts_for = NULL;
414 void unit_free(Unit *u) {
421 if (u->manager->n_reloading <= 0)
422 unit_remove_transient(u);
424 bus_unit_send_removed_signal(u);
426 if (u->load_state != UNIT_STUB)
427 if (UNIT_VTABLE(u)->done)
428 UNIT_VTABLE(u)->done(u);
430 unit_free_requires_mounts_for(u);
432 SET_FOREACH(t, u->names, i)
433 hashmap_remove_value(u->manager->units, t, u);
447 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
448 bidi_set_free(u, u->dependencies[d]);
450 if (u->type != _UNIT_TYPE_INVALID)
451 LIST_REMOVE(units_by_type, u->manager->units_by_type[u->type], u);
453 if (u->in_load_queue)
454 LIST_REMOVE(load_queue, u->manager->load_queue, u);
456 if (u->in_dbus_queue)
457 LIST_REMOVE(dbus_queue, u->manager->dbus_unit_queue, u);
459 if (u->in_cleanup_queue)
460 LIST_REMOVE(cleanup_queue, u->manager->cleanup_queue, u);
462 if (u->in_gc_queue) {
463 LIST_REMOVE(gc_queue, u->manager->gc_queue, u);
464 u->manager->n_in_gc_queue--;
467 if (u->in_cgroup_queue)
468 LIST_REMOVE(cgroup_queue, u->manager->cgroup_queue, u);
470 if (u->cgroup_path) {
471 hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
472 free(u->cgroup_path);
475 free(u->description);
476 strv_free(u->documentation);
477 free(u->fragment_path);
478 free(u->source_path);
479 strv_free(u->dropin_paths);
482 set_free_free(u->names);
484 condition_free_list(u->conditions);
486 unit_ref_unset(&u->slice);
489 unit_ref_unset(u->refs);
494 UnitActiveState unit_active_state(Unit *u) {
497 if (u->load_state == UNIT_MERGED)
498 return unit_active_state(unit_follow_merge(u));
500 /* After a reload it might happen that a unit is not correctly
501 * loaded but still has a process around. That's why we won't
502 * shortcut failed loading to UNIT_INACTIVE_FAILED. */
504 return UNIT_VTABLE(u)->active_state(u);
507 const char* unit_sub_state_to_string(Unit *u) {
510 return UNIT_VTABLE(u)->sub_state_to_string(u);
513 static void complete_move(Set **s, Set **other) {
521 set_move(*s, *other);
528 static void merge_names(Unit *u, Unit *other) {
535 complete_move(&u->names, &other->names);
537 set_free_free(other->names);
541 SET_FOREACH(t, u->names, i)
542 assert_se(hashmap_replace(u->manager->units, t, u) == 0);
545 static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
552 assert(d < _UNIT_DEPENDENCY_MAX);
554 /* Fix backwards pointers */
555 SET_FOREACH(back, other->dependencies[d], i) {
558 for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++) {
559 r = set_remove_and_put(back->dependencies[k], other, u);
561 set_remove(back->dependencies[k], other);
563 assert(r >= 0 || r == -ENOENT);
567 complete_move(&u->dependencies[d], &other->dependencies[d]);
569 set_free(other->dependencies[d]);
570 other->dependencies[d] = NULL;
573 int unit_merge(Unit *u, Unit *other) {
578 assert(u->manager == other->manager);
579 assert(u->type != _UNIT_TYPE_INVALID);
581 other = unit_follow_merge(other);
586 if (u->type != other->type)
589 if (!u->instance != !other->instance)
592 if (other->load_state != UNIT_STUB &&
593 other->load_state != UNIT_NOT_FOUND)
602 if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
606 merge_names(u, other);
608 /* Redirect all references */
610 unit_ref_set(other->refs, u);
612 /* Merge dependencies */
613 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
614 merge_dependencies(u, other, d);
616 other->load_state = UNIT_MERGED;
617 other->merged_into = u;
619 /* If there is still some data attached to the other node, we
620 * don't need it anymore, and can free it. */
621 if (other->load_state != UNIT_STUB)
622 if (UNIT_VTABLE(other)->done)
623 UNIT_VTABLE(other)->done(other);
625 unit_add_to_dbus_queue(u);
626 unit_add_to_cleanup_queue(other);
631 int unit_merge_by_name(Unit *u, const char *name) {
634 _cleanup_free_ char *s = NULL;
639 if (unit_name_is_template(name)) {
643 s = unit_name_replace_instance(name, u->instance);
650 other = manager_get_unit(u->manager, name);
652 r = unit_add_name(u, name);
654 r = unit_merge(u, other);
659 Unit* unit_follow_merge(Unit *u) {
662 while (u->load_state == UNIT_MERGED)
663 assert_se(u = u->merged_into);
668 int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
674 if (c->std_output != EXEC_OUTPUT_KMSG &&
675 c->std_output != EXEC_OUTPUT_SYSLOG &&
676 c->std_output != EXEC_OUTPUT_JOURNAL &&
677 c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
678 c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
679 c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
680 c->std_error != EXEC_OUTPUT_KMSG &&
681 c->std_error != EXEC_OUTPUT_SYSLOG &&
682 c->std_error != EXEC_OUTPUT_JOURNAL &&
683 c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
684 c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
685 c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE)
688 /* If syslog or kernel logging is requested, make sure our own
689 * logging daemon is run first. */
691 if (u->manager->running_as == SYSTEMD_SYSTEM) {
692 r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true);
700 const char *unit_description(Unit *u) {
704 return u->description;
709 void unit_dump(Unit *u, FILE *f, const char *prefix) {
713 _cleanup_free_ char *p2 = NULL;
716 timestamp1[FORMAT_TIMESTAMP_MAX],
717 timestamp2[FORMAT_TIMESTAMP_MAX],
718 timestamp3[FORMAT_TIMESTAMP_MAX],
719 timestamp4[FORMAT_TIMESTAMP_MAX],
720 timespan[FORMAT_TIMESPAN_MAX];
722 _cleanup_set_free_ Set *following_set = NULL;
726 assert(u->type >= 0);
730 p2 = strappend(prefix, "\t");
731 prefix2 = p2 ? p2 : prefix;
735 "%s\tDescription: %s\n"
737 "%s\tUnit Load State: %s\n"
738 "%s\tUnit Active State: %s\n"
739 "%s\tInactive Exit Timestamp: %s\n"
740 "%s\tActive Enter Timestamp: %s\n"
741 "%s\tActive Exit Timestamp: %s\n"
742 "%s\tInactive Enter Timestamp: %s\n"
743 "%s\tGC Check Good: %s\n"
744 "%s\tNeed Daemon Reload: %s\n"
745 "%s\tTransient: %s\n"
748 "%s\tCGroup realized: %s\n"
749 "%s\tCGroup mask: 0x%x\n"
750 "%s\tCGroup members mask: 0x%x\n",
752 prefix, unit_description(u),
753 prefix, strna(u->instance),
754 prefix, unit_load_state_to_string(u->load_state),
755 prefix, unit_active_state_to_string(unit_active_state(u)),
756 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->inactive_exit_timestamp.realtime)),
757 prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->active_enter_timestamp.realtime)),
758 prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)),
759 prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)),
760 prefix, yes_no(unit_check_gc(u)),
761 prefix, yes_no(unit_need_daemon_reload(u)),
762 prefix, yes_no(u->transient),
763 prefix, strna(unit_slice_name(u)),
764 prefix, strna(u->cgroup_path),
765 prefix, yes_no(u->cgroup_realized),
766 prefix, u->cgroup_mask,
767 prefix, u->cgroup_members_mask);
769 SET_FOREACH(t, u->names, i)
770 fprintf(f, "%s\tName: %s\n", prefix, t);
772 STRV_FOREACH(j, u->documentation)
773 fprintf(f, "%s\tDocumentation: %s\n", prefix, *j);
775 following = unit_following(u);
777 fprintf(f, "%s\tFollowing: %s\n", prefix, following->id);
779 r = unit_following_set(u, &following_set);
783 SET_FOREACH(other, following_set, i)
784 fprintf(f, "%s\tFollowing Set Member: %s\n", prefix, other->id);
787 if (u->fragment_path)
788 fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path);
791 fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path);
793 STRV_FOREACH(j, u->dropin_paths)
794 fprintf(f, "%s\tDropIn Path: %s\n", prefix, *j);
796 if (u->job_timeout > 0)
797 fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
799 condition_dump_list(u->conditions, f, prefix);
801 if (dual_timestamp_is_set(&u->condition_timestamp))
803 "%s\tCondition Timestamp: %s\n"
804 "%s\tCondition Result: %s\n",
805 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->condition_timestamp.realtime)),
806 prefix, yes_no(u->condition_result));
808 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
811 SET_FOREACH(other, u->dependencies[d], i)
812 fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
815 if (!strv_isempty(u->requires_mounts_for)) {
817 "%s\tRequiresMountsFor:", prefix);
819 STRV_FOREACH(j, u->requires_mounts_for)
820 fprintf(f, " %s", *j);
825 if (u->load_state == UNIT_LOADED) {
828 "%s\tStopWhenUnneeded: %s\n"
829 "%s\tRefuseManualStart: %s\n"
830 "%s\tRefuseManualStop: %s\n"
831 "%s\tDefaultDependencies: %s\n"
832 "%s\tOnFailureJobMode: %s\n"
833 "%s\tIgnoreOnIsolate: %s\n"
834 "%s\tIgnoreOnSnapshot: %s\n",
835 prefix, yes_no(u->stop_when_unneeded),
836 prefix, yes_no(u->refuse_manual_start),
837 prefix, yes_no(u->refuse_manual_stop),
838 prefix, yes_no(u->default_dependencies),
839 prefix, job_mode_to_string(u->on_failure_job_mode),
840 prefix, yes_no(u->ignore_on_isolate),
841 prefix, yes_no(u->ignore_on_snapshot));
843 if (UNIT_VTABLE(u)->dump)
844 UNIT_VTABLE(u)->dump(u, f, prefix2);
846 } else if (u->load_state == UNIT_MERGED)
848 "%s\tMerged into: %s\n",
849 prefix, u->merged_into->id);
850 else if (u->load_state == UNIT_ERROR)
851 fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->load_error));
855 job_dump(u->job, f, prefix2);
858 job_dump(u->nop_job, f, prefix2);
862 /* Common implementation for multiple backends */
863 int unit_load_fragment_and_dropin(Unit *u) {
868 /* Load a .{service,socket,...} file */
869 r = unit_load_fragment(u);
873 if (u->load_state == UNIT_STUB)
876 /* Load drop-in directory data */
877 r = unit_load_dropin(unit_follow_merge(u));
884 /* Common implementation for multiple backends */
885 int unit_load_fragment_and_dropin_optional(Unit *u) {
890 /* Same as unit_load_fragment_and_dropin(), but whether
891 * something can be loaded or not doesn't matter. */
893 /* Load a .service file */
894 r = unit_load_fragment(u);
898 if (u->load_state == UNIT_STUB)
899 u->load_state = UNIT_LOADED;
901 /* Load drop-in directory data */
902 r = unit_load_dropin(unit_follow_merge(u));
909 int unit_add_default_target_dependency(Unit *u, Unit *target) {
913 if (target->type != UNIT_TARGET)
916 /* Only add the dependency if both units are loaded, so that
917 * that loop check below is reliable */
918 if (u->load_state != UNIT_LOADED ||
919 target->load_state != UNIT_LOADED)
922 /* If either side wants no automatic dependencies, then let's
924 if (!u->default_dependencies ||
925 !target->default_dependencies)
928 /* Don't create loops */
929 if (set_get(target->dependencies[UNIT_BEFORE], u))
932 return unit_add_dependency(target, UNIT_AFTER, u, true);
935 static int unit_add_default_dependencies(Unit *u) {
937 static const UnitDependency deps[] = {
939 UNIT_REQUIRED_BY_OVERRIDABLE,
951 for (k = 0; k < ELEMENTSOF(deps); k++)
952 SET_FOREACH(target, u->dependencies[deps[k]], i) {
953 r = unit_add_default_target_dependency(u, target);
958 if (u->default_dependencies && unit_get_cgroup_context(u)) {
959 if (UNIT_ISSET(u->slice))
960 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true);
962 r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, SPECIAL_ROOT_SLICE, NULL, true);
971 static int unit_add_mount_links(Unit *u) {
977 STRV_FOREACH(i, u->requires_mounts_for) {
978 char prefix[strlen(*i) + 1];
980 PATH_FOREACH_PREFIX_MORE(prefix, *i) {
983 r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m);
991 if (m->load_state != UNIT_LOADED)
994 r = unit_add_dependency(u, UNIT_AFTER, m, true);
998 if (m->fragment_path) {
999 r = unit_add_dependency(u, UNIT_REQUIRES, m, true);
1009 int unit_load(Unit *u) {
1014 if (u->in_load_queue) {
1015 LIST_REMOVE(load_queue, u->manager->load_queue, u);
1016 u->in_load_queue = false;
1019 if (u->type == _UNIT_TYPE_INVALID)
1022 if (u->load_state != UNIT_STUB)
1025 if (UNIT_VTABLE(u)->load) {
1026 r = UNIT_VTABLE(u)->load(u);
1031 if (u->load_state == UNIT_STUB) {
1036 if (u->load_state == UNIT_LOADED) {
1038 if (u->default_dependencies) {
1039 r = unit_add_default_dependencies(u);
1044 unit_update_member_masks(u);
1046 r = unit_add_mount_links(u);
1050 if (u->on_failure_job_mode == JOB_ISOLATE &&
1051 set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
1053 log_error_unit(u->id,
1054 "More than one OnFailure= dependencies specified for %s but OnFailureJobMode=isolate set. Refusing.", u->id);
1061 assert((u->load_state != UNIT_MERGED) == !u->merged_into);
1063 unit_add_to_dbus_queue(unit_follow_merge(u));
1064 unit_add_to_gc_queue(u);
1069 u->load_state = u->load_state == UNIT_STUB ? UNIT_NOT_FOUND : UNIT_ERROR;
1071 unit_add_to_dbus_queue(u);
1072 unit_add_to_gc_queue(u);
1074 log_debug_unit(u->id, "Failed to load configuration for %s: %s",
1075 u->id, strerror(-r));
1080 static bool unit_condition_test(Unit *u) {
1083 dual_timestamp_get(&u->condition_timestamp);
1084 u->condition_result = condition_test_list(u->id, u->conditions);
1086 return u->condition_result;
1089 _pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
1090 const UnitStatusMessageFormats *format_table;
1094 assert(t < _JOB_TYPE_MAX);
1096 if (t != JOB_START && t != JOB_STOP)
1099 format_table = &UNIT_VTABLE(u)->status_message_formats;
1103 return format_table->starting_stopping[t == JOB_STOP];
1106 _pure_ static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) {
1111 assert(t < _JOB_TYPE_MAX);
1113 format = unit_get_status_message_format(u, t);
1117 /* Return generic strings */
1119 return "Starting %s.";
1120 else if (t == JOB_STOP)
1121 return "Stopping %s.";
1122 else if (t == JOB_RELOAD)
1123 return "Reloading %s.";
1128 static void unit_status_print_starting_stopping(Unit *u, JobType t) {
1133 /* We only print status messages for selected units on
1134 * selected operations. */
1136 format = unit_get_status_message_format(u, t);
1140 unit_status_printf(u, "", format);
1143 #pragma GCC diagnostic push
1144 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
1145 static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
1152 if (t != JOB_START && t != JOB_STOP && t != JOB_RELOAD)
1155 if (log_on_console())
1158 /* We log status messages for all units and all operations. */
1160 format = unit_get_status_message_format_try_harder(u, t);
1164 snprintf(buf, sizeof(buf), format, unit_description(u));
1167 mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
1168 t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
1169 SD_MESSAGE_UNIT_RELOADING;
1171 log_struct_unit(LOG_INFO,
1177 #pragma GCC diagnostic pop
1180 * -EBADR: This unit type does not support starting.
1181 * -EALREADY: Unit is already started.
1182 * -EAGAIN: An operation is already in progress. Retry later.
1183 * -ECANCELED: Too many requests for now.
1185 int unit_start(Unit *u) {
1186 UnitActiveState state;
1191 if (u->load_state != UNIT_LOADED)
1194 /* If this is already started, then this will succeed. Note
1195 * that this will even succeed if this unit is not startable
1196 * by the user. This is relied on to detect when we need to
1197 * wait for units and when waiting is finished. */
1198 state = unit_active_state(u);
1199 if (UNIT_IS_ACTIVE_OR_RELOADING(state))
1202 /* If the conditions failed, don't do anything at all. If we
1203 * already are activating this call might still be useful to
1204 * speed up activation in case there is some hold-off time,
1205 * but we don't want to recheck the condition in that case. */
1206 if (state != UNIT_ACTIVATING &&
1207 !unit_condition_test(u)) {
1208 log_debug_unit(u->id, "Starting of %s requested but condition failed. Ignoring.", u->id);
1212 /* Forward to the main object, if we aren't it. */
1213 following = unit_following(u);
1215 log_debug_unit(u->id, "Redirecting start request from %s to %s.",
1216 u->id, following->id);
1217 return unit_start(following);
1220 unit_status_log_starting_stopping_reloading(u, JOB_START);
1221 unit_status_print_starting_stopping(u, JOB_START);
1223 /* If it is stopped, but we cannot start it, then fail */
1224 if (!UNIT_VTABLE(u)->start)
1227 /* We don't suppress calls to ->start() here when we are
1228 * already starting, to allow this request to be used as a
1229 * "hurry up" call, for example when the unit is in some "auto
1230 * restart" state where it waits for a holdoff timer to elapse
1231 * before it will start again. */
1233 unit_add_to_dbus_queue(u);
1235 return UNIT_VTABLE(u)->start(u);
1238 bool unit_can_start(Unit *u) {
1241 return !!UNIT_VTABLE(u)->start;
1244 bool unit_can_isolate(Unit *u) {
1247 return unit_can_start(u) &&
1252 * -EBADR: This unit type does not support stopping.
1253 * -EALREADY: Unit is already stopped.
1254 * -EAGAIN: An operation is already in progress. Retry later.
1256 int unit_stop(Unit *u) {
1257 UnitActiveState state;
1262 state = unit_active_state(u);
1263 if (UNIT_IS_INACTIVE_OR_FAILED(state))
1266 if ((following = unit_following(u))) {
1267 log_debug_unit(u->id, "Redirecting stop request from %s to %s.",
1268 u->id, following->id);
1269 return unit_stop(following);
1272 unit_status_log_starting_stopping_reloading(u, JOB_STOP);
1273 unit_status_print_starting_stopping(u, JOB_STOP);
1275 if (!UNIT_VTABLE(u)->stop)
1278 unit_add_to_dbus_queue(u);
1280 return UNIT_VTABLE(u)->stop(u);
1284 * -EBADR: This unit type does not support reloading.
1285 * -ENOEXEC: Unit is not started.
1286 * -EAGAIN: An operation is already in progress. Retry later.
1288 int unit_reload(Unit *u) {
1289 UnitActiveState state;
1294 if (u->load_state != UNIT_LOADED)
1297 if (!unit_can_reload(u))
1300 state = unit_active_state(u);
1301 if (state == UNIT_RELOADING)
1304 if (state != UNIT_ACTIVE)
1307 following = unit_following(u);
1309 log_debug_unit(u->id, "Redirecting reload request from %s to %s.",
1310 u->id, following->id);
1311 return unit_reload(following);
1314 unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
1316 unit_add_to_dbus_queue(u);
1317 return UNIT_VTABLE(u)->reload(u);
1320 bool unit_can_reload(Unit *u) {
1323 if (!UNIT_VTABLE(u)->reload)
1326 if (!UNIT_VTABLE(u)->can_reload)
1329 return UNIT_VTABLE(u)->can_reload(u);
1332 static void unit_check_unneeded(Unit *u) {
1338 /* If this service shall be shut down when unneeded then do
1341 if (!u->stop_when_unneeded)
1344 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1347 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
1348 if (unit_active_or_pending(other))
1351 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
1352 if (unit_active_or_pending(other))
1355 SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
1356 if (unit_active_or_pending(other))
1359 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1360 if (unit_active_or_pending(other))
1363 log_info_unit(u->id, "Service %s is not needed anymore. Stopping.", u->id);
1365 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
1366 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
1369 static void retroactively_start_dependencies(Unit *u) {
1374 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1376 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1377 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1378 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1379 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1381 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1382 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1383 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1384 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1386 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1387 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1388 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1389 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1391 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1392 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1393 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1394 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1396 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
1397 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1398 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1400 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
1401 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1402 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1405 static void retroactively_stop_dependencies(Unit *u) {
1410 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1412 /* Pull down units which are bound to us recursively if enabled */
1413 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1414 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1415 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1418 static void check_unneeded_dependencies(Unit *u) {
1423 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1425 /* Garbage collect services that might not be needed anymore, if enabled */
1426 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1427 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1428 unit_check_unneeded(other);
1429 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1430 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1431 unit_check_unneeded(other);
1432 SET_FOREACH(other, u->dependencies[UNIT_WANTS], 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], i)
1436 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1437 unit_check_unneeded(other);
1438 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
1439 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1440 unit_check_unneeded(other);
1441 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1442 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1443 unit_check_unneeded(other);
1446 void unit_start_on_failure(Unit *u) {
1452 if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
1455 log_info_unit(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
1457 SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
1460 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_job_mode, true, NULL, NULL);
1462 log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
1466 void unit_trigger_notify(Unit *u) {
1472 SET_FOREACH(other, u->dependencies[UNIT_TRIGGERED_BY], i)
1473 if (UNIT_VTABLE(other)->trigger_notify)
1474 UNIT_VTABLE(other)->trigger_notify(other, u);
1477 void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
1482 assert(os < _UNIT_ACTIVE_STATE_MAX);
1483 assert(ns < _UNIT_ACTIVE_STATE_MAX);
1485 /* Note that this is called for all low-level state changes,
1486 * even if they might map to the same high-level
1487 * UnitActiveState! That means that ns == os is OK an expected
1488 * behavior here. For example: if a mount point is remounted
1489 * this function will be called too! */
1493 if (m->n_reloading <= 0) {
1496 dual_timestamp_get(&ts);
1498 if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
1499 u->inactive_exit_timestamp = ts;
1500 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
1501 u->inactive_enter_timestamp = ts;
1503 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
1504 u->active_enter_timestamp = ts;
1505 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
1506 u->active_exit_timestamp = ts;
1509 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1510 unit_destroy_cgroup(u);
1512 /* Note that this doesn't apply to RemainAfterExit services exiting
1513 * sucessfully, since there's no change of state in that case. Which is
1514 * why it is handled in service_set_state() */
1515 if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1516 ExecContext *ec = unit_get_exec_context(u);
1517 if (ec && exec_context_may_touch_console(ec)) {
1518 if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1521 if (m->n_on_console == 0)
1522 /* unset no_console_output flag, since the console is free */
1523 m->no_console_output = false;
1532 if (u->job->state == JOB_WAITING)
1534 /* So we reached a different state for this
1535 * job. Let's see if we can run it now if it
1536 * failed previously due to EAGAIN. */
1537 job_add_to_run_queue(u->job);
1539 /* Let's check whether this state change constitutes a
1540 * finished job, or maybe contradicts a running job and
1541 * hence needs to invalidate jobs. */
1543 switch (u->job->type) {
1546 case JOB_VERIFY_ACTIVE:
1548 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
1549 job_finish_and_invalidate(u->job, JOB_DONE, true);
1550 else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
1553 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1554 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1560 case JOB_RELOAD_OR_START:
1562 if (u->job->state == JOB_RUNNING) {
1563 if (ns == UNIT_ACTIVE)
1564 job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
1565 else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
1568 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1569 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1577 case JOB_TRY_RESTART:
1579 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1580 job_finish_and_invalidate(u->job, JOB_DONE, true);
1581 else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
1583 job_finish_and_invalidate(u->job, JOB_FAILED, true);
1589 assert_not_reached("Job type unknown");
1595 if (m->n_reloading <= 0) {
1597 /* If this state change happened without being
1598 * requested by a job, then let's retroactively start
1599 * or stop dependencies. We skip that step when
1600 * deserializing, since we don't want to create any
1601 * additional jobs just because something is already
1605 if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1606 retroactively_start_dependencies(u);
1607 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1608 retroactively_stop_dependencies(u);
1611 /* stop unneeded units regardless if going down was expected or not */
1612 if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1613 check_unneeded_dependencies(u);
1615 if (ns != os && ns == UNIT_FAILED) {
1616 log_notice_unit(u->id,
1617 "Unit %s entered failed state.", u->id);
1618 unit_start_on_failure(u);
1622 /* Some names are special */
1623 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
1625 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
1626 /* The bus just might have become available,
1627 * hence try to connect to it, if we aren't
1631 if (u->type == UNIT_SERVICE &&
1632 !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
1633 m->n_reloading <= 0) {
1634 /* Write audit record if we have just finished starting up */
1635 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
1639 if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
1640 manager_send_unit_plymouth(m, u);
1644 /* We don't care about D-Bus here, since we'll get an
1645 * asynchronous notification for it anyway. */
1647 if (u->type == UNIT_SERVICE &&
1648 UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1649 !UNIT_IS_INACTIVE_OR_FAILED(os) &&
1650 m->n_reloading <= 0) {
1652 /* Hmm, if there was no start record written
1653 * write it now, so that we always have a nice
1656 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
1658 if (ns == UNIT_INACTIVE)
1659 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
1661 /* Write audit record if we have just finished shutting down */
1662 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
1664 u->in_audit = false;
1668 manager_recheck_journal(m);
1669 unit_trigger_notify(u);
1671 /* Maybe we finished startup and are now ready for being
1672 * stopped because unneeded? */
1673 if (u->manager->n_reloading <= 0)
1674 unit_check_unneeded(u);
1676 unit_add_to_dbus_queue(u);
1677 unit_add_to_gc_queue(u);
1680 int unit_watch_pid(Unit *u, pid_t pid) {
1684 /* Watch a specific PID. We only support one unit watching
1685 * each PID for now. */
1687 return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1690 void unit_unwatch_pid(Unit *u, pid_t pid) {
1694 hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1697 bool unit_job_is_applicable(Unit *u, JobType j) {
1699 assert(j >= 0 && j < _JOB_TYPE_MAX);
1703 case JOB_VERIFY_ACTIVE:
1710 case JOB_TRY_RESTART:
1711 return unit_can_start(u);
1714 return unit_can_reload(u);
1716 case JOB_RELOAD_OR_START:
1717 return unit_can_reload(u) && unit_can_start(u);
1720 assert_not_reached("Invalid job type");
1724 int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
1726 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
1727 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
1728 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1729 [UNIT_WANTS] = UNIT_WANTED_BY,
1730 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
1731 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1732 [UNIT_BINDS_TO] = UNIT_BOUND_BY,
1733 [UNIT_PART_OF] = UNIT_CONSISTS_OF,
1734 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
1735 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
1736 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
1737 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
1738 [UNIT_CONSISTS_OF] = UNIT_PART_OF,
1739 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
1740 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
1741 [UNIT_BEFORE] = UNIT_AFTER,
1742 [UNIT_AFTER] = UNIT_BEFORE,
1743 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
1744 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
1745 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
1746 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
1747 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
1748 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
1749 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
1750 [UNIT_JOINS_NAMESPACE_OF] = UNIT_JOINS_NAMESPACE_OF,
1752 int r, q = 0, v = 0, w = 0;
1755 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
1758 u = unit_follow_merge(u);
1759 other = unit_follow_merge(other);
1761 /* We won't allow dependencies on ourselves. We will not
1762 * consider them an error however. */
1766 r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func);
1770 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID) {
1771 r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func);
1776 if (add_reference) {
1777 r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func);
1781 r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func);
1786 q = set_put(u->dependencies[d], other);
1790 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID && inverse_table[d] != d) {
1791 v = set_put(other->dependencies[inverse_table[d]], u);
1798 if (add_reference) {
1799 w = set_put(u->dependencies[UNIT_REFERENCES], other);
1805 r = set_put(other->dependencies[UNIT_REFERENCED_BY], u);
1810 unit_add_to_dbus_queue(u);
1815 set_remove(u->dependencies[d], other);
1818 set_remove(other->dependencies[inverse_table[d]], u);
1821 set_remove(u->dependencies[UNIT_REFERENCES], other);
1826 int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
1831 if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
1834 if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
1840 static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
1844 assert(name || path);
1848 name = path_get_file_name(path);
1850 if (!unit_name_is_template(name)) {
1856 s = unit_name_replace_instance(name, u->instance);
1858 _cleanup_free_ char *i = NULL;
1860 i = unit_name_to_prefix(u->id);
1864 s = unit_name_replace_instance(name, i);
1874 int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1877 _cleanup_free_ char *s = NULL;
1880 assert(name || path);
1882 name = resolve_template(u, name, path, &s);
1886 r = manager_load_unit(u->manager, name, path, NULL, &other);
1890 return unit_add_dependency(u, d, other, add_reference);
1893 int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1896 _cleanup_free_ char *s = NULL;
1899 assert(name || path);
1901 if (!(name = resolve_template(u, name, path, &s)))
1904 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1907 r = unit_add_two_dependencies(u, d, e, other, add_reference);
1912 int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1915 _cleanup_free_ char *s = NULL;
1918 assert(name || path);
1920 if (!(name = resolve_template(u, name, path, &s)))
1923 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1926 r = unit_add_dependency(other, d, u, add_reference);
1931 int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1934 _cleanup_free_ char *s = NULL;
1937 assert(name || path);
1939 if (!(name = resolve_template(u, name, path, &s)))
1942 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1945 if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
1951 int set_unit_path(const char *p) {
1952 _cleanup_free_ char *c = NULL;
1954 /* This is mostly for debug purposes */
1955 c = path_make_absolute_cwd(p);
1956 if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0)
1962 char *unit_dbus_path(Unit *u) {
1968 return unit_dbus_path_from_name(u->id);
1971 char *unit_default_cgroup_path(Unit *u) {
1972 _cleanup_free_ char *escaped = NULL, *slice = NULL;
1977 if (unit_has_name(u, SPECIAL_ROOT_SLICE))
1978 return strdup(u->manager->cgroup_root);
1980 if (UNIT_ISSET(u->slice) && !unit_has_name(UNIT_DEREF(u->slice), SPECIAL_ROOT_SLICE)) {
1981 r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice);
1986 escaped = cg_escape(u->id);
1991 return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL);
1993 return strjoin(u->manager->cgroup_root, "/", escaped, NULL);
1996 int unit_add_default_slice(Unit *u) {
1997 _cleanup_free_ char *b = NULL;
1998 const char *slice_name;
2004 if (UNIT_ISSET(u->slice))
2007 if (!unit_get_cgroup_context(u))
2011 _cleanup_free_ char *prefix = NULL, *escaped = NULL;
2013 /* Implicitly place all instantiated units in their
2014 * own per-template slice */
2016 prefix = unit_name_to_prefix(u->id);
2020 /* The prefix is already escaped, but it might include
2021 * "-" which has a special meaning for slice units,
2022 * hence escape it here extra. */
2023 escaped = strreplace(prefix, "-", "\\x2d");
2027 if (u->manager->running_as == SYSTEMD_SYSTEM)
2028 b = strjoin("system-", escaped, ".slice", NULL);
2030 b = strappend(escaped, ".slice");
2037 u->manager->running_as == SYSTEMD_SYSTEM
2038 ? SPECIAL_SYSTEM_SLICE
2039 : SPECIAL_ROOT_SLICE;
2041 r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
2045 unit_ref_set(&u->slice, slice);
2049 const char *unit_slice_name(Unit *u) {
2052 if (!UNIT_ISSET(u->slice))
2055 return UNIT_DEREF(u->slice)->id;
2058 int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
2059 _cleanup_free_ char *t = NULL;
2066 t = unit_name_change_suffix(u->id, type);
2070 assert(!unit_has_name(u, t));
2072 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
2073 assert(r < 0 || *_found != u);
2077 int unit_watch_bus_name(Unit *u, const char *name) {
2081 /* Watch a specific name on the bus. We only support one unit
2082 * watching each name for now. */
2084 return hashmap_put(u->manager->watch_bus, name, u);
2087 void unit_unwatch_bus_name(Unit *u, const char *name) {
2091 hashmap_remove_value(u->manager->watch_bus, name, u);
2094 bool unit_can_serialize(Unit *u) {
2097 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2100 int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
2108 if (!unit_can_serialize(u))
2111 r = UNIT_VTABLE(u)->serialize(u, f, fds);
2115 rt = unit_get_exec_runtime(u);
2117 r = exec_runtime_serialize(rt, u, f, fds);
2122 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2123 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2124 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2125 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2126 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
2128 if (dual_timestamp_is_set(&u->condition_timestamp))
2129 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
2131 unit_serialize_item(u, f, "transient", yes_no(u->transient));
2134 unit_serialize_item(u, f, "cgroup", u->cgroup_path);
2136 if (serialize_jobs) {
2138 fprintf(f, "job\n");
2139 job_serialize(u->job, f, fds);
2143 fprintf(f, "job\n");
2144 job_serialize(u->nop_job, f, fds);
2153 void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2164 va_start(ap, format);
2165 vfprintf(f, format, ap);
2171 void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2177 fprintf(f, "%s=%s\n", key, value);
2180 int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
2182 ExecRuntime **rt = NULL;
2189 if (!unit_can_serialize(u))
2192 offset = UNIT_VTABLE(u)->exec_runtime_offset;
2194 rt = (ExecRuntime**) ((uint8_t*) u + offset);
2197 char line[LINE_MAX], *l, *v;
2200 if (!fgets(line, sizeof(line), f)) {
2213 k = strcspn(l, "=");
2221 if (streq(l, "job")) {
2223 /* new-style serialized job */
2224 Job *j = job_new_raw(u);
2228 r = job_deserialize(j, f, fds);
2234 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2240 r = job_install_deserialized(j);
2242 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2247 if (j->state == JOB_RUNNING)
2248 u->manager->n_running_jobs++;
2251 JobType type = job_type_from_string(v);
2253 log_debug("Failed to parse job type value %s", v);
2255 u->deserialized_job = type;
2258 } else if (streq(l, "inactive-exit-timestamp")) {
2259 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
2261 } else if (streq(l, "active-enter-timestamp")) {
2262 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
2264 } else if (streq(l, "active-exit-timestamp")) {
2265 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
2267 } else if (streq(l, "inactive-enter-timestamp")) {
2268 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
2270 } else if (streq(l, "condition-timestamp")) {
2271 dual_timestamp_deserialize(v, &u->condition_timestamp);
2273 } else if (streq(l, "condition-result")) {
2276 b = parse_boolean(v);
2278 log_debug("Failed to parse condition result value %s", v);
2280 u->condition_result = b;
2284 } else if (streq(l, "transient")) {
2287 b = parse_boolean(v);
2289 log_debug("Failed to parse transient bool %s", v);
2294 } else if (streq(l, "cgroup")) {
2301 free(u->cgroup_path);
2304 assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1);
2309 r = exec_runtime_deserialize_item(rt, u, l, v, fds);
2316 r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds);
2322 int unit_add_node_link(Unit *u, const char *what, bool wants) {
2324 _cleanup_free_ char *e = NULL;
2332 /* Adds in links to the device node that this unit is based on */
2334 if (!is_device_path(what))
2337 e = unit_name_from_path(what, ".device");
2341 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
2346 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
2351 r = unit_add_dependency(device, UNIT_WANTS, u, false);
2359 int unit_coldplug(Unit *u) {
2364 if (UNIT_VTABLE(u)->coldplug)
2365 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2369 r = job_coldplug(u->job);
2372 } else if (u->deserialized_job >= 0) {
2374 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2378 u->deserialized_job = _JOB_TYPE_INVALID;
2384 #pragma GCC diagnostic push
2385 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
2386 void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) {
2387 manager_status_printf(u->manager, false, status, unit_status_msg_format, unit_description(u));
2389 #pragma GCC diagnostic pop
2391 bool unit_need_daemon_reload(Unit *u) {
2392 _cleanup_strv_free_ char **t = NULL;
2395 unsigned loaded_cnt, current_cnt;
2399 if (u->fragment_path) {
2401 if (stat(u->fragment_path, &st) < 0)
2402 /* What, cannot access this anymore? */
2405 if (u->fragment_mtime > 0 &&
2406 timespec_load(&st.st_mtim) != u->fragment_mtime)
2410 if (u->source_path) {
2412 if (stat(u->source_path, &st) < 0)
2415 if (u->source_mtime > 0 &&
2416 timespec_load(&st.st_mtim) != u->source_mtime)
2420 t = unit_find_dropin_paths(u);
2421 loaded_cnt = strv_length(t);
2422 current_cnt = strv_length(u->dropin_paths);
2424 if (loaded_cnt == current_cnt) {
2425 if (loaded_cnt == 0)
2428 if (strv_overlap(u->dropin_paths, t)) {
2429 STRV_FOREACH(path, u->dropin_paths) {
2431 if (stat(*path, &st) < 0)
2434 if (u->dropin_mtime > 0 &&
2435 timespec_load(&st.st_mtim) > u->dropin_mtime)
2446 void unit_reset_failed(Unit *u) {
2449 if (UNIT_VTABLE(u)->reset_failed)
2450 UNIT_VTABLE(u)->reset_failed(u);
2453 Unit *unit_following(Unit *u) {
2456 if (UNIT_VTABLE(u)->following)
2457 return UNIT_VTABLE(u)->following(u);
2462 bool unit_stop_pending(Unit *u) {
2465 /* This call does check the current state of the unit. It's
2466 * hence useful to be called from state change calls of the
2467 * unit itself, where the state isn't updated yet. This is
2468 * different from unit_inactive_or_pending() which checks both
2469 * the current state and for a queued job. */
2471 return u->job && u->job->type == JOB_STOP;
2474 bool unit_inactive_or_pending(Unit *u) {
2477 /* Returns true if the unit is inactive or going down */
2479 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2482 if (unit_stop_pending(u))
2488 bool unit_active_or_pending(Unit *u) {
2491 /* Returns true if the unit is active or going up */
2493 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2497 (u->job->type == JOB_START ||
2498 u->job->type == JOB_RELOAD_OR_START ||
2499 u->job->type == JOB_RESTART))
2505 int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error) {
2507 assert(w >= 0 && w < _KILL_WHO_MAX);
2509 assert(signo < _NSIG);
2511 if (!UNIT_VTABLE(u)->kill)
2514 return UNIT_VTABLE(u)->kill(u, w, signo, error);
2517 static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
2521 pid_set = set_new(trivial_hash_func, trivial_compare_func);
2525 /* Exclude the main/control pids from being killed via the cgroup */
2527 r = set_put(pid_set, LONG_TO_PTR(main_pid));
2532 if (control_pid > 0) {
2533 r = set_put(pid_set, LONG_TO_PTR(control_pid));
2545 int unit_kill_common(
2551 sd_bus_error *error) {
2555 if (who == KILL_MAIN && main_pid <= 0) {
2557 sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
2559 sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
2563 if (who == KILL_CONTROL && control_pid <= 0) {
2564 if (control_pid < 0)
2565 sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
2567 sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
2571 if (who == KILL_CONTROL || who == KILL_ALL)
2572 if (control_pid > 0)
2573 if (kill(control_pid, signo) < 0)
2576 if (who == KILL_MAIN || who == KILL_ALL)
2578 if (kill(main_pid, signo) < 0)
2581 if (who == KILL_ALL && u->cgroup_path) {
2582 _cleanup_set_free_ Set *pid_set = NULL;
2585 /* Exclude the main/control pids from being killed via the cgroup */
2586 pid_set = unit_pid_set(main_pid, control_pid);
2590 q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
2591 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
2598 int unit_following_set(Unit *u, Set **s) {
2602 if (UNIT_VTABLE(u)->following_set)
2603 return UNIT_VTABLE(u)->following_set(u, s);
2609 UnitFileState unit_get_unit_file_state(Unit *u) {
2612 if (u->unit_file_state < 0 && u->fragment_path)
2613 u->unit_file_state = unit_file_get_state(
2614 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
2615 NULL, path_get_file_name(u->fragment_path));
2617 return u->unit_file_state;
2620 Unit* unit_ref_set(UnitRef *ref, Unit *u) {
2625 unit_ref_unset(ref);
2628 LIST_PREPEND(refs, u->refs, ref);
2632 void unit_ref_unset(UnitRef *ref) {
2638 LIST_REMOVE(refs, ref->unit->refs, ref);
2642 int unit_exec_context_defaults(Unit *u, ExecContext *c) {
2649 /* This only copies in the ones that need memory */
2650 for (i = 0; i < RLIMIT_NLIMITS; i++)
2651 if (u->manager->rlimit[i] && !c->rlimit[i]) {
2652 c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
2657 if (u->manager->running_as == SYSTEMD_USER &&
2658 !c->working_directory) {
2660 r = get_home_dir(&c->working_directory);
2668 ExecContext *unit_get_exec_context(Unit *u) {
2672 offset = UNIT_VTABLE(u)->exec_context_offset;
2676 return (ExecContext*) ((uint8_t*) u + offset);
2679 KillContext *unit_get_kill_context(Unit *u) {
2683 offset = UNIT_VTABLE(u)->kill_context_offset;
2687 return (KillContext*) ((uint8_t*) u + offset);
2690 CGroupContext *unit_get_cgroup_context(Unit *u) {
2693 offset = UNIT_VTABLE(u)->cgroup_context_offset;
2697 return (CGroupContext*) ((uint8_t*) u + offset);
2700 ExecRuntime *unit_get_exec_runtime(Unit *u) {
2703 offset = UNIT_VTABLE(u)->exec_runtime_offset;
2707 return *(ExecRuntime**) ((uint8_t*) u + offset);
2710 static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) {
2711 _cleanup_free_ char *b = NULL;
2719 assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME));
2721 b = xescape(name, "/.");
2725 if (!filename_is_safe(b))
2728 if (u->manager->running_as == SYSTEMD_USER) {
2729 _cleanup_free_ char *c = NULL;
2731 r = user_config_home(&c);
2737 p = strjoin(c, "/", u->id, ".d", NULL);
2738 } else if (mode & UNIT_PERSISTENT)
2739 p = strjoin("/etc/systemd/system/", u->id, ".d", NULL);
2741 p = strjoin("/run/systemd/system/", u->id, ".d", NULL);
2745 q = strjoin(p, "/90-", b, ".conf", NULL);
2756 int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2757 _cleanup_free_ char *p = NULL, *q = NULL;
2764 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2767 r = drop_in_file(u, mode, name, &p, &q);
2772 return write_string_file_atomic_label(q, data);
2775 int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2776 _cleanup_free_ char *p = NULL;
2784 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2787 va_start(ap, format);
2788 r = vasprintf(&p, format, ap);
2794 return unit_write_drop_in(u, mode, name, p);
2797 int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2798 _cleanup_free_ char *ndata = NULL;
2804 if (!UNIT_VTABLE(u)->private_section)
2807 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2810 ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
2814 return unit_write_drop_in(u, mode, name, ndata);
2817 int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2818 _cleanup_free_ char *p = NULL;
2826 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2829 va_start(ap, format);
2830 r = vasprintf(&p, format, ap);
2836 return unit_write_drop_in_private(u, mode, name, p);
2839 int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
2840 _cleanup_free_ char *p = NULL, *q = NULL;
2845 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2848 r = drop_in_file(u, mode, name, &p, &q);
2853 r = errno == ENOENT ? 0 : -errno;
2861 int unit_make_transient(Unit *u) {
2866 u->load_state = UNIT_STUB;
2868 u->transient = true;
2870 free(u->fragment_path);
2871 u->fragment_path = NULL;
2873 if (u->manager->running_as == SYSTEMD_USER) {
2874 _cleanup_free_ char *c = NULL;
2876 r = user_config_home(&c);
2882 u->fragment_path = strjoin(c, "/", u->id, NULL);
2883 if (!u->fragment_path)
2888 u->fragment_path = strappend("/run/systemd/system/", u->id);
2889 if (!u->fragment_path)
2892 mkdir_p("/run/systemd/system", 0755);
2895 return write_string_file_atomic_label(u->fragment_path, "# Transient stub");
2898 int unit_kill_context(
2904 bool main_pid_alien) {
2906 int sig, wait_for_exit = 0, r;
2911 if (c->kill_mode == KILL_NONE)
2914 sig = sigkill ? SIGKILL : c->kill_signal;
2917 r = kill_and_sigcont(main_pid, sig);
2919 if (r < 0 && r != -ESRCH) {
2920 _cleanup_free_ char *comm = NULL;
2921 get_process_comm(main_pid, &comm);
2923 log_warning_unit(u->id, "Failed to kill main process %li (%s): %s",
2924 (long) main_pid, strna(comm), strerror(-r));
2926 wait_for_exit = !main_pid_alien;
2929 kill(main_pid, SIGHUP);
2933 if (control_pid > 0) {
2934 r = kill_and_sigcont(control_pid, sig);
2936 if (r < 0 && r != -ESRCH) {
2937 _cleanup_free_ char *comm = NULL;
2938 get_process_comm(control_pid, &comm);
2940 log_warning_unit(u->id,
2941 "Failed to kill control process %li (%s): %s",
2942 (long) control_pid, strna(comm), strerror(-r));
2944 wait_for_exit = true;
2947 kill(control_pid, SIGHUP);
2951 if (c->kill_mode == KILL_CONTROL_GROUP && u->cgroup_path) {
2952 _cleanup_set_free_ Set *pid_set = NULL;
2954 /* Exclude the main/control pids from being killed via the cgroup */
2955 pid_set = unit_pid_set(main_pid, control_pid);
2959 r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set);
2961 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
2962 log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
2964 wait_for_exit = true;
2965 if (c->send_sighup) {
2968 pid_set = unit_pid_set(main_pid, control_pid);
2972 cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, SIGHUP, true, true, false, pid_set);
2977 return wait_for_exit;
2980 int unit_require_mounts_for(Unit *u, const char *path) {
2981 char prefix[strlen(path) + 1], *p;
2987 /* Registers a unit for requiring a certain path and all its
2988 * prefixes. We keep a simple array of these paths in the
2989 * unit, since its usually short. However, we build a prefix
2990 * table for all possible prefixes so that new appearing mount
2991 * units can easily determine which units to make themselves a
2998 path_kill_slashes(p);
3000 if (!path_is_absolute(p)) {
3005 if (!path_is_safe(p)) {
3010 if (strv_contains(u->requires_mounts_for, p)) {
3015 r = strv_push(&u->requires_mounts_for, p);
3021 PATH_FOREACH_PREFIX_MORE(prefix, p) {
3024 x = hashmap_get(u->manager->units_requiring_mounts_for, prefix);
3028 if (!u->manager->units_requiring_mounts_for) {
3029 u->manager->units_requiring_mounts_for = hashmap_new(string_hash_func, string_compare_func);
3030 if (!u->manager->units_requiring_mounts_for)
3038 x = set_new(NULL, NULL);
3044 r = hashmap_put(u->manager->units_requiring_mounts_for, q, x);
3060 int unit_setup_exec_runtime(Unit *u) {
3066 offset = UNIT_VTABLE(u)->exec_runtime_offset;
3069 /* Check if ther already is an ExecRuntime for this unit? */
3070 rt = (ExecRuntime**) ((uint8_t*) u + offset);
3074 /* Try to get it from somebody else */
3075 SET_FOREACH(other, u->dependencies[UNIT_JOINS_NAMESPACE_OF], i) {
3077 *rt = unit_get_exec_runtime(other);
3079 exec_runtime_ref(*rt);
3084 return exec_runtime_make(rt, unit_get_exec_context(u), u->id);
3087 static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
3088 [UNIT_ACTIVE] = "active",
3089 [UNIT_RELOADING] = "reloading",
3090 [UNIT_INACTIVE] = "inactive",
3091 [UNIT_FAILED] = "failed",
3092 [UNIT_ACTIVATING] = "activating",
3093 [UNIT_DEACTIVATING] = "deactivating"
3096 DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
3098 static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
3099 [UNIT_REQUIRES] = "Requires",
3100 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
3101 [UNIT_REQUISITE] = "Requisite",
3102 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
3103 [UNIT_WANTS] = "Wants",
3104 [UNIT_BINDS_TO] = "BindsTo",
3105 [UNIT_PART_OF] = "PartOf",
3106 [UNIT_REQUIRED_BY] = "RequiredBy",
3107 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
3108 [UNIT_WANTED_BY] = "WantedBy",
3109 [UNIT_BOUND_BY] = "BoundBy",
3110 [UNIT_CONSISTS_OF] = "ConsistsOf",
3111 [UNIT_CONFLICTS] = "Conflicts",
3112 [UNIT_CONFLICTED_BY] = "ConflictedBy",
3113 [UNIT_BEFORE] = "Before",
3114 [UNIT_AFTER] = "After",
3115 [UNIT_ON_FAILURE] = "OnFailure",
3116 [UNIT_TRIGGERS] = "Triggers",
3117 [UNIT_TRIGGERED_BY] = "TriggeredBy",
3118 [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
3119 [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
3120 [UNIT_REFERENCES] = "References",
3121 [UNIT_REFERENCED_BY] = "ReferencedBy",
3122 [UNIT_JOINS_NAMESPACE_OF] = "JoinsNamespaceOf",
3125 DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);