]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-service.c
bus: introduce concept of "const" properties
[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),
4d4c80d0
LP
63 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]), 0),
64 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStart", offsetof(Service, exec_command[SERVICE_EXEC_START]), 0),
65 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Service, exec_command[SERVICE_EXEC_START_POST]), 0),
66 BUS_EXEC_COMMAND_LIST_VTABLE("ExecReload", offsetof(Service, exec_command[SERVICE_EXEC_RELOAD]), 0),
67 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStop", offsetof(Service, exec_command[SERVICE_EXEC_STOP]), 0),
68 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPost", offsetof(Service, exec_command[SERVICE_EXEC_STOP_POST]), 0),
718db961 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 171
6ce270b1
LP
172 r = sd_bus_message_exit_container(message);
173 if (r < 0)
174 return r;
175
c2756a68
LP
176 if (mode != UNIT_CHECK) {
177 _cleanup_free_ char *buf = NULL;
178 _cleanup_fclose_ FILE *f = NULL;
179 ExecCommand *c;
180 size_t size = 0;
181
182 if (n == 0) {
183 exec_command_free_list(s->exec_command[SERVICE_EXEC_START]);
184 s->exec_command[SERVICE_EXEC_START] = NULL;
185 }
186
187 f = open_memstream(&buf, &size);
188 if (!f)
189 return -ENOMEM;
190
191 fputs("ExecStart=\n", f);
192
193 LIST_FOREACH(command, c, s->exec_command[SERVICE_EXEC_START]) {
a6fde353 194 _cleanup_free_ char *a;
c2756a68 195
a6fde353
ZJS
196 a = strv_join_quoted(c->argv);
197 if (!a)
198 return -ENOMEM;
c2756a68 199
a6fde353
ZJS
200 fprintf(f, "ExecStart=%s@%s %s\n",
201 c->ignore ? "-" : "",
202 c->path,
203 a);
c2756a68
LP
204 }
205
206 fflush(f);
b9ec9359 207 unit_write_drop_in_private(UNIT(s), mode, name, buf);
c2756a68
LP
208 }
209
210 return 1;
211 }
212
213 return 0;
214}
215
74c964d3
LP
216int bus_service_set_property(
217 Unit *u,
218 const char *name,
718db961 219 sd_bus_message *message,
74c964d3 220 UnitSetPropertiesMode mode,
718db961 221 sd_bus_error *error) {
74c964d3
LP
222
223 Service *s = SERVICE(u);
224 int r;
225
718db961 226 assert(s);
74c964d3 227 assert(name);
718db961 228 assert(message);
74c964d3 229
718db961 230 r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
74c964d3
LP
231 if (r != 0)
232 return r;
233
c2756a68
LP
234 if (u->transient && u->load_state == UNIT_STUB) {
235 /* This is a transient unit, let's load a little more */
236
718db961 237 r = bus_service_set_transient_property(s, name, message, mode, error);
c2756a68
LP
238 if (r != 0)
239 return r;
a6c0353b 240
718db961 241 r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
a6c0353b
LP
242 if (r != 0)
243 return r;
c2756a68
LP
244 }
245
74c964d3
LP
246 return 0;
247}
248
249int bus_service_commit_properties(Unit *u) {
250 assert(u);
251
252 unit_realize_cgroup(u);
253 return 0;
254}