]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/machine/machine-dbus.c
bus: let's simplify things by getting rid of unnecessary bus parameters
[thirdparty/systemd.git] / src / machine / machine-dbus.c
CommitLineData
9444b1f2
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2011 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 <errno.h>
23#include <string.h>
24
c3350683 25#include "bus-util.h"
927b1649 26#include "strv.h"
1ee306e1 27#include "machine.h"
9444b1f2 28
c3350683
LP
29static int property_get_id(
30 sd_bus *bus,
31 const char *path,
32 const char *interface,
33 const char *property,
34 sd_bus_message *reply,
35 sd_bus_error *error,
36 void *userdata) {
9444b1f2 37
c3350683
LP
38 Machine *m = userdata;
39 int r;
9444b1f2 40
c3350683
LP
41 assert(bus);
42 assert(reply);
43 assert(m);
44
45 r = sd_bus_message_append_array(reply, 'y', &m->id, 16);
46 if (r < 0)
47 return r;
9444b1f2 48
c3350683 49 return 1;
9444b1f2
LP
50}
51
c3350683
LP
52static int property_get_state(
53 sd_bus *bus,
54 const char *path,
55 const char *interface,
56 const char *property,
57 sd_bus_message *reply,
58 sd_bus_error *error,
59 void *userdata) {
60
61 Machine *m = userdata;
fb6becb4 62 const char *state;
c3350683 63 int r;
fb6becb4 64
c3350683
LP
65 assert(bus);
66 assert(reply);
fb6becb4
LP
67 assert(m);
68
69 state = machine_state_to_string(machine_get_state(m));
70
c3350683
LP
71 r = sd_bus_message_append_basic(reply, 's', state);
72 if (r < 0)
73 return r;
fb6becb4 74
c3350683 75 return 1;
fb6becb4
LP
76}
77
c3350683 78static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass);
9444b1f2 79
c3350683
LP
80static int method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata) {
81 Machine *m = userdata;
82 int r;
9444b1f2 83
c3350683
LP
84 assert(bus);
85 assert(message);
86 assert(m);
9444b1f2 87
c3350683
LP
88 r = machine_stop(m);
89 if (r < 0)
df2d202e 90 return sd_bus_reply_method_errno(message, r, NULL);
9444b1f2 91
df2d202e 92 return sd_bus_reply_method_return(message, NULL);
9444b1f2
LP
93}
94
c3350683
LP
95static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata) {
96 Machine *m = userdata;
97 const char *swho;
98 int32_t signo;
99 KillWho who;
9444b1f2
LP
100 int r;
101
c3350683 102 assert(bus);
9444b1f2 103 assert(message);
c3350683 104 assert(m);
9444b1f2 105
c3350683
LP
106 r = sd_bus_message_read(message, "si", &swho, &signo);
107 if (r < 0)
df2d202e 108 return sd_bus_reply_method_errno(message, r, NULL);
9444b1f2 109
c3350683
LP
110 if (isempty(swho))
111 who = KILL_ALL;
112 else {
113 who = kill_who_from_string(swho);
114 if (who < 0)
df2d202e 115 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
9444b1f2
LP
116 }
117
c3350683 118 if (signo <= 0 || signo >= _NSIG)
df2d202e 119 return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
9444b1f2 120
c3350683
LP
121 r = machine_kill(m, who, signo);
122 if (r < 0)
df2d202e 123 return sd_bus_reply_method_errno(message, r, NULL);
9444b1f2 124
df2d202e 125 return sd_bus_reply_method_return(message, NULL);
9444b1f2
LP
126}
127
c3350683
LP
128const sd_bus_vtable machine_vtable[] = {
129 SD_BUS_VTABLE_START(0),
130 SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Machine, name), 0),
131 SD_BUS_PROPERTY("Id", "ay", property_get_id, 0, 0),
132 SD_BUS_PROPERTY("Timestamp", "t", NULL, offsetof(Machine, timestamp.realtime), 0),
133 SD_BUS_PROPERTY("TimestampMonotonic", "t", NULL, offsetof(Machine, timestamp.monotonic), 0),
134 SD_BUS_PROPERTY("Service", "s", NULL, offsetof(Machine, service), 0),
135 SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Machine, scope), 0),
136 SD_BUS_PROPERTY("Leader", "u", NULL, offsetof(Machine, leader), 0),
137 SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Machine, class), 0),
138 SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
139 SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(Machine, root_directory), 0),
140 SD_BUS_METHOD("Terminate", NULL, NULL, method_terminate, 0),
141 SD_BUS_METHOD("Kill", "si", NULL, method_kill, 0),
142 SD_BUS_VTABLE_END
143};
9444b1f2 144
c3350683 145int machine_object_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
c3350683
LP
146 Manager *m = userdata;
147 Machine *machine;
927b1649 148 int r;
9444b1f2 149
c3350683
LP
150 assert(bus);
151 assert(path);
152 assert(interface);
153 assert(found);
154 assert(m);
9444b1f2 155
927b1649
LP
156 if (streq(path, "/org/freedesktop/machine1/machine/self")) {
157 sd_bus_message *message;
158 pid_t pid;
9444b1f2 159
927b1649
LP
160 message = sd_bus_get_current(bus);
161 if (!message)
162 return 0;
163
164 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
165 if (r < 0)
166 return 0;
9444b1f2 167
927b1649
LP
168 r = manager_get_machine_by_pid(m, pid, &machine);
169 if (r <= 0)
170 return 0;
171 } else {
172 _cleanup_free_ char *e = NULL;
173 const char *p;
174
175 p = startswith(path, "/org/freedesktop/machine1/machine/");
176 if (!p)
177 return 0;
178
28383ba1 179 e = sd_bus_label_unescape(p);
927b1649
LP
180 if (!e)
181 return -ENOMEM;
182
183 machine = hashmap_get(m->machines, e);
184 if (!machine)
185 return 0;
186 }
9444b1f2 187
c3350683
LP
188 *found = machine;
189 return 1;
9444b1f2
LP
190}
191
9444b1f2
LP
192char *machine_bus_path(Machine *m) {
193 _cleanup_free_ char *e = NULL;
194
195 assert(m);
196
28383ba1 197 e = sd_bus_label_escape(m->name);
9444b1f2
LP
198 if (!e)
199 return NULL;
200
1ee306e1 201 return strappend("/org/freedesktop/machine1/machine/", e);
9444b1f2
LP
202}
203
927b1649
LP
204int machine_node_enumerator(sd_bus *bus, const char *path, char ***nodes, void *userdata) {
205 _cleanup_strv_free_ char **l = NULL;
206 Machine *machine = NULL;
207 Manager *m = userdata;
208 Iterator i;
209 int r;
210
211 assert(bus);
212 assert(path);
213 assert(nodes);
214
215 HASHMAP_FOREACH(machine, m->machines, i) {
216 char *p;
217
218 p = machine_bus_path(machine);
219 if (!p)
220 return -ENOMEM;
221
222 r = strv_push(&l, p);
223 if (r < 0) {
224 free(p);
225 return r;
226 }
227 }
228
229 *nodes = l;
230 l = NULL;
231
232 return 1;
233}
234
9444b1f2 235int machine_send_signal(Machine *m, bool new_machine) {
9444b1f2
LP
236 _cleanup_free_ char *p = NULL;
237
238 assert(m);
239
9444b1f2
LP
240 p = machine_bus_path(m);
241 if (!p)
242 return -ENOMEM;
243
c3350683
LP
244 return sd_bus_emit_signal(
245 m->manager->bus,
246 "/org/freedesktop/machine1",
247 "org.freedesktop.machine1.Manager",
248 new_machine ? "MachineNew" : "MachineRemoved",
249 "so", m->name, p);
9444b1f2
LP
250}
251
c3350683
LP
252int machine_send_create_reply(Machine *m, sd_bus_error *error) {
253 _cleanup_bus_message_unref_ sd_bus_message *c = NULL;
9444b1f2
LP
254 _cleanup_free_ char *p = NULL;
255
256 assert(m);
257
fb6becb4
LP
258 if (!m->create_message)
259 return 0;
260
c3350683
LP
261 c = m->create_message;
262 m->create_message = NULL;
fb6becb4 263
a658cafa 264 if (error)
df2d202e 265 return sd_bus_reply_method_error(c, error);
a658cafa 266
76e66585
LP
267 /* Update the machine state file before we notify the client
268 * about the result. */
269 machine_save(m);
270
c3350683
LP
271 p = machine_bus_path(m);
272 if (!p)
273 return -ENOMEM;
fb6becb4 274
df2d202e 275 return sd_bus_reply_method_return(c, "o", p);
fb6becb4 276}