chiark / gitweb /
manager: don't do plymouth in a container
[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
27 #include "sd-bus.h"
28 #include "log.h"
29 #include "strv.h"
30 #include "mkdir.h"
31 #include "missing.h"
32 #include "dbus-unit.h"
33 #include "dbus-job.h"
34 #include "dbus-manager.h"
35 #include "dbus-execute.h"
36 #include "dbus-kill.h"
37 #include "dbus-cgroup.h"
38 #include "special.h"
39 #include "dbus.h"
40 #include "bus-util.h"
41 #include "bus-error.h"
42 #include "bus-errors.h"
43 #include "strxcpyx.h"
44 #include "dbus-client-track.h"
45
46 #define CONNECTIONS_MAX 512
47
48 static void destroy_bus(Manager *m, sd_bus **bus);
49
50 int bus_send_queued_message(Manager *m) {
51         int r;
52
53         assert(m);
54
55         if (!m->queued_message)
56                 return 0;
57
58         assert(m->queued_message_bus);
59
60         /* If we cannot get rid of this message we won't dispatch any
61          * D-Bus messages, so that we won't end up wanting to queue
62          * another message. */
63
64         r = sd_bus_send(m->queued_message_bus, m->queued_message, NULL);
65         if (r < 0)
66                 log_warning("Failed to send queued message: %s", strerror(-r));
67
68         m->queued_message = sd_bus_message_unref(m->queued_message);
69         m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
70
71         return 0;
72 }
73
74 static int signal_agent_released(sd_bus *bus, sd_bus_message *message, void *userdata) {
75         Manager *m = userdata;
76         const char *cgroup;
77         int r;
78
79         assert(bus);
80         assert(message);
81         assert(m);
82
83         r = sd_bus_message_read(message, "s", &cgroup);
84         if (r < 0) {
85                 bus_log_parse_error(r);
86                 return 0;
87         }
88
89         manager_notify_cgroup_empty(m, cgroup);
90
91         if (m->running_as == SYSTEMD_SYSTEM && m->system_bus) {
92                 /* If we are running as system manager, forward the
93                  * message to the system bus */
94
95                 r = sd_bus_send(m->system_bus, message, NULL);
96                 if (r < 0)
97                         log_warning("Failed to forward Released message: %s", strerror(-r));
98         }
99
100         return 0;
101 }
102
103 static int signal_disconnected(sd_bus *bus, sd_bus_message *message, void *userdata) {
104         Manager *m = userdata;
105
106         assert(bus);
107         assert(message);
108         assert(m);
109
110         if (bus == m->api_bus)
111                 destroy_bus(m, &m->api_bus);
112         if (bus == m->system_bus)
113                 destroy_bus(m, &m->system_bus);
114         if (set_remove(m->private_buses, bus)) {
115                 log_debug("Got disconnect on private connection.");
116                 destroy_bus(m, &bus);
117         }
118
119         return 0;
120 }
121
122 static int signal_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata) {
123         const char *name, *old_owner, *new_owner;
124         Manager *m = userdata;
125         int r;
126
127         assert(bus);
128         assert(message);
129         assert(m);
130
131         r = sd_bus_message_read(message, "sss", &name, &old_owner, &new_owner);
132         if (r < 0) {
133                 bus_log_parse_error(r);
134                 return 0;
135         }
136
137         manager_dispatch_bus_name_owner_changed(
138                         m, name,
139                         isempty(old_owner) ? NULL : old_owner,
140                         isempty(new_owner) ? NULL : new_owner);
141
142         return 0;
143 }
144
145 static int signal_activation_request(sd_bus *bus, sd_bus_message *message, void *userdata) {
146         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
147         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
148         Manager *m = userdata;
149         const char *name;
150         Unit *u;
151         int r;
152
153         assert(bus);
154         assert(message);
155         assert(m);
156
157         r = sd_bus_message_read(message, "s", &name);
158         if (r < 0) {
159                 bus_log_parse_error(r);
160                 return 0;
161         }
162
163         if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) ||
164             manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET)) {
165                 r = sd_bus_error_setf(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
166                 goto failed;
167         }
168
169         r = manager_load_unit(m, name, NULL, &error, &u);
170         if (r < 0)
171                 goto failed;
172
173         if (u->refuse_manual_start) {
174                 r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, %u may be requested by dependency only.", u->id);
175                 goto failed;
176         }
177
178         r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
179         if (r < 0)
180                 goto failed;
181
182         /* Successfully queued, that's it for us */
183         return 0;
184
185 failed:
186         if (!sd_bus_error_is_set(&error))
187                 sd_bus_error_set_errno(&error, r);
188
189         log_debug("D-Bus activation failed for %s: %s", name, bus_error_message(&error, r));
190
191         r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure", &reply);
192         if (r < 0) {
193                 bus_log_create_error(r);
194                 return 0;
195         }
196
197         r = sd_bus_message_append(reply, "sss", error.name, error.message);
198         if (r < 0) {
199                 bus_log_create_error(r);
200                 return 0;
201         }
202
203         r = sd_bus_send_to(bus, reply, "org.freedesktop.DBus", NULL);
204         if (r < 0) {
205                 log_error("Failed to respond with to bus activation request: %s", strerror(-r));
206                 return r;
207         }
208
209         return 0;
210 }
211
212 static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
213         Manager *m = userdata;
214         Job *j;
215         int r;
216
217         assert(bus);
218         assert(path);
219         assert(interface);
220         assert(found);
221         assert(m);
222
223         r = manager_get_job_from_dbus_path(m, path, &j);
224         if (r < 0)
225                 return 0;
226
227         *found = j;
228         return 1;
229 }
230
231 static Unit *find_unit(Manager *m, sd_bus *bus, const char *path) {
232         Unit *u;
233         int r;
234
235         assert(m);
236         assert(bus);
237         assert(path);
238
239         if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
240                 sd_bus_message *message;
241                 pid_t pid;
242
243                 message = sd_bus_get_current(bus);
244                 if (!message)
245                         return NULL;
246
247                 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
248                 if (r < 0)
249                         return NULL;
250
251                 u = manager_get_unit_by_pid(m, pid);
252         } else {
253                 r = manager_load_unit_from_dbus_path(m, path, NULL, &u);
254                 if (r < 0)
255                         return NULL;
256         }
257
258         return u;
259 }
260
261 static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
262         Manager *m = userdata;
263         Unit *u;
264
265         assert(bus);
266         assert(path);
267         assert(interface);
268         assert(found);
269         assert(m);
270
271         u = find_unit(m, bus, path);
272         if (!u)
273                 return 0;
274
275         *found = u;
276         return 1;
277 }
278
279 static int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
280         Manager *m = userdata;
281         Unit *u;
282
283         assert(bus);
284         assert(path);
285         assert(interface);
286         assert(found);
287         assert(m);
288
289         u = find_unit(m, bus, path);
290         if (!u)
291                 return 0;
292
293         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
294                 return 0;
295
296         *found = u;
297         return 1;
298 }
299
300 static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
301         Manager *m = userdata;
302         Unit *u;
303
304         assert(bus);
305         assert(path);
306         assert(interface);
307         assert(found);
308         assert(m);
309
310         u = find_unit(m, bus, path);
311         if (!u)
312                 return 0;
313
314         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
315                 return 0;
316
317         if (!unit_get_cgroup_context(u))
318                 return 0;
319
320         *found = u;
321         return 1;
322 }
323
324 static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
325         Manager *m = userdata;
326         CGroupContext *c;
327         Unit *u;
328
329         assert(bus);
330         assert(path);
331         assert(interface);
332         assert(found);
333         assert(m);
334
335         u = find_unit(m, bus, path);
336         if (!u)
337                 return 0;
338
339         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
340                 return 0;
341
342         c = unit_get_cgroup_context(u);
343         if (!c)
344                 return 0;
345
346         *found = c;
347         return 1;
348 }
349
350 static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
351         Manager *m = userdata;
352         ExecContext *c;
353         Unit *u;
354
355         assert(bus);
356         assert(path);
357         assert(interface);
358         assert(found);
359         assert(m);
360
361         u = find_unit(m, bus, path);
362         if (!u)
363                 return 0;
364
365         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
366                 return 0;
367
368         c = unit_get_exec_context(u);
369         if (!c)
370                 return 0;
371
372         *found = c;
373         return 1;
374 }
375
376 static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
377         Manager *m = userdata;
378         KillContext *c;
379         Unit *u;
380
381         assert(bus);
382         assert(path);
383         assert(interface);
384         assert(found);
385         assert(m);
386
387         u = find_unit(m, bus, path);
388         if (!u)
389                 return 0;
390
391         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
392                 return 0;
393
394         c = unit_get_kill_context(u);
395         if (!c)
396                 return 0;
397
398         *found = c;
399         return 1;
400 }
401
402 static int bus_job_enumerate(sd_bus *bus, const char *path, char ***nodes, void *userdata) {
403         _cleanup_free_ char **l = NULL;
404         Manager *m = userdata;
405         unsigned k = 0;
406         Iterator i;
407         Job *j;
408
409         l = new0(char*, hashmap_size(m->jobs)+1);
410         if (!l)
411                 return -ENOMEM;
412
413         HASHMAP_FOREACH(j, m->jobs, i) {
414                 l[k] = job_dbus_path(j);
415                 if (!l[k])
416                         return -ENOMEM;
417
418                 k++;
419         }
420
421         assert(hashmap_size(m->jobs) == k);
422
423         *nodes = l;
424         l = NULL;
425
426         return k;
427 }
428
429 static int bus_unit_enumerate(sd_bus *bus, const char *path, char ***nodes, void *userdata) {
430         _cleanup_free_ char **l = NULL;
431         Manager *m = userdata;
432         unsigned k = 0;
433         Iterator i;
434         Unit *u;
435
436         l = new0(char*, hashmap_size(m->units)+1);
437         if (!l)
438                 return -ENOMEM;
439
440         HASHMAP_FOREACH(u, m->units, i) {
441                 l[k] = unit_dbus_path(u);
442                 if (!l[k])
443                         return -ENOMEM;
444
445                 k++;
446         }
447
448         *nodes = l;
449         l = NULL;
450
451         return k;
452 }
453
454 static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
455         UnitType t;
456         int r;
457
458         assert(m);
459         assert(bus);
460
461         r = sd_bus_add_object_vtable(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
462         if (r < 0) {
463                 log_error("Failed to register Manager vtable: %s", strerror(-r));
464                 return r;
465         }
466
467         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
468         if (r < 0) {
469                 log_error("Failed to register Job vtable: %s", strerror(-r));
470                 return r;
471         }
472
473         r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
474         if (r < 0) {
475                 log_error("Failed to add job enumerator: %s", strerror(-r));
476                 return r;
477         }
478
479         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
480         if (r < 0) {
481                 log_error("Failed to register Unit vtable: %s", strerror(-r));
482                 return r;
483         }
484
485         r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
486         if (r < 0) {
487                 log_error("Failed to add job enumerator: %s", strerror(-r));
488                 return r;
489         }
490
491         for (t = 0; t < _UNIT_TYPE_MAX; t++) {
492                 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
493                 if (r < 0)  {
494                         log_error("Failed to register type specific vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
495                         return r;
496                 }
497
498                 if (unit_vtable[t]->cgroup_context_offset > 0) {
499                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
500                         if (r < 0) {
501                                 log_error("Failed to register control group unit vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
502                                 return r;
503                         }
504
505                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
506                         if (r < 0) {
507                                 log_error("Failed to register control group vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
508                                 return r;
509                         }
510                 }
511
512                 if (unit_vtable[t]->exec_context_offset > 0) {
513                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
514                         if (r < 0) {
515                                 log_error("Failed to register execute vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
516                                 return r;
517                         }
518                 }
519
520                 if (unit_vtable[t]->kill_context_offset > 0) {
521                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
522                         if (r < 0) {
523                                 log_error("Failed to register kill vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
524                                 return r;
525                         }
526                 }
527         }
528
529         return 0;
530 }
531
532 static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
533         int r;
534
535         assert(m);
536         assert(bus);
537
538         r = sd_bus_add_match(
539                         bus,
540                         "type='signal',"
541                         "path='/org/freedesktop/DBus/Local',"
542                         "interface='org.freedesktop.DBus.Local',"
543                         "member='Disconnected'",
544                         signal_disconnected, m);
545
546         if (r < 0) {
547                 log_error("Failed to register match for Disconnected message: %s", strerror(-r));
548                 return r;
549         }
550
551         return 0;
552 }
553
554 static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
555         _cleanup_bus_unref_ sd_bus *bus = NULL;
556         _cleanup_close_ int nfd = -1;
557         Manager *m = userdata;
558         sd_id128_t id;
559         int r;
560
561         assert(s);
562         assert(m);
563
564         nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
565         if (nfd < 0) {
566                 log_warning("Failed to accept private connection, ignoring: %m");
567                 return 0;
568         }
569
570         if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
571                 log_warning("Too many concurrent connections, refusing");
572                 return 0;
573         }
574
575         r = set_ensure_allocated(&m->private_buses, trivial_hash_func, trivial_compare_func);
576         if (r < 0) {
577                 log_oom();
578                 return 0;
579         }
580
581         r = sd_bus_new(&bus);
582         if (r < 0) {
583                 log_warning("Failed to allocate new private connection bus: %s", strerror(-r));
584                 return 0;
585         }
586
587         r = sd_bus_set_fd(bus, nfd, nfd);
588         if (r < 0) {
589                 log_warning("Failed to set fd on new connection bus: %s", strerror(-r));
590                 return 0;
591         }
592
593         nfd = -1;
594
595         r = bus_check_peercred(bus);
596         if (r < 0) {
597                 log_warning("Incoming private connection from unprivileged client, refusing: %s", strerror(-r));
598                 return 0;
599         }
600
601         assert_se(sd_id128_randomize(&id) >= 0);
602
603         r = sd_bus_set_server(bus, 1, id);
604         if (r < 0) {
605                 log_warning("Failed to enable server support for new connection bus: %s", strerror(-r));
606                 return 0;
607         }
608
609         r = sd_bus_start(bus);
610         if (r < 0) {
611                 log_warning("Failed to start new connection bus: %s", strerror(-r));
612                 return 0;
613         }
614
615         r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
616         if (r < 0) {
617                 log_warning("Failed to attach new connection bus to event loop: %s", strerror(-r));
618                 return 0;
619         }
620
621         if (m->running_as == SYSTEMD_SYSTEM) {
622                 /* When we run as system instance we get the Released
623                  * signal via a direct connection */
624
625                 r = sd_bus_add_match(
626                                 bus,
627                                 "type='signal',"
628                                 "interface='org.freedesktop.systemd1.Agent',"
629                                 "member='Released',"
630                                 "path='/org/freedesktop/systemd1/agent'",
631                                 signal_agent_released, m);
632
633                 if (r < 0) {
634                         log_warning("Failed to register Released match on new connection bus: %s", strerror(-r));
635                         return 0;
636                 }
637         }
638
639         r = bus_setup_disconnected_match(m, bus);
640         if (r < 0)
641                 return 0;
642
643         r = bus_setup_api_vtables(m, bus);
644         if (r < 0) {
645                 log_warning("Failed to set up API vtables on new connection bus: %s", strerror(-r));
646                 return 0;
647         }
648
649         r = set_put(m->private_buses, bus);
650         if (r < 0) {
651                 log_warning("Failed to add new conenction bus to set: %s", strerror(-r));
652                 return 0;
653         }
654
655         bus = NULL;
656
657         log_debug("Accepted new private connection.");
658
659         return 0;
660 }
661
662 static int bus_list_names(Manager *m, sd_bus *bus) {
663         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
664         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
665         const char *name;
666         int r;
667
668         assert(m);
669         assert(bus);
670
671         r = sd_bus_call_method(
672                         bus,
673                         "org.freedesktop.DBus",
674                         "/org/freedesktop/DBus",
675                         "org.freedesktop.DBus",
676                         "ListNames",
677                         &error, &reply,
678                         NULL);
679         if (r < 0) {
680                 log_error("Failed to get initial list of names: %s", bus_error_message(&error, r));
681                 return r;
682         }
683
684         r = sd_bus_message_enter_container(reply, 'a', "s");
685         if (r < 0)
686                 return bus_log_parse_error(r);
687
688         /* This is a bit hacky, we say the owner of the name is the
689          * name itself, because we don't want the extra traffic to
690          * figure out the real owner. */
691         while ((r = sd_bus_message_read(reply, "s", &name)) > 0)
692                 manager_dispatch_bus_name_owner_changed(m, name, NULL, name);
693         if (r < 0)
694                 return bus_log_parse_error(r);
695
696         r = sd_bus_message_exit_container(reply);
697         if (r < 0)
698                 return bus_log_parse_error(r);
699
700         return 0;
701 }
702
703 static int bus_setup_api(Manager *m, sd_bus *bus) {
704         int r;
705
706         assert(m);
707         assert(bus);
708
709         r = bus_setup_api_vtables(m, bus);
710         if (r < 0)
711                 return r;
712
713         r = sd_bus_add_match(
714                         bus,
715                         "type='signal',"
716                         "sender='org.freedesktop.DBus',"
717                         "path='/org/freedesktop/DBus',"
718                         "interface='org.freedesktop.DBus',"
719                         "member='NameOwnerChanged'",
720                         signal_name_owner_changed, m);
721         if (r < 0)
722                 log_warning("Failed to subscribe to NameOwnerChanged signal: %s", strerror(-r));
723
724         r = sd_bus_add_match(
725                         bus,
726                         "type='signal',"
727                         "sender='org.freedesktop.DBus',"
728                         "path='/org/freedesktop/DBus',"
729                         "interface='org.freedesktop.systemd1.Activator',"
730                         "member='ActivationRequest'",
731                         signal_activation_request, m);
732         if (r < 0)
733                 log_warning("Failed to subscribe to activation signal: %s", strerror(-r));
734
735         /* Allow replacing of our name, to ease implementation of
736          * reexecution, where we keep the old connection open until
737          * after the new connection is set up and the name installed
738          * to allow clients to synchronously wait for reexecution to
739          * finish */
740         r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING);
741         if (r < 0) {
742                 log_error("Failed to register name: %s", strerror(-r));
743                 return r;
744         }
745
746         if (r != SD_BUS_NAME_PRIMARY_OWNER) {
747                 log_error("Failed to acquire name.");
748                 return -EEXIST;
749         }
750
751         bus_list_names(m, bus);
752
753         log_debug("Successfully connected to API bus.");
754         return 0;
755 }
756
757 static int bus_init_api(Manager *m) {
758         _cleanup_bus_unref_ sd_bus *bus = NULL;
759         int r;
760
761         if (m->api_bus)
762                 return 0;
763
764         /* The API and system bus is the same if we are running in system mode */
765         if (m->running_as == SYSTEMD_SYSTEM && m->system_bus)
766                 bus = sd_bus_ref(m->system_bus);
767         else {
768                 if (m->running_as == SYSTEMD_SYSTEM)
769                         r = sd_bus_open_system(&bus);
770                 else
771                         r = sd_bus_open_user(&bus);
772
773                 if (r < 0) {
774                         log_debug("Failed to connect to API bus, retrying later...");
775                         return 0;
776                 }
777
778                 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
779                 if (r < 0) {
780                         log_error("Failed to attach API bus to event loop: %s", strerror(-r));
781                         return 0;
782                 }
783
784                 r = bus_setup_disconnected_match(m, bus);
785                 if (r < 0)
786                         return 0;
787         }
788
789         r = bus_setup_api(m, bus);
790         if (r < 0) {
791                 log_error("Failed to set up API bus: %s", strerror(-r));
792                 return 0;
793         }
794
795         m->api_bus = bus;
796         bus = NULL;
797
798         return 0;
799 }
800
801 static int bus_setup_system(Manager *m, sd_bus *bus) {
802         int r;
803
804         assert(m);
805         assert(bus);
806
807         if (m->running_as == SYSTEMD_SYSTEM)
808                 return 0;
809
810         /* If we are a user instance we get the Released message via
811          * the system bus */
812         r = sd_bus_add_match(
813                         bus,
814                         "type='signal',"
815                         "interface='org.freedesktop.systemd1.Agent',"
816                         "member='Released',"
817                         "path='/org/freedesktop/systemd1/agent'",
818                         signal_agent_released, m);
819
820         if (r < 0)
821                 log_warning("Failed to register Released match on system bus: %s", strerror(-r));
822
823         log_debug("Successfully connected to system bus.");
824         return 0;
825 }
826
827 static int bus_init_system(Manager *m) {
828         _cleanup_bus_unref_ sd_bus *bus = NULL;
829         int r;
830
831         if (m->system_bus)
832                 return 0;
833
834         /* The API and system bus is the same if we are running in system mode */
835         if (m->running_as == SYSTEMD_SYSTEM && m->api_bus) {
836                 m->system_bus = sd_bus_ref(m->api_bus);
837                 return 0;
838         }
839
840         r = sd_bus_open_system(&bus);
841         if (r < 0) {
842                 log_debug("Failed to connect to system bus, retrying later...");
843                 return 0;
844         }
845
846         r = bus_setup_disconnected_match(m, bus);
847         if (r < 0)
848                 return 0;
849
850         r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
851         if (r < 0) {
852                 log_error("Failed to attach system bus to event loop: %s", strerror(-r));
853                 return 0;
854         }
855
856         r = bus_setup_system(m, bus);
857         if (r < 0) {
858                 log_error("Fauiled to set up system bus: %s", strerror(-r));
859                 return 0;
860         }
861
862         m->system_bus = bus;
863         bus = NULL;
864
865         return 0;
866 }
867
868 static int bus_init_private(Manager *m) {
869         _cleanup_close_ int fd = -1;
870         union sockaddr_union sa = {
871                 .un.sun_family = AF_UNIX
872         };
873         sd_event_source *s;
874         socklen_t salen;
875         int r;
876
877         assert(m);
878
879         if (m->private_listen_fd >= 0)
880                 return 0;
881
882         if (m->running_as == SYSTEMD_SYSTEM) {
883
884                 /* We want the private bus only when running as init */
885                 if (getpid() != 1)
886                         return 0;
887
888                 strcpy(sa.un.sun_path, "/run/systemd/private");
889                 salen = offsetof(union sockaddr_union, un.sun_path) + sizeof("/run/systemd/private") - 1;
890         } else {
891                 size_t left = sizeof(sa.un.sun_path);
892                 char *p = sa.un.sun_path;
893                 const char *e;
894
895                 e = secure_getenv("XDG_RUNTIME_DIR");
896                 if (!e) {
897                         log_error("Failed to determine XDG_RUNTIME_DIR");
898                         return -EHOSTDOWN;
899                 }
900
901                 left = strpcpy(&p, left, e);
902                 left = strpcpy(&p, left, "/systemd/private");
903
904                 salen = sizeof(sa.un) - left;
905
906                 mkdir_parents_label(sa.un.sun_path, 0755);
907         }
908
909         unlink(sa.un.sun_path);
910
911         fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
912         if (fd < 0) {
913                 log_error("Failed to allocate private socket: %m");
914                 return -errno;
915         }
916
917         r = bind(fd, &sa.sa, salen);
918         if (r < 0) {
919                 log_error("Failed to bind private socket: %m");
920                 return -errno;
921         }
922
923         r = listen(fd, SOMAXCONN);
924         if (r < 0) {
925                 log_error("Failed to make private socket listening: %m");
926                 return -errno;
927         }
928
929         r = sd_event_add_io(m->event, fd, EPOLLIN, bus_on_connection, m, &s);
930         if (r < 0) {
931                 log_error("Failed to allocate event source: %s", strerror(-r));
932                 return r;
933         }
934
935         m->private_listen_fd = fd;
936         m->private_listen_event_source = s;
937         fd = -1;
938
939         log_debug("Successfully created private D-Bus server.");
940
941         return 0;
942 }
943
944 int bus_init(Manager *m, bool try_bus_connect) {
945         int r;
946
947         if (try_bus_connect) {
948                 r = bus_init_system(m);
949                 if (r < 0)
950                         return r;
951
952                 r = bus_init_api(m);
953                 if (r < 0)
954                         return r;
955         }
956
957         r = bus_init_private(m);
958         if (r < 0)
959                 return r;
960
961         return 0;
962 }
963
964 static void destroy_bus(Manager *m, sd_bus **bus) {
965         Iterator i;
966         Job *j;
967
968         assert(m);
969         assert(bus);
970
971         if (!*bus)
972                 return;
973
974         /* Get rid of tracked clients on this bus */
975         bus_client_untrack_bus(m->subscribed, *bus);
976         HASHMAP_FOREACH(j, m->jobs, i)
977                 bus_client_untrack_bus(j->subscribed, *bus);
978
979         /* Get rid of queued message on this bus */
980         if (m->queued_message_bus == *bus) {
981                 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
982
983                 if (m->queued_message)
984                         m->queued_message = sd_bus_message_unref(m->queued_message);
985         }
986
987         /* Possibly flush unwritten data, but only if we are
988          * unprivileged, since we don't want to sync here */
989         if (m->running_as != SYSTEMD_SYSTEM)
990                 sd_bus_flush(*bus);
991
992         /* And destroy the object */
993         sd_bus_close(*bus);
994         *bus = sd_bus_unref(*bus);
995 }
996
997 void bus_done(Manager *m) {
998         sd_bus *b;
999
1000         assert(m);
1001
1002         if (m->api_bus)
1003                 destroy_bus(m, &m->api_bus);
1004         if (m->system_bus)
1005                 destroy_bus(m, &m->system_bus);
1006         while ((b = set_steal_first(m->private_buses)))
1007                 destroy_bus(m, &b);
1008
1009         set_free(m->private_buses);
1010         set_free(m->subscribed);
1011
1012         if (m->private_listen_event_source)
1013                 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1014
1015         if (m->private_listen_fd >= 0) {
1016                 close_nointr_nofail(m->private_listen_fd);
1017                 m->private_listen_fd = -1;
1018         }
1019 }
1020
1021 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1022         Iterator i;
1023         sd_bus *b;
1024         int fd;
1025
1026         assert(m);
1027         assert(fds);
1028
1029         /* When we are about to reexecute we add all D-Bus fds to the
1030          * set to pass over to the newly executed systemd. They won't
1031          * be used there however, except thatt they are closed at the
1032          * very end of deserialization, those making it possible for
1033          * clients to synchronously wait for systemd to reexec by
1034          * simply waiting for disconnection */
1035
1036         if (m->api_bus) {
1037                 fd = sd_bus_get_fd(m->api_bus);
1038                 if (fd >= 0) {
1039                         fd = fdset_put_dup(fds, fd);
1040                         if (fd < 0)
1041                                 return fd;
1042                 }
1043         }
1044
1045         SET_FOREACH(b, m->private_buses, i) {
1046                 fd = sd_bus_get_fd(b);
1047                 if (fd >= 0) {
1048                         fd = fdset_put_dup(fds, fd);
1049                         if (fd < 0)
1050                                 return fd;
1051                 }
1052         }
1053
1054         /* We don't offer any APIs on the system bus (well, unless it
1055          * is the same as the API bus) hence we don't bother with it
1056          * here */
1057
1058         return 0;
1059 }
1060
1061 void bus_serialize(Manager *m, FILE *f) {
1062         assert(m);
1063         assert(f);
1064
1065         bus_client_track_serialize(m, f, m->subscribed);
1066 }
1067
1068 int bus_deserialize_item(Manager *m, const char *line) {
1069         assert(m);
1070         assert(line);
1071
1072         return bus_client_track_deserialize_item(m, &m->subscribed, line);
1073 }