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