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, TEMPLATE_INVALID)) {
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 #pragma GCC diagnostic push
1129 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
1130 static void unit_status_print_starting_stopping(Unit *u, JobType t) {
1135 /* We only print status messages for selected units on
1136 * selected operations. */
1138 format = unit_get_status_message_format(u, t);
1142 unit_status_printf(u, "", format);
1144 #pragma GCC diagnostic pop
1146 #pragma GCC diagnostic push
1147 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
1148 static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
1155 if (t != JOB_START && t != JOB_STOP && t != JOB_RELOAD)
1158 if (log_on_console())
1161 /* We log status messages for all units and all operations. */
1163 format = unit_get_status_message_format_try_harder(u, t);
1167 snprintf(buf, sizeof(buf), format, unit_description(u));
1170 mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
1171 t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
1172 SD_MESSAGE_UNIT_RELOADING;
1174 log_struct_unit(LOG_INFO,
1180 #pragma GCC diagnostic pop
1183 * -EBADR: This unit type does not support starting.
1184 * -EALREADY: Unit is already started.
1185 * -EAGAIN: An operation is already in progress. Retry later.
1186 * -ECANCELED: Too many requests for now.
1188 int unit_start(Unit *u) {
1189 UnitActiveState state;
1194 if (u->load_state != UNIT_LOADED)
1197 /* If this is already started, then this will succeed. Note
1198 * that this will even succeed if this unit is not startable
1199 * by the user. This is relied on to detect when we need to
1200 * wait for units and when waiting is finished. */
1201 state = unit_active_state(u);
1202 if (UNIT_IS_ACTIVE_OR_RELOADING(state))
1205 /* If the conditions failed, don't do anything at all. If we
1206 * already are activating this call might still be useful to
1207 * speed up activation in case there is some hold-off time,
1208 * but we don't want to recheck the condition in that case. */
1209 if (state != UNIT_ACTIVATING &&
1210 !unit_condition_test(u)) {
1211 log_debug_unit(u->id, "Starting of %s requested but condition failed. Ignoring.", u->id);
1215 /* Forward to the main object, if we aren't it. */
1216 following = unit_following(u);
1218 log_debug_unit(u->id, "Redirecting start request from %s to %s.",
1219 u->id, following->id);
1220 return unit_start(following);
1223 unit_status_log_starting_stopping_reloading(u, JOB_START);
1224 unit_status_print_starting_stopping(u, JOB_START);
1226 /* If it is stopped, but we cannot start it, then fail */
1227 if (!UNIT_VTABLE(u)->start)
1230 /* We don't suppress calls to ->start() here when we are
1231 * already starting, to allow this request to be used as a
1232 * "hurry up" call, for example when the unit is in some "auto
1233 * restart" state where it waits for a holdoff timer to elapse
1234 * before it will start again. */
1236 unit_add_to_dbus_queue(u);
1238 return UNIT_VTABLE(u)->start(u);
1241 bool unit_can_start(Unit *u) {
1244 return !!UNIT_VTABLE(u)->start;
1247 bool unit_can_isolate(Unit *u) {
1250 return unit_can_start(u) &&
1255 * -EBADR: This unit type does not support stopping.
1256 * -EALREADY: Unit is already stopped.
1257 * -EAGAIN: An operation is already in progress. Retry later.
1259 int unit_stop(Unit *u) {
1260 UnitActiveState state;
1265 state = unit_active_state(u);
1266 if (UNIT_IS_INACTIVE_OR_FAILED(state))
1269 if ((following = unit_following(u))) {
1270 log_debug_unit(u->id, "Redirecting stop request from %s to %s.",
1271 u->id, following->id);
1272 return unit_stop(following);
1275 unit_status_log_starting_stopping_reloading(u, JOB_STOP);
1276 unit_status_print_starting_stopping(u, JOB_STOP);
1278 if (!UNIT_VTABLE(u)->stop)
1281 unit_add_to_dbus_queue(u);
1283 return UNIT_VTABLE(u)->stop(u);
1287 * -EBADR: This unit type does not support reloading.
1288 * -ENOEXEC: Unit is not started.
1289 * -EAGAIN: An operation is already in progress. Retry later.
1291 int unit_reload(Unit *u) {
1292 UnitActiveState state;
1297 if (u->load_state != UNIT_LOADED)
1300 if (!unit_can_reload(u))
1303 state = unit_active_state(u);
1304 if (state == UNIT_RELOADING)
1307 if (state != UNIT_ACTIVE) {
1308 log_warning_unit(u->id, "Unit %s cannot be reloaded because it is inactive.",
1313 following = unit_following(u);
1315 log_debug_unit(u->id, "Redirecting reload request from %s to %s.",
1316 u->id, following->id);
1317 return unit_reload(following);
1320 unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
1322 unit_add_to_dbus_queue(u);
1323 return UNIT_VTABLE(u)->reload(u);
1326 bool unit_can_reload(Unit *u) {
1329 if (!UNIT_VTABLE(u)->reload)
1332 if (!UNIT_VTABLE(u)->can_reload)
1335 return UNIT_VTABLE(u)->can_reload(u);
1338 static void unit_check_unneeded(Unit *u) {
1344 /* If this service shall be shut down when unneeded then do
1347 if (!u->stop_when_unneeded)
1350 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1353 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
1354 if (unit_active_or_pending(other))
1357 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
1358 if (unit_active_or_pending(other))
1361 SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
1362 if (unit_active_or_pending(other))
1365 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1366 if (unit_active_or_pending(other))
1369 log_info_unit(u->id, "Service %s is not needed anymore. Stopping.", u->id);
1371 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
1372 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
1375 static void retroactively_start_dependencies(Unit *u) {
1380 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1382 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1383 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1384 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1385 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1387 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1388 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1389 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1390 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1392 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1393 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1394 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1395 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1397 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1398 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1399 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1400 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1402 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
1403 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1404 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1406 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
1407 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1408 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1411 static void retroactively_stop_dependencies(Unit *u) {
1416 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1418 /* Pull down units which are bound to us recursively if enabled */
1419 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1420 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1421 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1424 static void check_unneeded_dependencies(Unit *u) {
1429 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1431 /* Garbage collect services that might not be needed anymore, if enabled */
1432 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1433 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1434 unit_check_unneeded(other);
1435 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_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_WANTS], i)
1439 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1440 unit_check_unneeded(other);
1441 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
1442 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1443 unit_check_unneeded(other);
1444 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
1445 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1446 unit_check_unneeded(other);
1447 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1448 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1449 unit_check_unneeded(other);
1452 void unit_start_on_failure(Unit *u) {
1458 if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
1461 log_info_unit(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
1463 SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
1466 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_job_mode, true, NULL, NULL);
1468 log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
1472 void unit_trigger_notify(Unit *u) {
1478 SET_FOREACH(other, u->dependencies[UNIT_TRIGGERED_BY], i)
1479 if (UNIT_VTABLE(other)->trigger_notify)
1480 UNIT_VTABLE(other)->trigger_notify(other, u);
1483 void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
1488 assert(os < _UNIT_ACTIVE_STATE_MAX);
1489 assert(ns < _UNIT_ACTIVE_STATE_MAX);
1491 /* Note that this is called for all low-level state changes,
1492 * even if they might map to the same high-level
1493 * UnitActiveState! That means that ns == os is OK an expected
1494 * behavior here. For example: if a mount point is remounted
1495 * this function will be called too! */
1499 if (m->n_reloading <= 0) {
1502 dual_timestamp_get(&ts);
1504 if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
1505 u->inactive_exit_timestamp = ts;
1506 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
1507 u->inactive_enter_timestamp = ts;
1509 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
1510 u->active_enter_timestamp = ts;
1511 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
1512 u->active_exit_timestamp = ts;
1515 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1516 unit_destroy_cgroup(u);
1518 /* Note that this doesn't apply to RemainAfterExit services exiting
1519 * sucessfully, since there's no change of state in that case. Which is
1520 * why it is handled in service_set_state() */
1521 if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1522 ExecContext *ec = unit_get_exec_context(u);
1523 if (ec && exec_context_may_touch_console(ec)) {
1524 if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1527 if (m->n_on_console == 0)
1528 /* unset no_console_output flag, since the console is free */
1529 m->no_console_output = false;
1538 if (u->job->state == JOB_WAITING)
1540 /* So we reached a different state for this
1541 * job. Let's see if we can run it now if it
1542 * failed previously due to EAGAIN. */
1543 job_add_to_run_queue(u->job);
1545 /* Let's check whether this state change constitutes a
1546 * finished job, or maybe contradicts a running job and
1547 * hence needs to invalidate jobs. */
1549 switch (u->job->type) {
1552 case JOB_VERIFY_ACTIVE:
1554 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
1555 job_finish_and_invalidate(u->job, JOB_DONE, true);
1556 else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
1559 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1560 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1566 case JOB_RELOAD_OR_START:
1568 if (u->job->state == JOB_RUNNING) {
1569 if (ns == UNIT_ACTIVE)
1570 job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
1571 else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
1574 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1575 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1583 case JOB_TRY_RESTART:
1585 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1586 job_finish_and_invalidate(u->job, JOB_DONE, true);
1587 else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
1589 job_finish_and_invalidate(u->job, JOB_FAILED, true);
1595 assert_not_reached("Job type unknown");
1601 if (m->n_reloading <= 0) {
1603 /* If this state change happened without being
1604 * requested by a job, then let's retroactively start
1605 * or stop dependencies. We skip that step when
1606 * deserializing, since we don't want to create any
1607 * additional jobs just because something is already
1611 if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1612 retroactively_start_dependencies(u);
1613 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1614 retroactively_stop_dependencies(u);
1617 /* stop unneeded units regardless if going down was expected or not */
1618 if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1619 check_unneeded_dependencies(u);
1621 if (ns != os && ns == UNIT_FAILED) {
1622 log_notice_unit(u->id,
1623 "Unit %s entered failed state.", u->id);
1624 unit_start_on_failure(u);
1628 /* Some names are special */
1629 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
1631 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
1632 /* The bus just might have become available,
1633 * hence try to connect to it, if we aren't
1637 if (u->type == UNIT_SERVICE &&
1638 !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
1639 m->n_reloading <= 0) {
1640 /* Write audit record if we have just finished starting up */
1641 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
1645 if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
1646 manager_send_unit_plymouth(m, u);
1650 /* We don't care about D-Bus here, since we'll get an
1651 * asynchronous notification for it anyway. */
1653 if (u->type == UNIT_SERVICE &&
1654 UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1655 !UNIT_IS_INACTIVE_OR_FAILED(os) &&
1656 m->n_reloading <= 0) {
1658 /* Hmm, if there was no start record written
1659 * write it now, so that we always have a nice
1662 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
1664 if (ns == UNIT_INACTIVE)
1665 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
1667 /* Write audit record if we have just finished shutting down */
1668 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
1670 u->in_audit = false;
1674 manager_recheck_journal(m);
1675 unit_trigger_notify(u);
1677 /* Maybe we finished startup and are now ready for being
1678 * stopped because unneeded? */
1679 if (u->manager->n_reloading <= 0)
1680 unit_check_unneeded(u);
1682 unit_add_to_dbus_queue(u);
1683 unit_add_to_gc_queue(u);
1686 int unit_watch_pid(Unit *u, pid_t pid) {
1690 /* Watch a specific PID. We only support one unit watching
1691 * each PID for now. */
1693 return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1696 void unit_unwatch_pid(Unit *u, pid_t pid) {
1700 hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1703 bool unit_job_is_applicable(Unit *u, JobType j) {
1705 assert(j >= 0 && j < _JOB_TYPE_MAX);
1709 case JOB_VERIFY_ACTIVE:
1716 case JOB_TRY_RESTART:
1717 return unit_can_start(u);
1720 return unit_can_reload(u);
1722 case JOB_RELOAD_OR_START:
1723 return unit_can_reload(u) && unit_can_start(u);
1726 assert_not_reached("Invalid job type");
1730 int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
1732 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
1733 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
1734 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1735 [UNIT_WANTS] = UNIT_WANTED_BY,
1736 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
1737 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1738 [UNIT_BINDS_TO] = UNIT_BOUND_BY,
1739 [UNIT_PART_OF] = UNIT_CONSISTS_OF,
1740 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
1741 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
1742 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
1743 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
1744 [UNIT_CONSISTS_OF] = UNIT_PART_OF,
1745 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
1746 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
1747 [UNIT_BEFORE] = UNIT_AFTER,
1748 [UNIT_AFTER] = UNIT_BEFORE,
1749 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
1750 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
1751 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
1752 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
1753 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
1754 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
1755 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
1756 [UNIT_JOINS_NAMESPACE_OF] = UNIT_JOINS_NAMESPACE_OF,
1758 int r, q = 0, v = 0, w = 0;
1761 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
1764 u = unit_follow_merge(u);
1765 other = unit_follow_merge(other);
1767 /* We won't allow dependencies on ourselves. We will not
1768 * consider them an error however. */
1772 r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func);
1776 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID) {
1777 r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func);
1782 if (add_reference) {
1783 r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func);
1787 r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func);
1792 q = set_put(u->dependencies[d], other);
1796 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID && inverse_table[d] != d) {
1797 v = set_put(other->dependencies[inverse_table[d]], u);
1804 if (add_reference) {
1805 w = set_put(u->dependencies[UNIT_REFERENCES], other);
1811 r = set_put(other->dependencies[UNIT_REFERENCED_BY], u);
1816 unit_add_to_dbus_queue(u);
1821 set_remove(u->dependencies[d], other);
1824 set_remove(other->dependencies[inverse_table[d]], u);
1827 set_remove(u->dependencies[UNIT_REFERENCES], other);
1832 int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
1837 if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
1840 if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
1846 static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
1850 assert(name || path);
1854 name = basename(path);
1856 if (!unit_name_is_template(name)) {
1862 s = unit_name_replace_instance(name, u->instance);
1864 _cleanup_free_ char *i = NULL;
1866 i = unit_name_to_prefix(u->id);
1870 s = unit_name_replace_instance(name, i);
1880 int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1883 _cleanup_free_ char *s = NULL;
1886 assert(name || path);
1888 name = resolve_template(u, name, path, &s);
1892 r = manager_load_unit(u->manager, name, path, NULL, &other);
1896 return unit_add_dependency(u, d, other, add_reference);
1899 int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1902 _cleanup_free_ char *s = NULL;
1905 assert(name || path);
1907 if (!(name = resolve_template(u, name, path, &s)))
1910 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1913 r = unit_add_two_dependencies(u, d, e, other, add_reference);
1918 int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1921 _cleanup_free_ char *s = NULL;
1924 assert(name || path);
1926 if (!(name = resolve_template(u, name, path, &s)))
1929 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1932 r = unit_add_dependency(other, d, u, add_reference);
1937 int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1940 _cleanup_free_ char *s = NULL;
1943 assert(name || path);
1945 if (!(name = resolve_template(u, name, path, &s)))
1948 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1951 if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
1957 int set_unit_path(const char *p) {
1958 _cleanup_free_ char *c = NULL;
1960 /* This is mostly for debug purposes */
1961 c = path_make_absolute_cwd(p);
1962 if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0)
1968 char *unit_dbus_path(Unit *u) {
1974 return unit_dbus_path_from_name(u->id);
1977 char *unit_default_cgroup_path(Unit *u) {
1978 _cleanup_free_ char *escaped = NULL, *slice = NULL;
1983 if (unit_has_name(u, SPECIAL_ROOT_SLICE))
1984 return strdup(u->manager->cgroup_root);
1986 if (UNIT_ISSET(u->slice) && !unit_has_name(UNIT_DEREF(u->slice), SPECIAL_ROOT_SLICE)) {
1987 r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice);
1992 escaped = cg_escape(u->id);
1997 return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL);
1999 return strjoin(u->manager->cgroup_root, "/", escaped, NULL);
2002 int unit_add_default_slice(Unit *u) {
2003 _cleanup_free_ char *b = NULL;
2004 const char *slice_name;
2010 if (UNIT_ISSET(u->slice))
2013 if (!unit_get_cgroup_context(u))
2017 _cleanup_free_ char *prefix = NULL, *escaped = NULL;
2019 /* Implicitly place all instantiated units in their
2020 * own per-template slice */
2022 prefix = unit_name_to_prefix(u->id);
2026 /* The prefix is already escaped, but it might include
2027 * "-" which has a special meaning for slice units,
2028 * hence escape it here extra. */
2029 escaped = strreplace(prefix, "-", "\\x2d");
2033 if (u->manager->running_as == SYSTEMD_SYSTEM)
2034 b = strjoin("system-", escaped, ".slice", NULL);
2036 b = strappend(escaped, ".slice");
2043 u->manager->running_as == SYSTEMD_SYSTEM
2044 ? SPECIAL_SYSTEM_SLICE
2045 : SPECIAL_ROOT_SLICE;
2047 r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
2051 unit_ref_set(&u->slice, slice);
2055 const char *unit_slice_name(Unit *u) {
2058 if (!UNIT_ISSET(u->slice))
2061 return UNIT_DEREF(u->slice)->id;
2064 int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
2065 _cleanup_free_ char *t = NULL;
2072 t = unit_name_change_suffix(u->id, type);
2076 assert(!unit_has_name(u, t));
2078 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
2079 assert(r < 0 || *_found != u);
2083 int unit_watch_bus_name(Unit *u, const char *name) {
2087 /* Watch a specific name on the bus. We only support one unit
2088 * watching each name for now. */
2090 return hashmap_put(u->manager->watch_bus, name, u);
2093 void unit_unwatch_bus_name(Unit *u, const char *name) {
2097 hashmap_remove_value(u->manager->watch_bus, name, u);
2100 bool unit_can_serialize(Unit *u) {
2103 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2106 int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
2114 if (!unit_can_serialize(u))
2117 r = UNIT_VTABLE(u)->serialize(u, f, fds);
2121 rt = unit_get_exec_runtime(u);
2123 r = exec_runtime_serialize(rt, u, f, fds);
2128 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2129 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2130 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2131 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2132 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
2134 if (dual_timestamp_is_set(&u->condition_timestamp))
2135 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
2137 unit_serialize_item(u, f, "transient", yes_no(u->transient));
2140 unit_serialize_item(u, f, "cgroup", u->cgroup_path);
2142 if (serialize_jobs) {
2144 fprintf(f, "job\n");
2145 job_serialize(u->job, f, fds);
2149 fprintf(f, "job\n");
2150 job_serialize(u->nop_job, f, fds);
2159 void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2170 va_start(ap, format);
2171 vfprintf(f, format, ap);
2177 void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2183 fprintf(f, "%s=%s\n", key, value);
2186 int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
2188 ExecRuntime **rt = NULL;
2195 if (!unit_can_serialize(u))
2198 offset = UNIT_VTABLE(u)->exec_runtime_offset;
2200 rt = (ExecRuntime**) ((uint8_t*) u + offset);
2203 char line[LINE_MAX], *l, *v;
2206 if (!fgets(line, sizeof(line), f)) {
2219 k = strcspn(l, "=");
2227 if (streq(l, "job")) {
2229 /* new-style serialized job */
2230 Job *j = job_new_raw(u);
2234 r = job_deserialize(j, f, fds);
2240 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2246 r = job_install_deserialized(j);
2248 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2253 if (j->state == JOB_RUNNING)
2254 u->manager->n_running_jobs++;
2257 JobType type = job_type_from_string(v);
2259 log_debug("Failed to parse job type value %s", v);
2261 u->deserialized_job = type;
2264 } else if (streq(l, "inactive-exit-timestamp")) {
2265 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
2267 } else if (streq(l, "active-enter-timestamp")) {
2268 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
2270 } else if (streq(l, "active-exit-timestamp")) {
2271 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
2273 } else if (streq(l, "inactive-enter-timestamp")) {
2274 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
2276 } else if (streq(l, "condition-timestamp")) {
2277 dual_timestamp_deserialize(v, &u->condition_timestamp);
2279 } else if (streq(l, "condition-result")) {
2282 b = parse_boolean(v);
2284 log_debug("Failed to parse condition result value %s", v);
2286 u->condition_result = b;
2290 } else if (streq(l, "transient")) {
2293 b = parse_boolean(v);
2295 log_debug("Failed to parse transient bool %s", v);
2300 } else if (streq(l, "cgroup")) {
2307 free(u->cgroup_path);
2310 assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1);
2315 r = exec_runtime_deserialize_item(rt, u, l, v, fds);
2322 r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds);
2328 int unit_add_node_link(Unit *u, const char *what, bool wants) {
2330 _cleanup_free_ char *e = NULL;
2338 /* Adds in links to the device node that this unit is based on */
2340 if (!is_device_path(what))
2343 e = unit_name_from_path(what, ".device");
2347 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
2352 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
2357 r = unit_add_dependency(device, UNIT_WANTS, u, false);
2365 int unit_coldplug(Unit *u) {
2370 if (UNIT_VTABLE(u)->coldplug)
2371 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2375 r = job_coldplug(u->job);
2378 } else if (u->deserialized_job >= 0) {
2380 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2384 u->deserialized_job = _JOB_TYPE_INVALID;
2390 #pragma GCC diagnostic push
2391 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
2392 void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) {
2393 manager_status_printf(u->manager, false, status, unit_status_msg_format, unit_description(u));
2395 #pragma GCC diagnostic pop
2397 bool unit_need_daemon_reload(Unit *u) {
2398 _cleanup_strv_free_ char **t = NULL;
2401 unsigned loaded_cnt, current_cnt;
2405 if (u->fragment_path) {
2407 if (stat(u->fragment_path, &st) < 0)
2408 /* What, cannot access this anymore? */
2411 if (u->fragment_mtime > 0 &&
2412 timespec_load(&st.st_mtim) != u->fragment_mtime)
2416 if (u->source_path) {
2418 if (stat(u->source_path, &st) < 0)
2421 if (u->source_mtime > 0 &&
2422 timespec_load(&st.st_mtim) != u->source_mtime)
2426 t = unit_find_dropin_paths(u);
2427 loaded_cnt = strv_length(t);
2428 current_cnt = strv_length(u->dropin_paths);
2430 if (loaded_cnt == current_cnt) {
2431 if (loaded_cnt == 0)
2434 if (strv_overlap(u->dropin_paths, t)) {
2435 STRV_FOREACH(path, u->dropin_paths) {
2437 if (stat(*path, &st) < 0)
2440 if (u->dropin_mtime > 0 &&
2441 timespec_load(&st.st_mtim) > u->dropin_mtime)
2452 void unit_reset_failed(Unit *u) {
2455 if (UNIT_VTABLE(u)->reset_failed)
2456 UNIT_VTABLE(u)->reset_failed(u);
2459 Unit *unit_following(Unit *u) {
2462 if (UNIT_VTABLE(u)->following)
2463 return UNIT_VTABLE(u)->following(u);
2468 bool unit_stop_pending(Unit *u) {
2471 /* This call does check the current state of the unit. It's
2472 * hence useful to be called from state change calls of the
2473 * unit itself, where the state isn't updated yet. This is
2474 * different from unit_inactive_or_pending() which checks both
2475 * the current state and for a queued job. */
2477 return u->job && u->job->type == JOB_STOP;
2480 bool unit_inactive_or_pending(Unit *u) {
2483 /* Returns true if the unit is inactive or going down */
2485 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2488 if (unit_stop_pending(u))
2494 bool unit_active_or_pending(Unit *u) {
2497 /* Returns true if the unit is active or going up */
2499 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2503 (u->job->type == JOB_START ||
2504 u->job->type == JOB_RELOAD_OR_START ||
2505 u->job->type == JOB_RESTART))
2511 int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error) {
2513 assert(w >= 0 && w < _KILL_WHO_MAX);
2515 assert(signo < _NSIG);
2517 if (!UNIT_VTABLE(u)->kill)
2520 return UNIT_VTABLE(u)->kill(u, w, signo, error);
2523 static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
2527 pid_set = set_new(trivial_hash_func, trivial_compare_func);
2531 /* Exclude the main/control pids from being killed via the cgroup */
2533 r = set_put(pid_set, LONG_TO_PTR(main_pid));
2538 if (control_pid > 0) {
2539 r = set_put(pid_set, LONG_TO_PTR(control_pid));
2551 int unit_kill_common(
2557 sd_bus_error *error) {
2561 if (who == KILL_MAIN && main_pid <= 0) {
2563 sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
2565 sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
2569 if (who == KILL_CONTROL && control_pid <= 0) {
2570 if (control_pid < 0)
2571 sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
2573 sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
2577 if (who == KILL_CONTROL || who == KILL_ALL)
2578 if (control_pid > 0)
2579 if (kill(control_pid, signo) < 0)
2582 if (who == KILL_MAIN || who == KILL_ALL)
2584 if (kill(main_pid, signo) < 0)
2587 if (who == KILL_ALL && u->cgroup_path) {
2588 _cleanup_set_free_ Set *pid_set = NULL;
2591 /* Exclude the main/control pids from being killed via the cgroup */
2592 pid_set = unit_pid_set(main_pid, control_pid);
2596 q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
2597 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
2604 int unit_following_set(Unit *u, Set **s) {
2608 if (UNIT_VTABLE(u)->following_set)
2609 return UNIT_VTABLE(u)->following_set(u, s);
2615 UnitFileState unit_get_unit_file_state(Unit *u) {
2618 if (u->unit_file_state < 0 && u->fragment_path)
2619 u->unit_file_state = unit_file_get_state(
2620 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
2621 NULL, basename(u->fragment_path));
2623 return u->unit_file_state;
2626 Unit* unit_ref_set(UnitRef *ref, Unit *u) {
2631 unit_ref_unset(ref);
2634 LIST_PREPEND(refs, u->refs, ref);
2638 void unit_ref_unset(UnitRef *ref) {
2644 LIST_REMOVE(refs, ref->unit->refs, ref);
2648 int unit_exec_context_defaults(Unit *u, ExecContext *c) {
2655 /* This only copies in the ones that need memory */
2656 for (i = 0; i < RLIMIT_NLIMITS; i++)
2657 if (u->manager->rlimit[i] && !c->rlimit[i]) {
2658 c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
2663 if (u->manager->running_as == SYSTEMD_USER &&
2664 !c->working_directory) {
2666 r = get_home_dir(&c->working_directory);
2674 ExecContext *unit_get_exec_context(Unit *u) {
2678 offset = UNIT_VTABLE(u)->exec_context_offset;
2682 return (ExecContext*) ((uint8_t*) u + offset);
2685 KillContext *unit_get_kill_context(Unit *u) {
2689 offset = UNIT_VTABLE(u)->kill_context_offset;
2693 return (KillContext*) ((uint8_t*) u + offset);
2696 CGroupContext *unit_get_cgroup_context(Unit *u) {
2699 offset = UNIT_VTABLE(u)->cgroup_context_offset;
2703 return (CGroupContext*) ((uint8_t*) u + offset);
2706 ExecRuntime *unit_get_exec_runtime(Unit *u) {
2709 offset = UNIT_VTABLE(u)->exec_runtime_offset;
2713 return *(ExecRuntime**) ((uint8_t*) u + offset);
2716 static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) {
2717 _cleanup_free_ char *b = NULL;
2725 assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME));
2727 b = xescape(name, "/.");
2731 if (!filename_is_safe(b))
2734 if (u->manager->running_as == SYSTEMD_USER) {
2735 _cleanup_free_ char *c = NULL;
2737 r = user_config_home(&c);
2743 p = strjoin(c, "/", u->id, ".d", NULL);
2744 } else if (mode & UNIT_PERSISTENT)
2745 p = strjoin("/etc/systemd/system/", u->id, ".d", NULL);
2747 p = strjoin("/run/systemd/system/", u->id, ".d", NULL);
2751 q = strjoin(p, "/90-", b, ".conf", NULL);
2762 int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2763 _cleanup_free_ char *p = NULL, *q = NULL;
2770 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2773 r = drop_in_file(u, mode, name, &p, &q);
2778 return write_string_file_atomic_label(q, data);
2781 int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2782 _cleanup_free_ char *p = NULL;
2790 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2793 va_start(ap, format);
2794 r = vasprintf(&p, format, ap);
2800 return unit_write_drop_in(u, mode, name, p);
2803 int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2804 _cleanup_free_ char *ndata = NULL;
2810 if (!UNIT_VTABLE(u)->private_section)
2813 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2816 ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
2820 return unit_write_drop_in(u, mode, name, ndata);
2823 int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2824 _cleanup_free_ char *p = NULL;
2832 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2835 va_start(ap, format);
2836 r = vasprintf(&p, format, ap);
2842 return unit_write_drop_in_private(u, mode, name, p);
2845 int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
2846 _cleanup_free_ char *p = NULL, *q = NULL;
2851 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2854 r = drop_in_file(u, mode, name, &p, &q);
2859 r = errno == ENOENT ? 0 : -errno;
2867 int unit_make_transient(Unit *u) {
2872 u->load_state = UNIT_STUB;
2874 u->transient = true;
2876 free(u->fragment_path);
2877 u->fragment_path = NULL;
2879 if (u->manager->running_as == SYSTEMD_USER) {
2880 _cleanup_free_ char *c = NULL;
2882 r = user_config_home(&c);
2888 u->fragment_path = strjoin(c, "/", u->id, NULL);
2889 if (!u->fragment_path)
2894 u->fragment_path = strappend("/run/systemd/system/", u->id);
2895 if (!u->fragment_path)
2898 mkdir_p("/run/systemd/system", 0755);
2901 return write_string_file_atomic_label(u->fragment_path, "# Transient stub");
2904 int unit_kill_context(
2910 bool main_pid_alien) {
2912 int sig, wait_for_exit = 0, r;
2917 if (c->kill_mode == KILL_NONE)
2920 sig = sigkill ? SIGKILL : c->kill_signal;
2923 r = kill_and_sigcont(main_pid, sig);
2925 if (r < 0 && r != -ESRCH) {
2926 _cleanup_free_ char *comm = NULL;
2927 get_process_comm(main_pid, &comm);
2929 log_warning_unit(u->id, "Failed to kill main process %li (%s): %s",
2930 (long) main_pid, strna(comm), strerror(-r));
2932 wait_for_exit = !main_pid_alien;
2935 kill(main_pid, SIGHUP);
2939 if (control_pid > 0) {
2940 r = kill_and_sigcont(control_pid, sig);
2942 if (r < 0 && r != -ESRCH) {
2943 _cleanup_free_ char *comm = NULL;
2944 get_process_comm(control_pid, &comm);
2946 log_warning_unit(u->id,
2947 "Failed to kill control process %li (%s): %s",
2948 (long) control_pid, strna(comm), strerror(-r));
2950 wait_for_exit = true;
2953 kill(control_pid, SIGHUP);
2957 if (c->kill_mode == KILL_CONTROL_GROUP && u->cgroup_path) {
2958 _cleanup_set_free_ Set *pid_set = NULL;
2960 /* Exclude the main/control pids from being killed via the cgroup */
2961 pid_set = unit_pid_set(main_pid, control_pid);
2965 r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set);
2967 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
2968 log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
2970 wait_for_exit = true;
2971 if (c->send_sighup) {
2974 pid_set = unit_pid_set(main_pid, control_pid);
2978 cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, SIGHUP, true, true, false, pid_set);
2983 return wait_for_exit;
2986 int unit_require_mounts_for(Unit *u, const char *path) {
2987 char prefix[strlen(path) + 1], *p;
2993 /* Registers a unit for requiring a certain path and all its
2994 * prefixes. We keep a simple array of these paths in the
2995 * unit, since its usually short. However, we build a prefix
2996 * table for all possible prefixes so that new appearing mount
2997 * units can easily determine which units to make themselves a
3004 path_kill_slashes(p);
3006 if (!path_is_absolute(p)) {
3011 if (!path_is_safe(p)) {
3016 if (strv_contains(u->requires_mounts_for, p)) {
3021 r = strv_push(&u->requires_mounts_for, p);
3027 PATH_FOREACH_PREFIX_MORE(prefix, p) {
3030 x = hashmap_get(u->manager->units_requiring_mounts_for, prefix);
3034 if (!u->manager->units_requiring_mounts_for) {
3035 u->manager->units_requiring_mounts_for = hashmap_new(string_hash_func, string_compare_func);
3036 if (!u->manager->units_requiring_mounts_for)
3044 x = set_new(NULL, NULL);
3050 r = hashmap_put(u->manager->units_requiring_mounts_for, q, x);
3066 int unit_setup_exec_runtime(Unit *u) {
3072 offset = UNIT_VTABLE(u)->exec_runtime_offset;
3075 /* Check if ther already is an ExecRuntime for this unit? */
3076 rt = (ExecRuntime**) ((uint8_t*) u + offset);
3080 /* Try to get it from somebody else */
3081 SET_FOREACH(other, u->dependencies[UNIT_JOINS_NAMESPACE_OF], i) {
3083 *rt = unit_get_exec_runtime(other);
3085 exec_runtime_ref(*rt);
3090 return exec_runtime_make(rt, unit_get_exec_context(u), u->id);
3093 static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
3094 [UNIT_ACTIVE] = "active",
3095 [UNIT_RELOADING] = "reloading",
3096 [UNIT_INACTIVE] = "inactive",
3097 [UNIT_FAILED] = "failed",
3098 [UNIT_ACTIVATING] = "activating",
3099 [UNIT_DEACTIVATING] = "deactivating"
3102 DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
3104 static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
3105 [UNIT_REQUIRES] = "Requires",
3106 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
3107 [UNIT_REQUISITE] = "Requisite",
3108 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
3109 [UNIT_WANTS] = "Wants",
3110 [UNIT_BINDS_TO] = "BindsTo",
3111 [UNIT_PART_OF] = "PartOf",
3112 [UNIT_REQUIRED_BY] = "RequiredBy",
3113 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
3114 [UNIT_WANTED_BY] = "WantedBy",
3115 [UNIT_BOUND_BY] = "BoundBy",
3116 [UNIT_CONSISTS_OF] = "ConsistsOf",
3117 [UNIT_CONFLICTS] = "Conflicts",
3118 [UNIT_CONFLICTED_BY] = "ConflictedBy",
3119 [UNIT_BEFORE] = "Before",
3120 [UNIT_AFTER] = "After",
3121 [UNIT_ON_FAILURE] = "OnFailure",
3122 [UNIT_TRIGGERS] = "Triggers",
3123 [UNIT_TRIGGERED_BY] = "TriggeredBy",
3124 [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
3125 [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
3126 [UNIT_REFERENCES] = "References",
3127 [UNIT_REFERENCED_BY] = "ReferencedBy",
3128 [UNIT_JOINS_NAMESPACE_OF] = "JoinsNamespaceOf",
3131 DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);