]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-service.c
core: convert PID 1 to libsystemd-bus
[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);
37static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_start_limit_action, start_limit_action, StartLimitAction);
38
39const sd_bus_vtable bus_service_vtable[] = {
40 SD_BUS_VTABLE_START(0),
41 SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Service, type), 0),
42 SD_BUS_PROPERTY("Restart", "s", property_get_restart, offsetof(Service, restart), 0),
43 SD_BUS_PROPERTY("PIDFile", "s", NULL, offsetof(Service, pid_file), 0),
44 SD_BUS_PROPERTY("NotifyAccess", "s", property_get_notify_access, offsetof(Service, notify_access), 0),
45 SD_BUS_PROPERTY("RestartUSec", "t", bus_property_get_usec, offsetof(Service, restart_usec), 0),
46 SD_BUS_PROPERTY("TimeoutStartUSec", "t", bus_property_get_usec, offsetof(Service, timeout_start_usec), 0),
47 SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Service, timeout_stop_usec), 0),
48 SD_BUS_PROPERTY("WatchdogUSec", "t", bus_property_get_usec, offsetof(Service, watchdog_usec), 0),
49 BUS_PROPERTY_DUAL_TIMESTAMP("WatchdogTimestamp", offsetof(Service, watchdog_timestamp), 0),
50 SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Service, start_limit.interval), 0),
51 SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Service, start_limit.burst), 0),
52 SD_BUS_PROPERTY("StartLimitAction", "s", property_get_start_limit_action, offsetof(Service, start_limit_action), 0),
53 SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool, offsetof(Service, permissions_start_only), 0),
54 SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool, offsetof(Service, root_directory_start_only), 0),
55 SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool, offsetof(Service, remain_after_exit), 0),
56 SD_BUS_PROPERTY("GuessMainPID", "b", bus_property_get_bool, offsetof(Service, guess_main_pid), 0),
57 SD_BUS_PROPERTY("MainPID", "u", bus_property_get_pid, offsetof(Service, main_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
58 SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Service, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
59 SD_BUS_PROPERTY("BusName", "s", NULL, offsetof(Service, bus_name), 0),
60 SD_BUS_PROPERTY("StatusText", "s", NULL, offsetof(Service, status_text), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
61 SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Service, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
62 BUS_EXEC_STATUS_VTABLE("ExecMain", offsetof(Service, main_exec_status), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
63 BUS_EXEC_COMMAND_VTABLE("ExecStartPre", offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]), 0),
64 BUS_EXEC_COMMAND_VTABLE("ExecStart", offsetof(Service, exec_command[SERVICE_EXEC_START]), 0),
65 BUS_EXEC_COMMAND_VTABLE("ExecStartPost", offsetof(Service, exec_command[SERVICE_EXEC_START_POST]), 0),
66 BUS_EXEC_COMMAND_VTABLE("ExecReload", offsetof(Service, exec_command[SERVICE_EXEC_RELOAD]), 0),
67 BUS_EXEC_COMMAND_VTABLE("ExecStop", offsetof(Service, exec_command[SERVICE_EXEC_STOP]), 0),
68 BUS_EXEC_COMMAND_VTABLE("ExecStopPost", offsetof(Service, exec_command[SERVICE_EXEC_STOP_POST]), 0),
69 SD_BUS_VTABLE_END
d200735e
MS
70};
71
718db961
LP
72const char* const bus_service_changing_properties[] = {
73 "ExecMainStartTimestamp",
74 "ExecMainStartTimestampMonotonic",
75 "ExecMainExitTimestamp",
76 "ExecMainExitTimestampMonotonic",
77 "ExecMainPID",
78 "ExecMainCode",
79 "ExecMainStatus",
80 "MainPID",
81 "ControlPID",
82 "StatusText",
83 "Result",
84 NULL
d200735e
MS
85};
86
9f2e86af 87static int bus_service_set_transient_property(
c2756a68
LP
88 Service *s,
89 const char *name,
718db961 90 sd_bus_message *message,
c2756a68 91 UnitSetPropertiesMode mode,
718db961 92 sd_bus_error *error) {
c2756a68
LP
93
94 int r;
95
c2756a68 96 assert(s);
718db961
LP
97 assert(name);
98 assert(message);
c2756a68 99
6577c7ce 100 if (streq(name, "RemainAfterExit")) {
718db961 101 int b;
6577c7ce 102
718db961
LP
103 r = sd_bus_message_read(message, "b", &b);
104 if (r < 0)
105 return r;
6577c7ce 106
718db961 107 if (mode != UNIT_CHECK) {
6577c7ce
LP
108 s->remain_after_exit = b;
109 unit_write_drop_in_private_format(UNIT(s), mode, name, "RemainAfterExit=%s\n", yes_no(b));
110 }
111
112 return 1;
113
114 } else if (streq(name, "ExecStart")) {
c2756a68
LP
115 unsigned n = 0;
116
718db961
LP
117 r = sd_bus_message_enter_container(message, 'a', "(sasb)");
118 if (r < 0)
119 return r;
c2756a68 120
718db961 121 while ((r = sd_bus_message_enter_container(message, 'r', "sasb")) > 0) {
c2756a68 122 _cleanup_strv_free_ char **argv = NULL;
c2756a68 123 const char *path;
718db961 124 int b;
c2756a68 125
718db961
LP
126 r = sd_bus_message_read(message, "s", &path);
127 if (r < 0)
128 return r;
c2756a68 129
718db961
LP
130 if (!path_is_absolute(path))
131 return sd_bus_error_set_errnof(error, EINVAL, "Path %s is not absolute.", path);
c2756a68 132
718db961 133 r = sd_bus_message_read_strv(message, &argv);
c2756a68
LP
134 if (r < 0)
135 return r;
136
718db961
LP
137 r = sd_bus_message_read(message, "b", &b);
138 if (r < 0)
139 return r;
c2756a68 140
718db961
LP
141 r = sd_bus_message_exit_container(message);
142 if (r < 0)
143 return r;
c2756a68
LP
144
145 if (mode != UNIT_CHECK) {
146 ExecCommand *c;
147
148 c = new0(ExecCommand, 1);
149 if (!c)
150 return -ENOMEM;
151
152 c->path = strdup(path);
153 if (!c->path) {
154 free(c);
155 return -ENOMEM;
156 }
157
158 c->argv = argv;
159 argv = NULL;
160
718db961 161 c->ignore = b;
c2756a68
LP
162
163 path_kill_slashes(c->path);
164 exec_command_append_list(&s->exec_command[SERVICE_EXEC_START], c);
165 }
166
167 n++;
c2756a68 168 }
718db961
LP
169 if (r < 0)
170 return r;
c2756a68
LP
171
172 if (mode != UNIT_CHECK) {
173 _cleanup_free_ char *buf = NULL;
174 _cleanup_fclose_ FILE *f = NULL;
175 ExecCommand *c;
176 size_t size = 0;
177
178 if (n == 0) {
179 exec_command_free_list(s->exec_command[SERVICE_EXEC_START]);
180 s->exec_command[SERVICE_EXEC_START] = NULL;
181 }
182
183 f = open_memstream(&buf, &size);
184 if (!f)
185 return -ENOMEM;
186
187 fputs("ExecStart=\n", f);
188
189 LIST_FOREACH(command, c, s->exec_command[SERVICE_EXEC_START]) {
a6fde353 190 _cleanup_free_ char *a;
c2756a68 191
a6fde353
ZJS
192 a = strv_join_quoted(c->argv);
193 if (!a)
194 return -ENOMEM;
c2756a68 195
a6fde353
ZJS
196 fprintf(f, "ExecStart=%s@%s %s\n",
197 c->ignore ? "-" : "",
198 c->path,
199 a);
c2756a68
LP
200 }
201
202 fflush(f);
b9ec9359 203 unit_write_drop_in_private(UNIT(s), mode, name, buf);
c2756a68
LP
204 }
205
206 return 1;
207 }
208
209 return 0;
210}
211
74c964d3
LP
212int bus_service_set_property(
213 Unit *u,
214 const char *name,
718db961 215 sd_bus_message *message,
74c964d3 216 UnitSetPropertiesMode mode,
718db961 217 sd_bus_error *error) {
74c964d3
LP
218
219 Service *s = SERVICE(u);
220 int r;
221
718db961 222 assert(s);
74c964d3 223 assert(name);
718db961 224 assert(message);
74c964d3 225
718db961 226 r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
74c964d3
LP
227 if (r != 0)
228 return r;
229
c2756a68
LP
230 if (u->transient && u->load_state == UNIT_STUB) {
231 /* This is a transient unit, let's load a little more */
232
718db961 233 r = bus_service_set_transient_property(s, name, message, mode, error);
c2756a68
LP
234 if (r != 0)
235 return r;
a6c0353b 236
718db961 237 r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
a6c0353b
LP
238 if (r != 0)
239 return r;
c2756a68
LP
240 }
241
74c964d3
LP
242 return 0;
243}
244
245int bus_service_commit_properties(Unit *u) {
246 assert(u);
247
248 unit_realize_cgroup(u);
249 return 0;
250}