]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/target.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / core / target.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
c22cbe26 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
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
a7334b09
LP
11 (at your option) any later version.
12
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
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
4139c1b2 22#include "dbus-target.h"
07630cea 23#include "log.h"
514f4ef5 24#include "special.h"
07630cea 25#include "string-util.h"
b2bb3dbe 26#include "unit-name.h"
07630cea
LP
27#include "unit.h"
28#include "target.h"
c22cbe26 29
fa068367
LP
30static const UnitActiveState state_translation_table[_TARGET_STATE_MAX] = {
31 [TARGET_DEAD] = UNIT_INACTIVE,
32 [TARGET_ACTIVE] = UNIT_ACTIVE
33};
34
fa068367
LP
35static void target_set_state(Target *t, TargetState state) {
36 TargetState old_state;
37 assert(t);
38
39 old_state = t->state;
40 t->state = state;
41
e537352b 42 if (state != old_state)
40d50879 43 log_debug("%s changed %s -> %s",
1124fe6f 44 UNIT(t)->id,
a16e1123
LP
45 target_state_to_string(old_state),
46 target_state_to_string(state));
c22cbe26 47
e2f3b44c 48 unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true);
fa068367
LP
49}
50
a40eb732 51static int target_add_default_dependencies(Target *t) {
1850161f 52
21256a2b
LP
53 static const UnitDependency deps[] = {
54 UNIT_REQUIRES,
55 UNIT_REQUIRES_OVERRIDABLE,
56 UNIT_REQUISITE,
57 UNIT_REQUISITE_OVERRIDABLE,
58 UNIT_WANTS,
1850161f
LP
59 UNIT_BINDS_TO,
60 UNIT_PART_OF
21256a2b
LP
61 };
62
bba34eed
LP
63 Iterator i;
64 Unit *other;
65 int r;
21256a2b 66 unsigned k;
bba34eed 67
98bc2000 68 assert(t);
a40eb732 69
bba34eed
LP
70 /* Imply ordering for requirement dependencies on target
71 * units. Note that when the user created a contradicting
72 * ordering manually we won't add anything in here to make
73 * sure we don't create a loop. */
74
21256a2b 75 for (k = 0; k < ELEMENTSOF(deps); k++)
1850161f
LP
76 SET_FOREACH(other, UNIT(t)->dependencies[deps[k]], i) {
77 r = unit_add_default_target_dependency(other, UNIT(t));
78 if (r < 0)
21256a2b 79 return r;
1850161f 80 }
bba34eed 81
b401e1fb 82 /* Make sure targets are unloaded on shutdown */
ead8e478 83 return unit_add_dependency_by_name(UNIT(t), UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
a40eb732
LP
84}
85
86static int target_load(Unit *u) {
87 Target *t = TARGET(u);
88 int r;
89
90 assert(t);
91
1850161f
LP
92 r = unit_load_fragment_and_dropin(u);
93 if (r < 0)
a40eb732
LP
94 return r;
95
96 /* This is a new unit? Then let's add in some extras */
1850161f
LP
97 if (u->load_state == UNIT_LOADED && u->default_dependencies) {
98 r = target_add_default_dependencies(t);
99 if (r < 0)
100 return r;
a40eb732
LP
101 }
102
103 return 0;
104}
105
be847e82 106static int target_coldplug(Unit *u) {
a16e1123
LP
107 Target *t = TARGET(u);
108
109 assert(t);
110 assert(t->state == TARGET_DEAD);
111
112 if (t->deserialized_state != t->state)
113 target_set_state(t, t->deserialized_state);
114
115 return 0;
116}
117
118static void target_dump(Unit *u, FILE *f, const char *prefix) {
119 Target *t = TARGET(u);
120
121 assert(t);
122 assert(f);
123
124 fprintf(f,
125 "%sTarget State: %s\n",
126 prefix, target_state_to_string(t->state));
127}
128
fa068367
LP
129static int target_start(Unit *u) {
130 Target *t = TARGET(u);
131
132 assert(t);
133 assert(t->state == TARGET_DEAD);
134
135 target_set_state(t, TARGET_ACTIVE);
82a2b6bb 136 return 1;
fa068367 137}
c22cbe26 138
fa068367
LP
139static int target_stop(Unit *u) {
140 Target *t = TARGET(u);
141
142 assert(t);
143 assert(t->state == TARGET_ACTIVE);
144
145 target_set_state(t, TARGET_DEAD);
82a2b6bb 146 return 1;
c22cbe26
LP
147}
148
a16e1123
LP
149static int target_serialize(Unit *u, FILE *f, FDSet *fds) {
150 Target *s = TARGET(u);
151
152 assert(s);
153 assert(f);
154 assert(fds);
155
156 unit_serialize_item(u, f, "state", target_state_to_string(s->state));
157 return 0;
158}
159
160static int target_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
161 Target *s = TARGET(u);
162
163 assert(u);
164 assert(key);
165 assert(value);
166 assert(fds);
167
168 if (streq(key, "state")) {
169 TargetState state;
170
1850161f
LP
171 state = target_state_from_string(value);
172 if (state < 0)
a16e1123
LP
173 log_debug("Failed to parse state value %s", value);
174 else
175 s->deserialized_state = state;
176
177 } else
178 log_debug("Unknown serialization key '%s'", key);
179
180 return 0;
181}
182
44a6b1b6 183_pure_ static UnitActiveState target_active_state(Unit *u) {
fa068367
LP
184 assert(u);
185
186 return state_translation_table[TARGET(u)->state];
c22cbe26
LP
187}
188
44a6b1b6 189_pure_ static const char *target_sub_state_to_string(Unit *u) {
10a94420
LP
190 assert(u);
191
a16e1123 192 return target_state_to_string(TARGET(u)->state);
10a94420
LP
193}
194
87f0e418 195const UnitVTable target_vtable = {
7d17cfbc 196 .object_size = sizeof(Target),
718db961 197
f975e971
LP
198 .sections =
199 "Unit\0"
200 "Target\0"
201 "Install\0",
c22cbe26 202
a40eb732 203 .load = target_load,
a16e1123 204 .coldplug = target_coldplug,
fa068367
LP
205
206 .dump = target_dump,
207
208 .start = target_start,
209 .stop = target_stop,
c22cbe26 210
a16e1123
LP
211 .serialize = target_serialize,
212 .deserialize_item = target_deserialize_item,
213
10a94420 214 .active_state = target_active_state,
4139c1b2
LP
215 .sub_state_to_string = target_sub_state_to_string,
216
718db961 217 .bus_vtable = bus_target_vtable,
c6918296
MS
218
219 .status_message_formats = {
220 .finished_start_job = {
221 [JOB_DONE] = "Reached target %s.",
c6918296
MS
222 },
223 .finished_stop_job = {
224 [JOB_DONE] = "Stopped target %s.",
225 },
226 },
c22cbe26 227};