chiark / gitweb /
bus: include connection name in credentials structure
[elogind.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 }