]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-service.c
When warning about unsupported options, be more detailed
[thirdparty/systemd.git] / src / core / dbus-service.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4139c1b2
LP
2
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
4139c1b2
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.
4139c1b2 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
4139c1b2
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
c2756a68
LP
22#include "strv.h"
23#include "path-util.h"
718db961
LP
24#include "unit.h"
25#include "service.h"
4139c1b2
LP
26#include "dbus-unit.h"
27#include "dbus-execute.h"
4819ff03 28#include "dbus-kill.h"
4ad49000 29#include "dbus-cgroup.h"
4ad49000 30#include "dbus-service.h"
718db961
LP
31#include "bus-util.h"
32
33static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, service_type, ServiceType);
34static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, service_result, ServiceResult);
35static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart, service_restart, ServiceRestart);
36static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_notify_access, notify_access, NotifyAccess);
bf500566 37static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_failure_action, failure_action, FailureAction);
718db961
LP
38
39const sd_bus_vtable bus_service_vtable[] = {
40 SD_BUS_VTABLE_START(0),
556089dc
LP
41 SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Service, type), SD_BUS_VTABLE_PROPERTY_CONST),
42 SD_BUS_PROPERTY("Restart", "s", property_get_restart, offsetof(Service, restart), SD_BUS_VTABLE_PROPERTY_CONST),
43 SD_BUS_PROPERTY("PIDFile", "s", NULL, offsetof(Service, pid_file), SD_BUS_VTABLE_PROPERTY_CONST),
44 SD_BUS_PROPERTY("NotifyAccess", "s", property_get_notify_access, offsetof(Service, notify_access), SD_BUS_VTABLE_PROPERTY_CONST),
45 SD_BUS_PROPERTY("RestartUSec", "t", bus_property_get_usec, offsetof(Service, restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
46 SD_BUS_PROPERTY("TimeoutStartUSec", "t", bus_property_get_usec, offsetof(Service, timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
47 SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Service, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
48 SD_BUS_PROPERTY("WatchdogUSec", "t", bus_property_get_usec, offsetof(Service, watchdog_usec), SD_BUS_VTABLE_PROPERTY_CONST),
718db961 49 BUS_PROPERTY_DUAL_TIMESTAMP("WatchdogTimestamp", offsetof(Service, watchdog_timestamp), 0),
556089dc
LP
50 SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Service, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
51 SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Service, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
bf500566 52 SD_BUS_PROPERTY("StartLimitAction", "s", property_get_failure_action, offsetof(Service, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
efe6e7d3 53 SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Service, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
bf500566 54 SD_BUS_PROPERTY("FailureAction", "s", property_get_failure_action, offsetof(Service, failure_action), SD_BUS_VTABLE_PROPERTY_CONST),
556089dc
LP
55 SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool, offsetof(Service, permissions_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
56 SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool, offsetof(Service, root_directory_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
57 SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool, offsetof(Service, remain_after_exit), SD_BUS_VTABLE_PROPERTY_CONST),
58 SD_BUS_PROPERTY("GuessMainPID", "b", bus_property_get_bool, offsetof(Service, guess_main_pid), SD_BUS_VTABLE_PROPERTY_CONST),
718db961
LP
59 SD_BUS_PROPERTY("MainPID", "u", bus_property_get_pid, offsetof(Service, main_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
60 SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Service, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
556089dc 61 SD_BUS_PROPERTY("BusName", "s", NULL, offsetof(Service, bus_name), SD_BUS_VTABLE_PROPERTY_CONST),
718db961 62 SD_BUS_PROPERTY("StatusText", "s", NULL, offsetof(Service, status_text), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
4774e357 63 SD_BUS_PROPERTY("StatusErrno", "i", NULL, offsetof(Service, status_errno), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
718db961
LP
64 SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Service, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
65 BUS_EXEC_STATUS_VTABLE("ExecMain", offsetof(Service, main_exec_status), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
556089dc
LP
66 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
67 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStart", offsetof(Service, exec_command[SERVICE_EXEC_START]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
68 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Service, exec_command[SERVICE_EXEC_START_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
69 BUS_EXEC_COMMAND_LIST_VTABLE("ExecReload", offsetof(Service, exec_command[SERVICE_EXEC_RELOAD]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
70 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStop", offsetof(Service, exec_command[SERVICE_EXEC_STOP]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
71 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPost", offsetof(Service, exec_command[SERVICE_EXEC_STOP_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
718db961 72 SD_BUS_VTABLE_END
d200735e
MS
73};
74
9f2e86af 75static int bus_service_set_transient_property(
c2756a68
LP
76 Service *s,
77 const char *name,
718db961 78 sd_bus_message *message,
c2756a68 79 UnitSetPropertiesMode mode,
718db961 80 sd_bus_error *error) {
c2756a68
LP
81
82 int r;
83
c2756a68 84 assert(s);
718db961
LP
85 assert(name);
86 assert(message);
c2756a68 87
6577c7ce 88 if (streq(name, "RemainAfterExit")) {
718db961 89 int b;
6577c7ce 90
718db961
LP
91 r = sd_bus_message_read(message, "b", &b);
92 if (r < 0)
93 return r;
6577c7ce 94
718db961 95 if (mode != UNIT_CHECK) {
6577c7ce
LP
96 s->remain_after_exit = b;
97 unit_write_drop_in_private_format(UNIT(s), mode, name, "RemainAfterExit=%s\n", yes_no(b));
98 }
99
100 return 1;
101
c7040b5d
LP
102 } else if (streq(name, "Type")) {
103 const char *t;
104 ServiceType k;
105
106 r = sd_bus_message_read(message, "s", &t);
107 if (r < 0)
108 return r;
109
110 k = service_type_from_string(t);
111 if (k < 0)
112 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid service type %s", t);
113
114 if (mode != UNIT_CHECK) {
115 s->type = k;
116 unit_write_drop_in_private_format(UNIT(s), mode, name, "Type=%s\n", service_type_to_string(s->type));
117 }
118
119 return 1;
120
6577c7ce 121 } else if (streq(name, "ExecStart")) {
c2756a68
LP
122 unsigned n = 0;
123
718db961
LP
124 r = sd_bus_message_enter_container(message, 'a', "(sasb)");
125 if (r < 0)
126 return r;
c2756a68 127
718db961 128 while ((r = sd_bus_message_enter_container(message, 'r', "sasb")) > 0) {
c2756a68 129 _cleanup_strv_free_ char **argv = NULL;
c2756a68 130 const char *path;
718db961 131 int b;
c2756a68 132
718db961
LP
133 r = sd_bus_message_read(message, "s", &path);
134 if (r < 0)
135 return r;
c2756a68 136
718db961
LP
137 if (!path_is_absolute(path))
138 return sd_bus_error_set_errnof(error, EINVAL, "Path %s is not absolute.", path);
c2756a68 139
718db961 140 r = sd_bus_message_read_strv(message, &argv);
c2756a68
LP
141 if (r < 0)
142 return r;
143
718db961
LP
144 r = sd_bus_message_read(message, "b", &b);
145 if (r < 0)
146 return r;
c2756a68 147
718db961
LP
148 r = sd_bus_message_exit_container(message);
149 if (r < 0)
150 return r;
c2756a68
LP
151
152 if (mode != UNIT_CHECK) {
153 ExecCommand *c;
154
155 c = new0(ExecCommand, 1);
156 if (!c)
157 return -ENOMEM;
158
159 c->path = strdup(path);
160 if (!c->path) {
161 free(c);
162 return -ENOMEM;
163 }
164
165 c->argv = argv;
166 argv = NULL;
167
718db961 168 c->ignore = b;
c2756a68
LP
169
170 path_kill_slashes(c->path);
171 exec_command_append_list(&s->exec_command[SERVICE_EXEC_START], c);
172 }
173
174 n++;
c2756a68 175 }
c7040b5d 176
718db961
LP
177 if (r < 0)
178 return r;
c2756a68 179
6ce270b1
LP
180 r = sd_bus_message_exit_container(message);
181 if (r < 0)
182 return r;
183
c2756a68
LP
184 if (mode != UNIT_CHECK) {
185 _cleanup_free_ char *buf = NULL;
186 _cleanup_fclose_ FILE *f = NULL;
187 ExecCommand *c;
188 size_t size = 0;
189
190 if (n == 0) {
191 exec_command_free_list(s->exec_command[SERVICE_EXEC_START]);
192 s->exec_command[SERVICE_EXEC_START] = NULL;
193 }
194
195 f = open_memstream(&buf, &size);
196 if (!f)
197 return -ENOMEM;
198
199 fputs("ExecStart=\n", f);
200
201 LIST_FOREACH(command, c, s->exec_command[SERVICE_EXEC_START]) {
a6fde353 202 _cleanup_free_ char *a;
c2756a68 203
a6fde353
ZJS
204 a = strv_join_quoted(c->argv);
205 if (!a)
206 return -ENOMEM;
c2756a68 207
a6fde353
ZJS
208 fprintf(f, "ExecStart=%s@%s %s\n",
209 c->ignore ? "-" : "",
210 c->path,
211 a);
c2756a68
LP
212 }
213
214 fflush(f);
b9ec9359 215 unit_write_drop_in_private(UNIT(s), mode, name, buf);
c2756a68
LP
216 }
217
218 return 1;
219 }
220
221 return 0;
222}
223
74c964d3
LP
224int bus_service_set_property(
225 Unit *u,
226 const char *name,
718db961 227 sd_bus_message *message,
74c964d3 228 UnitSetPropertiesMode mode,
718db961 229 sd_bus_error *error) {
74c964d3
LP
230
231 Service *s = SERVICE(u);
232 int r;
233
718db961 234 assert(s);
74c964d3 235 assert(name);
718db961 236 assert(message);
74c964d3 237
718db961 238 r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
74c964d3
LP
239 if (r != 0)
240 return r;
241
c2756a68
LP
242 if (u->transient && u->load_state == UNIT_STUB) {
243 /* This is a transient unit, let's load a little more */
244
718db961 245 r = bus_service_set_transient_property(s, name, message, mode, error);
c2756a68
LP
246 if (r != 0)
247 return r;
a6c0353b 248
c7040b5d
LP
249 r = bus_exec_context_set_transient_property(u, &s->exec_context, name, message, mode, error);
250 if (r != 0)
251 return r;
252
718db961 253 r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
a6c0353b
LP
254 if (r != 0)
255 return r;
c2756a68
LP
256 }
257
74c964d3
LP
258 return 0;
259}
260
261int bus_service_commit_properties(Unit *u) {
262 assert(u);
263
bc432dc7 264 unit_update_cgroup_members_masks(u);
74c964d3 265 unit_realize_cgroup(u);
bc432dc7 266
74c964d3
LP
267 return 0;
268}