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"
47 #include "cgroup-attr.h"
50 const UnitVTable
* const unit_vtable
[_UNIT_TYPE_MAX
] = {
51 [UNIT_SERVICE
] = &service_vtable
,
52 [UNIT_TIMER
] = &timer_vtable
,
53 [UNIT_SOCKET
] = &socket_vtable
,
54 [UNIT_TARGET
] = &target_vtable
,
55 [UNIT_DEVICE
] = &device_vtable
,
56 [UNIT_MOUNT
] = &mount_vtable
,
57 [UNIT_AUTOMOUNT
] = &automount_vtable
,
58 [UNIT_SNAPSHOT
] = &snapshot_vtable
,
59 [UNIT_SWAP
] = &swap_vtable
,
60 [UNIT_PATH
] = &path_vtable
63 Unit
*unit_new(Manager
*m
, size_t size
) {
67 assert(size
>= sizeof(Unit
));
73 u
->names
= set_new(string_hash_func
, string_compare_func
);
80 u
->type
= _UNIT_TYPE_INVALID
;
81 u
->deserialized_job
= _JOB_TYPE_INVALID
;
82 u
->default_dependencies
= true;
83 u
->unit_file_state
= _UNIT_FILE_STATE_INVALID
;
88 bool unit_has_name(Unit
*u
, const char *name
) {
92 return !!set_get(u
->names
, (char*) name
);
95 int unit_add_name(Unit
*u
, const char *text
) {
103 if (unit_name_is_template(text
)) {
107 s
= unit_name_replace_instance(text
, u
->instance
);
114 if (!unit_name_is_valid(s
, false)) {
119 assert_se((t
= unit_name_to_type(s
)) >= 0);
121 if (u
->type
!= _UNIT_TYPE_INVALID
&& t
!= u
->type
) {
126 if ((r
= unit_name_to_instance(s
, &i
)) < 0)
129 if (i
&& unit_vtable
[t
]->no_instances
) {
134 /* Ensure that this unit is either instanced or not instanced,
136 if (u
->type
!= _UNIT_TYPE_INVALID
&& !u
->instance
!= !i
) {
141 if (unit_vtable
[t
]->no_alias
&&
142 !set_isempty(u
->names
) &&
143 !set_get(u
->names
, s
)) {
148 if (hashmap_size(u
->manager
->units
) >= MANAGER_MAX_NAMES
) {
153 if ((r
= set_put(u
->names
, s
)) < 0) {
159 if ((r
= hashmap_put(u
->manager
->units
, s
, u
)) < 0) {
160 set_remove(u
->names
, s
);
164 if (u
->type
== _UNIT_TYPE_INVALID
) {
170 LIST_PREPEND(Unit
, units_by_type
, u
->manager
->units_by_type
[t
], u
);
172 if (UNIT_VTABLE(u
)->init
)
173 UNIT_VTABLE(u
)->init(u
);
177 unit_add_to_dbus_queue(u
);
187 int unit_choose_id(Unit
*u
, const char *name
) {
188 char *s
, *t
= NULL
, *i
;
194 if (unit_name_is_template(name
)) {
199 if (!(t
= unit_name_replace_instance(name
, u
->instance
)))
205 /* Selects one of the names of this unit as the id */
206 s
= set_get(u
->names
, (char*) name
);
212 if ((r
= unit_name_to_instance(s
, &i
)) < 0)
220 unit_add_to_dbus_queue(u
);
225 int unit_set_description(Unit
*u
, const char *description
) {
230 if (!(s
= strdup(description
)))
233 free(u
->description
);
236 unit_add_to_dbus_queue(u
);
240 bool unit_check_gc(Unit
*u
) {
243 if (u
->load_state
== UNIT_STUB
)
246 if (UNIT_VTABLE(u
)->no_gc
)
258 if (unit_active_state(u
) != UNIT_INACTIVE
)
264 if (UNIT_VTABLE(u
)->check_gc
)
265 if (UNIT_VTABLE(u
)->check_gc(u
))
271 void unit_add_to_load_queue(Unit
*u
) {
273 assert(u
->type
!= _UNIT_TYPE_INVALID
);
275 if (u
->load_state
!= UNIT_STUB
|| u
->in_load_queue
)
278 LIST_PREPEND(Unit
, load_queue
, u
->manager
->load_queue
, u
);
279 u
->in_load_queue
= true;
282 void unit_add_to_cleanup_queue(Unit
*u
) {
285 if (u
->in_cleanup_queue
)
288 LIST_PREPEND(Unit
, cleanup_queue
, u
->manager
->cleanup_queue
, u
);
289 u
->in_cleanup_queue
= true;
292 void unit_add_to_gc_queue(Unit
*u
) {
295 if (u
->in_gc_queue
|| u
->in_cleanup_queue
)
298 if (unit_check_gc(u
))
301 LIST_PREPEND(Unit
, gc_queue
, u
->manager
->gc_queue
, u
);
302 u
->in_gc_queue
= true;
304 u
->manager
->n_in_gc_queue
++;
306 if (u
->manager
->gc_queue_timestamp
<= 0)
307 u
->manager
->gc_queue_timestamp
= now(CLOCK_MONOTONIC
);
310 void unit_add_to_dbus_queue(Unit
*u
) {
312 assert(u
->type
!= _UNIT_TYPE_INVALID
);
314 if (u
->load_state
== UNIT_STUB
|| u
->in_dbus_queue
)
317 /* Shortcut things if nobody cares */
318 if (!bus_has_subscriber(u
->manager
)) {
319 u
->sent_dbus_new_signal
= true;
323 LIST_PREPEND(Unit
, dbus_queue
, u
->manager
->dbus_unit_queue
, u
);
324 u
->in_dbus_queue
= true;
327 static void bidi_set_free(Unit
*u
, Set
*s
) {
333 /* Frees the set and makes sure we are dropped from the
334 * inverse pointers */
336 SET_FOREACH(other
, s
, i
) {
339 for (d
= 0; d
< _UNIT_DEPENDENCY_MAX
; d
++)
340 set_remove(other
->dependencies
[d
], u
);
342 unit_add_to_gc_queue(other
);
348 void unit_free(Unit
*u
) {
355 bus_unit_send_removed_signal(u
);
357 if (u
->load_state
!= UNIT_STUB
)
358 if (UNIT_VTABLE(u
)->done
)
359 UNIT_VTABLE(u
)->done(u
);
361 SET_FOREACH(t
, u
->names
, i
)
362 hashmap_remove_value(u
->manager
->units
, t
, u
);
376 for (d
= 0; d
< _UNIT_DEPENDENCY_MAX
; d
++)
377 bidi_set_free(u
, u
->dependencies
[d
]);
379 if (u
->requires_mounts_for
) {
380 LIST_REMOVE(Unit
, has_requires_mounts_for
, u
->manager
->has_requires_mounts_for
, u
);
381 strv_free(u
->requires_mounts_for
);
384 if (u
->type
!= _UNIT_TYPE_INVALID
)
385 LIST_REMOVE(Unit
, units_by_type
, u
->manager
->units_by_type
[u
->type
], u
);
387 if (u
->in_load_queue
)
388 LIST_REMOVE(Unit
, load_queue
, u
->manager
->load_queue
, u
);
390 if (u
->in_dbus_queue
)
391 LIST_REMOVE(Unit
, dbus_queue
, u
->manager
->dbus_unit_queue
, u
);
393 if (u
->in_cleanup_queue
)
394 LIST_REMOVE(Unit
, cleanup_queue
, u
->manager
->cleanup_queue
, u
);
396 if (u
->in_gc_queue
) {
397 LIST_REMOVE(Unit
, gc_queue
, u
->manager
->gc_queue
, u
);
398 u
->manager
->n_in_gc_queue
--;
401 cgroup_bonding_free_list(u
->cgroup_bondings
, u
->manager
->n_reloading
<= 0);
402 cgroup_attribute_free_list(u
->cgroup_attributes
);
404 free(u
->description
);
405 strv_free(u
->documentation
);
406 free(u
->fragment_path
);
407 free(u
->source_path
);
410 set_free_free(u
->names
);
412 condition_free_list(u
->conditions
);
415 unit_ref_unset(u
->refs
);
420 UnitActiveState
unit_active_state(Unit
*u
) {
423 if (u
->load_state
== UNIT_MERGED
)
424 return unit_active_state(unit_follow_merge(u
));
426 /* After a reload it might happen that a unit is not correctly
427 * loaded but still has a process around. That's why we won't
428 * shortcut failed loading to UNIT_INACTIVE_FAILED. */
430 return UNIT_VTABLE(u
)->active_state(u
);
433 const char* unit_sub_state_to_string(Unit
*u
) {
436 return UNIT_VTABLE(u
)->sub_state_to_string(u
);
439 static void complete_move(Set
**s
, Set
**other
) {
447 set_move(*s
, *other
);
454 static void merge_names(Unit
*u
, Unit
*other
) {
461 complete_move(&u
->names
, &other
->names
);
463 set_free_free(other
->names
);
467 SET_FOREACH(t
, u
->names
, i
)
468 assert_se(hashmap_replace(u
->manager
->units
, t
, u
) == 0);
471 static void merge_dependencies(Unit
*u
, Unit
*other
, UnitDependency d
) {
478 assert(d
< _UNIT_DEPENDENCY_MAX
);
480 /* Fix backwards pointers */
481 SET_FOREACH(back
, other
->dependencies
[d
], i
) {
484 for (k
= 0; k
< _UNIT_DEPENDENCY_MAX
; k
++)
485 if ((r
= set_remove_and_put(back
->dependencies
[k
], other
, u
)) < 0) {
488 set_remove(back
->dependencies
[k
], other
);
490 assert(r
== -ENOENT
);
494 complete_move(&u
->dependencies
[d
], &other
->dependencies
[d
]);
496 set_free(other
->dependencies
[d
]);
497 other
->dependencies
[d
] = NULL
;
500 int unit_merge(Unit
*u
, Unit
*other
) {
505 assert(u
->manager
== other
->manager
);
506 assert(u
->type
!= _UNIT_TYPE_INVALID
);
508 other
= unit_follow_merge(other
);
513 if (u
->type
!= other
->type
)
516 if (!u
->instance
!= !other
->instance
)
519 if (other
->load_state
!= UNIT_STUB
&&
520 other
->load_state
!= UNIT_ERROR
)
529 if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other
)))
533 merge_names(u
, other
);
535 /* Redirect all references */
537 unit_ref_set(other
->refs
, u
);
539 /* Merge dependencies */
540 for (d
= 0; d
< _UNIT_DEPENDENCY_MAX
; d
++)
541 merge_dependencies(u
, other
, d
);
543 other
->load_state
= UNIT_MERGED
;
544 other
->merged_into
= u
;
546 /* If there is still some data attached to the other node, we
547 * don't need it anymore, and can free it. */
548 if (other
->load_state
!= UNIT_STUB
)
549 if (UNIT_VTABLE(other
)->done
)
550 UNIT_VTABLE(other
)->done(other
);
552 unit_add_to_dbus_queue(u
);
553 unit_add_to_cleanup_queue(other
);
558 int unit_merge_by_name(Unit
*u
, const char *name
) {
566 if (unit_name_is_template(name
)) {
570 if (!(s
= unit_name_replace_instance(name
, u
->instance
)))
576 if (!(other
= manager_get_unit(u
->manager
, name
)))
577 r
= unit_add_name(u
, name
);
579 r
= unit_merge(u
, other
);
585 Unit
* unit_follow_merge(Unit
*u
) {
588 while (u
->load_state
== UNIT_MERGED
)
589 assert_se(u
= u
->merged_into
);
594 int unit_add_exec_dependencies(Unit
*u
, ExecContext
*c
) {
600 if (c
->std_output
!= EXEC_OUTPUT_KMSG
&&
601 c
->std_output
!= EXEC_OUTPUT_SYSLOG
&&
602 c
->std_output
!= EXEC_OUTPUT_JOURNAL
&&
603 c
->std_output
!= EXEC_OUTPUT_KMSG_AND_CONSOLE
&&
604 c
->std_output
!= EXEC_OUTPUT_SYSLOG_AND_CONSOLE
&&
605 c
->std_output
!= EXEC_OUTPUT_JOURNAL_AND_CONSOLE
&&
606 c
->std_error
!= EXEC_OUTPUT_KMSG
&&
607 c
->std_error
!= EXEC_OUTPUT_SYSLOG
&&
608 c
->std_error
!= EXEC_OUTPUT_JOURNAL
&&
609 c
->std_error
!= EXEC_OUTPUT_KMSG_AND_CONSOLE
&&
610 c
->std_error
!= EXEC_OUTPUT_JOURNAL_AND_CONSOLE
&&
611 c
->std_error
!= EXEC_OUTPUT_SYSLOG_AND_CONSOLE
)
614 /* If syslog or kernel logging is requested, make sure our own
615 * logging daemon is run first. */
617 if (u
->manager
->running_as
== SYSTEMD_SYSTEM
)
618 if ((r
= unit_add_two_dependencies_by_name(u
, UNIT_REQUIRES
, UNIT_AFTER
, SPECIAL_JOURNALD_SOCKET
, NULL
, true)) < 0)
624 const char *unit_description(Unit
*u
) {
628 return u
->description
;
633 void unit_dump(Unit
*u
, FILE *f
, const char *prefix
) {
640 timestamp1
[FORMAT_TIMESTAMP_MAX
],
641 timestamp2
[FORMAT_TIMESTAMP_MAX
],
642 timestamp3
[FORMAT_TIMESTAMP_MAX
],
643 timestamp4
[FORMAT_TIMESTAMP_MAX
],
644 timespan
[FORMAT_TIMESPAN_MAX
];
648 assert(u
->type
>= 0);
652 p2
= strappend(prefix
, "\t");
653 prefix2
= p2
? p2
: prefix
;
657 "%s\tDescription: %s\n"
659 "%s\tUnit Load State: %s\n"
660 "%s\tUnit Active State: %s\n"
661 "%s\tInactive Exit Timestamp: %s\n"
662 "%s\tActive Enter Timestamp: %s\n"
663 "%s\tActive Exit Timestamp: %s\n"
664 "%s\tInactive Enter Timestamp: %s\n"
665 "%s\tGC Check Good: %s\n"
666 "%s\tNeed Daemon Reload: %s\n",
668 prefix
, unit_description(u
),
669 prefix
, strna(u
->instance
),
670 prefix
, unit_load_state_to_string(u
->load_state
),
671 prefix
, unit_active_state_to_string(unit_active_state(u
)),
672 prefix
, strna(format_timestamp(timestamp1
, sizeof(timestamp1
), u
->inactive_exit_timestamp
.realtime
)),
673 prefix
, strna(format_timestamp(timestamp2
, sizeof(timestamp2
), u
->active_enter_timestamp
.realtime
)),
674 prefix
, strna(format_timestamp(timestamp3
, sizeof(timestamp3
), u
->active_exit_timestamp
.realtime
)),
675 prefix
, strna(format_timestamp(timestamp4
, sizeof(timestamp4
), u
->inactive_enter_timestamp
.realtime
)),
676 prefix
, yes_no(unit_check_gc(u
)),
677 prefix
, yes_no(unit_need_daemon_reload(u
)));
679 SET_FOREACH(t
, u
->names
, i
)
680 fprintf(f
, "%s\tName: %s\n", prefix
, t
);
682 STRV_FOREACH(j
, u
->documentation
)
683 fprintf(f
, "%s\tDocumentation: %s\n", prefix
, *j
);
685 if ((following
= unit_following(u
)))
686 fprintf(f
, "%s\tFollowing: %s\n", prefix
, following
->id
);
688 if (u
->fragment_path
)
689 fprintf(f
, "%s\tFragment Path: %s\n", prefix
, u
->fragment_path
);
692 fprintf(f
, "%s\tSource Path: %s\n", prefix
, u
->source_path
);
694 if (u
->job_timeout
> 0)
695 fprintf(f
, "%s\tJob Timeout: %s\n", prefix
, format_timespan(timespan
, sizeof(timespan
), u
->job_timeout
));
697 condition_dump_list(u
->conditions
, f
, prefix
);
699 if (dual_timestamp_is_set(&u
->condition_timestamp
))
701 "%s\tCondition Timestamp: %s\n"
702 "%s\tCondition Result: %s\n",
703 prefix
, strna(format_timestamp(timestamp1
, sizeof(timestamp1
), u
->condition_timestamp
.realtime
)),
704 prefix
, yes_no(u
->condition_result
));
706 for (d
= 0; d
< _UNIT_DEPENDENCY_MAX
; d
++) {
709 SET_FOREACH(other
, u
->dependencies
[d
], i
)
710 fprintf(f
, "%s\t%s: %s\n", prefix
, unit_dependency_to_string(d
), other
->id
);
713 if (!strv_isempty(u
->requires_mounts_for
)) {
715 "%s\tRequiresMountsFor:", prefix
);
717 STRV_FOREACH(j
, u
->requires_mounts_for
)
718 fprintf(f
, " %s", *j
);
723 if (u
->load_state
== UNIT_LOADED
) {
728 "%s\tStopWhenUnneeded: %s\n"
729 "%s\tRefuseManualStart: %s\n"
730 "%s\tRefuseManualStop: %s\n"
731 "%s\tDefaultDependencies: %s\n"
732 "%s\tOnFailureIsolate: %s\n"
733 "%s\tIgnoreOnIsolate: %s\n"
734 "%s\tIgnoreOnSnapshot: %s\n",
735 prefix
, yes_no(u
->stop_when_unneeded
),
736 prefix
, yes_no(u
->refuse_manual_start
),
737 prefix
, yes_no(u
->refuse_manual_stop
),
738 prefix
, yes_no(u
->default_dependencies
),
739 prefix
, yes_no(u
->on_failure_isolate
),
740 prefix
, yes_no(u
->ignore_on_isolate
),
741 prefix
, yes_no(u
->ignore_on_snapshot
));
743 LIST_FOREACH(by_unit
, b
, u
->cgroup_bondings
)
744 fprintf(f
, "%s\tControlGroup: %s:%s\n",
745 prefix
, b
->controller
, b
->path
);
747 LIST_FOREACH(by_unit
, a
, u
->cgroup_attributes
) {
751 a
->map_callback(a
->controller
, a
->name
, a
->value
, &v
);
753 fprintf(f
, "%s\tControlGroupAttribute: %s %s \"%s\"\n",
754 prefix
, a
->controller
, a
->name
, v
? v
: a
->value
);
759 if (UNIT_VTABLE(u
)->dump
)
760 UNIT_VTABLE(u
)->dump(u
, f
, prefix2
);
762 } else if (u
->load_state
== UNIT_MERGED
)
764 "%s\tMerged into: %s\n",
765 prefix
, u
->merged_into
->id
);
766 else if (u
->load_state
== UNIT_ERROR
)
767 fprintf(f
, "%s\tLoad Error Code: %s\n", prefix
, strerror(-u
->load_error
));
771 job_dump(u
->job
, f
, prefix2
);
774 job_dump(u
->nop_job
, f
, prefix2
);
779 /* Common implementation for multiple backends */
780 int unit_load_fragment_and_dropin(Unit
*u
) {
785 /* Load a .service file */
786 if ((r
= unit_load_fragment(u
)) < 0)
789 if (u
->load_state
== UNIT_STUB
)
792 /* Load drop-in directory data */
793 if ((r
= unit_load_dropin(unit_follow_merge(u
))) < 0)
799 /* Common implementation for multiple backends */
800 int unit_load_fragment_and_dropin_optional(Unit
*u
) {
805 /* Same as unit_load_fragment_and_dropin(), but whether
806 * something can be loaded or not doesn't matter. */
808 /* Load a .service file */
809 if ((r
= unit_load_fragment(u
)) < 0)
812 if (u
->load_state
== UNIT_STUB
)
813 u
->load_state
= UNIT_LOADED
;
815 /* Load drop-in directory data */
816 if ((r
= unit_load_dropin(unit_follow_merge(u
))) < 0)
822 int unit_add_default_target_dependency(Unit
*u
, Unit
*target
) {
826 if (target
->type
!= UNIT_TARGET
)
829 /* Only add the dependency if both units are loaded, so that
830 * that loop check below is reliable */
831 if (u
->load_state
!= UNIT_LOADED
||
832 target
->load_state
!= UNIT_LOADED
)
835 /* If either side wants no automatic dependencies, then let's
837 if (!u
->default_dependencies
||
838 !target
->default_dependencies
)
841 /* Don't create loops */
842 if (set_get(target
->dependencies
[UNIT_BEFORE
], u
))
845 return unit_add_dependency(target
, UNIT_AFTER
, u
, true);
848 static int unit_add_default_dependencies(Unit
*u
) {
849 static const UnitDependency deps
[] = {
851 UNIT_REQUIRED_BY_OVERRIDABLE
,
863 for (k
= 0; k
< ELEMENTSOF(deps
); k
++)
864 SET_FOREACH(target
, u
->dependencies
[deps
[k
]], i
)
865 if ((r
= unit_add_default_target_dependency(u
, target
)) < 0)
871 int unit_load(Unit
*u
) {
876 if (u
->in_load_queue
) {
877 LIST_REMOVE(Unit
, load_queue
, u
->manager
->load_queue
, u
);
878 u
->in_load_queue
= false;
881 if (u
->type
== _UNIT_TYPE_INVALID
)
884 if (u
->load_state
!= UNIT_STUB
)
887 if (UNIT_VTABLE(u
)->load
)
888 if ((r
= UNIT_VTABLE(u
)->load(u
)) < 0)
891 if (u
->load_state
== UNIT_STUB
) {
896 if (u
->load_state
== UNIT_LOADED
&&
897 u
->default_dependencies
)
898 if ((r
= unit_add_default_dependencies(u
)) < 0)
901 if (u
->load_state
== UNIT_LOADED
) {
902 r
= unit_add_mount_links(u
);
907 if (u
->on_failure_isolate
&&
908 set_size(u
->dependencies
[UNIT_ON_FAILURE
]) > 1) {
910 log_error("More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.",
917 assert((u
->load_state
!= UNIT_MERGED
) == !u
->merged_into
);
919 unit_add_to_dbus_queue(unit_follow_merge(u
));
920 unit_add_to_gc_queue(u
);
925 u
->load_state
= UNIT_ERROR
;
927 unit_add_to_dbus_queue(u
);
928 unit_add_to_gc_queue(u
);
930 log_debug("Failed to load configuration for %s: %s", u
->id
, strerror(-r
));
935 bool unit_condition_test(Unit
*u
) {
938 dual_timestamp_get(&u
->condition_timestamp
);
939 u
->condition_result
= condition_test_list(u
->conditions
);
941 return u
->condition_result
;
944 static const char* unit_get_status_message_format(Unit
*u
, JobType t
) {
945 const UnitStatusMessageFormats
*format_table
;
949 assert(t
< _JOB_TYPE_MAX
);
951 if (t
!= JOB_START
&& t
!= JOB_STOP
)
954 format_table
= &UNIT_VTABLE(u
)->status_message_formats
;
958 return format_table
->starting_stopping
[t
== JOB_STOP
];
961 static const char *unit_get_status_message_format_try_harder(Unit
*u
, JobType t
) {
966 assert(t
< _JOB_TYPE_MAX
);
968 format
= unit_get_status_message_format(u
, t
);
972 /* Return generic strings */
974 return "Starting %s.";
975 else if (t
== JOB_STOP
)
976 return "Stopping %s.";
977 else if (t
== JOB_RELOAD
)
978 return "Reloading %s.";
983 static void unit_status_print_starting_stopping(Unit
*u
, JobType t
) {
988 /* We only print status messages for selected units on
989 * selected operations. */
991 format
= unit_get_status_message_format(u
, t
);
995 unit_status_printf(u
, "", format
, unit_description(u
));
998 #pragma GCC diagnostic push
999 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
1000 static void unit_status_log_starting_stopping_reloading(Unit
*u
, JobType t
) {
1007 if (t
!= JOB_START
&& t
!= JOB_STOP
&& t
!= JOB_RELOAD
)
1010 if (log_on_console())
1013 /* We log status messages for all units and all operations. */
1015 format
= unit_get_status_message_format_try_harder(u
, t
);
1019 snprintf(buf
, sizeof(buf
), format
, unit_description(u
));
1022 mid
= t
== JOB_START
? SD_MESSAGE_UNIT_STARTING
:
1023 t
== JOB_STOP
? SD_MESSAGE_UNIT_STOPPING
:
1024 SD_MESSAGE_UNIT_RELOADING
;
1026 log_struct_unit(LOG_INFO
,
1032 #pragma GCC diagnostic pop
1035 * -EBADR: This unit type does not support starting.
1036 * -EALREADY: Unit is already started.
1037 * -EAGAIN: An operation is already in progress. Retry later.
1038 * -ECANCELED: Too many requests for now.
1040 int unit_start(Unit
*u
) {
1041 UnitActiveState state
;
1046 if (u
->load_state
!= UNIT_LOADED
)
1049 /* If this is already started, then this will succeed. Note
1050 * that this will even succeed if this unit is not startable
1051 * by the user. This is relied on to detect when we need to
1052 * wait for units and when waiting is finished. */
1053 state
= unit_active_state(u
);
1054 if (UNIT_IS_ACTIVE_OR_RELOADING(state
))
1057 /* If the conditions failed, don't do anything at all. If we
1058 * already are activating this call might still be useful to
1059 * speed up activation in case there is some hold-off time,
1060 * but we don't want to recheck the condition in that case. */
1061 if (state
!= UNIT_ACTIVATING
&&
1062 !unit_condition_test(u
)) {
1063 log_debug("Starting of %s requested but condition failed. Ignoring.", u
->id
);
1067 /* Forward to the main object, if we aren't it. */
1068 if ((following
= unit_following(u
))) {
1069 log_debug("Redirecting start request from %s to %s.", u
->id
, following
->id
);
1070 return unit_start(following
);
1073 unit_status_log_starting_stopping_reloading(u
, JOB_START
);
1074 unit_status_print_starting_stopping(u
, JOB_START
);
1076 /* If it is stopped, but we cannot start it, then fail */
1077 if (!UNIT_VTABLE(u
)->start
)
1080 /* We don't suppress calls to ->start() here when we are
1081 * already starting, to allow this request to be used as a
1082 * "hurry up" call, for example when the unit is in some "auto
1083 * restart" state where it waits for a holdoff timer to elapse
1084 * before it will start again. */
1086 unit_add_to_dbus_queue(u
);
1088 return UNIT_VTABLE(u
)->start(u
);
1091 bool unit_can_start(Unit
*u
) {
1094 return !!UNIT_VTABLE(u
)->start
;
1097 bool unit_can_isolate(Unit
*u
) {
1100 return unit_can_start(u
) &&
1105 * -EBADR: This unit type does not support stopping.
1106 * -EALREADY: Unit is already stopped.
1107 * -EAGAIN: An operation is already in progress. Retry later.
1109 int unit_stop(Unit
*u
) {
1110 UnitActiveState state
;
1115 state
= unit_active_state(u
);
1116 if (UNIT_IS_INACTIVE_OR_FAILED(state
))
1119 if ((following
= unit_following(u
))) {
1120 log_debug("Redirecting stop request from %s to %s.", u
->id
, following
->id
);
1121 return unit_stop(following
);
1124 unit_status_log_starting_stopping_reloading(u
, JOB_STOP
);
1125 unit_status_print_starting_stopping(u
, JOB_STOP
);
1127 if (!UNIT_VTABLE(u
)->stop
)
1130 unit_add_to_dbus_queue(u
);
1132 return UNIT_VTABLE(u
)->stop(u
);
1136 * -EBADR: This unit type does not support reloading.
1137 * -ENOEXEC: Unit is not started.
1138 * -EAGAIN: An operation is already in progress. Retry later.
1140 int unit_reload(Unit
*u
) {
1141 UnitActiveState state
;
1146 if (u
->load_state
!= UNIT_LOADED
)
1149 if (!unit_can_reload(u
))
1152 state
= unit_active_state(u
);
1153 if (state
== UNIT_RELOADING
)
1156 if (state
!= UNIT_ACTIVE
)
1159 if ((following
= unit_following(u
))) {
1160 log_debug("Redirecting reload request from %s to %s.", u
->id
, following
->id
);
1161 return unit_reload(following
);
1164 unit_status_log_starting_stopping_reloading(u
, JOB_RELOAD
);
1166 unit_add_to_dbus_queue(u
);
1167 return UNIT_VTABLE(u
)->reload(u
);
1170 bool unit_can_reload(Unit
*u
) {
1173 if (!UNIT_VTABLE(u
)->reload
)
1176 if (!UNIT_VTABLE(u
)->can_reload
)
1179 return UNIT_VTABLE(u
)->can_reload(u
);
1182 static void unit_check_unneeded(Unit
*u
) {
1188 /* If this service shall be shut down when unneeded then do
1191 if (!u
->stop_when_unneeded
)
1194 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u
)))
1197 SET_FOREACH(other
, u
->dependencies
[UNIT_REQUIRED_BY
], i
)
1198 if (unit_pending_active(other
))
1201 SET_FOREACH(other
, u
->dependencies
[UNIT_REQUIRED_BY_OVERRIDABLE
], i
)
1202 if (unit_pending_active(other
))
1205 SET_FOREACH(other
, u
->dependencies
[UNIT_WANTED_BY
], i
)
1206 if (unit_pending_active(other
))
1209 SET_FOREACH(other
, u
->dependencies
[UNIT_BOUND_BY
], i
)
1210 if (unit_pending_active(other
))
1213 log_info("Service %s is not needed anymore. Stopping.", u
->id
);
1215 /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
1216 manager_add_job(u
->manager
, JOB_STOP
, u
, JOB_FAIL
, true, NULL
, NULL
);
1219 static void retroactively_start_dependencies(Unit
*u
) {
1224 assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u
)));
1226 SET_FOREACH(other
, u
->dependencies
[UNIT_REQUIRES
], i
)
1227 if (!set_get(u
->dependencies
[UNIT_AFTER
], other
) &&
1228 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other
)))
1229 manager_add_job(u
->manager
, JOB_START
, other
, JOB_REPLACE
, true, NULL
, NULL
);
1231 SET_FOREACH(other
, u
->dependencies
[UNIT_BINDS_TO
], i
)
1232 if (!set_get(u
->dependencies
[UNIT_AFTER
], other
) &&
1233 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other
)))
1234 manager_add_job(u
->manager
, JOB_START
, other
, JOB_REPLACE
, true, NULL
, NULL
);
1236 SET_FOREACH(other
, u
->dependencies
[UNIT_REQUIRES_OVERRIDABLE
], i
)
1237 if (!set_get(u
->dependencies
[UNIT_AFTER
], other
) &&
1238 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other
)))
1239 manager_add_job(u
->manager
, JOB_START
, other
, JOB_FAIL
, false, NULL
, NULL
);
1241 SET_FOREACH(other
, u
->dependencies
[UNIT_REQUISITE
], i
)
1242 if (!set_get(u
->dependencies
[UNIT_AFTER
], other
) &&
1243 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other
)))
1244 manager_add_job(u
->manager
, JOB_START
, other
, JOB_REPLACE
, true, NULL
, NULL
);
1246 SET_FOREACH(other
, u
->dependencies
[UNIT_WANTS
], i
)
1247 if (!set_get(u
->dependencies
[UNIT_AFTER
], other
) &&
1248 !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other
)))
1249 manager_add_job(u
->manager
, JOB_START
, other
, JOB_FAIL
, false, NULL
, NULL
);
1251 SET_FOREACH(other
, u
->dependencies
[UNIT_CONFLICTS
], i
)
1252 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other
)))
1253 manager_add_job(u
->manager
, JOB_STOP
, other
, JOB_REPLACE
, true, NULL
, NULL
);
1255 SET_FOREACH(other
, u
->dependencies
[UNIT_CONFLICTED_BY
], i
)
1256 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other
)))
1257 manager_add_job(u
->manager
, JOB_STOP
, other
, JOB_REPLACE
, true, NULL
, NULL
);
1260 static void retroactively_stop_dependencies(Unit
*u
) {
1265 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u
)));
1267 /* Pull down units which are bound to us recursively if enabled */
1268 SET_FOREACH(other
, u
->dependencies
[UNIT_BOUND_BY
], i
)
1269 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other
)))
1270 manager_add_job(u
->manager
, JOB_STOP
, other
, JOB_REPLACE
, true, NULL
, NULL
);
1273 static void check_unneeded_dependencies(Unit
*u
) {
1278 assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u
)));
1280 /* Garbage collect services that might not be needed anymore, if enabled */
1281 SET_FOREACH(other
, u
->dependencies
[UNIT_REQUIRES
], i
)
1282 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other
)))
1283 unit_check_unneeded(other
);
1284 SET_FOREACH(other
, u
->dependencies
[UNIT_REQUIRES_OVERRIDABLE
], i
)
1285 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other
)))
1286 unit_check_unneeded(other
);
1287 SET_FOREACH(other
, u
->dependencies
[UNIT_WANTS
], i
)
1288 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other
)))
1289 unit_check_unneeded(other
);
1290 SET_FOREACH(other
, u
->dependencies
[UNIT_REQUISITE
], i
)
1291 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other
)))
1292 unit_check_unneeded(other
);
1293 SET_FOREACH(other
, u
->dependencies
[UNIT_REQUISITE_OVERRIDABLE
], i
)
1294 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other
)))
1295 unit_check_unneeded(other
);
1296 SET_FOREACH(other
, u
->dependencies
[UNIT_BINDS_TO
], i
)
1297 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other
)))
1298 unit_check_unneeded(other
);
1301 void unit_trigger_on_failure(Unit
*u
) {
1307 if (set_size(u
->dependencies
[UNIT_ON_FAILURE
]) <= 0)
1310 log_info("Triggering OnFailure= dependencies of %s.", u
->id
);
1312 SET_FOREACH(other
, u
->dependencies
[UNIT_ON_FAILURE
], i
) {
1315 if ((r
= manager_add_job(u
->manager
, JOB_START
, other
, u
->on_failure_isolate
? JOB_ISOLATE
: JOB_REPLACE
, true, NULL
, NULL
)) < 0)
1316 log_error("Failed to enqueue OnFailure= job: %s", strerror(-r
));
1320 void unit_notify(Unit
*u
, UnitActiveState os
, UnitActiveState ns
, bool reload_success
) {
1324 assert(os
< _UNIT_ACTIVE_STATE_MAX
);
1325 assert(ns
< _UNIT_ACTIVE_STATE_MAX
);
1327 /* Note that this is called for all low-level state changes,
1328 * even if they might map to the same high-level
1329 * UnitActiveState! That means that ns == os is OK an expected
1330 * behavior here. For example: if a mount point is remounted
1331 * this function will be called too! */
1333 if (u
->manager
->n_reloading
<= 0) {
1336 dual_timestamp_get(&ts
);
1338 if (UNIT_IS_INACTIVE_OR_FAILED(os
) && !UNIT_IS_INACTIVE_OR_FAILED(ns
))
1339 u
->inactive_exit_timestamp
= ts
;
1340 else if (!UNIT_IS_INACTIVE_OR_FAILED(os
) && UNIT_IS_INACTIVE_OR_FAILED(ns
))
1341 u
->inactive_enter_timestamp
= ts
;
1343 if (!UNIT_IS_ACTIVE_OR_RELOADING(os
) && UNIT_IS_ACTIVE_OR_RELOADING(ns
))
1344 u
->active_enter_timestamp
= ts
;
1345 else if (UNIT_IS_ACTIVE_OR_RELOADING(os
) && !UNIT_IS_ACTIVE_OR_RELOADING(ns
))
1346 u
->active_exit_timestamp
= ts
;
1348 timer_unit_notify(u
, ns
);
1349 path_unit_notify(u
, ns
);
1352 if (UNIT_IS_INACTIVE_OR_FAILED(ns
))
1353 cgroup_bonding_trim_list(u
->cgroup_bondings
, true);
1358 if (u
->job
->state
== JOB_WAITING
)
1360 /* So we reached a different state for this
1361 * job. Let's see if we can run it now if it
1362 * failed previously due to EAGAIN. */
1363 job_add_to_run_queue(u
->job
);
1365 /* Let's check whether this state change constitutes a
1366 * finished job, or maybe contradicts a running job and
1367 * hence needs to invalidate jobs. */
1369 switch (u
->job
->type
) {
1372 case JOB_VERIFY_ACTIVE
:
1374 if (UNIT_IS_ACTIVE_OR_RELOADING(ns
))
1375 job_finish_and_invalidate(u
->job
, JOB_DONE
, true);
1376 else if (u
->job
->state
== JOB_RUNNING
&& ns
!= UNIT_ACTIVATING
) {
1379 if (UNIT_IS_INACTIVE_OR_FAILED(ns
))
1380 job_finish_and_invalidate(u
->job
, ns
== UNIT_FAILED
? JOB_FAILED
: JOB_DONE
, true);
1386 case JOB_RELOAD_OR_START
:
1388 if (u
->job
->state
== JOB_RUNNING
) {
1389 if (ns
== UNIT_ACTIVE
)
1390 job_finish_and_invalidate(u
->job
, reload_success
? JOB_DONE
: JOB_FAILED
, true);
1391 else if (ns
!= UNIT_ACTIVATING
&& ns
!= UNIT_RELOADING
) {
1394 if (UNIT_IS_INACTIVE_OR_FAILED(ns
))
1395 job_finish_and_invalidate(u
->job
, ns
== UNIT_FAILED
? JOB_FAILED
: JOB_DONE
, true);
1403 case JOB_TRY_RESTART
:
1405 if (UNIT_IS_INACTIVE_OR_FAILED(ns
))
1406 job_finish_and_invalidate(u
->job
, JOB_DONE
, true);
1407 else if (u
->job
->state
== JOB_RUNNING
&& ns
!= UNIT_DEACTIVATING
) {
1409 job_finish_and_invalidate(u
->job
, JOB_FAILED
, true);
1415 assert_not_reached("Job type unknown");
1421 if (u
->manager
->n_reloading
<= 0) {
1423 /* If this state change happened without being
1424 * requested by a job, then let's retroactively start
1425 * or stop dependencies. We skip that step when
1426 * deserializing, since we don't want to create any
1427 * additional jobs just because something is already
1431 if (UNIT_IS_INACTIVE_OR_FAILED(os
) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns
))
1432 retroactively_start_dependencies(u
);
1433 else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os
) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns
))
1434 retroactively_stop_dependencies(u
);
1437 /* stop unneeded units regardless if going down was expected or not */
1438 if (UNIT_IS_ACTIVE_OR_ACTIVATING(os
) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns
))
1439 check_unneeded_dependencies(u
);
1441 if (ns
!= os
&& ns
== UNIT_FAILED
) {
1442 log_struct_unit(LOG_NOTICE
,
1444 "MESSAGE=Unit %s entered failed state", u
->id
,
1446 unit_trigger_on_failure(u
);
1450 /* Some names are special */
1451 if (UNIT_IS_ACTIVE_OR_RELOADING(ns
)) {
1453 if (unit_has_name(u
, SPECIAL_DBUS_SERVICE
))
1454 /* The bus just might have become available,
1455 * hence try to connect to it, if we aren't
1457 bus_init(u
->manager
, true);
1459 if (u
->type
== UNIT_SERVICE
&&
1460 !UNIT_IS_ACTIVE_OR_RELOADING(os
) &&
1461 u
->manager
->n_reloading
<= 0) {
1462 /* Write audit record if we have just finished starting up */
1463 manager_send_unit_audit(u
->manager
, u
, AUDIT_SERVICE_START
, true);
1467 if (!UNIT_IS_ACTIVE_OR_RELOADING(os
))
1468 manager_send_unit_plymouth(u
->manager
, u
);
1472 /* We don't care about D-Bus here, since we'll get an
1473 * asynchronous notification for it anyway. */
1475 if (u
->type
== UNIT_SERVICE
&&
1476 UNIT_IS_INACTIVE_OR_FAILED(ns
) &&
1477 !UNIT_IS_INACTIVE_OR_FAILED(os
) &&
1478 u
->manager
->n_reloading
<= 0) {
1480 /* Hmm, if there was no start record written
1481 * write it now, so that we always have a nice
1484 manager_send_unit_audit(u
->manager
, u
, AUDIT_SERVICE_START
, ns
== UNIT_INACTIVE
);
1486 if (ns
== UNIT_INACTIVE
)
1487 manager_send_unit_audit(u
->manager
, u
, AUDIT_SERVICE_STOP
, true);
1489 /* Write audit record if we have just finished shutting down */
1490 manager_send_unit_audit(u
->manager
, u
, AUDIT_SERVICE_STOP
, ns
== UNIT_INACTIVE
);
1492 u
->in_audit
= false;
1496 manager_recheck_journal(u
->manager
);
1498 /* Maybe we finished startup and are now ready for being
1499 * stopped because unneeded? */
1500 unit_check_unneeded(u
);
1502 unit_add_to_dbus_queue(u
);
1503 unit_add_to_gc_queue(u
);
1506 int unit_watch_fd(Unit
*u
, int fd
, uint32_t events
, Watch
*w
) {
1507 struct epoll_event ev
;
1512 assert(w
->type
== WATCH_INVALID
|| (w
->type
== WATCH_FD
&& w
->fd
== fd
&& w
->data
.unit
== u
));
1518 if (epoll_ctl(u
->manager
->epoll_fd
,
1519 w
->type
== WATCH_INVALID
? EPOLL_CTL_ADD
: EPOLL_CTL_MOD
,
1531 void unit_unwatch_fd(Unit
*u
, Watch
*w
) {
1535 if (w
->type
== WATCH_INVALID
)
1538 assert(w
->type
== WATCH_FD
);
1539 assert(w
->data
.unit
== u
);
1540 assert_se(epoll_ctl(u
->manager
->epoll_fd
, EPOLL_CTL_DEL
, w
->fd
, NULL
) >= 0);
1543 w
->type
= WATCH_INVALID
;
1544 w
->data
.unit
= NULL
;
1547 int unit_watch_pid(Unit
*u
, pid_t pid
) {
1551 /* Watch a specific PID. We only support one unit watching
1552 * each PID for now. */
1554 return hashmap_put(u
->manager
->watch_pids
, LONG_TO_PTR(pid
), u
);
1557 void unit_unwatch_pid(Unit
*u
, pid_t pid
) {
1561 hashmap_remove_value(u
->manager
->watch_pids
, LONG_TO_PTR(pid
), u
);
1564 int unit_watch_timer(Unit
*u
, clockid_t clock_id
, bool relative
, usec_t usec
, Watch
*w
) {
1565 struct itimerspec its
;
1571 assert(w
->type
== WATCH_INVALID
|| (w
->type
== WATCH_UNIT_TIMER
&& w
->data
.unit
== u
));
1573 /* This will try to reuse the old timer if there is one */
1575 if (w
->type
== WATCH_UNIT_TIMER
) {
1576 assert(w
->data
.unit
== u
);
1581 } else if (w
->type
== WATCH_INVALID
) {
1584 fd
= timerfd_create(clock_id
, TFD_NONBLOCK
|TFD_CLOEXEC
);
1588 assert_not_reached("Invalid watch type");
1593 /* Set absolute time in the past, but not 0, since we
1594 * don't want to disarm the timer */
1595 its
.it_value
.tv_sec
= 0;
1596 its
.it_value
.tv_nsec
= 1;
1598 flags
= TFD_TIMER_ABSTIME
;
1600 timespec_store(&its
.it_value
, usec
);
1601 flags
= relative
? 0 : TFD_TIMER_ABSTIME
;
1604 /* This will also flush the elapse counter */
1605 if (timerfd_settime(fd
, flags
, &its
, NULL
) < 0)
1608 if (w
->type
== WATCH_INVALID
) {
1609 struct epoll_event ev
;
1613 ev
.events
= EPOLLIN
;
1615 if (epoll_ctl(u
->manager
->epoll_fd
, EPOLL_CTL_ADD
, fd
, &ev
) < 0)
1619 w
->type
= WATCH_UNIT_TIMER
;
1627 close_nointr_nofail(fd
);
1632 void unit_unwatch_timer(Unit
*u
, Watch
*w
) {
1636 if (w
->type
== WATCH_INVALID
)
1639 assert(w
->type
== WATCH_UNIT_TIMER
);
1640 assert(w
->data
.unit
== u
);
1643 assert_se(epoll_ctl(u
->manager
->epoll_fd
, EPOLL_CTL_DEL
, w
->fd
, NULL
) >= 0);
1644 close_nointr_nofail(w
->fd
);
1647 w
->type
= WATCH_INVALID
;
1648 w
->data
.unit
= NULL
;
1651 bool unit_job_is_applicable(Unit
*u
, JobType j
) {
1653 assert(j
>= 0 && j
< _JOB_TYPE_MAX
);
1657 case JOB_VERIFY_ACTIVE
:
1664 case JOB_TRY_RESTART
:
1665 return unit_can_start(u
);
1668 return unit_can_reload(u
);
1670 case JOB_RELOAD_OR_START
:
1671 return unit_can_reload(u
) && unit_can_start(u
);
1674 assert_not_reached("Invalid job type");
1678 int unit_add_dependency(Unit
*u
, UnitDependency d
, Unit
*other
, bool add_reference
) {
1680 static const UnitDependency inverse_table
[_UNIT_DEPENDENCY_MAX
] = {
1681 [UNIT_REQUIRES
] = UNIT_REQUIRED_BY
,
1682 [UNIT_REQUIRES_OVERRIDABLE
] = UNIT_REQUIRED_BY_OVERRIDABLE
,
1683 [UNIT_WANTS
] = UNIT_WANTED_BY
,
1684 [UNIT_REQUISITE
] = UNIT_REQUIRED_BY
,
1685 [UNIT_REQUISITE_OVERRIDABLE
] = UNIT_REQUIRED_BY_OVERRIDABLE
,
1686 [UNIT_BINDS_TO
] = UNIT_BOUND_BY
,
1687 [UNIT_PART_OF
] = UNIT_CONSISTS_OF
,
1688 [UNIT_REQUIRED_BY
] = _UNIT_DEPENDENCY_INVALID
,
1689 [UNIT_REQUIRED_BY_OVERRIDABLE
] = _UNIT_DEPENDENCY_INVALID
,
1690 [UNIT_WANTED_BY
] = _UNIT_DEPENDENCY_INVALID
,
1691 [UNIT_BOUND_BY
] = UNIT_BINDS_TO
,
1692 [UNIT_CONSISTS_OF
] = UNIT_PART_OF
,
1693 [UNIT_CONFLICTS
] = UNIT_CONFLICTED_BY
,
1694 [UNIT_CONFLICTED_BY
] = UNIT_CONFLICTS
,
1695 [UNIT_BEFORE
] = UNIT_AFTER
,
1696 [UNIT_AFTER
] = UNIT_BEFORE
,
1697 [UNIT_ON_FAILURE
] = _UNIT_DEPENDENCY_INVALID
,
1698 [UNIT_REFERENCES
] = UNIT_REFERENCED_BY
,
1699 [UNIT_REFERENCED_BY
] = UNIT_REFERENCES
,
1700 [UNIT_TRIGGERS
] = UNIT_TRIGGERED_BY
,
1701 [UNIT_TRIGGERED_BY
] = UNIT_TRIGGERS
,
1702 [UNIT_PROPAGATES_RELOAD_TO
] = UNIT_RELOAD_PROPAGATED_FROM
,
1703 [UNIT_RELOAD_PROPAGATED_FROM
] = UNIT_PROPAGATES_RELOAD_TO
,
1705 int r
, q
= 0, v
= 0, w
= 0;
1708 assert(d
>= 0 && d
< _UNIT_DEPENDENCY_MAX
);
1711 u
= unit_follow_merge(u
);
1712 other
= unit_follow_merge(other
);
1714 /* We won't allow dependencies on ourselves. We will not
1715 * consider them an error however. */
1719 if ((r
= set_ensure_allocated(&u
->dependencies
[d
], trivial_hash_func
, trivial_compare_func
)) < 0)
1722 if (inverse_table
[d
] != _UNIT_DEPENDENCY_INVALID
)
1723 if ((r
= set_ensure_allocated(&other
->dependencies
[inverse_table
[d
]], trivial_hash_func
, trivial_compare_func
)) < 0)
1727 if ((r
= set_ensure_allocated(&u
->dependencies
[UNIT_REFERENCES
], trivial_hash_func
, trivial_compare_func
)) < 0 ||
1728 (r
= set_ensure_allocated(&other
->dependencies
[UNIT_REFERENCED_BY
], trivial_hash_func
, trivial_compare_func
)) < 0)
1731 if ((q
= set_put(u
->dependencies
[d
], other
)) < 0)
1734 if (inverse_table
[d
] != _UNIT_DEPENDENCY_INVALID
)
1735 if ((v
= set_put(other
->dependencies
[inverse_table
[d
]], u
)) < 0) {
1740 if (add_reference
) {
1741 if ((w
= set_put(u
->dependencies
[UNIT_REFERENCES
], other
)) < 0) {
1746 if ((r
= set_put(other
->dependencies
[UNIT_REFERENCED_BY
], u
)) < 0)
1750 unit_add_to_dbus_queue(u
);
1755 set_remove(u
->dependencies
[d
], other
);
1758 set_remove(other
->dependencies
[inverse_table
[d
]], u
);
1761 set_remove(u
->dependencies
[UNIT_REFERENCES
], other
);
1766 int unit_add_two_dependencies(Unit
*u
, UnitDependency d
, UnitDependency e
, Unit
*other
, bool add_reference
) {
1771 if ((r
= unit_add_dependency(u
, d
, other
, add_reference
)) < 0)
1774 if ((r
= unit_add_dependency(u
, e
, other
, add_reference
)) < 0)
1780 static const char *resolve_template(Unit
*u
, const char *name
, const char*path
, char **p
) {
1784 assert(name
|| path
);
1788 name
= path_get_file_name(path
);
1790 if (!unit_name_is_template(name
)) {
1796 s
= unit_name_replace_instance(name
, u
->instance
);
1800 i
= unit_name_to_prefix(u
->id
);
1804 s
= unit_name_replace_instance(name
, i
);
1815 int unit_add_dependency_by_name(Unit
*u
, UnitDependency d
, const char *name
, const char *path
, bool add_reference
) {
1818 _cleanup_free_
char *s
= NULL
;
1821 assert(name
|| path
);
1823 name
= resolve_template(u
, name
, path
, &s
);
1827 r
= manager_load_unit(u
->manager
, name
, path
, NULL
, &other
);
1831 return unit_add_dependency(u
, d
, other
, add_reference
);
1834 int unit_add_two_dependencies_by_name(Unit
*u
, UnitDependency d
, UnitDependency e
, const char *name
, const char *path
, bool add_reference
) {
1840 assert(name
|| path
);
1842 if (!(name
= resolve_template(u
, name
, path
, &s
)))
1845 if ((r
= manager_load_unit(u
->manager
, name
, path
, NULL
, &other
)) < 0)
1848 r
= unit_add_two_dependencies(u
, d
, e
, other
, add_reference
);
1855 int unit_add_dependency_by_name_inverse(Unit
*u
, UnitDependency d
, const char *name
, const char *path
, bool add_reference
) {
1861 assert(name
|| path
);
1863 if (!(name
= resolve_template(u
, name
, path
, &s
)))
1866 if ((r
= manager_load_unit(u
->manager
, name
, path
, NULL
, &other
)) < 0)
1869 r
= unit_add_dependency(other
, d
, u
, add_reference
);
1876 int unit_add_two_dependencies_by_name_inverse(Unit
*u
, UnitDependency d
, UnitDependency e
, const char *name
, const char *path
, bool add_reference
) {
1882 assert(name
|| path
);
1884 if (!(name
= resolve_template(u
, name
, path
, &s
)))
1887 if ((r
= manager_load_unit(u
->manager
, name
, path
, NULL
, &other
)) < 0)
1890 if ((r
= unit_add_two_dependencies(other
, d
, e
, u
, add_reference
)) < 0)
1898 int set_unit_path(const char *p
) {
1902 /* This is mostly for debug purposes */
1904 if (path_is_absolute(p
)) {
1905 if (!(c
= strdup(p
)))
1908 if (!(cwd
= get_current_dir_name()))
1911 r
= asprintf(&c
, "%s/%s", cwd
, p
);
1918 if (setenv("SYSTEMD_UNIT_PATH", c
, 0) < 0) {
1927 char *unit_dbus_path(Unit
*u
) {
1933 return unit_dbus_path_from_name(u
->id
);
1936 int unit_add_cgroup(Unit
*u
, CGroupBonding
*b
) {
1944 if (!b
->controller
) {
1945 b
->controller
= strdup(SYSTEMD_CGROUP_CONTROLLER
);
1952 /* Ensure this hasn't been added yet */
1955 if (streq(b
->controller
, SYSTEMD_CGROUP_CONTROLLER
)) {
1958 l
= hashmap_get(u
->manager
->cgroup_bondings
, b
->path
);
1959 LIST_PREPEND(CGroupBonding
, by_path
, l
, b
);
1961 r
= hashmap_replace(u
->manager
->cgroup_bondings
, b
->path
, l
);
1963 LIST_REMOVE(CGroupBonding
, by_path
, l
, b
);
1968 LIST_PREPEND(CGroupBonding
, by_unit
, u
->cgroup_bondings
, b
);
1974 char *unit_default_cgroup_path(Unit
*u
) {
1978 _cleanup_free_
char *t
= NULL
;
1980 t
= unit_name_template(u
->id
);
1984 return strjoin(u
->manager
->cgroup_hierarchy
, "/", t
, "/", u
->instance
, NULL
);
1986 return strjoin(u
->manager
->cgroup_hierarchy
, "/", u
->id
, NULL
);
1989 int unit_add_cgroup_from_text(Unit
*u
, const char *name
, bool overwrite
, CGroupBonding
**ret
) {
1990 char *controller
= NULL
, *path
= NULL
;
1991 CGroupBonding
*b
= NULL
;
1998 r
= cg_split_spec(name
, &controller
, &path
);
2003 path
= unit_default_cgroup_path(u
);
2008 controller
= strdup(SYSTEMD_CGROUP_CONTROLLER
);
2012 if (!path
|| !controller
) {
2018 b
= cgroup_bonding_find_list(u
->cgroup_bondings
, controller
);
2020 if (streq(path
, b
->path
)) {
2029 if (overwrite
&& !b
->essential
) {
2036 b
->realized
= false;
2049 b
= new0(CGroupBonding
, 1);
2055 b
->controller
= controller
;
2058 b
->essential
= streq(controller
, SYSTEMD_CGROUP_CONTROLLER
);
2060 r
= unit_add_cgroup(u
, b
);
2077 static int unit_add_one_default_cgroup(Unit
*u
, const char *controller
) {
2078 CGroupBonding
*b
= NULL
;
2084 controller
= SYSTEMD_CGROUP_CONTROLLER
;
2086 if (cgroup_bonding_find_list(u
->cgroup_bondings
, controller
))
2089 b
= new0(CGroupBonding
, 1);
2093 b
->controller
= strdup(controller
);
2097 b
->path
= unit_default_cgroup_path(u
);
2102 b
->essential
= streq(controller
, SYSTEMD_CGROUP_CONTROLLER
);
2104 r
= unit_add_cgroup(u
, b
);
2112 free(b
->controller
);
2118 int unit_add_default_cgroups(Unit
*u
) {
2125 /* Adds in the default cgroups, if they weren't specified
2128 if (!u
->manager
->cgroup_hierarchy
)
2131 r
= unit_add_one_default_cgroup(u
, NULL
);
2135 STRV_FOREACH(c
, u
->manager
->default_controllers
)
2136 unit_add_one_default_cgroup(u
, *c
);
2138 LIST_FOREACH(by_unit
, a
, u
->cgroup_attributes
)
2139 unit_add_one_default_cgroup(u
, a
->controller
);
2144 CGroupBonding
* unit_get_default_cgroup(Unit
*u
) {
2147 return cgroup_bonding_find_list(u
->cgroup_bondings
, NULL
);
2150 int unit_add_cgroup_attribute(
2152 const char *controller
,
2155 CGroupAttributeMapCallback map_callback
,
2156 CGroupAttribute
**ret
) {
2158 _cleanup_free_
char *c
= NULL
;
2167 r
= cg_controller_from_attr(name
, &c
);
2173 if (!filename_is_safe(name
))
2176 if (!filename_is_safe(controller
))
2180 if (!controller
|| streq(controller
, SYSTEMD_CGROUP_CONTROLLER
))
2183 a
= cgroup_attribute_find_list(u
->cgroup_attributes
, controller
, name
);
2187 if (streq(value
, a
->value
)) {
2207 a
= new0(CGroupAttribute
, 1);
2215 a
->controller
= strdup(controller
);
2217 a
->name
= strdup(name
);
2218 a
->value
= strdup(value
);
2220 if (!a
->controller
|| !a
->name
|| !a
->value
) {
2221 free(a
->controller
);
2229 a
->map_callback
= map_callback
;
2232 LIST_PREPEND(CGroupAttribute
, by_unit
, u
->cgroup_attributes
, a
);
2240 int unit_load_related_unit(Unit
*u
, const char *type
, Unit
**_found
) {
2248 if (!(t
= unit_name_change_suffix(u
->id
, type
)))
2251 assert(!unit_has_name(u
, t
));
2253 r
= manager_load_unit(u
->manager
, t
, NULL
, NULL
, _found
);
2256 assert(r
< 0 || *_found
!= u
);
2261 int unit_get_related_unit(Unit
*u
, const char *type
, Unit
**_found
) {
2269 if (!(t
= unit_name_change_suffix(u
->id
, type
)))
2272 assert(!unit_has_name(u
, t
));
2274 found
= manager_get_unit(u
->manager
, t
);
2284 int unit_watch_bus_name(Unit
*u
, const char *name
) {
2288 /* Watch a specific name on the bus. We only support one unit
2289 * watching each name for now. */
2291 return hashmap_put(u
->manager
->watch_bus
, name
, u
);
2294 void unit_unwatch_bus_name(Unit
*u
, const char *name
) {
2298 hashmap_remove_value(u
->manager
->watch_bus
, name
, u
);
2301 bool unit_can_serialize(Unit
*u
) {
2304 return UNIT_VTABLE(u
)->serialize
&& UNIT_VTABLE(u
)->deserialize_item
;
2307 int unit_serialize(Unit
*u
, FILE *f
, FDSet
*fds
, bool serialize_jobs
) {
2314 if (!unit_can_serialize(u
))
2317 if ((r
= UNIT_VTABLE(u
)->serialize(u
, f
, fds
)) < 0)
2321 if (serialize_jobs
) {
2323 fprintf(f
, "job\n");
2324 job_serialize(u
->job
, f
, fds
);
2328 fprintf(f
, "job\n");
2329 job_serialize(u
->nop_job
, f
, fds
);
2333 dual_timestamp_serialize(f
, "inactive-exit-timestamp", &u
->inactive_exit_timestamp
);
2334 dual_timestamp_serialize(f
, "active-enter-timestamp", &u
->active_enter_timestamp
);
2335 dual_timestamp_serialize(f
, "active-exit-timestamp", &u
->active_exit_timestamp
);
2336 dual_timestamp_serialize(f
, "inactive-enter-timestamp", &u
->inactive_enter_timestamp
);
2337 dual_timestamp_serialize(f
, "condition-timestamp", &u
->condition_timestamp
);
2339 if (dual_timestamp_is_set(&u
->condition_timestamp
))
2340 unit_serialize_item(u
, f
, "condition-result", yes_no(u
->condition_result
));
2347 void unit_serialize_item_format(Unit
*u
, FILE *f
, const char *key
, const char *format
, ...) {
2358 va_start(ap
, format
);
2359 vfprintf(f
, format
, ap
);
2365 void unit_serialize_item(Unit
*u
, FILE *f
, const char *key
, const char *value
) {
2371 fprintf(f
, "%s=%s\n", key
, value
);
2374 int unit_deserialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
2381 if (!unit_can_serialize(u
))
2385 char line
[LINE_MAX
], *l
, *v
;
2388 if (!fgets(line
, sizeof(line
), f
)) {
2401 k
= strcspn(l
, "=");
2409 if (streq(l
, "job")) {
2411 /* new-style serialized job */
2412 Job
*j
= job_new_raw(u
);
2416 r
= job_deserialize(j
, f
, fds
);
2422 r
= hashmap_put(u
->manager
->jobs
, UINT32_TO_PTR(j
->id
), j
);
2428 r
= job_install_deserialized(j
);
2430 hashmap_remove(u
->manager
->jobs
, UINT32_TO_PTR(j
->id
));
2436 JobType type
= job_type_from_string(v
);
2438 log_debug("Failed to parse job type value %s", v
);
2440 u
->deserialized_job
= type
;
2443 } else if (streq(l
, "inactive-exit-timestamp")) {
2444 dual_timestamp_deserialize(v
, &u
->inactive_exit_timestamp
);
2446 } else if (streq(l
, "active-enter-timestamp")) {
2447 dual_timestamp_deserialize(v
, &u
->active_enter_timestamp
);
2449 } else if (streq(l
, "active-exit-timestamp")) {
2450 dual_timestamp_deserialize(v
, &u
->active_exit_timestamp
);
2452 } else if (streq(l
, "inactive-enter-timestamp")) {
2453 dual_timestamp_deserialize(v
, &u
->inactive_enter_timestamp
);
2455 } else if (streq(l
, "condition-timestamp")) {
2456 dual_timestamp_deserialize(v
, &u
->condition_timestamp
);
2458 } else if (streq(l
, "condition-result")) {
2461 if ((b
= parse_boolean(v
)) < 0)
2462 log_debug("Failed to parse condition result value %s", v
);
2464 u
->condition_result
= b
;
2469 if ((r
= UNIT_VTABLE(u
)->deserialize_item(u
, l
, v
, fds
)) < 0)
2474 int unit_add_node_link(Unit
*u
, const char *what
, bool wants
) {
2484 /* Adds in links to the device node that this unit is based on */
2486 if (!is_device_path(what
))
2489 e
= unit_name_from_path(what
, ".device");
2493 r
= manager_load_unit(u
->manager
, e
, NULL
, NULL
, &device
);
2498 r
= unit_add_two_dependencies(u
, UNIT_AFTER
, UNIT_BINDS_TO
, device
, true);
2503 r
= unit_add_dependency(device
, UNIT_WANTS
, u
, false);
2511 int unit_coldplug(Unit
*u
) {
2516 if (UNIT_VTABLE(u
)->coldplug
)
2517 if ((r
= UNIT_VTABLE(u
)->coldplug(u
)) < 0)
2521 r
= job_coldplug(u
->job
);
2524 } else if (u
->deserialized_job
>= 0) {
2526 r
= manager_add_job(u
->manager
, u
->deserialized_job
, u
, JOB_IGNORE_REQUIREMENTS
, false, NULL
, NULL
);
2530 u
->deserialized_job
= _JOB_TYPE_INVALID
;
2536 void unit_status_printf(Unit
*u
, const char *status
, const char *format
, ...) {
2542 if (!manager_get_show_status(u
->manager
))
2545 if (!manager_is_booting_or_shutting_down(u
->manager
))
2548 va_start(ap
, format
);
2549 status_vprintf(status
, true, format
, ap
);
2553 bool unit_need_daemon_reload(Unit
*u
) {
2558 if (u
->fragment_path
) {
2560 if (stat(u
->fragment_path
, &st
) < 0)
2561 /* What, cannot access this anymore? */
2564 if (u
->fragment_mtime
> 0 &&
2565 timespec_load(&st
.st_mtim
) != u
->fragment_mtime
)
2569 if (u
->source_path
) {
2571 if (stat(u
->source_path
, &st
) < 0)
2574 if (u
->source_mtime
> 0 &&
2575 timespec_load(&st
.st_mtim
) != u
->source_mtime
)
2582 void unit_reset_failed(Unit
*u
) {
2585 if (UNIT_VTABLE(u
)->reset_failed
)
2586 UNIT_VTABLE(u
)->reset_failed(u
);
2589 Unit
*unit_following(Unit
*u
) {
2592 if (UNIT_VTABLE(u
)->following
)
2593 return UNIT_VTABLE(u
)->following(u
);
2598 bool unit_pending_inactive(Unit
*u
) {
2601 /* Returns true if the unit is inactive or going down */
2603 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u
)))
2606 if (u
->job
&& u
->job
->type
== JOB_STOP
)
2612 bool unit_pending_active(Unit
*u
) {
2615 /* Returns true if the unit is active or going up */
2617 if (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u
)))
2621 (u
->job
->type
== JOB_START
||
2622 u
->job
->type
== JOB_RELOAD_OR_START
||
2623 u
->job
->type
== JOB_RESTART
))
2629 int unit_kill(Unit
*u
, KillWho w
, int signo
, DBusError
*error
) {
2631 assert(w
>= 0 && w
< _KILL_WHO_MAX
);
2633 assert(signo
< _NSIG
);
2635 if (!UNIT_VTABLE(u
)->kill
)
2638 return UNIT_VTABLE(u
)->kill(u
, w
, signo
, error
);
2641 int unit_following_set(Unit
*u
, Set
**s
) {
2645 if (UNIT_VTABLE(u
)->following_set
)
2646 return UNIT_VTABLE(u
)->following_set(u
, s
);
2652 UnitFileState
unit_get_unit_file_state(Unit
*u
) {
2655 if (u
->unit_file_state
< 0 && u
->fragment_path
)
2656 u
->unit_file_state
= unit_file_get_state(
2657 u
->manager
->running_as
== SYSTEMD_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
,
2658 NULL
, path_get_file_name(u
->fragment_path
));
2660 return u
->unit_file_state
;
2663 Unit
* unit_ref_set(UnitRef
*ref
, Unit
*u
) {
2668 unit_ref_unset(ref
);
2671 LIST_PREPEND(UnitRef
, refs
, u
->refs
, ref
);
2675 void unit_ref_unset(UnitRef
*ref
) {
2681 LIST_REMOVE(UnitRef
, refs
, ref
->unit
->refs
, ref
);
2685 int unit_add_one_mount_link(Unit
*u
, Mount
*m
) {
2691 if (u
->load_state
!= UNIT_LOADED
||
2692 UNIT(m
)->load_state
!= UNIT_LOADED
)
2695 STRV_FOREACH(i
, u
->requires_mounts_for
) {
2700 if (!path_startswith(*i
, m
->where
))
2703 return unit_add_two_dependencies(u
, UNIT_AFTER
, UNIT_REQUIRES
, UNIT(m
), true);
2709 int unit_add_mount_links(Unit
*u
) {
2715 LIST_FOREACH(units_by_type
, other
, u
->manager
->units_by_type
[UNIT_MOUNT
]) {
2716 r
= unit_add_one_mount_link(u
, MOUNT(other
));
2724 int unit_exec_context_defaults(Unit
*u
, ExecContext
*c
) {
2731 /* 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 int unit_write_drop_in(Unit
*u
, bool runtime
, const char *name
, const char *data
) {
2763 _cleanup_free_
char *p
= NULL
, *q
= NULL
;
2766 if (u
->manager
->running_as
!= SYSTEMD_SYSTEM
)
2769 if (!filename_is_safe(name
))
2772 p
= strjoin(runtime
? "/run/systemd/system/" : "/etc/systemd/system/", u
->id
, ".d", NULL
);
2776 q
= strjoin(p
, "/50-", name
, ".conf", NULL
);
2781 return write_one_line_file_atomic(q
, data
);
2784 int unit_remove_drop_in(Unit
*u
, bool runtime
, const char *name
) {
2785 _cleanup_free_
char *p
= NULL
, *q
= NULL
;
2789 if (u
->manager
->running_as
!= SYSTEMD_SYSTEM
)
2792 if (!filename_is_safe(name
))
2795 p
= strjoin(runtime
? "/run/systemd/system/" : "/etc/systemd/system/", u
->id
, ".d", NULL
);
2799 q
= strjoin(p
, "/50-", name
, ".conf", NULL
);
2810 int unit_kill_context(
2816 bool main_pid_alien
) {
2818 int sig
, wait_for_exit
= 0, r
;
2823 if (c
->kill_mode
== KILL_NONE
)
2826 sig
= sigkill
? SIGKILL
: c
->kill_signal
;
2829 r
= kill_and_sigcont(main_pid
, sig
);
2831 if (r
< 0 && r
!= -ESRCH
) {
2832 _cleanup_free_
char *comm
= NULL
;
2833 get_process_comm(main_pid
, &comm
);
2835 log_warning_unit(u
->id
, "Failed to kill main process %li (%s): %s",
2836 (long) main_pid
, strna(comm
), strerror(-r
));
2838 wait_for_exit
= !main_pid_alien
;
2841 if (control_pid
> 0) {
2842 r
= kill_and_sigcont(control_pid
, sig
);
2844 if (r
< 0 && r
!= -ESRCH
) {
2845 _cleanup_free_
char *comm
= NULL
;
2846 get_process_comm(control_pid
, &comm
);
2848 log_warning_unit(u
->id
,
2849 "Failed to kill control process %li (%s): %s",
2850 (long) control_pid
, strna(comm
), strerror(-r
));
2852 wait_for_exit
= true;
2855 if (c
->kill_mode
== KILL_CONTROL_GROUP
) {
2856 _cleanup_set_free_ Set
*pid_set
= NULL
;
2858 pid_set
= set_new(trivial_hash_func
, trivial_compare_func
);
2862 /* Exclude the main/control pids from being killed via the cgroup */
2864 r
= set_put(pid_set
, LONG_TO_PTR(main_pid
));
2869 if (control_pid
> 0) {
2870 r
= set_put(pid_set
, LONG_TO_PTR(control_pid
));
2875 r
= cgroup_bonding_kill_list(u
->cgroup_bondings
, sig
, true, false, pid_set
, NULL
);
2877 if (r
!= -EAGAIN
&& r
!= -ESRCH
&& r
!= -ENOENT
)
2878 log_warning_unit(u
->id
, "Failed to kill control group: %s", strerror(-r
));
2880 wait_for_exit
= true;
2883 return wait_for_exit
;
2886 static const char* const unit_active_state_table
[_UNIT_ACTIVE_STATE_MAX
] = {
2887 [UNIT_ACTIVE
] = "active",
2888 [UNIT_RELOADING
] = "reloading",
2889 [UNIT_INACTIVE
] = "inactive",
2890 [UNIT_FAILED
] = "failed",
2891 [UNIT_ACTIVATING
] = "activating",
2892 [UNIT_DEACTIVATING
] = "deactivating"
2895 DEFINE_STRING_TABLE_LOOKUP(unit_active_state
, UnitActiveState
);
2897 static const char* const unit_dependency_table
[_UNIT_DEPENDENCY_MAX
] = {
2898 [UNIT_REQUIRES
] = "Requires",
2899 [UNIT_REQUIRES_OVERRIDABLE
] = "RequiresOverridable",
2900 [UNIT_REQUISITE
] = "Requisite",
2901 [UNIT_REQUISITE_OVERRIDABLE
] = "RequisiteOverridable",
2902 [UNIT_WANTS
] = "Wants",
2903 [UNIT_BINDS_TO
] = "BindsTo",
2904 [UNIT_PART_OF
] = "PartOf",
2905 [UNIT_REQUIRED_BY
] = "RequiredBy",
2906 [UNIT_REQUIRED_BY_OVERRIDABLE
] = "RequiredByOverridable",
2907 [UNIT_WANTED_BY
] = "WantedBy",
2908 [UNIT_BOUND_BY
] = "BoundBy",
2909 [UNIT_CONSISTS_OF
] = "ConsistsOf",
2910 [UNIT_CONFLICTS
] = "Conflicts",
2911 [UNIT_CONFLICTED_BY
] = "ConflictedBy",
2912 [UNIT_BEFORE
] = "Before",
2913 [UNIT_AFTER
] = "After",
2914 [UNIT_ON_FAILURE
] = "OnFailure",
2915 [UNIT_TRIGGERS
] = "Triggers",
2916 [UNIT_TRIGGERED_BY
] = "TriggeredBy",
2917 [UNIT_PROPAGATES_RELOAD_TO
] = "PropagatesReloadTo",
2918 [UNIT_RELOAD_PROPAGATED_FROM
] = "ReloadPropagatedFrom",
2919 [UNIT_REFERENCES
] = "References",
2920 [UNIT_REFERENCED_BY
] = "ReferencedBy",
2923 DEFINE_STRING_TABLE_LOOKUP(unit_dependency
, UnitDependency
);