chiark / gitweb /
core: send out "Reloading" signal before and after doing a full reload/reexec of...
[elogind.git] / src / core / dbus.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 <sys/epoll.h>
23 #include <sys/timerfd.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <dbus/dbus.h>
27
28 #include "dbus.h"
29 #include "log.h"
30 #include "strv.h"
31 #include "mkdir.h"
32 #include "missing.h"
33 #include "dbus-unit.h"
34 #include "dbus-job.h"
35 #include "dbus-manager.h"
36 #include "dbus-service.h"
37 #include "dbus-socket.h"
38 #include "dbus-target.h"
39 #include "dbus-device.h"
40 #include "dbus-mount.h"
41 #include "dbus-automount.h"
42 #include "dbus-snapshot.h"
43 #include "dbus-swap.h"
44 #include "dbus-timer.h"
45 #include "dbus-path.h"
46 #include "bus-errors.h"
47 #include "special.h"
48 #include "dbus-common.h"
49
50 #define CONNECTIONS_MAX 512
51
52 /* Well-known address (http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-types) */
53 #define DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=/var/run/dbus/system_bus_socket"
54 /* Only used as a fallback */
55 #define DBUS_SESSION_BUS_DEFAULT_ADDRESS "autolaunch:"
56
57 static const char bus_properties_interface[] = BUS_PROPERTIES_INTERFACE;
58 static const char bus_introspectable_interface[] = BUS_INTROSPECTABLE_INTERFACE;
59
60 const char *const bus_interface_table[] = {
61         "org.freedesktop.DBus.Properties",     bus_properties_interface,
62         "org.freedesktop.DBus.Introspectable", bus_introspectable_interface,
63         "org.freedesktop.systemd1.Manager",    bus_manager_interface,
64         "org.freedesktop.systemd1.Job",        bus_job_interface,
65         "org.freedesktop.systemd1.Unit",       bus_unit_interface,
66         "org.freedesktop.systemd1.Service",    bus_service_interface,
67         "org.freedesktop.systemd1.Socket",     bus_socket_interface,
68         "org.freedesktop.systemd1.Target",     bus_target_interface,
69         "org.freedesktop.systemd1.Device",     bus_device_interface,
70         "org.freedesktop.systemd1.Mount",      bus_mount_interface,
71         "org.freedesktop.systemd1.Automount",  bus_automount_interface,
72         "org.freedesktop.systemd1.Snapshot",   bus_snapshot_interface,
73         "org.freedesktop.systemd1.Swap",       bus_swap_interface,
74         "org.freedesktop.systemd1.Timer",      bus_timer_interface,
75         "org.freedesktop.systemd1.Path",       bus_path_interface,
76         NULL
77 };
78
79 static void bus_done_api(Manager *m);
80 static void bus_done_system(Manager *m);
81 static void bus_done_private(Manager *m);
82 static void shutdown_connection(Manager *m, DBusConnection *c);
83
84 static void bus_dispatch_status(DBusConnection *bus, DBusDispatchStatus status, void *data)  {
85         Manager *m = data;
86
87         assert(bus);
88         assert(m);
89
90         /* We maintain two sets, one for those connections where we
91          * requested a dispatch, and another where we didn't. And then,
92          * we move the connections between the two sets. */
93
94         if (status == DBUS_DISPATCH_COMPLETE)
95                 set_move_one(m->bus_connections, m->bus_connections_for_dispatch, bus);
96         else
97                 set_move_one(m->bus_connections_for_dispatch, m->bus_connections, bus);
98 }
99
100 void bus_watch_event(Manager *m, Watch *w, int events) {
101         assert(m);
102         assert(w);
103
104         /* This is called by the event loop whenever there is
105          * something happening on D-Bus' file handles. */
106
107         if (!dbus_watch_get_enabled(w->data.bus_watch))
108                 return;
109
110         dbus_watch_handle(w->data.bus_watch, bus_events_to_flags(events));
111 }
112
113 static dbus_bool_t bus_add_watch(DBusWatch *bus_watch, void *data) {
114         Manager *m = data;
115         Watch *w;
116         struct epoll_event ev;
117
118         assert(bus_watch);
119         assert(m);
120
121         if (!(w = new0(Watch, 1)))
122                 return FALSE;
123
124         w->fd = dbus_watch_get_unix_fd(bus_watch);
125         w->type = WATCH_DBUS_WATCH;
126         w->data.bus_watch = bus_watch;
127
128         zero(ev);
129         ev.events = bus_flags_to_events(bus_watch);
130         ev.data.ptr = w;
131
132         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) {
133
134                 if (errno != EEXIST) {
135                         free(w);
136                         return FALSE;
137                 }
138
139                 /* Hmm, bloody D-Bus creates multiple watches on the
140                  * same fd. epoll() does not like that. As a dirty
141                  * hack we simply dup() the fd and hence get a second
142                  * one we can safely add to the epoll(). */
143
144                 if ((w->fd = dup(w->fd)) < 0) {
145                         free(w);
146                         return FALSE;
147                 }
148
149                 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) {
150                         close_nointr_nofail(w->fd);
151                         free(w);
152                         return FALSE;
153                 }
154
155                 w->fd_is_dupped = true;
156         }
157
158         dbus_watch_set_data(bus_watch, w, NULL);
159
160         return TRUE;
161 }
162
163 static void bus_remove_watch(DBusWatch *bus_watch, void *data) {
164         Manager *m = data;
165         Watch *w;
166
167         assert(bus_watch);
168         assert(m);
169
170         w = dbus_watch_get_data(bus_watch);
171         if (!w)
172                 return;
173
174         assert(w->type == WATCH_DBUS_WATCH);
175         assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
176
177         if (w->fd_is_dupped)
178                 close_nointr_nofail(w->fd);
179
180         free(w);
181 }
182
183 static void bus_toggle_watch(DBusWatch *bus_watch, void *data) {
184         Manager *m = data;
185         Watch *w;
186         struct epoll_event ev;
187
188         assert(bus_watch);
189         assert(m);
190
191         w = dbus_watch_get_data(bus_watch);
192         if (!w)
193                 return;
194
195         assert(w->type == WATCH_DBUS_WATCH);
196
197         zero(ev);
198         ev.events = bus_flags_to_events(bus_watch);
199         ev.data.ptr = w;
200
201         assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_MOD, w->fd, &ev) == 0);
202 }
203
204 static int bus_timeout_arm(Manager *m, Watch *w) {
205         struct itimerspec its = {};
206
207         assert(m);
208         assert(w);
209
210         if (dbus_timeout_get_enabled(w->data.bus_timeout)) {
211                 timespec_store(&its.it_value, dbus_timeout_get_interval(w->data.bus_timeout) * USEC_PER_MSEC);
212                 its.it_interval = its.it_value;
213         }
214
215         if (timerfd_settime(w->fd, 0, &its, NULL) < 0)
216                 return -errno;
217
218         return 0;
219 }
220
221 void bus_timeout_event(Manager *m, Watch *w, int events) {
222         assert(m);
223         assert(w);
224
225         /* This is called by the event loop whenever there is
226          * something happening on D-Bus' file handles. */
227
228         if (!(dbus_timeout_get_enabled(w->data.bus_timeout)))
229                 return;
230
231         dbus_timeout_handle(w->data.bus_timeout);
232 }
233
234 static dbus_bool_t bus_add_timeout(DBusTimeout *timeout, void *data) {
235         Manager *m = data;
236         Watch *w;
237         struct epoll_event ev;
238
239         assert(timeout);
240         assert(m);
241
242         if (!(w = new0(Watch, 1)))
243                 return FALSE;
244
245         if ((w->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0)
246                 goto fail;
247
248         w->type = WATCH_DBUS_TIMEOUT;
249         w->data.bus_timeout = timeout;
250
251         if (bus_timeout_arm(m, w) < 0)
252                 goto fail;
253
254         zero(ev);
255         ev.events = EPOLLIN;
256         ev.data.ptr = w;
257
258         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0)
259                 goto fail;
260
261         dbus_timeout_set_data(timeout, w, NULL);
262
263         return TRUE;
264
265 fail:
266         if (w->fd >= 0)
267                 close_nointr_nofail(w->fd);
268
269         free(w);
270         return FALSE;
271 }
272
273 static void bus_remove_timeout(DBusTimeout *timeout, void *data) {
274         Manager *m = data;
275         Watch *w;
276
277         assert(timeout);
278         assert(m);
279
280         w = dbus_timeout_get_data(timeout);
281         if (!w)
282                 return;
283
284         assert(w->type == WATCH_DBUS_TIMEOUT);
285
286         assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
287         close_nointr_nofail(w->fd);
288         free(w);
289 }
290
291 static void bus_toggle_timeout(DBusTimeout *timeout, void *data) {
292         Manager *m = data;
293         Watch *w;
294         int r;
295
296         assert(timeout);
297         assert(m);
298
299         w = dbus_timeout_get_data(timeout);
300         if (!w)
301                 return;
302
303         assert(w->type == WATCH_DBUS_TIMEOUT);
304
305         if ((r = bus_timeout_arm(m, w)) < 0)
306                 log_error("Failed to rearm timer: %s", strerror(-r));
307 }
308
309 static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) {
310         Manager *m = data;
311         DBusError error;
312         DBusMessage *reply = NULL;
313
314         assert(connection);
315         assert(message);
316         assert(m);
317
318         dbus_error_init(&error);
319
320         if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL ||
321             dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
322                 log_debug("Got D-Bus request: %s.%s() on %s",
323                           dbus_message_get_interface(message),
324                           dbus_message_get_member(message),
325                           dbus_message_get_path(message));
326
327         if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
328                 log_debug("API D-Bus connection terminated.");
329                 bus_done_api(m);
330
331         } else if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
332                 const char *name, *old_owner, *new_owner;
333
334                 if (!dbus_message_get_args(message, &error,
335                                            DBUS_TYPE_STRING, &name,
336                                            DBUS_TYPE_STRING, &old_owner,
337                                            DBUS_TYPE_STRING, &new_owner,
338                                            DBUS_TYPE_INVALID))
339                         log_error("Failed to parse NameOwnerChanged message: %s", bus_error_message(&error));
340                 else  {
341                         if (set_remove(BUS_CONNECTION_SUBSCRIBED(m, connection), (char*) name))
342                                 log_debug("Subscription client vanished: %s (left: %u)", name, set_size(BUS_CONNECTION_SUBSCRIBED(m, connection)));
343
344                         if (old_owner[0] == 0)
345                                 old_owner = NULL;
346
347                         if (new_owner[0] == 0)
348                                 new_owner = NULL;
349
350                         manager_dispatch_bus_name_owner_changed(m, name, old_owner, new_owner);
351                 }
352         } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Activator", "ActivationRequest")) {
353                 const char *name;
354
355                 if (!dbus_message_get_args(message, &error,
356                                            DBUS_TYPE_STRING, &name,
357                                            DBUS_TYPE_INVALID))
358                         log_error("Failed to parse ActivationRequest message: %s", bus_error_message(&error));
359                 else  {
360                         int r;
361                         Unit *u;
362
363                         log_debug("Got D-Bus activation request for %s", name);
364
365                         if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) ||
366                             manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET)) {
367                                 r = -EADDRNOTAVAIL;
368                                 dbus_set_error(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
369                         } else {
370                                 r = manager_load_unit(m, name, NULL, &error, &u);
371
372                                 if (r >= 0 && u->refuse_manual_start)
373                                         r = -EPERM;
374
375                                 if (r >= 0)
376                                         r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
377                         }
378
379                         if (r < 0) {
380                                 const char *id, *text;
381
382                                 log_debug("D-Bus activation failed for %s: %s", name, strerror(-r));
383
384                                 if (!(reply = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure")))
385                                         goto oom;
386
387                                 id = error.name ? error.name : bus_errno_to_dbus(r);
388                                 text = bus_error(&error, r);
389
390                                 if (!dbus_message_set_destination(reply, DBUS_SERVICE_DBUS) ||
391                                     !dbus_message_append_args(reply,
392                                                               DBUS_TYPE_STRING, &name,
393                                                               DBUS_TYPE_STRING, &id,
394                                                               DBUS_TYPE_STRING, &text,
395                                                               DBUS_TYPE_INVALID))
396                                         goto oom;
397                         }
398
399                         /* On success we don't do anything, the service will be spawned now */
400                 }
401         }
402
403         dbus_error_free(&error);
404
405         if (reply) {
406                 if (!bus_maybe_send_reply(connection, message, reply))
407                         goto oom;
408
409                 dbus_message_unref(reply);
410         }
411
412         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
413
414 oom:
415         if (reply)
416                 dbus_message_unref(reply);
417
418         dbus_error_free(&error);
419
420         return DBUS_HANDLER_RESULT_NEED_MEMORY;
421 }
422
423 static DBusHandlerResult system_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) {
424         Manager *m = data;
425         DBusError error;
426
427         assert(connection);
428         assert(message);
429         assert(m);
430
431         dbus_error_init(&error);
432
433         if (m->api_bus != m->system_bus &&
434             (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL ||
435              dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL))
436                 log_debug("Got D-Bus request on system bus: %s.%s() on %s",
437                           dbus_message_get_interface(message),
438                           dbus_message_get_member(message),
439                           dbus_message_get_path(message));
440
441         if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
442                 log_debug("System D-Bus connection terminated.");
443                 bus_done_system(m);
444
445         } else if (m->running_as != SYSTEMD_SYSTEM &&
446                    dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) {
447
448                 const char *cgroup;
449
450                 if (!dbus_message_get_args(message, &error,
451                                            DBUS_TYPE_STRING, &cgroup,
452                                            DBUS_TYPE_INVALID))
453                         log_error("Failed to parse Released message: %s", bus_error_message(&error));
454                 else
455                         manager_notify_cgroup_empty(m, cgroup);
456         }
457
458         dbus_error_free(&error);
459         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
460 }
461
462 static DBusHandlerResult private_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) {
463         Manager *m = data;
464         DBusError error;
465
466         assert(connection);
467         assert(message);
468         assert(m);
469
470         dbus_error_init(&error);
471
472         if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL ||
473             dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
474                 log_debug("Got D-Bus request: %s.%s() on %s",
475                           dbus_message_get_interface(message),
476                           dbus_message_get_member(message),
477                           dbus_message_get_path(message));
478
479         if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected"))
480                 shutdown_connection(m, connection);
481         else if (m->running_as == SYSTEMD_SYSTEM &&
482                  dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) {
483
484                 const char *cgroup;
485
486                 if (!dbus_message_get_args(message, &error,
487                                            DBUS_TYPE_STRING, &cgroup,
488                                            DBUS_TYPE_INVALID))
489                         log_error("Failed to parse Released message: %s", bus_error_message(&error));
490                 else
491                         manager_notify_cgroup_empty(m, cgroup);
492
493                 /* Forward the message to the system bus, so that user
494                  * instances are notified as well */
495
496                 if (m->system_bus)
497                         dbus_connection_send(m->system_bus, message, NULL);
498         }
499
500         dbus_error_free(&error);
501
502         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
503 }
504
505 unsigned bus_dispatch(Manager *m) {
506         DBusConnection *c;
507
508         assert(m);
509
510         if (m->queued_message) {
511                 /* If we cannot get rid of this message we won't
512                  * dispatch any D-Bus messages, so that we won't end
513                  * up wanting to queue another message. */
514
515                 if (m->queued_message_connection)
516                         if (!dbus_connection_send(m->queued_message_connection, m->queued_message, NULL))
517                                 return 0;
518
519                 dbus_message_unref(m->queued_message);
520                 m->queued_message = NULL;
521                 m->queued_message_connection = NULL;
522         }
523
524         if ((c = set_first(m->bus_connections_for_dispatch))) {
525                 if (dbus_connection_dispatch(c) == DBUS_DISPATCH_COMPLETE)
526                         set_move_one(m->bus_connections, m->bus_connections_for_dispatch, c);
527
528                 return 1;
529         }
530
531         return 0;
532 }
533
534 static void request_name_pending_cb(DBusPendingCall *pending, void *userdata) {
535         DBusMessage *reply;
536         DBusError error;
537
538         dbus_error_init(&error);
539
540         assert_se(reply = dbus_pending_call_steal_reply(pending));
541
542         switch (dbus_message_get_type(reply)) {
543
544         case DBUS_MESSAGE_TYPE_ERROR:
545
546                 assert_se(dbus_set_error_from_message(&error, reply));
547                 log_warning("RequestName() failed: %s", bus_error_message(&error));
548                 break;
549
550         case DBUS_MESSAGE_TYPE_METHOD_RETURN: {
551                 uint32_t r;
552
553                 if (!dbus_message_get_args(reply,
554                                            &error,
555                                            DBUS_TYPE_UINT32, &r,
556                                            DBUS_TYPE_INVALID)) {
557                         log_error("Failed to parse RequestName() reply: %s", bus_error_message(&error));
558                         break;
559                 }
560
561                 if (r == 1)
562                         log_debug("Successfully acquired name.");
563                 else
564                         log_error("Name already owned.");
565
566                 break;
567         }
568
569         default:
570                 assert_not_reached("Invalid reply message");
571         }
572
573         dbus_message_unref(reply);
574         dbus_error_free(&error);
575 }
576
577 static int request_name(Manager *m) {
578         const char *name = "org.freedesktop.systemd1";
579         /* Allow replacing of our name, to ease implementation of
580          * reexecution, where we keep the old connection open until
581          * after the new connection is set up and the name installed
582          * to allow clients to synchronously wait for reexecution to
583          * finish */
584         uint32_t flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT|DBUS_NAME_FLAG_REPLACE_EXISTING;
585         DBusMessage *message = NULL;
586         DBusPendingCall *pending = NULL;
587
588         if (!(message = dbus_message_new_method_call(
589                               DBUS_SERVICE_DBUS,
590                               DBUS_PATH_DBUS,
591                               DBUS_INTERFACE_DBUS,
592                               "RequestName")))
593                 goto oom;
594
595         if (!dbus_message_append_args(
596                             message,
597                             DBUS_TYPE_STRING, &name,
598                             DBUS_TYPE_UINT32, &flags,
599                             DBUS_TYPE_INVALID))
600                 goto oom;
601
602         if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1))
603                 goto oom;
604
605         if (!dbus_pending_call_set_notify(pending, request_name_pending_cb, m, NULL))
606                 goto oom;
607
608         dbus_message_unref(message);
609         dbus_pending_call_unref(pending);
610
611         /* We simple ask for the name and don't wait for it. Sooner or
612          * later we'll have it. */
613
614         return 0;
615
616 oom:
617         if (pending) {
618                 dbus_pending_call_cancel(pending);
619                 dbus_pending_call_unref(pending);
620         }
621
622         if (message)
623                 dbus_message_unref(message);
624
625         return -ENOMEM;
626 }
627
628 static void query_name_list_pending_cb(DBusPendingCall *pending, void *userdata) {
629         DBusMessage *reply;
630         DBusError error;
631         Manager *m = userdata;
632
633         assert(m);
634
635         dbus_error_init(&error);
636
637         assert_se(reply = dbus_pending_call_steal_reply(pending));
638
639         switch (dbus_message_get_type(reply)) {
640
641         case DBUS_MESSAGE_TYPE_ERROR:
642
643                 assert_se(dbus_set_error_from_message(&error, reply));
644                 log_warning("ListNames() failed: %s", bus_error_message(&error));
645                 break;
646
647         case DBUS_MESSAGE_TYPE_METHOD_RETURN: {
648                 int r;
649                 char **l;
650
651                 if ((r = bus_parse_strv(reply, &l)) < 0)
652                         log_warning("Failed to parse ListNames() reply: %s", strerror(-r));
653                 else {
654                         char **t;
655
656                         STRV_FOREACH(t, l)
657                                 /* This is a bit hacky, we say the
658                                  * owner of the name is the name
659                                  * itself, because we don't want the
660                                  * extra traffic to figure out the
661                                  * real owner. */
662                                 manager_dispatch_bus_name_owner_changed(m, *t, NULL, *t);
663
664                         strv_free(l);
665                 }
666
667                 break;
668         }
669
670         default:
671                 assert_not_reached("Invalid reply message");
672         }
673
674         dbus_message_unref(reply);
675         dbus_error_free(&error);
676 }
677
678 static int query_name_list(Manager *m) {
679         DBusMessage *message = NULL;
680         DBusPendingCall *pending = NULL;
681
682         /* Asks for the currently installed bus names */
683
684         if (!(message = dbus_message_new_method_call(
685                               DBUS_SERVICE_DBUS,
686                               DBUS_PATH_DBUS,
687                               DBUS_INTERFACE_DBUS,
688                               "ListNames")))
689                 goto oom;
690
691         if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1))
692                 goto oom;
693
694         if (!dbus_pending_call_set_notify(pending, query_name_list_pending_cb, m, NULL))
695                 goto oom;
696
697         dbus_message_unref(message);
698         dbus_pending_call_unref(pending);
699
700         /* We simple ask for the list and don't wait for it. Sooner or
701          * later we'll get it. */
702
703         return 0;
704
705 oom:
706         if (pending) {
707                 dbus_pending_call_cancel(pending);
708                 dbus_pending_call_unref(pending);
709         }
710
711         if (message)
712                 dbus_message_unref(message);
713
714         return -ENOMEM;
715 }
716
717 static int bus_setup_loop(Manager *m, DBusConnection *bus) {
718         assert(m);
719         assert(bus);
720
721         dbus_connection_set_exit_on_disconnect(bus, FALSE);
722
723         if (!dbus_connection_set_watch_functions(bus, bus_add_watch, bus_remove_watch, bus_toggle_watch, m, NULL) ||
724             !dbus_connection_set_timeout_functions(bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL))
725                 return log_oom();
726
727         if (set_put(m->bus_connections_for_dispatch, bus) < 0)
728                 return log_oom();
729
730         dbus_connection_set_dispatch_status_function(bus, bus_dispatch_status, m, NULL);
731         return 0;
732 }
733
734 static dbus_bool_t allow_only_same_user(DBusConnection *connection, unsigned long uid, void *data) {
735         return uid == 0 || uid == geteuid();
736 }
737
738 static void bus_new_connection(
739                 DBusServer *server,
740                 DBusConnection *new_connection,
741                 void *data) {
742
743         Manager *m = data;
744
745         assert(m);
746
747         if (set_size(m->bus_connections) >= CONNECTIONS_MAX) {
748                 log_error("Too many concurrent connections.");
749                 return;
750         }
751
752         dbus_connection_set_unix_user_function(new_connection, allow_only_same_user, NULL, NULL);
753
754         if (bus_setup_loop(m, new_connection) < 0)
755                 return;
756
757         if (!dbus_connection_register_object_path(new_connection, "/org/freedesktop/systemd1", &bus_manager_vtable, m) ||
758             !dbus_connection_register_fallback(new_connection, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) ||
759             !dbus_connection_register_fallback(new_connection, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) ||
760             !dbus_connection_add_filter(new_connection, private_bus_message_filter, m, NULL)) {
761                 log_oom();
762                 return;
763         }
764
765         log_debug("Accepted connection on private bus.");
766
767         dbus_connection_ref(new_connection);
768 }
769
770 static int init_registered_system_bus(Manager *m) {
771         char *id;
772
773         if (!dbus_connection_add_filter(m->system_bus, system_bus_message_filter, m, NULL))
774                 return log_oom();
775
776         if (m->running_as != SYSTEMD_SYSTEM) {
777                 DBusError error;
778
779                 dbus_error_init(&error);
780
781                 dbus_bus_add_match(m->system_bus,
782                                    "type='signal',"
783                                    "interface='org.freedesktop.systemd1.Agent',"
784                                    "member='Released',"
785                                    "path='/org/freedesktop/systemd1/agent'",
786                                    &error);
787
788                 if (dbus_error_is_set(&error)) {
789                         log_error("Failed to register match: %s", bus_error_message(&error));
790                         dbus_error_free(&error);
791                         return -1;
792                 }
793         }
794
795         log_debug("Successfully connected to system D-Bus bus %s as %s",
796                  strnull((id = dbus_connection_get_server_id(m->system_bus))),
797                  strnull(dbus_bus_get_unique_name(m->system_bus)));
798         dbus_free(id);
799
800         return 0;
801 }
802
803 static int init_registered_api_bus(Manager *m) {
804         int r;
805
806         if (!dbus_connection_register_object_path(m->api_bus, "/org/freedesktop/systemd1", &bus_manager_vtable, m) ||
807             !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) ||
808             !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) ||
809             !dbus_connection_add_filter(m->api_bus, api_bus_message_filter, m, NULL))
810                 return log_oom();
811
812         /* Get NameOwnerChange messages */
813         dbus_bus_add_match(m->api_bus,
814                            "type='signal',"
815                            "sender='"DBUS_SERVICE_DBUS"',"
816                            "interface='"DBUS_INTERFACE_DBUS"',"
817                            "member='NameOwnerChanged',"
818                            "path='"DBUS_PATH_DBUS"'",
819                            NULL);
820
821         /* Get activation requests */
822         dbus_bus_add_match(m->api_bus,
823                            "type='signal',"
824                            "sender='"DBUS_SERVICE_DBUS"',"
825                            "interface='org.freedesktop.systemd1.Activator',"
826                            "member='ActivationRequest',"
827                            "path='"DBUS_PATH_DBUS"'",
828                            NULL);
829
830         r = request_name(m);
831         if (r < 0)
832                 return r;
833
834         r = query_name_list(m);
835         if (r < 0)
836                 return r;
837
838         if (m->running_as == SYSTEMD_USER) {
839                 char *id;
840                 log_debug("Successfully connected to API D-Bus bus %s as %s",
841                          strnull((id = dbus_connection_get_server_id(m->api_bus))),
842                          strnull(dbus_bus_get_unique_name(m->api_bus)));
843                 dbus_free(id);
844         } else
845                 log_debug("Successfully initialized API on the system bus");
846
847         return 0;
848 }
849
850 static void bus_register_cb(DBusPendingCall *pending, void *userdata) {
851         Manager *m = userdata;
852         DBusConnection **conn;
853         DBusMessage *reply;
854         DBusError error;
855         const char *name;
856         int r = 0;
857
858         dbus_error_init(&error);
859
860         conn = dbus_pending_call_get_data(pending, m->conn_data_slot);
861         assert(conn == &m->system_bus || conn == &m->api_bus);
862
863         reply = dbus_pending_call_steal_reply(pending);
864
865         switch (dbus_message_get_type(reply)) {
866         case DBUS_MESSAGE_TYPE_ERROR:
867                 assert_se(dbus_set_error_from_message(&error, reply));
868                 log_warning("Failed to register to bus: %s", bus_error_message(&error));
869                 r = -1;
870                 break;
871         case DBUS_MESSAGE_TYPE_METHOD_RETURN:
872                 if (!dbus_message_get_args(reply, &error,
873                                            DBUS_TYPE_STRING, &name,
874                                            DBUS_TYPE_INVALID)) {
875                         log_error("Failed to parse Hello reply: %s", bus_error_message(&error));
876                         r = -1;
877                         break;
878                 }
879
880                 log_debug("Received name %s in reply to Hello", name);
881                 if (!dbus_bus_set_unique_name(*conn, name)) {
882                         log_error("Failed to set unique name");
883                         r = -1;
884                         break;
885                 }
886
887                 if (conn == &m->system_bus) {
888                         r = init_registered_system_bus(m);
889                         if (r == 0 && m->running_as == SYSTEMD_SYSTEM)
890                                 r = init_registered_api_bus(m);
891                 } else
892                         r = init_registered_api_bus(m);
893
894                 break;
895         default:
896                 assert_not_reached("Invalid reply message");
897         }
898
899         dbus_message_unref(reply);
900         dbus_error_free(&error);
901
902         if (r < 0) {
903                 if (conn == &m->system_bus) {
904                         log_debug("Failed setting up the system bus");
905                         bus_done_system(m);
906                 } else {
907                         log_debug("Failed setting up the API bus");
908                         bus_done_api(m);
909                 }
910         }
911 }
912
913 static int manager_bus_async_register(Manager *m, DBusConnection **conn) {
914         DBusMessage *message = NULL;
915         DBusPendingCall *pending = NULL;
916
917         message = dbus_message_new_method_call(DBUS_SERVICE_DBUS,
918                                                DBUS_PATH_DBUS,
919                                                DBUS_INTERFACE_DBUS,
920                                                "Hello");
921         if (!message)
922                 goto oom;
923
924         if (!dbus_connection_send_with_reply(*conn, message, &pending, -1))
925                 goto oom;
926
927         if (!dbus_pending_call_set_data(pending, m->conn_data_slot, conn, NULL))
928                 goto oom;
929
930         if (!dbus_pending_call_set_notify(pending, bus_register_cb, m, NULL))
931                 goto oom;
932
933         dbus_message_unref(message);
934         dbus_pending_call_unref(pending);
935
936         return 0;
937 oom:
938         if (pending) {
939                 dbus_pending_call_cancel(pending);
940                 dbus_pending_call_unref(pending);
941         }
942
943         if (message)
944                 dbus_message_unref(message);
945
946         return -ENOMEM;
947 }
948
949 static DBusConnection* manager_bus_connect_private(Manager *m, DBusBusType type) {
950         const char *address;
951         DBusConnection *connection;
952         DBusError error;
953
954         switch (type) {
955         case DBUS_BUS_SYSTEM:
956                 address = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
957                 if (!address || !address[0])
958                         address = DBUS_SYSTEM_BUS_DEFAULT_ADDRESS;
959                 break;
960         case DBUS_BUS_SESSION:
961                 address = secure_getenv("DBUS_SESSION_BUS_ADDRESS");
962                 if (!address || !address[0])
963                         address = DBUS_SESSION_BUS_DEFAULT_ADDRESS;
964                 break;
965         default:
966                 assert_not_reached("Invalid bus type");
967         }
968
969         dbus_error_init(&error);
970
971         connection = dbus_connection_open_private(address, &error);
972         if (!connection) {
973                 log_warning("Failed to open private bus connection: %s", bus_error_message(&error));
974                 goto fail;
975         }
976
977         return connection;
978
979 fail:
980         dbus_error_free(&error);
981         return NULL;
982 }
983
984 static int bus_init_system(Manager *m) {
985         int r;
986
987         if (m->system_bus)
988                 return 0;
989
990         m->system_bus = manager_bus_connect_private(m, DBUS_BUS_SYSTEM);
991         if (!m->system_bus) {
992                 log_debug("Failed to connect to system D-Bus, retrying later");
993                 r = 0;
994                 goto fail;
995         }
996
997         r = bus_setup_loop(m, m->system_bus);
998         if (r < 0)
999                 goto fail;
1000
1001         r = manager_bus_async_register(m, &m->system_bus);
1002         if (r < 0)
1003                 goto fail;
1004
1005         return 0;
1006 fail:
1007         bus_done_system(m);
1008
1009         return r;
1010 }
1011
1012 static int bus_init_api(Manager *m) {
1013         int r;
1014
1015         if (m->api_bus)
1016                 return 0;
1017
1018         if (m->running_as == SYSTEMD_SYSTEM) {
1019                 m->api_bus = m->system_bus;
1020                 /* In this mode there is no distinct connection to the API bus,
1021                  * the API is published on the system bus.
1022                  * bus_register_cb() is aware of that and will init the API
1023                  * when the system bus gets registered.
1024                  * No need to setup anything here. */
1025                 return 0;
1026         }
1027
1028         m->api_bus = manager_bus_connect_private(m, DBUS_BUS_SESSION);
1029         if (!m->api_bus) {
1030                 log_debug("Failed to connect to API D-Bus, retrying later");
1031                 r = 0;
1032                 goto fail;
1033         }
1034
1035         r = bus_setup_loop(m, m->api_bus);
1036         if (r < 0)
1037                 goto fail;
1038
1039         r = manager_bus_async_register(m, &m->api_bus);
1040         if (r < 0)
1041                 goto fail;
1042
1043         return 0;
1044 fail:
1045         bus_done_api(m);
1046
1047         return r;
1048 }
1049
1050 static int bus_init_private(Manager *m) {
1051         DBusError error;
1052         int r;
1053         static const char *const external_only[] = {
1054                 "EXTERNAL",
1055                 NULL
1056         };
1057
1058         assert(m);
1059
1060         dbus_error_init(&error);
1061
1062         if (m->private_bus)
1063                 return 0;
1064
1065         if (m->running_as == SYSTEMD_SYSTEM) {
1066
1067                 /* We want the private bus only when running as init */
1068                 if (getpid() != 1)
1069                         return 0;
1070
1071                 unlink("/run/systemd/private");
1072                 m->private_bus = dbus_server_listen("unix:path=/run/systemd/private", &error);
1073         } else {
1074                 const char *e;
1075                 char *p;
1076                 char *escaped;
1077
1078                 e = secure_getenv("XDG_RUNTIME_DIR");
1079                 if (!e)
1080                         return 0;
1081
1082                 if (asprintf(&p, "%s/systemd/private", e) < 0) {
1083                         r = log_oom();
1084                         goto fail;
1085                 }
1086
1087                 mkdir_parents_label(p, 0755);
1088                 unlink(p);
1089                 free(p);
1090
1091                 escaped = dbus_address_escape_value(e);
1092                 if (!escaped) {
1093                         r = log_oom();
1094                         goto fail;
1095                 }
1096                 if (asprintf(&p, "unix:path=%s/systemd/private", escaped) < 0) {
1097                         dbus_free(escaped);
1098                         r = log_oom();
1099                         goto fail;
1100                 }
1101                 dbus_free(escaped);
1102
1103                 m->private_bus = dbus_server_listen(p, &error);
1104                 free(p);
1105         }
1106
1107         if (!m->private_bus) {
1108                 log_error("Failed to create private D-Bus server: %s", bus_error_message(&error));
1109                 r = -EIO;
1110                 goto fail;
1111         }
1112
1113         if (!dbus_server_set_auth_mechanisms(m->private_bus, (const char**) external_only) ||
1114             !dbus_server_set_watch_functions(m->private_bus, bus_add_watch, bus_remove_watch, bus_toggle_watch, m, NULL) ||
1115             !dbus_server_set_timeout_functions(m->private_bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL)) {
1116                 r = log_oom();
1117                 goto fail;
1118         }
1119
1120         dbus_server_set_new_connection_function(m->private_bus, bus_new_connection, m, NULL);
1121
1122         log_debug("Successfully created private D-Bus server.");
1123
1124         return 0;
1125
1126 fail:
1127         bus_done_private(m);
1128         dbus_error_free(&error);
1129
1130         return r;
1131 }
1132
1133 int bus_init(Manager *m, bool try_bus_connect) {
1134         int r;
1135
1136         if (set_ensure_allocated(&m->bus_connections, trivial_hash_func, trivial_compare_func) < 0 ||
1137             set_ensure_allocated(&m->bus_connections_for_dispatch, trivial_hash_func, trivial_compare_func) < 0)
1138                 return log_oom();
1139
1140         if (m->name_data_slot < 0)
1141                 if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot))
1142                         return log_oom();
1143
1144         if (m->conn_data_slot < 0)
1145                 if (!dbus_pending_call_allocate_data_slot(&m->conn_data_slot))
1146                         return log_oom();
1147
1148         if (m->subscribed_data_slot < 0)
1149                 if (!dbus_connection_allocate_data_slot(&m->subscribed_data_slot))
1150                         return log_oom();
1151
1152         if (try_bus_connect) {
1153                 if ((r = bus_init_system(m)) < 0 ||
1154                     (r = bus_init_api(m)) < 0)
1155                         return r;
1156         }
1157
1158         r = bus_init_private(m);
1159         if (r < 0)
1160                 return r;
1161
1162         return 0;
1163 }
1164
1165 static void shutdown_connection(Manager *m, DBusConnection *c) {
1166         Job *j;
1167         Iterator i;
1168
1169         HASHMAP_FOREACH(j, m->jobs, i) {
1170                 JobBusClient *cl, *nextcl;
1171                 LIST_FOREACH_SAFE(client, cl, nextcl, j->bus_client_list) {
1172                         if (cl->bus == c) {
1173                                 LIST_REMOVE(JobBusClient, client, j->bus_client_list, cl);
1174                                 free(cl);
1175                         }
1176                 }
1177         }
1178
1179         set_remove(m->bus_connections, c);
1180         set_remove(m->bus_connections_for_dispatch, c);
1181         set_free_free(BUS_CONNECTION_SUBSCRIBED(m, c));
1182
1183         if (m->queued_message_connection == c) {
1184                 m->queued_message_connection = NULL;
1185
1186                 if (m->queued_message) {
1187                         dbus_message_unref(m->queued_message);
1188                         m->queued_message = NULL;
1189                 }
1190         }
1191
1192         dbus_connection_set_dispatch_status_function(c, NULL, NULL, NULL);
1193         /* system manager cannot afford to block on DBus */
1194         if (m->running_as != SYSTEMD_SYSTEM)
1195                 dbus_connection_flush(c);
1196         dbus_connection_close(c);
1197         dbus_connection_unref(c);
1198 }
1199
1200 static void bus_done_api(Manager *m) {
1201         if (!m->api_bus)
1202                 return;
1203
1204         if (m->running_as == SYSTEMD_USER)
1205                 shutdown_connection(m, m->api_bus);
1206
1207         m->api_bus = NULL;
1208
1209         if (m->queued_message) {
1210                 dbus_message_unref(m->queued_message);
1211                 m->queued_message = NULL;
1212         }
1213 }
1214
1215 static void bus_done_system(Manager *m) {
1216         if (!m->system_bus)
1217                 return;
1218
1219         if (m->running_as == SYSTEMD_SYSTEM)
1220                 bus_done_api(m);
1221
1222         shutdown_connection(m, m->system_bus);
1223         m->system_bus = NULL;
1224 }
1225
1226 static void bus_done_private(Manager *m) {
1227         if (!m->private_bus)
1228                 return;
1229
1230         dbus_server_disconnect(m->private_bus);
1231         dbus_server_unref(m->private_bus);
1232         m->private_bus = NULL;
1233 }
1234
1235 void bus_done(Manager *m) {
1236         DBusConnection *c;
1237
1238         bus_done_api(m);
1239         bus_done_system(m);
1240         bus_done_private(m);
1241
1242         while ((c = set_steal_first(m->bus_connections)))
1243                 shutdown_connection(m, c);
1244
1245         while ((c = set_steal_first(m->bus_connections_for_dispatch)))
1246                 shutdown_connection(m, c);
1247
1248         set_free(m->bus_connections);
1249         set_free(m->bus_connections_for_dispatch);
1250
1251         if (m->name_data_slot >= 0)
1252                 dbus_pending_call_free_data_slot(&m->name_data_slot);
1253
1254         if (m->conn_data_slot >= 0)
1255                 dbus_pending_call_free_data_slot(&m->conn_data_slot);
1256
1257         if (m->subscribed_data_slot >= 0)
1258                 dbus_connection_free_data_slot(&m->subscribed_data_slot);
1259 }
1260
1261 static void query_pid_pending_cb(DBusPendingCall *pending, void *userdata) {
1262         Manager *m = userdata;
1263         DBusMessage *reply;
1264         DBusError error;
1265         const char *name;
1266
1267         dbus_error_init(&error);
1268
1269         assert_se(name = BUS_PENDING_CALL_NAME(m, pending));
1270         assert_se(reply = dbus_pending_call_steal_reply(pending));
1271
1272         switch (dbus_message_get_type(reply)) {
1273
1274         case DBUS_MESSAGE_TYPE_ERROR:
1275
1276                 assert_se(dbus_set_error_from_message(&error, reply));
1277                 log_warning("GetConnectionUnixProcessID() failed: %s", bus_error_message(&error));
1278                 break;
1279
1280         case DBUS_MESSAGE_TYPE_METHOD_RETURN: {
1281                 uint32_t r;
1282
1283                 if (!dbus_message_get_args(reply,
1284                                            &error,
1285                                            DBUS_TYPE_UINT32, &r,
1286                                            DBUS_TYPE_INVALID)) {
1287                         log_error("Failed to parse GetConnectionUnixProcessID() reply: %s", bus_error_message(&error));
1288                         break;
1289                 }
1290
1291                 manager_dispatch_bus_query_pid_done(m, name, (pid_t) r);
1292                 break;
1293         }
1294
1295         default:
1296                 assert_not_reached("Invalid reply message");
1297         }
1298
1299         dbus_message_unref(reply);
1300         dbus_error_free(&error);
1301 }
1302
1303 int bus_query_pid(Manager *m, const char *name) {
1304         DBusMessage *message = NULL;
1305         DBusPendingCall *pending = NULL;
1306         char *n = NULL;
1307
1308         assert(m);
1309         assert(name);
1310
1311         if (!(message = dbus_message_new_method_call(
1312                               DBUS_SERVICE_DBUS,
1313                               DBUS_PATH_DBUS,
1314                               DBUS_INTERFACE_DBUS,
1315                               "GetConnectionUnixProcessID")))
1316                 goto oom;
1317
1318         if (!(dbus_message_append_args(
1319                               message,
1320                               DBUS_TYPE_STRING, &name,
1321                               DBUS_TYPE_INVALID)))
1322                 goto oom;
1323
1324         if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1))
1325                 goto oom;
1326
1327         if (!(n = strdup(name)))
1328                 goto oom;
1329
1330         if (!dbus_pending_call_set_data(pending, m->name_data_slot, n, free))
1331                 goto oom;
1332
1333         n = NULL;
1334
1335         if (!dbus_pending_call_set_notify(pending, query_pid_pending_cb, m, NULL))
1336                 goto oom;
1337
1338         dbus_message_unref(message);
1339         dbus_pending_call_unref(pending);
1340
1341         return 0;
1342
1343 oom:
1344         free(n);
1345
1346         if (pending) {
1347                 dbus_pending_call_cancel(pending);
1348                 dbus_pending_call_unref(pending);
1349         }
1350
1351         if (message)
1352                 dbus_message_unref(message);
1353
1354         return -ENOMEM;
1355 }
1356
1357 int bus_broadcast(Manager *m, DBusMessage *message) {
1358         bool oom = false;
1359         Iterator i;
1360         DBusConnection *c;
1361
1362         assert(m);
1363         assert(message);
1364
1365         SET_FOREACH(c, m->bus_connections_for_dispatch, i)
1366                 if (c != m->system_bus || m->running_as == SYSTEMD_SYSTEM)
1367                         oom = !dbus_connection_send(c, message, NULL);
1368
1369         SET_FOREACH(c, m->bus_connections, i)
1370                 if (c != m->system_bus || m->running_as == SYSTEMD_SYSTEM)
1371                         oom = !dbus_connection_send(c, message, NULL);
1372
1373         return oom ? -ENOMEM : 0;
1374 }
1375
1376 bool bus_has_subscriber(Manager *m) {
1377         Iterator i;
1378         DBusConnection *c;
1379
1380         assert(m);
1381
1382         /* If we are reloading then we might not have deserialized the
1383            subscribers yet, hence let's assume that there are some */
1384
1385         if (m->n_reloading > 0)
1386                 return true;
1387
1388         SET_FOREACH(c, m->bus_connections_for_dispatch, i)
1389                 if (bus_connection_has_subscriber(m, c))
1390                         return true;
1391
1392         SET_FOREACH(c, m->bus_connections, i)
1393                 if (bus_connection_has_subscriber(m, c))
1394                         return true;
1395
1396         return false;
1397 }
1398
1399 bool bus_connection_has_subscriber(Manager *m, DBusConnection *c) {
1400         assert(m);
1401         assert(c);
1402
1403         return !set_isempty(BUS_CONNECTION_SUBSCRIBED(m, c));
1404 }
1405
1406 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1407         Iterator i;
1408         DBusConnection *c;
1409
1410         assert(m);
1411         assert(fds);
1412
1413         /* When we are about to reexecute we add all D-Bus fds to the
1414          * set to pass over to the newly executed systemd. They won't
1415          * be used there however, except that they are closed at the
1416          * very end of deserialization, those making it possible for
1417          * clients to synchronously wait for systemd to reexec by
1418          * simply waiting for disconnection */
1419
1420         SET_FOREACH(c, m->bus_connections_for_dispatch, i) {
1421                 int fd;
1422
1423                 if (dbus_connection_get_unix_fd(c, &fd)) {
1424                         fd = fdset_put_dup(fds, fd);
1425
1426                         if (fd < 0)
1427                                 return fd;
1428                 }
1429         }
1430
1431         SET_FOREACH(c, m->bus_connections, i) {
1432                 int fd;
1433
1434                 if (dbus_connection_get_unix_fd(c, &fd)) {
1435                         fd = fdset_put_dup(fds, fd);
1436
1437                         if (fd < 0)
1438                                 return fd;
1439                 }
1440         }
1441
1442         return 0;
1443 }
1444
1445 void bus_broadcast_finished(
1446                 Manager *m,
1447                 usec_t firmware_usec,
1448                 usec_t loader_usec,
1449                 usec_t kernel_usec,
1450                 usec_t initrd_usec,
1451                 usec_t userspace_usec,
1452                 usec_t total_usec) {
1453
1454         _cleanup_dbus_message_unref_ DBusMessage *message = NULL;
1455
1456         assert(m);
1457
1458         message = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
1459         if (!message) {
1460                 log_oom();
1461                 return;
1462         }
1463
1464         assert_cc(sizeof(usec_t) == sizeof(uint64_t));
1465         if (!dbus_message_append_args(message,
1466                                       DBUS_TYPE_UINT64, &firmware_usec,
1467                                       DBUS_TYPE_UINT64, &loader_usec,
1468                                       DBUS_TYPE_UINT64, &kernel_usec,
1469                                       DBUS_TYPE_UINT64, &initrd_usec,
1470                                       DBUS_TYPE_UINT64, &userspace_usec,
1471                                       DBUS_TYPE_UINT64, &total_usec,
1472                                       DBUS_TYPE_INVALID)) {
1473                 log_oom();
1474                 return;
1475         }
1476
1477
1478         if (bus_broadcast(m, message) < 0) {
1479                 log_oom();
1480                 return;
1481         }
1482 }
1483
1484 void bus_broadcast_reloading(Manager *m, bool active) {
1485
1486         _cleanup_dbus_message_unref_ DBusMessage *message = NULL;
1487         dbus_bool_t b = active;
1488
1489         assert(m);
1490
1491         message = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
1492         if (!message) {
1493                 log_oom();
1494                 return;
1495         }
1496
1497         assert_cc(sizeof(usec_t) == sizeof(uint64_t));
1498         if (!dbus_message_append_args(message,
1499                                       DBUS_TYPE_BOOLEAN, &b,
1500                                       DBUS_TYPE_INVALID)) {
1501                 log_oom();
1502                 return;
1503         }
1504
1505
1506         if (bus_broadcast(m, message) < 0) {
1507                 log_oom();
1508                 return;
1509         }
1510 }
1511
1512 Set *bus_acquire_subscribed(Manager *m, DBusConnection *c) {
1513         Set *s;
1514
1515         assert(m);
1516         assert(c);
1517
1518         s = BUS_CONNECTION_SUBSCRIBED(m, c);
1519         if (s)
1520                 return s;
1521
1522         s = set_new(string_hash_func, string_compare_func);
1523         if (!s)
1524                 return NULL;
1525
1526         if (!dbus_connection_set_data(c, m->subscribed_data_slot, s, NULL)) {
1527                 set_free(s);
1528                 return NULL;
1529         }
1530
1531         return s;
1532 }
1533
1534 void bus_serialize(Manager *m, FILE *f) {
1535         char *client;
1536         Iterator i;
1537         Set *s;
1538
1539         assert(m);
1540         assert(f);
1541
1542         if (!m->api_bus)
1543                 return;
1544
1545         s = BUS_CONNECTION_SUBSCRIBED(m, m->api_bus);
1546         SET_FOREACH(client, s, i)
1547                 fprintf(f, "subscribed=%s\n", client);
1548 }
1549
1550 int bus_deserialize_item(Manager *m, const char *line) {
1551         const char *e;
1552         char *b;
1553         Set *s;
1554
1555         assert(m);
1556         assert(line);
1557
1558         if (!m->api_bus)
1559                 return 0;
1560
1561         e = startswith(line, "subscribed=");
1562         if (!e)
1563                 return 0;
1564
1565         s = bus_acquire_subscribed(m, m->api_bus);
1566         if (!s)
1567                 return -ENOMEM;
1568
1569         b = strdup(e);
1570         if (!b)
1571                 return -ENOMEM;
1572
1573         set_consume(s, b);
1574
1575         return 1;
1576 }