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 int unit_load(Unit *u) {
954 if (u->in_load_queue) {
955 LIST_REMOVE(load_queue, u->manager->load_queue, u);
956 u->in_load_queue = false;
959 if (u->type == _UNIT_TYPE_INVALID)
962 if (u->load_state != UNIT_STUB)
965 if (UNIT_VTABLE(u)->load) {
966 r = UNIT_VTABLE(u)->load(u);
971 if (u->load_state == UNIT_STUB) {
976 if (u->load_state == UNIT_LOADED) {
978 if (u->default_dependencies) {
979 r = unit_add_default_dependencies(u);
984 r = unit_add_mount_links(u);
988 if (u->on_failure_isolate &&
989 set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
991 log_error_unit(u->id,
992 "More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.", u->id);
999 assert((u->load_state != UNIT_MERGED) == !u->merged_into);
1001 unit_add_to_dbus_queue(unit_follow_merge(u));
1002 unit_add_to_gc_queue(u);
1007 u->load_state = u->load_state == UNIT_STUB ? UNIT_NOT_FOUND : UNIT_ERROR;
1009 unit_add_to_dbus_queue(u);
1010 unit_add_to_gc_queue(u);
1012 log_debug_unit(u->id, "Failed to load configuration for %s: %s",
1013 u->id, strerror(-r));
1018 bool unit_condition_test(Unit *u) {
1021 dual_timestamp_get(&u->condition_timestamp);
1022 u->condition_result = condition_test_list(u->id, u->conditions);
1024 return u->condition_result;
1027 _pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) {
1028 const UnitStatusMessageFormats *format_table;
1032 assert(t < _JOB_TYPE_MAX);
1034 if (t != JOB_START && t != JOB_STOP)
1037 format_table = &UNIT_VTABLE(u)->status_message_formats;
1041 return format_table->starting_stopping[t == JOB_STOP];
1044 _pure_ static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) {
1049 assert(t < _JOB_TYPE_MAX);
1051 format = unit_get_status_message_format(u, t);
1055 /* Return generic strings */
1057 return "Starting %s.";
1058 else if (t == JOB_STOP)
1059 return "Stopping %s.";
1060 else if (t == JOB_RELOAD)
1061 return "Reloading %s.";
1066 static void unit_status_print_starting_stopping(Unit *u, JobType t) {
1071 /* We only print status messages for selected units on
1072 * selected operations. */
1074 format = unit_get_status_message_format(u, t);
1078 unit_status_printf(u, "", format);
1081 #pragma GCC diagnostic push
1082 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
1083 static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) {
1090 if (t != JOB_START && t != JOB_STOP && t != JOB_RELOAD)
1093 if (log_on_console())
1096 /* We log status messages for all units and all operations. */
1098 format = unit_get_status_message_format_try_harder(u, t);
1102 snprintf(buf, sizeof(buf), format, unit_description(u));
1105 mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING :
1106 t == JOB_STOP ? SD_MESSAGE_UNIT_STOPPING :
1107 SD_MESSAGE_UNIT_RELOADING;
1109 log_struct_unit(LOG_INFO,
1115 #pragma GCC diagnostic pop
1118 * -EBADR: This unit type does not support starting.
1119 * -EALREADY: Unit is already started.
1120 * -EAGAIN: An operation is already in progress. Retry later.
1121 * -ECANCELED: Too many requests for now.
1123 int unit_start(Unit *u) {
1124 UnitActiveState state;
1129 if (u->load_state != UNIT_LOADED)
1132 /* If this is already started, then this will succeed. Note
1133 * that this will even succeed if this unit is not startable
1134 * by the user. This is relied on to detect when we need to
1135 * wait for units and when waiting is finished. */
1136 state = unit_active_state(u);
1137 if (UNIT_IS_ACTIVE_OR_RELOADING(state))
1140 /* If the conditions failed, don't do anything at all. If we
1141 * already are activating this call might still be useful to
1142 * speed up activation in case there is some hold-off time,
1143 * but we don't want to recheck the condition in that case. */
1144 if (state != UNIT_ACTIVATING &&
1145 !unit_condition_test(u)) {
1146 log_debug_unit(u->id, "Starting of %s requested but condition failed. Ignoring.", u->id);
1150 /* Forward to the main object, if we aren't it. */
1151 following = unit_following(u);
1153 log_debug_unit(u->id, "Redirecting start request from %s to %s.",
1154 u->id, following->id);
1155 return unit_start(following);
1158 unit_status_log_starting_stopping_reloading(u, JOB_START);
1159 unit_status_print_starting_stopping(u, JOB_START);
1161 /* If it is stopped, but we cannot start it, then fail */
1162 if (!UNIT_VTABLE(u)->start)
1165 /* We don't suppress calls to ->start() here when we are
1166 * already starting, to allow this request to be used as a
1167 * "hurry up" call, for example when the unit is in some "auto
1168 * restart" state where it waits for a holdoff timer to elapse
1169 * before it will start again. */
1171 unit_add_to_dbus_queue(u);
1173 return UNIT_VTABLE(u)->start(u);
1176 bool unit_can_start(Unit *u) {
1179 return !!UNIT_VTABLE(u)->start;
1182 bool unit_can_isolate(Unit *u) {
1185 return unit_can_start(u) &&
1190 * -EBADR: This unit type does not support stopping.
1191 * -EALREADY: Unit is already stopped.
1192 * -EAGAIN: An operation is already in progress. Retry later.
1194 int unit_stop(Unit *u) {
1195 UnitActiveState state;
1200 state = unit_active_state(u);
1201 if (UNIT_IS_INACTIVE_OR_FAILED(state))
1204 if ((following = unit_following(u))) {
1205 log_debug_unit(u->id, "Redirecting stop request from %s to %s.",
1206 u->id, following->id);
1207 return unit_stop(following);
1210 unit_status_log_starting_stopping_reloading(u, JOB_STOP);
1211 unit_status_print_starting_stopping(u, JOB_STOP);
1213 if (!UNIT_VTABLE(u)->stop)
1216 unit_add_to_dbus_queue(u);
1218 return UNIT_VTABLE(u)->stop(u);
1222 * -EBADR: This unit type does not support reloading.
1223 * -ENOEXEC: Unit is not started.
1224 * -EAGAIN: An operation is already in progress. Retry later.
1226 int unit_reload(Unit *u) {
1227 UnitActiveState state;
1232 if (u->load_state != UNIT_LOADED)
1235 if (!unit_can_reload(u))
1238 state = unit_active_state(u);
1239 if (state == UNIT_RELOADING)
1242 if (state != UNIT_ACTIVE)
1245 if ((following = unit_following(u))) {
1246 log_debug_unit(u->id, "Redirecting reload request from %s to %s.",
1247 u->id, following->id);
1248 return unit_reload(following);
1251 unit_status_log_starting_stopping_reloading(u, JOB_RELOAD);
1253 unit_add_to_dbus_queue(u);
1254 return UNIT_VTABLE(u)->reload(u);
1257 bool unit_can_reload(Unit *u) {
1260 if (!UNIT_VTABLE(u)->reload)
1263 if (!UNIT_VTABLE(u)->can_reload)
1266 return UNIT_VTABLE(u)->can_reload(u);
1269 static void unit_check_unneeded(Unit *u) {
1275 /* If this service shall be shut down when unneeded then do
1278 if (!u->stop_when_unneeded)
1281 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
1284 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
1285 if (unit_active_or_pending(other))
1288 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
1289 if (unit_active_or_pending(other))
1292 SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
1293 if (unit_active_or_pending(other))
1296 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1297 if (unit_active_or_pending(other))
1300 log_info_unit(u->id, "Service %s is not needed anymore. Stopping.", u->id);
1302 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
1303 manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
1306 static void retroactively_start_dependencies(Unit *u) {
1311 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
1313 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1314 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1315 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1316 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1318 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1319 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1320 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1321 manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1323 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1324 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1325 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1326 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1328 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1329 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1330 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1331 manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1333 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTS], i)
1334 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1335 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1337 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
1338 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1339 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1342 static void retroactively_stop_dependencies(Unit *u) {
1347 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1349 /* Pull down units which are bound to us recursively if enabled */
1350 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
1351 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1352 manager_add_job(u->manager, JOB_STOP, other, JOB_REPLACE, true, NULL, NULL);
1355 static void check_unneeded_dependencies(Unit *u) {
1360 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
1362 /* Garbage collect services that might not be needed anymore, if enabled */
1363 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES], i)
1364 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1365 unit_check_unneeded(other);
1366 SET_FOREACH(other, u->dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
1367 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1368 unit_check_unneeded(other);
1369 SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1370 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1371 unit_check_unneeded(other);
1372 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
1373 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1374 unit_check_unneeded(other);
1375 SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
1376 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1377 unit_check_unneeded(other);
1378 SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
1379 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
1380 unit_check_unneeded(other);
1383 void unit_start_on_failure(Unit *u) {
1389 if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
1392 log_info_unit(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
1394 SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
1397 r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL);
1399 log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
1403 void unit_trigger_notify(Unit *u) {
1409 SET_FOREACH(other, u->dependencies[UNIT_TRIGGERED_BY], i)
1410 if (UNIT_VTABLE(other)->trigger_notify)
1411 UNIT_VTABLE(other)->trigger_notify(other, u);
1414 void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
1419 assert(os < _UNIT_ACTIVE_STATE_MAX);
1420 assert(ns < _UNIT_ACTIVE_STATE_MAX);
1422 /* Note that this is called for all low-level state changes,
1423 * even if they might map to the same high-level
1424 * UnitActiveState! That means that ns == os is OK an expected
1425 * behavior here. For example: if a mount point is remounted
1426 * this function will be called too! */
1430 if (m->n_reloading <= 0) {
1433 dual_timestamp_get(&ts);
1435 if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns))
1436 u->inactive_exit_timestamp = ts;
1437 else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_INACTIVE_OR_FAILED(ns))
1438 u->inactive_enter_timestamp = ts;
1440 if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
1441 u->active_enter_timestamp = ts;
1442 else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
1443 u->active_exit_timestamp = ts;
1446 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1447 unit_destroy_cgroup(u);
1449 if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1450 ExecContext *ec = unit_get_exec_context(u);
1451 if (ec && exec_context_may_touch_console(ec)) {
1452 if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
1455 if (m->n_on_console == 0)
1456 /* unset no_console_output flag, since the console is free */
1457 m->no_console_output = 0;
1466 if (u->job->state == JOB_WAITING)
1468 /* So we reached a different state for this
1469 * job. Let's see if we can run it now if it
1470 * failed previously due to EAGAIN. */
1471 job_add_to_run_queue(u->job);
1473 /* Let's check whether this state change constitutes a
1474 * finished job, or maybe contradicts a running job and
1475 * hence needs to invalidate jobs. */
1477 switch (u->job->type) {
1480 case JOB_VERIFY_ACTIVE:
1482 if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
1483 job_finish_and_invalidate(u->job, JOB_DONE, true);
1484 else if (u->job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
1487 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1488 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1494 case JOB_RELOAD_OR_START:
1496 if (u->job->state == JOB_RUNNING) {
1497 if (ns == UNIT_ACTIVE)
1498 job_finish_and_invalidate(u->job, reload_success ? JOB_DONE : JOB_FAILED, true);
1499 else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
1502 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1503 job_finish_and_invalidate(u->job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE, true);
1511 case JOB_TRY_RESTART:
1513 if (UNIT_IS_INACTIVE_OR_FAILED(ns))
1514 job_finish_and_invalidate(u->job, JOB_DONE, true);
1515 else if (u->job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
1517 job_finish_and_invalidate(u->job, JOB_FAILED, true);
1523 assert_not_reached("Job type unknown");
1529 if (m->n_reloading <= 0) {
1531 /* If this state change happened without being
1532 * requested by a job, then let's retroactively start
1533 * or stop dependencies. We skip that step when
1534 * deserializing, since we don't want to create any
1535 * additional jobs just because something is already
1539 if (UNIT_IS_INACTIVE_OR_FAILED(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
1540 retroactively_start_dependencies(u);
1541 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1542 retroactively_stop_dependencies(u);
1545 /* stop unneeded units regardless if going down was expected or not */
1546 if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
1547 check_unneeded_dependencies(u);
1549 if (ns != os && ns == UNIT_FAILED) {
1550 log_notice_unit(u->id,
1551 "Unit %s entered failed state.", u->id);
1552 unit_start_on_failure(u);
1556 /* Some names are special */
1557 if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
1559 if (unit_has_name(u, SPECIAL_DBUS_SERVICE))
1560 /* The bus just might have become available,
1561 * hence try to connect to it, if we aren't
1565 if (u->type == UNIT_SERVICE &&
1566 !UNIT_IS_ACTIVE_OR_RELOADING(os) &&
1567 m->n_reloading <= 0) {
1568 /* Write audit record if we have just finished starting up */
1569 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true);
1573 if (!UNIT_IS_ACTIVE_OR_RELOADING(os))
1574 manager_send_unit_plymouth(m, u);
1578 /* We don't care about D-Bus here, since we'll get an
1579 * asynchronous notification for it anyway. */
1581 if (u->type == UNIT_SERVICE &&
1582 UNIT_IS_INACTIVE_OR_FAILED(ns) &&
1583 !UNIT_IS_INACTIVE_OR_FAILED(os) &&
1584 m->n_reloading <= 0) {
1586 /* Hmm, if there was no start record written
1587 * write it now, so that we always have a nice
1590 manager_send_unit_audit(m, u, AUDIT_SERVICE_START, ns == UNIT_INACTIVE);
1592 if (ns == UNIT_INACTIVE)
1593 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, true);
1595 /* Write audit record if we have just finished shutting down */
1596 manager_send_unit_audit(m, u, AUDIT_SERVICE_STOP, ns == UNIT_INACTIVE);
1598 u->in_audit = false;
1602 manager_recheck_journal(m);
1603 unit_trigger_notify(u);
1605 /* Maybe we finished startup and are now ready for being
1606 * stopped because unneeded? */
1607 if (u->manager->n_reloading <= 0)
1608 unit_check_unneeded(u);
1610 unit_add_to_dbus_queue(u);
1611 unit_add_to_gc_queue(u);
1614 int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) {
1615 struct epoll_event ev = {
1623 assert(w->type == WATCH_INVALID || (w->type == WATCH_FD && w->fd == fd && w->data.unit == u));
1625 if (epoll_ctl(u->manager->epoll_fd,
1626 w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD,
1638 void unit_unwatch_fd(Unit *u, Watch *w) {
1642 if (w->type == WATCH_INVALID)
1645 assert(w->type == WATCH_FD);
1646 assert(w->data.unit == u);
1647 assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
1650 w->type = WATCH_INVALID;
1651 w->data.unit = NULL;
1654 int unit_watch_pid(Unit *u, pid_t pid) {
1658 /* Watch a specific PID. We only support one unit watching
1659 * each PID for now. */
1661 return hashmap_put(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1664 void unit_unwatch_pid(Unit *u, pid_t pid) {
1668 hashmap_remove_value(u->manager->watch_pids, LONG_TO_PTR(pid), u);
1671 int unit_watch_timer(Unit *u, clockid_t clock_id, bool relative, usec_t usec, Watch *w) {
1672 struct itimerspec its = {};
1678 assert(w->type == WATCH_INVALID || (w->type == WATCH_UNIT_TIMER && w->data.unit == u));
1680 /* This will try to reuse the old timer if there is one */
1682 if (w->type == WATCH_UNIT_TIMER) {
1683 assert(w->data.unit == u);
1688 } else if (w->type == WATCH_INVALID) {
1691 fd = timerfd_create(clock_id, TFD_NONBLOCK|TFD_CLOEXEC);
1695 assert_not_reached("Invalid watch type");
1698 /* Set absolute time in the past, but not 0, since we
1699 * don't want to disarm the timer */
1700 its.it_value.tv_sec = 0;
1701 its.it_value.tv_nsec = 1;
1703 flags = TFD_TIMER_ABSTIME;
1705 timespec_store(&its.it_value, usec);
1706 flags = relative ? 0 : TFD_TIMER_ABSTIME;
1709 /* This will also flush the elapse counter */
1710 if (timerfd_settime(fd, flags, &its, NULL) < 0)
1713 if (w->type == WATCH_INVALID) {
1714 struct epoll_event ev = {
1719 if (epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
1723 w->type = WATCH_UNIT_TIMER;
1731 close_nointr_nofail(fd);
1736 void unit_unwatch_timer(Unit *u, Watch *w) {
1740 if (w->type == WATCH_INVALID)
1743 assert(w->type == WATCH_UNIT_TIMER);
1744 assert(w->data.unit == u);
1747 assert_se(epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
1748 close_nointr_nofail(w->fd);
1751 w->type = WATCH_INVALID;
1752 w->data.unit = NULL;
1755 bool unit_job_is_applicable(Unit *u, JobType j) {
1757 assert(j >= 0 && j < _JOB_TYPE_MAX);
1761 case JOB_VERIFY_ACTIVE:
1768 case JOB_TRY_RESTART:
1769 return unit_can_start(u);
1772 return unit_can_reload(u);
1774 case JOB_RELOAD_OR_START:
1775 return unit_can_reload(u) && unit_can_start(u);
1778 assert_not_reached("Invalid job type");
1782 int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) {
1784 static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
1785 [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
1786 [UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1787 [UNIT_WANTS] = UNIT_WANTED_BY,
1788 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
1789 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
1790 [UNIT_BINDS_TO] = UNIT_BOUND_BY,
1791 [UNIT_PART_OF] = UNIT_CONSISTS_OF,
1792 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
1793 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
1794 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
1795 [UNIT_BOUND_BY] = UNIT_BINDS_TO,
1796 [UNIT_CONSISTS_OF] = UNIT_PART_OF,
1797 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
1798 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
1799 [UNIT_BEFORE] = UNIT_AFTER,
1800 [UNIT_AFTER] = UNIT_BEFORE,
1801 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
1802 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
1803 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
1804 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
1805 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
1806 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
1807 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
1809 int r, q = 0, v = 0, w = 0;
1812 assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
1815 u = unit_follow_merge(u);
1816 other = unit_follow_merge(other);
1818 /* We won't allow dependencies on ourselves. We will not
1819 * consider them an error however. */
1823 if ((r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
1826 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
1827 if ((r = set_ensure_allocated(&other->dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
1831 if ((r = set_ensure_allocated(&u->dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
1832 (r = set_ensure_allocated(&other->dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
1835 if ((q = set_put(u->dependencies[d], other)) < 0)
1838 if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
1839 if ((v = set_put(other->dependencies[inverse_table[d]], u)) < 0) {
1844 if (add_reference) {
1845 if ((w = set_put(u->dependencies[UNIT_REFERENCES], other)) < 0) {
1850 if ((r = set_put(other->dependencies[UNIT_REFERENCED_BY], u)) < 0)
1854 unit_add_to_dbus_queue(u);
1859 set_remove(u->dependencies[d], other);
1862 set_remove(other->dependencies[inverse_table[d]], u);
1865 set_remove(u->dependencies[UNIT_REFERENCES], other);
1870 int unit_add_two_dependencies(Unit *u, UnitDependency d, UnitDependency e, Unit *other, bool add_reference) {
1875 if ((r = unit_add_dependency(u, d, other, add_reference)) < 0)
1878 if ((r = unit_add_dependency(u, e, other, add_reference)) < 0)
1884 static const char *resolve_template(Unit *u, const char *name, const char*path, char **p) {
1888 assert(name || path);
1892 name = path_get_file_name(path);
1894 if (!unit_name_is_template(name)) {
1900 s = unit_name_replace_instance(name, u->instance);
1902 _cleanup_free_ char *i = NULL;
1904 i = unit_name_to_prefix(u->id);
1908 s = unit_name_replace_instance(name, i);
1918 int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1921 _cleanup_free_ char *s = NULL;
1924 assert(name || path);
1926 name = resolve_template(u, name, path, &s);
1930 r = manager_load_unit(u->manager, name, path, NULL, &other);
1934 return unit_add_dependency(u, d, other, add_reference);
1937 int unit_add_two_dependencies_by_name(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 r = unit_add_two_dependencies(u, d, e, other, add_reference);
1956 int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) {
1959 _cleanup_free_ char *s = NULL;
1962 assert(name || path);
1964 if (!(name = resolve_template(u, name, path, &s)))
1967 if ((r = manager_load_unit(u->manager, name, path, NULL, &other)) < 0)
1970 r = unit_add_dependency(other, d, u, add_reference);
1975 int unit_add_two_dependencies_by_name_inverse(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 if ((r = unit_add_two_dependencies(other, d, e, u, add_reference)) < 0)
1995 int set_unit_path(const char *p) {
1996 _cleanup_free_ char *c = NULL;
1998 /* This is mostly for debug purposes */
1999 c = path_make_absolute_cwd(p);
2000 if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0)
2006 char *unit_dbus_path(Unit *u) {
2012 return unit_dbus_path_from_name(u->id);
2015 char *unit_default_cgroup_path(Unit *u) {
2016 _cleanup_free_ char *escaped = NULL, *slice = NULL;
2021 if (unit_has_name(u, SPECIAL_ROOT_SLICE))
2022 return strdup(u->manager->cgroup_root);
2024 if (UNIT_ISSET(u->slice) && !unit_has_name(UNIT_DEREF(u->slice), SPECIAL_ROOT_SLICE)) {
2025 r = cg_slice_to_path(UNIT_DEREF(u->slice)->id, &slice);
2030 escaped = cg_escape(u->id);
2035 return strjoin(u->manager->cgroup_root, "/", slice, "/", escaped, NULL);
2037 return strjoin(u->manager->cgroup_root, "/", escaped, NULL);
2040 int unit_add_default_slice(Unit *u) {
2041 _cleanup_free_ char *b = NULL;
2042 const char *slice_name;
2048 if (UNIT_ISSET(u->slice))
2051 if (!unit_get_cgroup_context(u))
2055 _cleanup_free_ char *prefix = NULL, *escaped = NULL;
2057 /* Implicitly place all instantiated units in their
2058 * own per-template slice */
2060 prefix = unit_name_to_prefix(u->id);
2064 /* The prefix is already escaped, but it might include
2065 * "-" which has a special meaning for slice units,
2066 * hence escape it here extra. */
2067 escaped = strreplace(prefix, "-", "\\x2d");
2071 if (u->manager->running_as == SYSTEMD_SYSTEM)
2072 b = strjoin("system-", escaped, ".slice", NULL);
2074 b = strappend(escaped, ".slice");
2081 u->manager->running_as == SYSTEMD_SYSTEM
2082 ? SPECIAL_SYSTEM_SLICE
2083 : SPECIAL_ROOT_SLICE;
2085 r = manager_load_unit(u->manager, slice_name, NULL, NULL, &slice);
2089 unit_ref_set(&u->slice, slice);
2093 const char *unit_slice_name(Unit *u) {
2096 if (!UNIT_ISSET(u->slice))
2099 return UNIT_DEREF(u->slice)->id;
2102 int unit_load_related_unit(Unit *u, const char *type, Unit **_found) {
2103 _cleanup_free_ char *t = NULL;
2110 t = unit_name_change_suffix(u->id, type);
2114 assert(!unit_has_name(u, t));
2116 r = manager_load_unit(u->manager, t, NULL, NULL, _found);
2117 assert(r < 0 || *_found != u);
2121 int unit_get_related_unit(Unit *u, const char *type, Unit **_found) {
2122 _cleanup_free_ char *t = NULL;
2129 t = unit_name_change_suffix(u->id, type);
2133 assert(!unit_has_name(u, t));
2135 found = manager_get_unit(u->manager, t);
2143 int unit_watch_bus_name(Unit *u, const char *name) {
2147 /* Watch a specific name on the bus. We only support one unit
2148 * watching each name for now. */
2150 return hashmap_put(u->manager->watch_bus, name, u);
2153 void unit_unwatch_bus_name(Unit *u, const char *name) {
2157 hashmap_remove_value(u->manager->watch_bus, name, u);
2160 bool unit_can_serialize(Unit *u) {
2163 return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
2166 int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
2173 if (!unit_can_serialize(u))
2176 r = UNIT_VTABLE(u)->serialize(u, f, fds);
2181 if (serialize_jobs) {
2183 fprintf(f, "job\n");
2184 job_serialize(u->job, f, fds);
2188 fprintf(f, "job\n");
2189 job_serialize(u->nop_job, f, fds);
2193 dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
2194 dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
2195 dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
2196 dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->inactive_enter_timestamp);
2197 dual_timestamp_serialize(f, "condition-timestamp", &u->condition_timestamp);
2199 if (dual_timestamp_is_set(&u->condition_timestamp))
2200 unit_serialize_item(u, f, "condition-result", yes_no(u->condition_result));
2202 unit_serialize_item(u, f, "transient", yes_no(u->transient));
2205 unit_serialize_item(u, f, "cgroup", u->cgroup_path);
2212 void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) {
2223 va_start(ap, format);
2224 vfprintf(f, format, ap);
2230 void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) {
2236 fprintf(f, "%s=%s\n", key, value);
2239 int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
2246 if (!unit_can_serialize(u))
2250 char line[LINE_MAX], *l, *v;
2253 if (!fgets(line, sizeof(line), f)) {
2266 k = strcspn(l, "=");
2274 if (streq(l, "job")) {
2276 /* new-style serialized job */
2277 Job *j = job_new_raw(u);
2281 r = job_deserialize(j, f, fds);
2287 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
2293 r = job_install_deserialized(j);
2295 hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
2300 if (j->state == JOB_RUNNING)
2301 u->manager->n_running_jobs++;
2304 JobType type = job_type_from_string(v);
2306 log_debug("Failed to parse job type value %s", v);
2308 u->deserialized_job = type;
2311 } else if (streq(l, "inactive-exit-timestamp")) {
2312 dual_timestamp_deserialize(v, &u->inactive_exit_timestamp);
2314 } else if (streq(l, "active-enter-timestamp")) {
2315 dual_timestamp_deserialize(v, &u->active_enter_timestamp);
2317 } else if (streq(l, "active-exit-timestamp")) {
2318 dual_timestamp_deserialize(v, &u->active_exit_timestamp);
2320 } else if (streq(l, "inactive-enter-timestamp")) {
2321 dual_timestamp_deserialize(v, &u->inactive_enter_timestamp);
2323 } else if (streq(l, "condition-timestamp")) {
2324 dual_timestamp_deserialize(v, &u->condition_timestamp);
2326 } else if (streq(l, "condition-result")) {
2329 b = parse_boolean(v);
2331 log_debug("Failed to parse condition result value %s", v);
2333 u->condition_result = b;
2337 } else if (streq(l, "transient")) {
2340 b = parse_boolean(v);
2342 log_debug("Failed to parse transient bool %s", v);
2347 } else if (streq(l, "cgroup")) {
2354 free(u->cgroup_path);
2357 assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1);
2361 r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds);
2367 int unit_add_node_link(Unit *u, const char *what, bool wants) {
2369 _cleanup_free_ char *e = NULL;
2377 /* Adds in links to the device node that this unit is based on */
2379 if (!is_device_path(what))
2382 e = unit_name_from_path(what, ".device");
2386 r = manager_load_unit(u->manager, e, NULL, NULL, &device);
2391 r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true);
2396 r = unit_add_dependency(device, UNIT_WANTS, u, false);
2404 int unit_coldplug(Unit *u) {
2409 if (UNIT_VTABLE(u)->coldplug)
2410 if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
2414 r = job_coldplug(u->job);
2417 } else if (u->deserialized_job >= 0) {
2419 r = manager_add_job(u->manager, u->deserialized_job, u, JOB_IGNORE_REQUIREMENTS, false, NULL, NULL);
2423 u->deserialized_job = _JOB_TYPE_INVALID;
2429 #pragma GCC diagnostic push
2430 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
2431 void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) {
2432 manager_status_printf(u->manager, false, status, unit_status_msg_format, unit_description(u));
2434 #pragma GCC diagnostic pop
2436 bool unit_need_daemon_reload(Unit *u) {
2437 _cleanup_strv_free_ char **t = NULL;
2440 unsigned loaded_cnt, current_cnt;
2444 if (u->fragment_path) {
2446 if (stat(u->fragment_path, &st) < 0)
2447 /* What, cannot access this anymore? */
2450 if (u->fragment_mtime > 0 &&
2451 timespec_load(&st.st_mtim) != u->fragment_mtime)
2455 if (u->source_path) {
2457 if (stat(u->source_path, &st) < 0)
2460 if (u->source_mtime > 0 &&
2461 timespec_load(&st.st_mtim) != u->source_mtime)
2465 t = unit_find_dropin_paths(u);
2466 loaded_cnt = strv_length(t);
2467 current_cnt = strv_length(u->dropin_paths);
2469 if (loaded_cnt == current_cnt) {
2470 if (loaded_cnt == 0)
2473 if (strv_overlap(u->dropin_paths, t)) {
2474 STRV_FOREACH(path, u->dropin_paths) {
2476 if (stat(*path, &st) < 0)
2479 if (u->dropin_mtime > 0 &&
2480 timespec_load(&st.st_mtim) > u->dropin_mtime)
2491 void unit_reset_failed(Unit *u) {
2494 if (UNIT_VTABLE(u)->reset_failed)
2495 UNIT_VTABLE(u)->reset_failed(u);
2498 Unit *unit_following(Unit *u) {
2501 if (UNIT_VTABLE(u)->following)
2502 return UNIT_VTABLE(u)->following(u);
2507 bool unit_stop_pending(Unit *u) {
2510 /* This call does check the current state of the unit. It's
2511 * hence useful to be called from state change calls of the
2512 * unit itself, where the state isn't updated yet. This is
2513 * different from unit_inactive_or_pending() which checks both
2514 * the current state and for a queued job. */
2516 return u->job && u->job->type == JOB_STOP;
2519 bool unit_inactive_or_pending(Unit *u) {
2522 /* Returns true if the unit is inactive or going down */
2524 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)))
2527 if (unit_stop_pending(u))
2533 bool unit_active_or_pending(Unit *u) {
2536 /* Returns true if the unit is active or going up */
2538 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
2542 (u->job->type == JOB_START ||
2543 u->job->type == JOB_RELOAD_OR_START ||
2544 u->job->type == JOB_RESTART))
2550 int unit_kill(Unit *u, KillWho w, int signo, DBusError *error) {
2552 assert(w >= 0 && w < _KILL_WHO_MAX);
2554 assert(signo < _NSIG);
2556 if (!UNIT_VTABLE(u)->kill)
2559 return UNIT_VTABLE(u)->kill(u, w, signo, error);
2562 static Set *unit_pid_set(pid_t main_pid, pid_t control_pid) {
2566 pid_set = set_new(trivial_hash_func, trivial_compare_func);
2570 /* Exclude the main/control pids from being killed via the cgroup */
2572 r = set_put(pid_set, LONG_TO_PTR(main_pid));
2577 if (control_pid > 0) {
2578 r = set_put(pid_set, LONG_TO_PTR(control_pid));
2590 int unit_kill_common(
2600 if (who == KILL_MAIN && main_pid <= 0) {
2602 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
2604 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
2608 if (who == KILL_CONTROL && control_pid <= 0) {
2609 if (control_pid < 0)
2610 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
2612 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
2616 if (who == KILL_CONTROL || who == KILL_ALL)
2617 if (control_pid > 0)
2618 if (kill(control_pid, signo) < 0)
2621 if (who == KILL_MAIN || who == KILL_ALL)
2623 if (kill(main_pid, signo) < 0)
2626 if (who == KILL_ALL && u->cgroup_path) {
2627 _cleanup_set_free_ Set *pid_set = NULL;
2630 /* Exclude the main/control pids from being killed via the cgroup */
2631 pid_set = unit_pid_set(main_pid, control_pid);
2635 q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, true, false, pid_set);
2636 if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
2643 int unit_following_set(Unit *u, Set **s) {
2647 if (UNIT_VTABLE(u)->following_set)
2648 return UNIT_VTABLE(u)->following_set(u, s);
2654 UnitFileState unit_get_unit_file_state(Unit *u) {
2657 if (u->unit_file_state < 0 && u->fragment_path)
2658 u->unit_file_state = unit_file_get_state(
2659 u->manager->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
2660 NULL, path_get_file_name(u->fragment_path));
2662 return u->unit_file_state;
2665 Unit* unit_ref_set(UnitRef *ref, Unit *u) {
2670 unit_ref_unset(ref);
2673 LIST_PREPEND(refs, u->refs, ref);
2677 void unit_ref_unset(UnitRef *ref) {
2683 LIST_REMOVE(refs, ref->unit->refs, ref);
2687 int unit_add_mount_links(Unit *u) {
2693 STRV_FOREACH(i, u->requires_mounts_for) {
2694 char prefix[strlen(*i) + 1];
2696 PATH_FOREACH_PREFIX_MORE(prefix, *i) {
2699 r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m);
2707 if (m->load_state != UNIT_LOADED)
2710 r = unit_add_dependency(u, UNIT_AFTER, m, true);
2714 if (m->fragment_path) {
2715 r = unit_add_dependency(u, UNIT_REQUIRES, m, true);
2725 int unit_exec_context_defaults(Unit *u, ExecContext *c) {
2732 /* This only copies in the ones that need memory */
2733 for (i = 0; i < RLIMIT_NLIMITS; i++)
2734 if (u->manager->rlimit[i] && !c->rlimit[i]) {
2735 c->rlimit[i] = newdup(struct rlimit, u->manager->rlimit[i], 1);
2740 if (u->manager->running_as == SYSTEMD_USER &&
2741 !c->working_directory) {
2743 r = get_home_dir(&c->working_directory);
2751 ExecContext *unit_get_exec_context(Unit *u) {
2755 offset = UNIT_VTABLE(u)->exec_context_offset;
2759 return (ExecContext*) ((uint8_t*) u + offset);
2762 CGroupContext *unit_get_cgroup_context(Unit *u) {
2765 offset = UNIT_VTABLE(u)->cgroup_context_offset;
2769 return (CGroupContext*) ((uint8_t*) u + offset);
2772 static int drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **_p, char **_q) {
2773 _cleanup_free_ char *b = NULL;
2781 assert(mode & (UNIT_PERSISTENT|UNIT_RUNTIME));
2783 b = xescape(name, "/.");
2787 if (!filename_is_safe(b))
2790 if (u->manager->running_as == SYSTEMD_USER) {
2791 _cleanup_free_ char *c = NULL;
2793 r = user_config_home(&c);
2799 p = strjoin(c, "/", u->id, ".d", NULL);
2800 } else if (mode & UNIT_PERSISTENT)
2801 p = strjoin("/etc/systemd/system/", u->id, ".d", NULL);
2803 p = strjoin("/run/systemd/system/", u->id, ".d", NULL);
2807 q = strjoin(p, "/90-", b, ".conf", NULL);
2818 int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2819 _cleanup_free_ char *p = NULL, *q = NULL;
2826 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2829 r = drop_in_file(u, mode, name, &p, &q);
2834 return write_string_file_atomic_label(q, data);
2837 int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2838 _cleanup_free_ char *p = NULL;
2846 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2849 va_start(ap, format);
2850 r = vasprintf(&p, format, ap);
2856 return unit_write_drop_in(u, mode, name, p);
2859 int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) {
2860 _cleanup_free_ char *ndata = NULL;
2866 if (!UNIT_VTABLE(u)->private_section)
2869 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2872 ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL);
2876 return unit_write_drop_in(u, mode, name, ndata);
2879 int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) {
2880 _cleanup_free_ char *p = NULL;
2888 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2891 va_start(ap, format);
2892 r = vasprintf(&p, format, ap);
2898 return unit_write_drop_in_private(u, mode, name, p);
2901 int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) {
2902 _cleanup_free_ char *p = NULL, *q = NULL;
2907 if (!(mode & (UNIT_PERSISTENT|UNIT_RUNTIME)))
2910 r = drop_in_file(u, mode, name, &p, &q);
2915 r = errno == ENOENT ? 0 : -errno;
2923 int unit_make_transient(Unit *u) {
2928 u->load_state = UNIT_STUB;
2930 u->transient = true;
2932 free(u->fragment_path);
2933 u->fragment_path = NULL;
2935 if (u->manager->running_as == SYSTEMD_USER) {
2936 _cleanup_free_ char *c = NULL;
2938 r = user_config_home(&c);
2944 u->fragment_path = strjoin(c, "/", u->id, NULL);
2945 if (!u->fragment_path)
2950 u->fragment_path = strappend("/run/systemd/system/", u->id);
2951 if (!u->fragment_path)
2954 mkdir_p("/run/systemd/system", 0755);
2957 return write_string_file_atomic_label(u->fragment_path, "# Transient stub");
2960 int unit_kill_context(
2966 bool main_pid_alien) {
2968 int sig, wait_for_exit = 0, r;
2973 if (c->kill_mode == KILL_NONE)
2976 sig = sigkill ? SIGKILL : c->kill_signal;
2979 r = kill_and_sigcont(main_pid, sig);
2981 if (r < 0 && r != -ESRCH) {
2982 _cleanup_free_ char *comm = NULL;
2983 get_process_comm(main_pid, &comm);
2985 log_warning_unit(u->id, "Failed to kill main process %li (%s): %s",
2986 (long) main_pid, strna(comm), strerror(-r));
2988 wait_for_exit = !main_pid_alien;
2991 kill(main_pid, SIGHUP);
2995 if (control_pid > 0) {
2996 r = kill_and_sigcont(control_pid, sig);
2998 if (r < 0 && r != -ESRCH) {
2999 _cleanup_free_ char *comm = NULL;
3000 get_process_comm(control_pid, &comm);
3002 log_warning_unit(u->id,
3003 "Failed to kill control process %li (%s): %s",
3004 (long) control_pid, strna(comm), strerror(-r));
3006 wait_for_exit = true;
3009 kill(control_pid, SIGHUP);
3013 if (c->kill_mode == KILL_CONTROL_GROUP && u->cgroup_path) {
3014 _cleanup_set_free_ Set *pid_set = NULL;
3016 /* Exclude the main/control pids from being killed via the cgroup */
3017 pid_set = unit_pid_set(main_pid, control_pid);
3021 r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, sig, true, true, false, pid_set);
3023 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
3024 log_warning_unit(u->id, "Failed to kill control group: %s", strerror(-r));
3026 wait_for_exit = true;
3027 if (c->send_sighup) {
3030 pid_set = unit_pid_set(main_pid, control_pid);
3034 cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, SIGHUP, true, true, false, pid_set);
3039 return wait_for_exit;
3042 int unit_require_mounts_for(Unit *u, const char *path) {
3043 char prefix[strlen(path) + 1], *p;
3049 /* Registers a unit for requiring a certain path and all its
3050 * prefixes. We keep a simple array of these paths in the
3051 * unit, since its usually short. However, we build a prefix
3052 * table for all possible prefixes so that new appearing mount
3053 * units can easily determine which units to make themselves a
3060 path_kill_slashes(p);
3062 if (!path_is_absolute(p)) {
3067 if (!path_is_safe(p)) {
3072 if (strv_contains(u->requires_mounts_for, p)) {
3077 r = strv_push(&u->requires_mounts_for, p);
3083 PATH_FOREACH_PREFIX_MORE(prefix, p) {
3086 x = hashmap_get(u->manager->units_requiring_mounts_for, prefix);
3090 if (!u->manager->units_requiring_mounts_for) {
3091 u->manager->units_requiring_mounts_for = hashmap_new(string_hash_func, string_compare_func);
3092 if (!u->manager->units_requiring_mounts_for)
3100 x = set_new(NULL, NULL);
3106 r = hashmap_put(u->manager->units_requiring_mounts_for, q, x);
3122 static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
3123 [UNIT_ACTIVE] = "active",
3124 [UNIT_RELOADING] = "reloading",
3125 [UNIT_INACTIVE] = "inactive",
3126 [UNIT_FAILED] = "failed",
3127 [UNIT_ACTIVATING] = "activating",
3128 [UNIT_DEACTIVATING] = "deactivating"
3131 DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState);
3133 static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
3134 [UNIT_REQUIRES] = "Requires",
3135 [UNIT_REQUIRES_OVERRIDABLE] = "RequiresOverridable",
3136 [UNIT_REQUISITE] = "Requisite",
3137 [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
3138 [UNIT_WANTS] = "Wants",
3139 [UNIT_BINDS_TO] = "BindsTo",
3140 [UNIT_PART_OF] = "PartOf",
3141 [UNIT_REQUIRED_BY] = "RequiredBy",
3142 [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
3143 [UNIT_WANTED_BY] = "WantedBy",
3144 [UNIT_BOUND_BY] = "BoundBy",
3145 [UNIT_CONSISTS_OF] = "ConsistsOf",
3146 [UNIT_CONFLICTS] = "Conflicts",
3147 [UNIT_CONFLICTED_BY] = "ConflictedBy",
3148 [UNIT_BEFORE] = "Before",
3149 [UNIT_AFTER] = "After",
3150 [UNIT_ON_FAILURE] = "OnFailure",
3151 [UNIT_TRIGGERS] = "Triggers",
3152 [UNIT_TRIGGERED_BY] = "TriggeredBy",
3153 [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
3154 [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
3155 [UNIT_REFERENCES] = "References",
3156 [UNIT_REFERENCED_BY] = "ReferencedBy",
3159 DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);