]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus-service.c
core: no need to list properties for PropertiesChanged messages anymore
[thirdparty/systemd.git] / src / core / dbus-service.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
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
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
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
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include "strv.h"
23 #include "path-util.h"
24 #include "unit.h"
25 #include "service.h"
26 #include "dbus-unit.h"
27 #include "dbus-execute.h"
28 #include "dbus-kill.h"
29 #include "dbus-cgroup.h"
30 #include "dbus-service.h"
31 #include "bus-util.h"
32
33 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, service_type, ServiceType);
34 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, service_result, ServiceResult);
35 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart, service_restart, ServiceRestart);
36 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_notify_access, notify_access, NotifyAccess);
37 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_start_limit_action, start_limit_action, StartLimitAction);
38
39 const sd_bus_vtable bus_service_vtable[] = {
40 SD_BUS_VTABLE_START(0),
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),
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), 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),
52 SD_BUS_PROPERTY("StartLimitAction", "s", property_get_start_limit_action, offsetof(Service, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
53 SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool, offsetof(Service, permissions_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
54 SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool, offsetof(Service, root_directory_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
55 SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool, offsetof(Service, remain_after_exit), SD_BUS_VTABLE_PROPERTY_CONST),
56 SD_BUS_PROPERTY("GuessMainPID", "b", bus_property_get_bool, offsetof(Service, guess_main_pid), SD_BUS_VTABLE_PROPERTY_CONST),
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), SD_BUS_VTABLE_PROPERTY_CONST),
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_LIST_VTABLE("ExecStartPre", offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
64 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStart", offsetof(Service, exec_command[SERVICE_EXEC_START]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
65 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Service, exec_command[SERVICE_EXEC_START_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
66 BUS_EXEC_COMMAND_LIST_VTABLE("ExecReload", offsetof(Service, exec_command[SERVICE_EXEC_RELOAD]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
67 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStop", offsetof(Service, exec_command[SERVICE_EXEC_STOP]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
68 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPost", offsetof(Service, exec_command[SERVICE_EXEC_STOP_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
69 SD_BUS_VTABLE_END
70 };
71
72 static int bus_service_set_transient_property(
73 Service *s,
74 const char *name,
75 sd_bus_message *message,
76 UnitSetPropertiesMode mode,
77 sd_bus_error *error) {
78
79 int r;
80
81 assert(s);
82 assert(name);
83 assert(message);
84
85 if (streq(name, "RemainAfterExit")) {
86 int b;
87
88 r = sd_bus_message_read(message, "b", &b);
89 if (r < 0)
90 return r;
91
92 if (mode != UNIT_CHECK) {
93 s->remain_after_exit = b;
94 unit_write_drop_in_private_format(UNIT(s), mode, name, "RemainAfterExit=%s\n", yes_no(b));
95 }
96
97 return 1;
98
99 } else if (streq(name, "ExecStart")) {
100 unsigned n = 0;
101
102 r = sd_bus_message_enter_container(message, 'a', "(sasb)");
103 if (r < 0)
104 return r;
105
106 while ((r = sd_bus_message_enter_container(message, 'r', "sasb")) > 0) {
107 _cleanup_strv_free_ char **argv = NULL;
108 const char *path;
109 int b;
110
111 r = sd_bus_message_read(message, "s", &path);
112 if (r < 0)
113 return r;
114
115 if (!path_is_absolute(path))
116 return sd_bus_error_set_errnof(error, EINVAL, "Path %s is not absolute.", path);
117
118 r = sd_bus_message_read_strv(message, &argv);
119 if (r < 0)
120 return r;
121
122 r = sd_bus_message_read(message, "b", &b);
123 if (r < 0)
124 return r;
125
126 r = sd_bus_message_exit_container(message);
127 if (r < 0)
128 return r;
129
130 if (mode != UNIT_CHECK) {
131 ExecCommand *c;
132
133 c = new0(ExecCommand, 1);
134 if (!c)
135 return -ENOMEM;
136
137 c->path = strdup(path);
138 if (!c->path) {
139 free(c);
140 return -ENOMEM;
141 }
142
143 c->argv = argv;
144 argv = NULL;
145
146 c->ignore = b;
147
148 path_kill_slashes(c->path);
149 exec_command_append_list(&s->exec_command[SERVICE_EXEC_START], c);
150 }
151
152 n++;
153 }
154 if (r < 0)
155 return r;
156
157 r = sd_bus_message_exit_container(message);
158 if (r < 0)
159 return r;
160
161 if (mode != UNIT_CHECK) {
162 _cleanup_free_ char *buf = NULL;
163 _cleanup_fclose_ FILE *f = NULL;
164 ExecCommand *c;
165 size_t size = 0;
166
167 if (n == 0) {
168 exec_command_free_list(s->exec_command[SERVICE_EXEC_START]);
169 s->exec_command[SERVICE_EXEC_START] = NULL;
170 }
171
172 f = open_memstream(&buf, &size);
173 if (!f)
174 return -ENOMEM;
175
176 fputs("ExecStart=\n", f);
177
178 LIST_FOREACH(command, c, s->exec_command[SERVICE_EXEC_START]) {
179 _cleanup_free_ char *a;
180
181 a = strv_join_quoted(c->argv);
182 if (!a)
183 return -ENOMEM;
184
185 fprintf(f, "ExecStart=%s@%s %s\n",
186 c->ignore ? "-" : "",
187 c->path,
188 a);
189 }
190
191 fflush(f);
192 unit_write_drop_in_private(UNIT(s), mode, name, buf);
193 }
194
195 return 1;
196 }
197
198 return 0;
199 }
200
201 int bus_service_set_property(
202 Unit *u,
203 const char *name,
204 sd_bus_message *message,
205 UnitSetPropertiesMode mode,
206 sd_bus_error *error) {
207
208 Service *s = SERVICE(u);
209 int r;
210
211 assert(s);
212 assert(name);
213 assert(message);
214
215 r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error);
216 if (r != 0)
217 return r;
218
219 if (u->transient && u->load_state == UNIT_STUB) {
220 /* This is a transient unit, let's load a little more */
221
222 r = bus_service_set_transient_property(s, name, message, mode, error);
223 if (r != 0)
224 return r;
225
226 r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error);
227 if (r != 0)
228 return r;
229 }
230
231 return 0;
232 }
233
234 int bus_service_commit_properties(Unit *u) {
235 assert(u);
236
237 unit_realize_cgroup(u);
238 return 0;
239 }