]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-bus/test-bus-chat.c
mount: mount all cgroup controllers in containers, too
[thirdparty/systemd.git] / src / libsystemd-bus / test-bus-chat.c
CommitLineData
89ffcd2a
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2013 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 <assert.h>
23#include <stdlib.h>
24#include <pthread.h>
e3017af9 25#include <unistd.h>
89ffcd2a
LP
26
27#include "log.h"
28#include "util.h"
29
30#include "sd-bus.h"
31#include "bus-message.h"
e3017af9 32#include "bus-error.h"
89ffcd2a
LP
33
34static int server_init(sd_bus **_bus) {
35 sd_bus *bus = NULL;
d728d708 36 sd_id128_t id;
89ffcd2a 37 int r;
20902f3e 38 const char *unique;
89ffcd2a
LP
39
40 assert(_bus);
41
42 r = sd_bus_open_user(&bus);
43 if (r < 0) {
44 log_error("Failed to connect to user bus: %s", strerror(-r));
45 goto fail;
46 }
47
d728d708
LP
48 r = sd_bus_get_peer(bus, &id);
49 if (r < 0) {
50 log_error("Failed to get peer ID: %s", strerror(-r));
51 goto fail;
52 }
53
20902f3e
LP
54 r = sd_bus_get_unique_name(bus, &unique);
55 if (r < 0) {
56 log_error("Failed to get unique name: %s", strerror(-r));
57 goto fail;
58 }
59
d728d708 60 log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id));
20902f3e 61 log_info("Unique ID: %s", unique);
d728d708 62 log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h'));
d728d708 63
89ffcd2a
LP
64 r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0);
65 if (r < 0) {
66 log_error("Failed to acquire name: %s", strerror(-r));
67 goto fail;
68 }
69
70 *_bus = bus;
71 return 0;
72
73fail:
74 if (bus)
75 sd_bus_unref(bus);
76
77 return r;
78}
79
e3017af9 80static int server(sd_bus *bus) {
89ffcd2a 81 int r;
e3017af9 82 bool client1_gone = false, client2_gone = false;
89ffcd2a 83
e3017af9 84 while (!client1_gone || !client2_gone) {
89ffcd2a 85 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2571ead1 86 pid_t pid = 0;
89ffcd2a
LP
87
88 r = sd_bus_process(bus, &m);
89 if (r < 0) {
90 log_error("Failed to process requests: %s", strerror(-r));
91 goto fail;
92 }
e3017af9 93
89ffcd2a
LP
94 if (r == 0) {
95 r = sd_bus_wait(bus, (uint64_t) -1);
96 if (r < 0) {
97 log_error("Failed to wait: %s", strerror(-r));
98 goto fail;
99 }
100
101 continue;
102 }
103
e3017af9
LP
104 if (!m)
105 continue;
106
2571ead1
LP
107 sd_bus_message_get_pid(m, &pid);
108 log_info("Got message! member=%s pid=%lu label=%s", strna(sd_bus_message_get_member(m)), (unsigned long) pid, strna(sd_bus_message_get_label(m)));
89ffcd2a
LP
109 /* bus_message_dump(m); */
110 /* sd_bus_message_rewind(m, true); */
111
112 if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) {
113 const char *hello;
114 _cleanup_free_ char *lowercase = NULL;
115
116 r = sd_bus_message_read(m, "s", &hello);
117 if (r < 0) {
118 log_error("Failed to get parameter: %s", strerror(-r));
119 goto fail;
120 }
121
122 r = sd_bus_message_new_method_return(bus, m, &reply);
123 if (r < 0) {
124 log_error("Failed to allocate return: %s", strerror(-r));
125 goto fail;
126 }
127
128 lowercase = strdup(hello);
129 if (!lowercase) {
130 r = log_oom();
131 goto fail;
132 }
133
134 ascii_strlower(lowercase);
135
136 r = sd_bus_message_append(reply, "s", lowercase);
137 if (r < 0) {
138 log_error("Failed to append message: %s", strerror(-r));
139 goto fail;
140 }
e3017af9
LP
141 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) {
142
143 r = sd_bus_message_new_method_return(bus, m, &reply);
144 if (r < 0) {
145 log_error("Failed to allocate return: %s", strerror(-r));
146 goto fail;
147 }
148
149 client1_gone = true;
150 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient2")) {
151
152 r = sd_bus_message_new_method_return(bus, m, &reply);
153 if (r < 0) {
154 log_error("Failed to allocate return: %s", strerror(-r));
155 goto fail;
156 }
157
158 client2_gone = true;
159 } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Slow")) {
160
161 r = sd_bus_message_new_method_return(bus, m, &reply);
162 if (r < 0) {
163 log_error("Failed to allocate return: %s", strerror(-r));
164 goto fail;
165 }
166
167 sleep(1);
168 } else if (sd_bus_message_is_method_call(m, NULL, NULL)) {
89ffcd2a
LP
169 const sd_bus_error e = SD_BUS_ERROR_INIT_CONST("org.freedesktop.DBus.Error.UnknownMethod", "Unknown method.");
170
171 r = sd_bus_message_new_method_error(bus, m, &e, &reply);
172 if (r < 0) {
173 log_error("Failed to allocate return: %s", strerror(-r));
174 goto fail;
175 }
176 }
177
178 if (reply) {
179 r = sd_bus_send(bus, reply, NULL);
180 if (r < 0) {
181 log_error("Failed to send reply: %s", strerror(-r));
182 goto fail;
183 }
e3017af9
LP
184
185 /* log_info("Sent"); */
186 /* bus_message_dump(reply); */
187 /* sd_bus_message_rewind(reply, true); */
89ffcd2a
LP
188 }
189 }
190
191 r = 0;
192
193fail:
e3017af9
LP
194 if (bus) {
195 sd_bus_flush(bus);
89ffcd2a 196 sd_bus_unref(bus);
e3017af9 197 }
89ffcd2a 198
e3017af9 199 return r;
89ffcd2a
LP
200}
201
e3017af9 202static void* client1(void*p) {
89ffcd2a
LP
203 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
204 sd_bus *bus = NULL;
205 sd_bus_error error = SD_BUS_ERROR_INIT;
206 const char *hello;
207 int r;
208
209 r = sd_bus_open_user(&bus);
210 if (r < 0) {
211 log_error("Failed to connect to user bus: %s", strerror(-r));
212 goto finish;
213 }
214
215 r = sd_bus_message_new_method_call(
216 bus,
217 "org.freedesktop.systemd.test",
218 "/",
219 "org.freedesktop.systemd.test",
220 "LowerCase",
221 &m);
222 if (r < 0) {
223 log_error("Failed to allocate method call: %s", strerror(-r));
224 goto finish;
225 }
226
227 r = sd_bus_message_append(m, "s", "HELLO");
228 if (r < 0) {
229 log_error("Failed to append string: %s", strerror(-r));
230 goto finish;
231 }
232
e3017af9 233 r = sd_bus_send_with_reply_and_block(bus, m, 0, &error, &reply);
89ffcd2a 234 if (r < 0) {
e3017af9 235 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
89ffcd2a
LP
236 goto finish;
237 }
238
239 r = sd_bus_message_read(reply, "s", &hello);
240 if (r < 0) {
241 log_error("Failed to get string: %s", strerror(-r));
242 goto finish;
243 }
244
245 assert(streq(hello, "hello"));
246
247 r = 0;
248
249finish:
250 if (bus) {
251 _cleanup_bus_message_unref_ sd_bus_message *q;
252
253 r = sd_bus_message_new_method_call(
254 bus,
255 "org.freedesktop.systemd.test",
256 "/",
257 "org.freedesktop.systemd.test",
e3017af9 258 "ExitClient1",
89ffcd2a
LP
259 &q);
260 if (r < 0) {
261 log_error("Failed to allocate method call: %s", strerror(-r));
262 goto finish;
263 }
264
265 sd_bus_send(bus, q, NULL);
266 sd_bus_flush(bus);
267 sd_bus_unref(bus);
268 }
269
270 sd_bus_error_free(&error);
e3017af9
LP
271 return INT_TO_PTR(r);
272}
273
274static int quit_callback(sd_bus *b, int ret, sd_bus_message *m, void *userdata) {
275 bool *x = userdata;
276
277 log_error("Quit callback: %s", strerror(ret));
278
279 *x = 1;
280 return 1;
281}
282
283static void* client2(void*p) {
284 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
285 sd_bus *bus = NULL;
286 sd_bus_error error = SD_BUS_ERROR_INIT;
e3017af9 287 bool quit = false;
b9bf7e2b
LP
288 const char *mid;
289 int r;
e3017af9
LP
290
291 r = sd_bus_open_user(&bus);
292 if (r < 0) {
293 log_error("Failed to connect to user bus: %s", strerror(-r));
294 goto finish;
295 }
296
b9bf7e2b
LP
297 r = sd_bus_message_new_method_call(
298 bus,
299 "org.freedesktop.systemd.test",
300 "/",
301 "org.freedesktop.DBus.Peer",
302 "GetMachineId",
303 &m);
304 if (r < 0) {
305 log_error("Failed to allocate method call: %s", strerror(-r));
306 goto finish;
307 }
308
309 r = sd_bus_send_with_reply_and_block(bus, m, 0, &error, &reply);
310 if (r < 0) {
311 log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
312 goto finish;
313 }
314
315 r = sd_bus_message_read(reply, "s", &mid);
316 if (r < 0) {
317 log_error("Failed to parse machine ID: %s", strerror(-r));
318 goto finish;
319 }
320
321 log_info("Machine ID is %s.", mid);
322
323 sd_bus_message_unref(m);
324 m = NULL;
325
e3017af9
LP
326 r = sd_bus_message_new_method_call(
327 bus,
328 "org.freedesktop.systemd.test",
329 "/",
330 "org.freedesktop.systemd.test",
331 "Slow",
332 &m);
333 if (r < 0) {
334 log_error("Failed to allocate method call: %s", strerror(-r));
335 goto finish;
336 }
337
b9bf7e2b
LP
338 sd_bus_message_unref(reply);
339 reply = NULL;
340
e3017af9
LP
341 r = sd_bus_send_with_reply_and_block(bus, m, 200 * USEC_PER_MSEC, &error, &reply);
342 if (r < 0)
343 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
344 else
345 log_info("Slow call succeed.");
346
347 sd_bus_message_unref(m);
348 m = NULL;
349
350 r = sd_bus_message_new_method_call(
351 bus,
352 "org.freedesktop.systemd.test",
353 "/",
354 "org.freedesktop.systemd.test",
355 "Slow",
356 &m);
357 if (r < 0) {
358 log_error("Failed to allocate method call: %s", strerror(-r));
359 goto finish;
360 }
361
362 r = sd_bus_send_with_reply(bus, m, quit_callback, &quit, 200 * USEC_PER_MSEC, NULL);
363 if (r < 0) {
364 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));
365 goto finish;
366 }
367
368 while (!quit) {
369 r = sd_bus_process(bus, NULL);
370 if (r < 0) {
371 log_error("Failed to process requests: %s", strerror(-r));
372 goto finish;
373 }
374 if (r == 0) {
375 r = sd_bus_wait(bus, (uint64_t) -1);
376 if (r < 0) {
377 log_error("Failed to wait: %s", strerror(-r));
378 goto finish;
379 }
380 }
381 }
382
383 r = 0;
384
385finish:
386 if (bus) {
387 _cleanup_bus_message_unref_ sd_bus_message *q;
388
389 r = sd_bus_message_new_method_call(
390 bus,
391 "org.freedesktop.systemd.test",
392 "/",
393 "org.freedesktop.systemd.test",
394 "ExitClient2",
395 &q);
396 if (r < 0) {
397 log_error("Failed to allocate method call: %s", strerror(-r));
398 goto finish;
399 }
400
401 sd_bus_send(bus, q, NULL);
402 sd_bus_flush(bus);
403 sd_bus_unref(bus);
404 }
405
406 sd_bus_error_free(&error);
407 return INT_TO_PTR(r);
89ffcd2a
LP
408}
409
410int main(int argc, char *argv[]) {
e3017af9 411 pthread_t c1, c2;
89ffcd2a
LP
412 sd_bus *bus;
413 void *p;
414 int q, r;
415
416 r = server_init(&bus);
417 if (r < 0)
418 return EXIT_FAILURE;
419
e3017af9
LP
420 log_info("Initialized...");
421
422 r = pthread_create(&c1, NULL, client1, bus);
423 if (r != 0)
89ffcd2a 424 return EXIT_FAILURE;
89ffcd2a 425
e3017af9
LP
426 r = pthread_create(&c2, NULL, client2, bus);
427 if (r != 0)
428 return EXIT_FAILURE;
89ffcd2a 429
e3017af9
LP
430 r = server(bus);
431
432 q = pthread_join(c1, &p);
433 if (q != 0)
434 return EXIT_FAILURE;
435 q = pthread_join(c2, &p);
89ffcd2a
LP
436 if (q != 0)
437 return EXIT_FAILURE;
438 if (r < 0)
439 return EXIT_FAILURE;
440
441 return EXIT_SUCCESS;
442}