]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/target.c
relicense to LGPLv2.1 (with exceptions)
[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
d46de8a1 22#include <errno.h>
23a177ef 23#include <signal.h>
b2bb3dbe 24#include <unistd.h>
d46de8a1 25
87f0e418 26#include "unit.h"
c22cbe26
LP
27#include "target.h"
28#include "load-fragment.h"
fa068367 29#include "log.h"
4139c1b2 30#include "dbus-target.h"
514f4ef5 31#include "special.h"
b2bb3dbe 32#include "unit-name.h"
c22cbe26 33
fa068367
LP
34static const UnitActiveState state_translation_table[_TARGET_STATE_MAX] = {
35 [TARGET_DEAD] = UNIT_INACTIVE,
36 [TARGET_ACTIVE] = UNIT_ACTIVE
37};
38
fa068367
LP
39static void target_set_state(Target *t, TargetState state) {
40 TargetState old_state;
41 assert(t);
42
43 old_state = t->state;
44 t->state = state;
45
e537352b 46 if (state != old_state)
40d50879 47 log_debug("%s changed %s -> %s",
1124fe6f 48 UNIT(t)->id,
a16e1123
LP
49 target_state_to_string(old_state),
50 target_state_to_string(state));
c22cbe26 51
e2f3b44c 52 unit_notify(UNIT(t), state_translation_table[old_state], state_translation_table[state], true);
fa068367
LP
53}
54
a40eb732 55static int target_add_default_dependencies(Target *t) {
21256a2b
LP
56 static const UnitDependency deps[] = {
57 UNIT_REQUIRES,
58 UNIT_REQUIRES_OVERRIDABLE,
59 UNIT_REQUISITE,
60 UNIT_REQUISITE_OVERRIDABLE,
61 UNIT_WANTS,
62 UNIT_BIND_TO
63 };
64
bba34eed
LP
65 Iterator i;
66 Unit *other;
67 int r;
21256a2b 68 unsigned k;
bba34eed 69
98bc2000 70 assert(t);
a40eb732 71
bba34eed
LP
72 /* Imply ordering for requirement dependencies on target
73 * units. Note that when the user created a contradicting
74 * ordering manually we won't add anything in here to make
75 * sure we don't create a loop. */
76
21256a2b 77 for (k = 0; k < ELEMENTSOF(deps); k++)
1124fe6f 78 SET_FOREACH(other, UNIT(t)->dependencies[deps[k]], i)
21256a2b
LP
79 if ((r = unit_add_default_target_dependency(other, UNIT(t))) < 0)
80 return r;
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
92 if ((r = unit_load_fragment_and_dropin(u)) < 0)
93 return r;
94
95 /* This is a new unit? Then let's add in some extras */
ac155bb8
MS
96 if (u->load_state == UNIT_LOADED) {
97 if (u->default_dependencies)
a40eb732
LP
98 if ((r = target_add_default_dependencies(t)) < 0)
99 return r;
100 }
101
102 return 0;
103}
104
a16e1123
LP
105static int target_coldplug(Unit *u) {
106 Target *t = TARGET(u);
107
108 assert(t);
109 assert(t->state == TARGET_DEAD);
110
111 if (t->deserialized_state != t->state)
112 target_set_state(t, t->deserialized_state);
113
114 return 0;
115}
116
117static void target_dump(Unit *u, FILE *f, const char *prefix) {
118 Target *t = TARGET(u);
119
120 assert(t);
121 assert(f);
122
123 fprintf(f,
124 "%sTarget State: %s\n",
125 prefix, target_state_to_string(t->state));
126}
127
fa068367
LP
128static int target_start(Unit *u) {
129 Target *t = TARGET(u);
130
131 assert(t);
132 assert(t->state == TARGET_DEAD);
133
134 target_set_state(t, TARGET_ACTIVE);
135 return 0;
136}
c22cbe26 137
fa068367
LP
138static int target_stop(Unit *u) {
139 Target *t = TARGET(u);
140
141 assert(t);
142 assert(t->state == TARGET_ACTIVE);
143
144 target_set_state(t, TARGET_DEAD);
145 return 0;
c22cbe26
LP
146}
147
a16e1123
LP
148static int target_serialize(Unit *u, FILE *f, FDSet *fds) {
149 Target *s = TARGET(u);
150
151 assert(s);
152 assert(f);
153 assert(fds);
154
155 unit_serialize_item(u, f, "state", target_state_to_string(s->state));
156 return 0;
157}
158
159static int target_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
160 Target *s = TARGET(u);
161
162 assert(u);
163 assert(key);
164 assert(value);
165 assert(fds);
166
167 if (streq(key, "state")) {
168 TargetState state;
169
170 if ((state = target_state_from_string(value)) < 0)
171 log_debug("Failed to parse state value %s", value);
172 else
173 s->deserialized_state = state;
174
175 } else
176 log_debug("Unknown serialization key '%s'", key);
177
178 return 0;
179}
180
87f0e418 181static UnitActiveState target_active_state(Unit *u) {
fa068367
LP
182 assert(u);
183
184 return state_translation_table[TARGET(u)->state];
c22cbe26
LP
185}
186
10a94420
LP
187static const char *target_sub_state_to_string(Unit *u) {
188 assert(u);
189
a16e1123 190 return target_state_to_string(TARGET(u)->state);
10a94420
LP
191}
192
a16e1123
LP
193static const char* const target_state_table[_TARGET_STATE_MAX] = {
194 [TARGET_DEAD] = "dead",
195 [TARGET_ACTIVE] = "active"
196};
197
198DEFINE_STRING_TABLE_LOOKUP(target_state, TargetState);
199
87f0e418 200const UnitVTable target_vtable = {
c22cbe26 201 .suffix = ".target",
7d17cfbc 202 .object_size = sizeof(Target),
f975e971
LP
203 .sections =
204 "Unit\0"
205 "Target\0"
206 "Install\0",
c22cbe26 207
a40eb732 208 .load = target_load,
a16e1123 209 .coldplug = target_coldplug,
fa068367
LP
210
211 .dump = target_dump,
212
213 .start = target_start,
214 .stop = target_stop,
c22cbe26 215
a16e1123
LP
216 .serialize = target_serialize,
217 .deserialize_item = target_deserialize_item,
218
10a94420 219 .active_state = target_active_state,
4139c1b2
LP
220 .sub_state_to_string = target_sub_state_to_string,
221
c4e2ceae 222 .bus_interface = "org.freedesktop.systemd1.Target",
4139c1b2 223 .bus_message_handler = bus_target_message_handler
c22cbe26 224};