1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include <sys/epoll.h>
26 #include <sys/timerfd.h>
32 #include "systemd/sd-id128.h"
33 #include "systemd/sd-messages.h"
38 #include "path-util.h"
39 #include "load-fragment.h"
40 #include "load-dropin.h"
42 #include "unit-name.h"
43 #include "dbus-unit.h"
45 #include "cgroup-util.h"
49 #include "fileio-label.h"
50 #include "bus-errors.h"
52 const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
53 [UNIT_SERVICE] = &service_vtable,
54 [UNIT_TIMER] = &timer_vtable,
55 [UNIT_SOCKET] = &socket_vtable,
56 [UNIT_TARGET] = &target_vtable,
57 [UNIT_DEVICE] = &device_vtable,
58 [UNIT_MOUNT] = &mount_vtable,
59 [UNIT_AUTOMOUNT] = &automount_vtable,
60 [UNIT_SNAPSHOT] = &snapshot_vtable,
61 [UNIT_SWAP] = &swap_vtable,
62 [UNIT_PATH] = &path_vtable,
63 [UNIT_SLICE] = &slice_vtable,
64 [UNIT_SCOPE] = &scope_vtable
67 Unit *unit_new(Manager *m, size_t size) {
71 assert(size >= sizeof(Unit));
77 u->names = set_new(string_hash_func, string_compare_func);
84 u->type = _UNIT_TYPE_INVALID;
85 u->deserialized_job = _JOB_TYPE_INVALID;
86 u->default_dependencies = true;
87 u->unit_file_state = _UNIT_FILE_STATE_INVALID;
92 bool unit_has_name(Unit *u, const char *name) {
96 return !!set_get(u->names, (char*) name);
99 int unit_add_name(Unit *u, const char *text) {
107 if (unit_name_is_template(text)) {
111 s = unit_name_replace_instance(text, u->instance);
118 if (!unit_name_is_valid(s, false)) {
123 assert_se((t = unit_name_to_type(s)) >= 0);
125 if (u->type != _UNIT_TYPE_INVALID && t != u->type) {
130 if ((r = unit_name_to_instance(s, &i)) < 0)
133 if (i && unit_vtable[t]->no_instances) {
138 /* Ensure that this unit is either instanced or not instanced,
140 if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) {
145 if (unit_vtable[t]->no_alias &&
146 !set_isempty(u->names) &&
147 !set_get(u->names, s)) {
152 if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) {
157 if ((r = set_put(u->names, s)) < 0) {
163 if ((r = hashmap_put(u->manager->units, s, u)) < 0) {
164 set_remove(u->names, s);
168 if (u->type == _UNIT_TYPE_INVALID) {
174 LIST_PREPEND(units_by_type, u->manager->units_by_type[t], u);
176 if (UNIT_VTABLE(u)->init)
177 UNIT_VTABLE(u)->init(u);
181 unit_add_to_dbus_queue(u);
191 int unit_choose_id(Unit *u, const char *name) {
193 _cleanup_free_ char *t = NULL;
199 if (unit_name_is_template(name)) {
204 if (!(t = unit_name_replace_instance(name, u->instance)))
210 /* Selects one of the names of this unit as the id */
211 s = set_get(u->names, (char*) name);
216 if ((r = unit_name_to_instance(s, &i)) < 0)
224 unit_add_to_dbus_queue(u);
229 int unit_set_description(Unit *u, const char *description) {
234 if (isempty(description))
237 s = strdup(description);
242 free(u->description);
245 unit_add_to_dbus_queue(u);
249 bool unit_check_gc(Unit *u) {
252 if (u->load_state == UNIT_STUB)
255 if (UNIT_VTABLE(u)->no_gc)
267 if (unit_active_state(u) != UNIT_INACTIVE)
273 if (UNIT_VTABLE(u)->check_gc)
274 if (UNIT_VTABLE(u)->check_gc(u))
280 void unit_add_to_load_queue(Unit *u) {
282 assert(u->type != _UNIT_TYPE_INVALID);
284 if (u->load_state != UNIT_STUB || u->in_load_queue)
287 LIST_PREPEND(load_queue, u->manager->load_queue, u);
288 u->in_load_queue = true;
291 void unit_add_to_cleanup_queue(Unit *u) {
294 if (u->in_cleanup_queue)
297 LIST_PREPEND(cleanup_queue, u->manager->cleanup_queue, u);
298 u->in_cleanup_queue = true;
301 void unit_add_to_gc_queue(Unit *u) {
304 if (u->in_gc_queue || u->in_cleanup_queue)
307 if (unit_check_gc(u))
310 LIST_PREPEND(gc_queue, u->manager->gc_queue, u);
311 u->in_gc_queue = true;
313 u->manager->n_in_gc_queue ++;
316 void unit_add_to_dbus_queue(Unit *u) {
318 assert(u->type != _UNIT_TYPE_INVALID);
320 if (u->load_state == UNIT_STUB || u->in_dbus_queue)
323 /* Shortcut things if nobody cares */
324 if (!bus_has_subscriber(u->manager)) {
325 u->sent_dbus_new_signal = true;
329 LIST_PREPEND(dbus_queue, u->manager->dbus_unit_queue, u);
330 u->in_dbus_queue = true;
333 static void bidi_set_free(Unit *u, Set *s) {
339 /* Frees the set and makes sure we are dropped from the
340 * inverse pointers */
342 SET_FOREACH(other, s, i) {
345 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
346 set_remove(other->dependencies[d], u);
348 unit_add_to_gc_queue(other);
354 static void unit_remove_transient(Unit *u) {
362 if (u->fragment_path)
363 unlink(u->fragment_path);
365 STRV_FOREACH(i, u->dropin_paths) {
366 _cleanup_free_ char *p = NULL;
371 r = path_get_parent(*i, &p);
377 static void unit_free_requires_mounts_for(Unit *u) {
380 STRV_FOREACH(j, u->requires_mounts_for) {
381 char s[strlen(*j) + 1];
383 PATH_FOREACH_PREFIX_MORE(s, *j) {
387 x = hashmap_get2(u->manager->units_requiring_mounts_for, s, (void**) &y);
393 if (set_isempty(x)) {
394 hashmap_remove(u->manager->units_requiring_mounts_for, y);
401 strv_free(u->requires_mounts_for);
402 u->requires_mounts_for = NULL;
405 void unit_free(Unit *u) {
412 if (u->manager->n_reloading <= 0)
413 unit_remove_transient(u);
415 bus_unit_send_removed_signal(u);
417 if (u->load_state != UNIT_STUB)
418 if (UNIT_VTABLE(u)->done)
419 UNIT_VTABLE(u)->done(u);
421 unit_free_requires_mounts_for(u);
423 SET_FOREACH(t, u->names, i)
424 hashmap_remove_value(u->manager->units, t, u);
438 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
439 bidi_set_free(u, u->dependencies[d]);
441 if (u->type != _UNIT_TYPE_INVALID)
442 LIST_REMOVE(units_by_type, u->manager->units_by_type[u->type], u);
444 if (u->in_load_queue)
445 LIST_REMOVE(load_queue, u->manager->load_queue, u);
447 if (u->in_dbus_queue)
448 LIST_REMOVE(dbus_queue, u->manager->dbus_unit_queue, u);
450 if (u->in_cleanup_queue)
451 LIST_REMOVE(cleanup_queue, u->manager->cleanup_queue, u);
453 if (u->in_gc_queue) {
454 LIST_REMOVE(gc_queue, u->manager->gc_queue, u);
455 u->manager->n_in_gc_queue--;
458 if (u->in_cgroup_queue)
459 LIST_REMOVE(cgroup_queue, u->manager->cgroup_queue, u);
461 if (u->cgroup_path) {
462 hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
463 free(u->cgroup_path);
466 free(u->description);
467 strv_free(u->documentation);
468 free(u->fragment_path);
469 free(u->source_path);
470 strv_free(u->dropin_paths);
473 set_free_free(u->names);
475 condition_free_list(u->conditions);
477 unit_ref_unset(&u->slice);
480 unit_ref_unset(u->refs);
485 UnitActiveState unit_active_state(Unit *u) {
488 if (u->load_state == UNIT_MERGED)
489 return unit_active_state(unit_follow_merge(u));
491 /* After a reload it might happen that a unit is not correctly
492 * loaded but still has a process around. That's why we won't
493 * shortcut failed loading to UNIT_INACTIVE_FAILED. */
495 return UNIT_VTABLE(u)->active_state(u);
498 const char* unit_sub_state_to_string(Unit *u) {
501 return UNIT_VTABLE(u)->sub_state_to_string(u);
504 static void complete_move(Set **s, Set **other) {
512 set_move(*s, *other);
519 static void merge_names(Unit *u, Unit *other) {
526 complete_move(&u->names, &other->names);
528 set_free_free(other->names);
532 SET_FOREACH(t, u->names, i)
533 assert_se(hashmap_replace(u->manager->units, t, u) == 0);
536 static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
543 assert(d < _UNIT_DEPENDENCY_MAX);
545 /* Fix backwards pointers */
546 SET_FOREACH(back, other->dependencies[d], i) {
549 for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++)
550 if ((r = set_remove_and_put(back->dependencies[k], other, u)) < 0) {
553 set_remove(back->dependencies[k], other);
555 assert(r == -ENOENT);
559 complete_move(&u->dependencies[d], &other->dependencies[d]);
561 set_free(other->dependencies[d]);
562 other->dependencies[d] = NULL;
565 int unit_merge(Unit *u, Unit *other) {
570 assert(u->manager == other->manager);
571 assert(u->type != _UNIT_TYPE_INVALID);
573 other = unit_follow_merge(other);
578 if (u->type != other->type)
581 if (!u->instance != !other->instance)
584 if (other->load_state != UNIT_STUB &&
585 other->load_state != UNIT_NOT_FOUND)
594 if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
598 merge_names(u, other);
600 /* Redirect all references */
602 unit_ref_set(other->refs, u);
604 /* Merge dependencies */
605 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
606 merge_dependencies(u, other, d);
608 other->load_state = UNIT_MERGED;
609 other->merged_into = u;
611 /* If there is still some data attached to the other node, we
612 * don't need it anymore, and can free it. */
613 if (other->load_state != UNIT_STUB)
614 if (UNIT_VTABLE(other)->done)
615 UNIT_VTABLE(other)->done(other);
617 unit_add_to_dbus_queue(u);
618 unit_add_to_cleanup_queue(other);
623 int unit_merge_by_name(Unit *u, const char *name) {
626 _cleanup_free_ char *s = NULL;
631 if (unit_name_is_template(name)) {
635 if (!(s = unit_name_replace_instance(name, u->instance)))
641 other = manager_get_unit(u->manager, name);
643 r = unit_add_name(u, name);
645 r = unit_merge(u, other);
650 Unit* unit_follow_merge(Unit *u) {
653 while (u->load_state == UNIT_MERGED)
654 assert_se(u = u->merged_into);
659 int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
665 if (c->std_output != EXEC_OUTPUT_KMSG &&
666 c->std_output != EXEC_OUTPUT_SYSLOG &&
667 c->std_output != EXEC_OUTPUT_JOURNAL &&
668 c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
669 c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
670 c->std_output != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
671 c->std_error != EXEC_OUTPUT_KMSG &&
672 c->std_error != EXEC_OUTPUT_SYSLOG &&
673 c->std_error != EXEC_OUTPUT_JOURNAL &&
674 c->std_error != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
675 c->std_error != EXEC_OUTPUT_JOURNAL_AND_CONSOLE &&
676 c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE)
679 /* If syslog or kernel logging is requested, make sure our own
680 * logging daemon is run first. */
682 if (u->manager->running_as == SYSTEMD_SYSTEM) {
683 r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_JOURNALD_SOCKET, NULL, true);
691 const char *unit_description(Unit *u) {
695 return u->description;
700 void unit_dump(Unit *u, FILE *f, const char *prefix) {
704 _cleanup_free_ char *p2 = NULL;
707 timestamp1[FORMAT_TIMESTAMP_MAX],
708 timestamp2[FORMAT_TIMESTAMP_MAX],
709 timestamp3[FORMAT_TIMESTAMP_MAX],
710 timestamp4[FORMAT_TIMESTAMP_MAX],
711 timespan[FORMAT_TIMESPAN_MAX];
715 assert(u->type >= 0);
719 p2 = strappend(prefix, "\t");
720 prefix2 = p2 ? p2 : prefix;
724 "%s\tDescription: %s\n"
726 "%s\tUnit Load State: %s\n"
727 "%s\tUnit Active State: %s\n"
728 "%s\tInactive Exit Timestamp: %s\n"
729 "%s\tActive Enter Timestamp: %s\n"
730 "%s\tActive Exit Timestamp: %s\n"
731 "%s\tInactive Enter Timestamp: %s\n"
732 "%s\tGC Check Good: %s\n"
733 "%s\tNeed Daemon Reload: %s\n"
734 "%s\tTransient: %s\n"
737 "%s\tCGroup realized: %s\n"
738 "%s\tCGroup mask: 0x%x\n",
740 prefix, unit_description(u),
741 prefix, strna(u->instance),
742 prefix, unit_load_state_to_string(u->load_state),
743 prefix, unit_active_state_to_string(unit_active_state(u)),
744 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->inactive_exit_timestamp.realtime)),
745 prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->active_enter_timestamp.realtime)),
746 prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->active_exit_timestamp.realtime)),
747 prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->inactive_enter_timestamp.realtime)),
748 prefix, yes_no(unit_check_gc(u)),
749 prefix, yes_no(unit_need_daemon_reload(u)),
750 prefix, yes_no(u->transient),
751 prefix, strna(unit_slice_name(u)),
752 prefix, strna(u->cgroup_path),
753 prefix, yes_no(u->cgroup_realized),
754 prefix, u->cgroup_mask);
756 SET_FOREACH(t, u->names, i)
757 fprintf(f, "%s\tName: %s\n", prefix, t);
759 STRV_FOREACH(j, u->documentation)
760 fprintf(f, "%s\tDocumentation: %s\n", prefix, *j);
762 if ((following = unit_following(u)))
763 fprintf(f, "%s\tFollowing: %s\n", prefix, following->id);
765 if (u->fragment_path)
766 fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path);
769 fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path);
771 STRV_FOREACH(j, u->dropin_paths)
772 fprintf(f, "%s\tDropIn Path: %s\n", prefix, *j);
774 if (u->job_timeout > 0)
775 fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
777 condition_dump_list(u->conditions, f, prefix);
779 if (dual_timestamp_is_set(&u->condition_timestamp))
781 "%s\tCondition Timestamp: %s\n"
782 "%s\tCondition Result: %s\n",
783 prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->condition_timestamp.realtime)),
784 prefix, yes_no(u->condition_result));
786 for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
789 SET_FOREACH(other, u->dependencies[d], i)
790 fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
793 if (!strv_isempty(u->requires_mounts_for)) {
795 "%s\tRequiresMountsFor:", prefix);
797 STRV_FOREACH(j, u->requires_mounts_for)
798 fprintf(f, " %s", *j);
803 if (u->load_state == UNIT_LOADED) {
806 "%s\tStopWhenUnneeded: %s\n"
807 "%s\tRefuseManualStart: %s\n"
808 "%s\tRefuseManualStop: %s\n"
809 "%s\tDefaultDependencies: %s\n"
810 "%s\tOnFailureIsolate: %s\n"
811 "%s\tIgnoreOnIsolate: %s\n"
812 "%s\tIgnoreOnSnapshot: %s\n",
813 prefix, yes_no(u->stop_when_unneeded),
814 prefix, yes_no(u->refuse_manual_start),
815 prefix, yes_no(u->refuse_manual_stop),
816 prefix, yes_no(u->default_dependencies),
817 prefix, yes_no(u->on_failure_isolate),
818 prefix, yes_no(u->ignore_on_isolate),
819 prefix, yes_no(u->ignore_on_snapshot));
821 if (UNIT_VTABLE(u)->dump)
822 UNIT_VTABLE(u)->dump(u, f, prefix2);
824 } else if (u->load_state == UNIT_MERGED)
826 "%s\tMerged into: %s\n",
827 prefix, u->merged_into->id);
828 else if (u->load_state == UNIT_ERROR)
829 fprintf(f, "%s\tLoad Error Code: %s\n", prefix, strerror(-u->load_error));
833 job_dump(u->job, f, prefix2);
836 job_dump(u->nop_job, f, prefix2);
840 /* Common implementation for multiple backends */
841 int unit_load_fragment_and_dropin(Unit *u) {
846 /* Load a .service file */
847 r = unit_load_fragment(u);
851 if (u->load_state == UNIT_STUB)
854 /* Load drop-in directory data */
855 r = unit_load_dropin(unit_follow_merge(u));
862 /* Common implementation for multiple backends */
863 int unit_load_fragment_and_dropin_optional(Unit *u) {
868 /* Same as unit_load_fragment_and_dropin(), but whether
869 * something can be loaded or not doesn't matter. */
871 /* Load a .service file */
872 r = unit_load_fragment(u);
876 if (u->load_state == UNIT_STUB)
877 u->load_state = UNIT_LOADED;
879 /* Load drop-in directory data */
880 r = unit_load_dropin(unit_follow_merge(u));
887 int unit_add_default_target_dependency(Unit *u, Unit *target) {
891 if (target->type != UNIT_TARGET)
894 /* Only add the dependency if both units are loaded, so that
895 * that loop check below is reliable */
896 if (u->load_state != UNIT_LOADED ||
897 target->load_state != UNIT_LOADED)
900 /* If either side wants no automatic dependencies, then let's
902 if (!u->default_dependencies ||
903 !target->default_dependencies)
906 /* Don't create loops */
907 if (set_get(target->dependencies[UNIT_BEFORE], u))
910 return unit_add_dependency(target, UNIT_AFTER, u, true);
913 static int unit_add_default_dependencies(Unit *u) {
915 static const UnitDependency deps[] = {
917 UNIT_REQUIRED_BY_OVERRIDABLE,
929 for (k = 0; k < ELEMENTSOF(deps); k++)
930 SET_FOREACH(target, u->dependencies[deps[k]], i) {
931 r = unit_add_default_target_dependency(u, target);
936 if (u->default_dependencies && unit_get_cgroup_context(u)) {
937 if (UNIT_ISSET(u->slice))
938 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true);
940 r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, SPECIAL_ROOT_SLICE, NULL, true);
949 static int unit_add_mount_links(Unit *u) {
955 STRV_FOREACH(i, u->requires_mounts_for) {
956 char prefix[strlen(*i) + 1];
958 PATH_FOREACH_PREFIX_MORE(prefix, *i) {
961 r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m);
969 if (m->load_state != UNIT_LOADED)
972 r = unit_add_dependency(u, UNIT_AFTER, m, true);
976 if (m->fragment_path) {
977 r = unit_add_dependency(u, UNIT_REQUIRES, m, true);
987 int unit_load(Unit *u) {
992 if (u->in_load_queue) {
993 LIST_REMOVE(load_queue, u->manager->load_queue, u);
994 u->in_load_queue = false;
997 if (u->type == _UNIT_TYPE_INVALID)
1000 if (u->load_state != UNIT_STUB)
1003 if (UNIT_VTABLE(u)->load) {
1004 r = UNIT_VTABLE(u)->load(u);
1009 if (u->load_state == UNIT_STUB) {
1014 if (u->load_state == UNIT_LOADED) {
1016 if (u->default_dependencies) {
1017 r = unit_add_default_dependencies(u);
1022 r = unit_add_mount_links(u);
1026 if (u->on_failure_isolate &&
1027 set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
1029 log_error_unit(u->id,
1030 "More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.", u->id);
1037 assert((u->load_state != UNIT_MERGED) == !u->merged_into);
1039 unit_add_to_dbus_queue(unit_follow_merge(u));
1040 unit_add_to_gc_queue(u);
1045 u->load_state = u->load_state == UNIT_STUB ? UNIT_NOT_FOUND : UNIT_ERROR;
1047 unit_add_to_dbus_queue(u);
1048 unit_add_to_gc_queue(u);
1050 log_debug_unit(u->id, "Failed to load configuration for %s: %s",
1051 u->id, strerror(-r));
1056 static bool unit_condition_test(Unit *u) {
1059 dual_timestamp_get(&u->condition_timestamp);
1060 u->condition_result = condition_test_list(u->id, u->conditions);
1062 return u->condition_result;
1065 _pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
1066 const UnitStatusMessageFormats *format_table;
1070 assert(t < _JOB_TYPE_MAX);
1072 if (t != JOB_START && t != JOB_STOP)
1075 format_table = &UNIT_VTABLE(u)->status_message_formats;
1079 return format_table->starting_stopping[t == JOB_STOP];
1082 _pure_ static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) {
1087 assert(t < _JOB_TYPE_MAX);
1089 format = unit_get_status_message_format(u, t);
1093 /* Return generic strings */
1095 return "Starting %s.";
1096 else if (t == JOB_STOP)
1097 return "Stopping %s.";
1098 else if (t == JOB_RELOAD)
1099 return "Reloading %s.";
1104 static void unit_status_print_starting_stopping(Unit *u, JobType t) {
1109 /* We only print status messages for selected units on
1110 * selected operations. */
1112 format = unit_get_status_message_format(u, t);
1116 unit_status_printf(u, "", format);
1119 #pragma GCC diagnostic push
1120 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
1121 static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
1128 if (t != JOB_START && t != JOB_STOP && t != JOB_RELOAD)
1131 if (log_on_console())
1134 /* We log status messages for all units and all operations. */
1136 format = unit_get_status_message_format_try_harder(u, t);
1140 snprintf(buf, sizeof(buf), format, unit_description(u));
1143 mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
1144 t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
1145 SD_MESSAGE_UNIT_RELOADING;
1147 log_struct_unit(LOG_INFO,
1153 #pragma GCC diagnostic pop
1156 * -EBADR: This unit type does not support starting.
1157 * -EALREADY: Unit is already started.
1158 * -EAGAIN: An operation is already in progress. Retry later.
1159 * -ECANCELED: Too many requests for now.
1161 int unit_start(Unit *u) {
1162 UnitActiveState state;
1167 if (u->load_state != UNIT_LOADED)
1170 /* If this is already started, then this will succeed. Note
1171 * that this will even succeed if this unit is not startable
1172 * by the user. This is relied on to detect when we need to
1173 * wait for units and when waiting is finished. */
1174 state = unit_active_state(u);
1175 if (UNIT_IS_ACTIVE_OR_RELOADING(state))
1178 /* If the conditions failed, don't do anything at all. If we
1179 * already are activating this call might still be useful to
1180 * speed up activation in case there is some hold-off time,
1181 * but we don't want to recheck the condition in that case. */
1182 if (state != UNIT_ACTIVATING &&
1183 !unit_condition_test(u)) {
1184 log_debug_unit(u->id, "Starting of %s requested but condition failed. Ignoring.", u->id);
1188 /* Forward to the main object, if we aren't it. */
1189 following = unit_following(u);
1191 log_debug_unit(u->id, "Redirecting start request from %s to %s.",
1192 u->id, following->id);
1193 return unit_start(following);
1196 unit_status_log_starting_stopping_reloading(u, JOB_START);
1197 unit_status_print_starting_stopping(u, JOB_START);
1199 /* If it is stopped, but we cannot start it, then fail */
1200 if (!UNIT_VTABLE(u)->start)
1203 /* We don't suppress calls to ->start() here when we are
1204 * already starting, to allow this request to be used as a
1205 * "hurry up" call, for example when the unit is in some "auto
1206 * restart" state where it waits for a holdoff timer to elapse
1207 * before it will start again. */
1209 unit_add_to_dbus_queue(u);
1211 return UNIT_VTABLE(u)->start(u);
1214 bool unit_can_start(Unit *u) {
1217 return !!UNIT_VTABLE(u)->start;
1220 bool unit_can_isolate(Unit *u) {
1223 return unit_can_start(u) &&
1228 * -EBADR: This unit type does not support stopping.
1229 * -EALREADY: Unit is already stopped.
1230 * -EAGAIN: An operation is already in progress. Retry later.
1232 int unit_stop(Unit *u) {
1233 UnitActiveState state;
1238 state = unit_active_state(u);
1239 if (UNIT_IS_INACTIVE_OR_FAILED(state))
1242 if ((following = unit_following(u))) {
1243 log_debug_unit(u->id, "Redirecting stop request from %s to %s.",
1244 u->id, following->id);
1245 return unit_stop(following);
1248 unit_status_log_starting_stopping_reloading(u, JOB_STOP);
1249 unit_status_print_starting_stopping(u, JOB_STOP);
1251 if (!UNIT_VTABLE(u)->stop)
1254 unit_add_to_dbus_queue(u);
1256 return UNIT_VTABLE(u)->stop(u);
1260 * -EBADR: This unit type does not support reloading.
1261 * -ENOEXEC: Unit is not started.
1262 * -EAGAIN: An operation is already in progress. Retry later.
1264 int unit_reload(Unit *u) {
1265 UnitActiveState state;
1270 if (u->load_state != UNIT_LOADED)
1273 if (!unit_can_reload(u))
1276 state = unit_active_state(u);
1277 if (state == UNIT_RELOADING)
1280 if (state != UNIT_ACTIVE)
1283 if ((following = unit_following(u))) {
1284 log_debug_unit(u->id, "Redirecting reload request from %s to %s.",
1285 u->id, following->id);
1286 return unit_reload(following);
1289 unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
1291 unit_add_to_dbus_queue(u);
1292 return UNIT_VTABLE(u)->reload(u);
1295 bool unit_can_reload(Unit *u) {
1298 if (!UNIT_VTABLE(u)->reload)
1301 if (!UNIT_VTABLE(u)->can_reload)
1304 return UNIT_VTABLE(u)->can_reload(u);
1307 static void unit_check_unneeded(Unit *u) {
1313 /* If this service shall be shut down when unneeded then do
1316 if (!u->stop_when_unneeded)
1319 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1322 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
1323 if (unit_active_or_pending(other))
1326 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
1327 if (unit_active_or_pending(other))
1330 SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
1331 if (unit_active_or_pending(other))
1334 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1335 if (unit_active_or_pending(other))
1338 log_info_unit(u->id, "Service %s is not needed anymore. Stopping.", u->id);
1340 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
1341 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
1344 static void retroactively_start_dependencies(Unit *u) {
1349 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1351 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1352 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1353 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1354 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1356 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1357 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1358 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1359 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1361 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1362 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1363 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1364 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1366 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1367 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1368 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1369 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1371 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
1372 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1373 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1375 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
1376 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1377 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1380 static void retroactively_stop_dependencies(Unit *u) {
1385 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1387 /* Pull down units which are bound to us recursively if enabled */
1388 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1389 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1390 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1393 static void check_unneeded_dependencies(Unit *u) {
1398 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1400 /* Garbage collect services that might not be needed anymore, if enabled */
1401 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1402 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1403 unit_check_unneeded(other);
1404 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1405 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1406 unit_check_unneeded(other);
1407 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1408 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1409 unit_check_unneeded(other);
1410 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
1411 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1412 unit_check_unneeded(other);
1413 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
1414 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1415 unit_check_unneeded(other);
1416 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1417 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1418 unit_check_unneeded(other);
1421 void unit_start_on_failure(Unit *u) {
1427 if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
1430 log_info_unit(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
1432 SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
1435 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL);
1437 log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
1441 void unit_trigger_notify(Unit *u) {
1447 SET_FOREACH(other, u->dependencies[UNIT_TRIGGERED_BY], i)
1448 if (UNIT_VTABLE(other)->trigger_notify)
1449 UNIT_VTABLE(other)->trigger_notify(other, u);
1452 void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
1457 assert(os < _UNIT_ACTIVE_STATE_MAX);
1458 assert(ns < _UNIT_ACTIVE_STATE_MAX);
1460 /* Note that this is called for all low-level state changes,
1461 * even if they might map to the same high-level
1462 * UnitActiveState! That means that ns == os is OK an expected
1463 * behavior here. For example: if a mount point is remounted
1464 * this function will be called too! */
1468 if (m->n_reloading <= 0) {
1471 dual_timestamp_get(&ts);
1473 if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
1474 u->inactive_exit_timestamp = ts;
1475 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
1476 u->inactive_enter_timestamp = ts;
1478 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
1479 u->active_enter_timestamp = ts;
1480 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
1481 u->active_exit_timestamp = ts;
1484 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1485 unit_destroy_cgroup(u);
1487 if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1488 ExecContext *ec = unit_get_exec_context(u);
1489 if (ec && exec_context_may_touch_console(ec)) {
1490 if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1493 if (m->n_on_console == 0)
1494 /* unset no_console_output flag, since the console is free */
1495 m->no_console_output = 0;
1504 if (u->job->state == JOB_WAITING)
1506 /* So we reached a different state for this
1507 * job. Let's see if we can run it now if it
1508 * failed previously due to EAGAIN. */
1509 job_add_to_run_queue(u->job);
1511 /* Let's check whether this state change constitutes a
1512 * finished job, or maybe contradicts a running job and
1513 * hence needs to invalidate jobs. */
1515 switch (u->job->type) {
1518 case JOB_VERIFY_ACTIVE:
1520 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
1521 job_finish_and_invalidate(u->job, JOB_DONE, true);
1522 else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
1525 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1526 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1532 case JOB_RELOAD_OR_START:
1534 if (u->job->state == JOB_RUNNING) {
1535 if (ns == UNIT_ACTIVE)
1536 job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
1537 else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
1540 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1541 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1549 case JOB_TRY_RESTART:
1551 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1552 job_finish_and_invalidate(u->job, JOB_DONE, true);
1553 else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
1555 job_finish_and_invalidate(u->job, JOB_FAILED, true);
1561 assert_not_reached("Job type unknown");
1567 if (m->n_reloading <= 0) {
1569 /* If this state change happened without being
1570 * requested by a job, then let's retroactively start
1571 * or stop dependencies. We skip that step when
1572 * deserializing, since we don't want to create any
1573 * additional jobs just because something is already
1577 if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1578 retroactively_start_dependencies(u);
1579 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1580 retroactively_stop_dependencies(u);
1583 /* stop unneeded units regardless if going down was expected or not */
1584 if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1585 check_unneeded_dependencies(u);
1587 if (ns != os && ns == UNIT_FAILED) {
1588 log_notice_unit(u->id,
1589 "Unit %s entered failed state.", u->id);
1590 unit_start_on_failure(u);
1594 /* Some names are special */
1595 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
1597 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
1598 /* The bus just might have become available,
1599 * hence try to connect to it, if we aren't
1603 if (u->type == UNIT_SERVICE &&
1604 !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
1605 m->n_reloading <= 0) {
1606 /* Write audit record if we have just finished starting up */
1607 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
1611 if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
1612 manager_send_unit_plymouth(m, u);
1616 /* We don't care about D-Bus here, since we'll get an
1617 * asynchronous notification for it anyway. */
1619 if (u->type == UNIT_SERVICE &&
1620 UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1621 !UNIT_IS_INACTIVE_OR_FAILED(os) &&
1622 m->n_reloading <= 0) {
1624 /* Hmm, if there was no start record written
1625 * write it now, so that we always have a nice
1628 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
1630 if (ns == UNIT_INACTIVE)
1631 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
1633 /* Write audit record if we have just finished shutting down */
1634 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
1636 u->in_audit = false;
1640 manager_recheck_journal(m);
1641 unit_trigger_notify(u);
1643 /* Maybe we finished startup and are now ready for being
1644 * stopped because unneeded? */
1645 if (u->manager->n_reloading <= 0)
1646 unit_check_unneeded(u);
1648 unit_add_to_dbus_queue(u);
1649 unit_add_to_gc_queue(u);
1652 int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) {
1653 struct epoll_event ev = {
1661 assert(w->type == WATCH_INVALID || (w->type == WATCH_FD && w->fd == fd && w->data.unit == u));
1663 if (epoll_ctl(u->manager->epoll_fd,
1664 w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD,
1676 void unit_unwatch_fd(Unit *u, Watch *w) {
1680 if (w->type == WATCH_INVALID)
1683 assert(w->type == WATCH_FD);
1684 assert(w->data.unit == u);
1685 assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
1688 w->type = WATCH_INVALID;
1689 w->data.unit = NULL;
1692 int unit_watch_pid(Unit *u, pid_t pid) {
1696 /* Watch a specific PID. We only support one unit watching
1697 * each PID for now. */
1699 return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1702 void unit_unwatch_pid(Unit *u, pid_t pid) {
1706 hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1709 int unit_watch_timer(Unit *u, clockid_t clock_id, bool relative, usec_t usec, Watch *w) {
1710 struct itimerspec its = {};
1716 assert(w->type == WATCH_INVALID || (w->type == WATCH_UNIT_TIMER && w->data.unit == u));
1718 /* This will try to reuse the old timer if there is one */
1720 if (w->type == WATCH_UNIT_TIMER) {
1721 assert(w->data.unit == u);
1726 } else if (w->type == WATCH_INVALID) {
1729 fd = timerfd_create(clock_id, TFD_NONBLOCK|TFD_CLOEXEC);
1733 assert_not_reached("Invalid watch type");
1736 /* Set absolute time in the past, but not 0, since we
1737 * don't want to disarm the timer */
1738 its.it_value.tv_sec = 0;
1739 its.it_value.tv_nsec = 1;
1741 flags = TFD_TIMER_ABSTIME;
1743 timespec_store(&its.it_value, usec);
1744 flags = relative ? 0 : TFD_TIMER_ABSTIME;
1747 /* This will also flush the elapse counter */
1748 if (timerfd_settime(fd, flags, &its, NULL) < 0)
1751 if (w->type == WATCH_INVALID) {
1752 struct epoll_event ev = {
1757 if (epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
1761 w->type = WATCH_UNIT_TIMER;
1769 close_nointr_nofail(fd);
1774 void unit_unwatch_timer(Unit *u, Watch *w) {
1778 if (w->type == WATCH_INVALID)
1781 assert(w->type == WATCH_UNIT_TIMER);
1782 assert(w->data.unit == u);
1785 assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
1786 close_nointr_nofail(w->fd);
1789 w->type = WATCH_INVALID;
1790 w->data.unit = NULL;
1793 bool unit_job_is_applicable(Unit *u, JobType j) {
1795 assert(j >= 0 && j < _JOB_TYPE_MAX);
1799 case JOB_VERIFY_ACTIVE:
1806 case JOB_TRY_RESTART:
1807 return unit_can_start(u);
1810 return unit_can_reload(u);
1812 case JOB_RELOAD_OR_START:
1813 return unit_can_reload(u) && unit_can_start(u);
1816 assert_not_reached("Invalid job type");
1820 int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
1822 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
1823 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
1824 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1825 [UNIT_WANTS] = UNIT_WANTED_BY,
1826 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
1827 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1828 [UNIT_BINDS_TO] = UNIT_BOUND_BY,
1829 [UNIT_PART_OF] = UNIT_CONSISTS_OF,
1830 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
1831 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
1832 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
1833 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
1834 [UNIT_CONSISTS_OF] = UNIT_PART_OF,
1835 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
1836 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
1837 [UNIT_BEFORE] = UNIT_AFTER,
1838 [UNIT_AFTER] = UNIT_BEFORE,
1839 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
1840 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
1841 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
1842 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
1843 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
1844 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
1845 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
1847 int r, q = 0, v = 0, w = 0;
1850 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
1853 u = unit_follow_merge(u);
1854 other = unit_follow_merge(other);
1856 /* We won't allow dependencies on ourselves. We will not
1857 * consider them an error however. */
1861 if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
1864 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
1865 if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
1869 if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
1870 (r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
1873 if ((q = set_put(u->dependencies[d], other)) < 0)
1876 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
1877 if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) {
1882 if (add_reference) {
1883 if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) {
1888 if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0)
1892 unit_add_to_dbus_queue(u);
1897 set_remove(u->dependencies[d], other);
1900 set_remove(other->dependencies[inverse_table[d]], u);
1903 set_remove(u->dependencies[UNIT_REFERENCES], other);
1908 int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
1913 if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
1916 if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
1922 static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
1926 assert(name || path);
1930 name = path_get_file_name(path);
1932 if (!unit_name_is_template(name)) {
1938 s = unit_name_replace_instance(name, u->instance);
1940 _cleanup_free_ char *i = NULL;
1942 i = unit_name_to_prefix(u->id);
1946 s = unit_name_replace_instance(name, i);
1956 int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1959 _cleanup_free_ char *s = NULL;
1962 assert(name || path);
1964 name = resolve_template(u, name, path, &s);
1968 r = manager_load_unit(u->manager, name, path, NULL, &other);
1972 return unit_add_dependency(u, d, other, add_reference);
1975 int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
1978 _cleanup_free_ char *s = NULL;
1981 assert(name || path);
1983 if (!(name = resolve_template(u, name, path, &s)))
1986 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1989 r = unit_add_two_dependencies(u, d, e, other, add_reference);
1994 int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1997 _cleanup_free_ char *s = NULL;
2000 assert(name || path);
2002 if (!(name = resolve_template(u, name, path, &s)))
2005 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
2008 r = unit_add_dependency(other, d, u, add_reference);
2013 int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) {
2016 _cleanup_free_ char *s = NULL;
2019 assert(name || path);
2021 if (!(name = resolve_template(u, name, path, &s)))
2024 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
2027 if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
2033 int set_unit_path(const char *p) {
2034 _cleanup_free_ char *c = NULL;
2036 /* This is mostly for debug purposes */
2037 c = path_make_absolute_cwd(p);
2038 if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0)
2044 char *unit_dbus_path(Unit *u) {
2050 return unit_dbus_path_from_name(u->id);
2053 char *unit_default_cgroup_path(Unit *u) {
2054 _cleanup_free_ char *escaped = NULL, *slice = NULL;
2059 if (unit_has_name(u, SPECIAL_ROOT_SLICE))
2060 return strdup(u->manager->cgroup_root);
2062 if (UNIT_ISSET(u->slice) && !unit_has_name(UNIT_DEREF(u->slice), SPECIAL_ROOT_SLICE)) {
2063 r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice);
2068 escaped = cg_escape(u->id);
2073 return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL);
2075 return strjoin(u->manager->cgroup_root, "/", escaped, NULL);
2078 int unit_add_default_slice(Unit *u) {
2079 _cleanup_free_ char *b = NULL;
2080 const char *slice_name;
2086 if (UNIT_ISSET(u->slice))
2089 if (!unit_get_cgroup_context(u))
2093 _cleanup_free_ char *prefix = NULL, *escaped = NULL;
2095 /* Implicitly place all instantiated units in their
2096 * own per-template slice */
2098 prefix = unit_name_to_prefix(u->id);
2102 /* The prefix is already escaped, but it might include
2103 * "-" which has a special meaning for slice units,
2104 * hence escape it here extra. */
2105 escaped = strreplace(prefix, "-", "\\x2d");
2109 if (u->manager->running_as == SYSTEMD_SYSTEM)
2110 b = strjoin("system-", escaped, ".slice", NULL);
2112 b = strappend(escaped, ".slice");
2119 u->manager->running_as == SYSTEMD_SYSTEM
2120 ? SPECIAL_SYSTEM_SLICE
2121 : SPECIAL_ROOT_SLICE;
2123 r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
2127 unit_ref_set(&u->slice, slice);
2131 const char *unit_slice_name(Unit *u) {
2134 if (!UNIT_ISSET(u->slice))
2137 return UNIT_DEREF(u->slice)->id;
2140 int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
2141 _cleanup_free_ char *t = NULL;
2148 t = unit_name_change_suffix(u->id, type);
2152 assert(!unit_has_name(u, t));
2154 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
2155 assert(r < 0 || *_found != u);
2159 int unit_watch_bus_name(Unit *u, const char *name) {
2163 /* Watch a specific name on the bus. We only support one unit
2164 * watching each name for now. */
2166 return hashmap_put(u->manager->watch_bus, name, u);
2169 void unit_unwatch_bus_name(Unit *u, const char *name) {
2173 hashmap_remove_value(u->manager->watch_bus, name, u);
2176 bool unit_can_serialize(Unit *u) {
2179 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2182 int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
2189 if (!unit_can_serialize(u))
2192 r = UNIT_VTABLE(u)->serialize(u, f, fds);
2197 if (serialize_jobs) {
2199 fprintf(f, "job\n");
2200 job_serialize(u->job, f, fds);
2204 fprintf(f, "job\n");
2205 job_serialize(u->nop_job, f, fds);
2209 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2210 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2211 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2212 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2213 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
2215 if (dual_timestamp_is_set(&u->condition_timestamp))
2216 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
2218 unit_serialize_item(u, f, "transient", yes_no(u->transient));
2221 unit_serialize_item(u, f, "cgroup", u->cgroup_path);
2228 void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2239 va_start(ap, format);
2240 vfprintf(f, format, ap);
2246 void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2252 fprintf(f, "%s=%s\n", key, value);
2255 int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
2262 if (!unit_can_serialize(u))
2266 char line[LINE_MAX], *l, *v;
2269 if (!fgets(line, sizeof(line), f)) {
2282 k = strcspn(l, "=");
2290 if (streq(l, "job")) {
2292 /* new-style serialized job */
2293 Job *j = job_new_raw(u);
2297 r = job_deserialize(j, f, fds);
2303 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2309 r = job_install_deserialized(j);
2311 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2316 if (j->state == JOB_RUNNING)
2317 u->manager->n_running_jobs++;
2320 JobType type = job_type_from_string(v);
2322 log_debug("Failed to parse job type value %s", v);
2324 u->deserialized_job = type;
2327 } else if (streq(l, "inactive-exit-timestamp")) {
2328 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
2330 } else if (streq(l, "active-enter-timestamp")) {
2331 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
2333 } else if (streq(l, "active-exit-timestamp")) {
2334 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
2336 } else if (streq(l, "inactive-enter-timestamp")) {
2337 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
2339 } else if (streq(l, "condition-timestamp")) {
2340 dual_timestamp_deserialize(v, &u->condition_timestamp);
2342 } else if (streq(l, "condition-result")) {
2345 b = parse_boolean(v);
2347 log_debug("Failed to parse condition result value %s", v);
2349 u->condition_result = b;
2353 } else if (streq(l, "transient")) {
2356 b = parse_boolean(v);
2358 log_debug("Failed to parse transient bool %s", v);
2363 } else if (streq(l, "cgroup")) {
2370 free(u->cgroup_path);
2373 assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1);
2377 r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds);
2383 int unit_add_node_link(Unit *u, const char *what, bool wants) {
2385 _cleanup_free_ char *e = NULL;
2393 /* Adds in links to the device node that this unit is based on */
2395 if (!is_device_path(what))
2398 e = unit_name_from_path(what, ".device");
2402 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
2407 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
2412 r = unit_add_dependency(device, UNIT_WANTS, u, false);
2420 int unit_coldplug(Unit *u) {
2425 if (UNIT_VTABLE(u)->coldplug)
2426 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2430 r = job_coldplug(u->job);
2433 } else if (u->deserialized_job >= 0) {
2435 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2439 u->deserialized_job = _JOB_TYPE_INVALID;
2445 #pragma GCC diagnostic push
2446 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
2447 void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) {
2448 manager_status_printf(u->manager, false, status, unit_status_msg_format, unit_description(u));
2450 #pragma GCC diagnostic pop
2452 bool unit_need_daemon_reload(Unit *u) {
2453 _cleanup_strv_free_ char **t = NULL;
2456 unsigned loaded_cnt, current_cnt;
2460 if (u->fragment_path) {
2462 if (stat(u->fragment_path, &st) < 0)
2463 /* What, cannot access this anymore? */
2466 if (u->fragment_mtime > 0 &&
2467 timespec_load(&st.st_mtim) != u->fragment_mtime)
2471 if (u->source_path) {
2473 if (stat(u->source_path, &st) < 0)
2476 if (u->source_mtime > 0 &&
2477 timespec_load(&st.st_mtim) != u->source_mtime)
2481 t = unit_find_dropin_paths(u);
2482 loaded_cnt = strv_length(t);
2483 current_cnt = strv_length(u->dropin_paths);
2485 if (loaded_cnt == current_cnt) {
2486 if (loaded_cnt == 0)
2489 if (strv_overlap(u->dropin_paths, t)) {
2490 STRV_FOREACH(path, u->dropin_paths) {
2492 if (stat(*path, &st) < 0)
2495 if (u->dropin_mtime > 0 &&
2496 timespec_load(&st.st_mtim) > u->dropin_mtime)
2507 void unit_reset_failed(Unit *u) {
2510 if (UNIT_VTABLE(u)->reset_failed)
2511 UNIT_VTABLE(u)->reset_failed(u);
2514 Unit *unit_following(Unit *u) {
2517 if (UNIT_VTABLE(u)->following)
2518 return UNIT_VTABLE(u)->following(u);
2523 bool unit_stop_pending(Unit *u) {
2526 /* This call does check the current state of the unit. It's
2527 * hence useful to be called from state change calls of the
2528 * unit itself, where the state isn't updated yet. This is
2529 * different from unit_inactive_or_pending() which checks both
2530 * the current state and for a queued job. */
2532 return u->job && u->job->type == JOB_STOP;
2535 bool unit_inactive_or_pending(Unit *u) {
2538 /* Returns true if the unit is inactive or going down */
2540 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2543 if (unit_stop_pending(u))
2549 bool unit_active_or_pending(Unit *u) {
2552 /* Returns true if the unit is active or going up */
2554 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2558 (u->job->type == JOB_START ||
2559 u->job->type == JOB_RELOAD_OR_START ||
2560 u->job->type == JOB_RESTART))
2566 int unit_kill(Unit *u, KillWho w, int signo, DBusError *error) {
2568 assert(w >= 0 && w < _KILL_WHO_MAX);
2570 assert(signo < _NSIG);
2572 if (!UNIT_VTABLE(u)->kill)
2575 return UNIT_VTABLE(u)->kill(u, w, signo, error);
2578 static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
2582 pid_set = set_new(trivial_hash_func, trivial_compare_func);
2586 /* Exclude the main/control pids from being killed via the cgroup */
2588 r = set_put(pid_set, LONG_TO_PTR(main_pid));
2593 if (control_pid > 0) {
2594 r = set_put(pid_set, LONG_TO_PTR(control_pid));
2606 int unit_kill_common(
2616 if (who == KILL_MAIN && main_pid <= 0) {
2618 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
2620 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
2624 if (who == KILL_CONTROL && control_pid <= 0) {
2625 if (control_pid < 0)
2626 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
2628 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
2632 if (who == KILL_CONTROL || who == KILL_ALL)
2633 if (control_pid > 0)
2634 if (kill(control_pid, signo) < 0)
2637 if (who == KILL_MAIN || who == KILL_ALL)
2639 if (kill(main_pid, signo) < 0)
2642 if (who == KILL_ALL && u->cgroup_path) {
2643 _cleanup_set_free_ Set *pid_set = NULL;
2646 /* Exclude the main/control pids from being killed via the cgroup */
2647 pid_set = unit_pid_set(main_pid, control_pid);
2651 q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
2652 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
2659 int unit_following_set(Unit *u, Set **s) {
2663 if (UNIT_VTABLE(u)->following_set)
2664 return UNIT_VTABLE(u)->following_set(u, s);
2670 UnitFileState unit_get_unit_file_state(Unit *u) {
2673 if (u->unit_file_state < 0 && u->fragment_path)
2674 u->unit_file_state = unit_file_get_state(
2675 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
2676 NULL, path_get_file_name(u->fragment_path));
2678 return u->unit_file_state;
2681 Unit* unit_ref_set(UnitRef *ref, Unit *u) {
2686 unit_ref_unset(ref);
2689 LIST_PREPEND(refs, u->refs, ref);
2693 void unit_ref_unset(UnitRef *ref) {
2699 LIST_REMOVE(refs, ref->unit->refs, ref);
2703 int unit_exec_context_defaults(Unit *u, ExecContext *c) {
2710 /* This only copies in the ones that need memory */
2711 for (i = 0; i < RLIMIT_NLIMITS; i++)
2712 if (u->manager->rlimit[i] && !c->rlimit[i]) {
2713 c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
2718 if (u->manager->running_as == SYSTEMD_USER &&
2719 !c->working_directory) {
2721 r = get_home_dir(&c->working_directory);
2729 ExecContext *unit_get_exec_context(Unit *u) {
2733 offset = UNIT_VTABLE(u)->exec_context_offset;
2737 return (ExecContext*) ((uint8_t*) u + offset);
2740 CGroupContext *unit_get_cgroup_context(Unit *u) {
2743 offset = UNIT_VTABLE(u)->cgroup_context_offset;
2747 return (CGroupContext*) ((uint8_t*) u + offset);
2750 static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) {
2751 _cleanup_free_ char *b = NULL;
2759 assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME));
2761 b = xescape(name, "/.");
2765 if (!filename_is_safe(b))
2768 if (u->manager->running_as == SYSTEMD_USER) {
2769 _cleanup_free_ char *c = NULL;
2771 r = user_config_home(&c);
2777 p = strjoin(c, "/", u->id, ".d", NULL);
2778 } else if (mode & UNIT_PERSISTENT)
2779 p = strjoin("/etc/systemd/system/", u->id, ".d", NULL);
2781 p = strjoin("/run/systemd/system/", u->id, ".d", NULL);
2785 q = strjoin(p, "/90-", b, ".conf", NULL);
2796 int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2797 _cleanup_free_ char *p = NULL, *q = NULL;
2804 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2807 r = drop_in_file(u, mode, name, &p, &q);
2812 return write_string_file_atomic_label(q, data);
2815 int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2816 _cleanup_free_ char *p = NULL;
2824 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2827 va_start(ap, format);
2828 r = vasprintf(&p, format, ap);
2834 return unit_write_drop_in(u, mode, name, p);
2837 int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2838 _cleanup_free_ char *ndata = NULL;
2844 if (!UNIT_VTABLE(u)->private_section)
2847 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2850 ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
2854 return unit_write_drop_in(u, mode, name, ndata);
2857 int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2858 _cleanup_free_ char *p = NULL;
2866 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2869 va_start(ap, format);
2870 r = vasprintf(&p, format, ap);
2876 return unit_write_drop_in_private(u, mode, name, p);
2879 int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
2880 _cleanup_free_ char *p = NULL, *q = NULL;
2885 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2888 r = drop_in_file(u, mode, name, &p, &q);
2893 r = errno == ENOENT ? 0 : -errno;
2901 int unit_make_transient(Unit *u) {
2906 u->load_state = UNIT_STUB;
2908 u->transient = true;
2910 free(u->fragment_path);
2911 u->fragment_path = NULL;
2913 if (u->manager->running_as == SYSTEMD_USER) {
2914 _cleanup_free_ char *c = NULL;
2916 r = user_config_home(&c);
2922 u->fragment_path = strjoin(c, "/", u->id, NULL);
2923 if (!u->fragment_path)
2928 u->fragment_path = strappend("/run/systemd/system/", u->id);
2929 if (!u->fragment_path)
2932 mkdir_p("/run/systemd/system", 0755);
2935 return write_string_file_atomic_label(u->fragment_path, "# Transient stub");
2938 int unit_kill_context(
2944 bool main_pid_alien) {
2946 int sig, wait_for_exit = 0, r;
2951 if (c->kill_mode == KILL_NONE)
2954 sig = sigkill ? SIGKILL : c->kill_signal;
2957 r = kill_and_sigcont(main_pid, sig);
2959 if (r < 0 && r != -ESRCH) {
2960 _cleanup_free_ char *comm = NULL;
2961 get_process_comm(main_pid, &comm);
2963 log_warning_unit(u->id, "Failed to kill main process %li (%s): %s",
2964 (long) main_pid, strna(comm), strerror(-r));
2966 wait_for_exit = !main_pid_alien;
2969 kill(main_pid, SIGHUP);
2973 if (control_pid > 0) {
2974 r = kill_and_sigcont(control_pid, sig);
2976 if (r < 0 && r != -ESRCH) {
2977 _cleanup_free_ char *comm = NULL;
2978 get_process_comm(control_pid, &comm);
2980 log_warning_unit(u->id,
2981 "Failed to kill control process %li (%s): %s",
2982 (long) control_pid, strna(comm), strerror(-r));
2984 wait_for_exit = true;
2987 kill(control_pid, SIGHUP);
2991 if (c->kill_mode == KILL_CONTROL_GROUP && u->cgroup_path) {
2992 _cleanup_set_free_ Set *pid_set = NULL;
2994 /* Exclude the main/control pids from being killed via the cgroup */
2995 pid_set = unit_pid_set(main_pid, control_pid);
2999 r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set);
3001 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
3002 log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
3004 wait_for_exit = true;
3005 if (c->send_sighup) {
3008 pid_set = unit_pid_set(main_pid, control_pid);
3012 cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, SIGHUP, true, true, false, pid_set);
3017 return wait_for_exit;
3020 int unit_require_mounts_for(Unit *u, const char *path) {
3021 char prefix[strlen(path) + 1], *p;
3027 /* Registers a unit for requiring a certain path and all its
3028 * prefixes. We keep a simple array of these paths in the
3029 * unit, since its usually short. However, we build a prefix
3030 * table for all possible prefixes so that new appearing mount
3031 * units can easily determine which units to make themselves a
3038 path_kill_slashes(p);
3040 if (!path_is_absolute(p)) {
3045 if (!path_is_safe(p)) {
3050 if (strv_contains(u->requires_mounts_for, p)) {
3055 r = strv_push(&u->requires_mounts_for, p);
3061 PATH_FOREACH_PREFIX_MORE(prefix, p) {
3064 x = hashmap_get(u->manager->units_requiring_mounts_for, prefix);
3068 if (!u->manager->units_requiring_mounts_for) {
3069 u->manager->units_requiring_mounts_for = hashmap_new(string_hash_func, string_compare_func);
3070 if (!u->manager->units_requiring_mounts_for)
3078 x = set_new(NULL, NULL);
3084 r = hashmap_put(u->manager->units_requiring_mounts_for, q, x);
3100 static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
3101 [UNIT_ACTIVE] = "active",
3102 [UNIT_RELOADING] = "reloading",
3103 [UNIT_INACTIVE] = "inactive",
3104 [UNIT_FAILED] = "failed",
3105 [UNIT_ACTIVATING] = "activating",
3106 [UNIT_DEACTIVATING] = "deactivating"
3109 DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
3111 static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
3112 [UNIT_REQUIRES] = "Requires",
3113 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
3114 [UNIT_REQUISITE] = "Requisite",
3115 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
3116 [UNIT_WANTS] = "Wants",
3117 [UNIT_BINDS_TO] = "BindsTo",
3118 [UNIT_PART_OF] = "PartOf",
3119 [UNIT_REQUIRED_BY] = "RequiredBy",
3120 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
3121 [UNIT_WANTED_BY] = "WantedBy",
3122 [UNIT_BOUND_BY] = "BoundBy",
3123 [UNIT_CONSISTS_OF] = "ConsistsOf",
3124 [UNIT_CONFLICTS] = "Conflicts",
3125 [UNIT_CONFLICTED_BY] = "ConflictedBy",
3126 [UNIT_BEFORE] = "Before",
3127 [UNIT_AFTER] = "After",
3128 [UNIT_ON_FAILURE] = "OnFailure",
3129 [UNIT_TRIGGERS] = "Triggers",
3130 [UNIT_TRIGGERED_BY] = "TriggeredBy",
3131 [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
3132 [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
3133 [UNIT_REFERENCES] = "References",
3134 [UNIT_REFERENCED_BY] = "ReferencedBy",
3137 DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);