1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
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.
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.
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/>.
22 #include <sys/epoll.h>
23 #include <sys/timerfd.h>
32 #include "dbus-unit.h"
34 #include "dbus-manager.h"
35 #include "dbus-execute.h"
36 #include "dbus-kill.h"
37 #include "dbus-cgroup.h"
41 #include "bus-error.h"
42 #include "bus-errors.h"
44 #include "dbus-client-track.h"
45 #include "bus-internal.h"
46 #include "selinux-access.h"
48 #define CONNECTIONS_MAX 512
50 static void destroy_bus(Manager *m, sd_bus **bus);
52 int bus_send_queued_message(Manager *m) {
57 if (!m->queued_message)
60 assert(m->queued_message_bus);
62 /* If we cannot get rid of this message we won't dispatch any
63 * D-Bus messages, so that we won't end up wanting to queue
66 r = sd_bus_send(m->queued_message_bus, m->queued_message, NULL);
68 log_warning("Failed to send queued message: %s", strerror(-r));
70 m->queued_message = sd_bus_message_unref(m->queued_message);
71 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
76 static int signal_agent_released(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
77 Manager *m = userdata;
85 r = sd_bus_message_read(message, "s", &cgroup);
87 bus_log_parse_error(r);
91 manager_notify_cgroup_empty(m, cgroup);
93 if (m->running_as == SYSTEMD_SYSTEM && m->system_bus) {
94 /* If we are running as system manager, forward the
95 * message to the system bus */
97 r = sd_bus_send(m->system_bus, message, NULL);
99 log_warning("Failed to forward Released message: %s", strerror(-r));
105 static int signal_disconnected(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
106 Manager *m = userdata;
112 if (bus == m->api_bus)
113 destroy_bus(m, &m->api_bus);
114 if (bus == m->system_bus)
115 destroy_bus(m, &m->system_bus);
116 if (set_remove(m->private_buses, bus)) {
117 log_debug("Got disconnect on private connection.");
118 destroy_bus(m, &bus);
124 static int signal_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
125 const char *name, *old_owner, *new_owner;
126 Manager *m = userdata;
133 r = sd_bus_message_read(message, "sss", &name, &old_owner, &new_owner);
135 bus_log_parse_error(r);
139 manager_dispatch_bus_name_owner_changed(
141 isempty(old_owner) ? NULL : old_owner,
142 isempty(new_owner) ? NULL : new_owner);
147 static int signal_activation_request(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
148 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
149 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
150 Manager *m = userdata;
159 r = sd_bus_message_read(message, "s", &name);
161 bus_log_parse_error(r);
165 if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) ||
166 manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET)) {
167 r = sd_bus_error_setf(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
171 r = manager_load_unit(m, name, NULL, &error, &u);
175 if (u->refuse_manual_start) {
176 r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, %u may be requested by dependency only.", u->id);
180 r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
184 /* Successfully queued, that's it for us */
188 if (!sd_bus_error_is_set(&error))
189 sd_bus_error_set_errno(&error, r);
191 log_debug("D-Bus activation failed for %s: %s", name, bus_error_message(&error, r));
193 r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure", &reply);
195 bus_log_create_error(r);
199 r = sd_bus_message_append(reply, "sss", name, error.name, error.message);
201 bus_log_create_error(r);
205 r = sd_bus_send_to(bus, reply, "org.freedesktop.DBus", NULL);
207 log_error("Failed to respond with to bus activation request: %s", strerror(-r));
214 static int selinux_filter(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
215 Manager *m = userdata;
216 const char *verb, *path;
224 /* Our own method calls are all protected individually with
225 * selinux checks, but the built-in interfaces need to be
228 if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set"))
230 else if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", NULL) ||
231 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", NULL) ||
232 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.ObjectManager", NULL) ||
233 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Peer", NULL))
238 path = sd_bus_message_get_path(message);
240 if (object_path_startswith("/org/freedesktop/systemd1", path)) {
242 r = selinux_access_check(bus, message, verb, error);
249 if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
250 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
253 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
257 r = sd_bus_creds_get_pid(creds, &pid);
261 u = manager_get_unit_by_pid(m, pid);
263 r = manager_get_job_from_dbus_path(m, path, &j);
267 manager_load_unit_from_dbus_path(m, path, NULL, &u);
273 r = selinux_unit_access_check(u, bus, message, verb, error);
280 static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
281 Manager *m = userdata;
291 r = manager_get_job_from_dbus_path(m, path, &j);
299 static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
307 if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
308 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
309 sd_bus_message *message;
312 message = sd_bus_get_current(bus);
316 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
320 r = sd_bus_creds_get_pid(creds, &pid);
324 u = manager_get_unit_by_pid(m, pid);
326 r = manager_load_unit_from_dbus_path(m, path, error, &u);
338 static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
339 Manager *m = userdata;
347 return find_unit(m, bus, path, (Unit**) found, error);
350 static int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
351 Manager *m = userdata;
361 r = find_unit(m, bus, path, &u, error);
365 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
372 static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
373 Manager *m = userdata;
383 r = find_unit(m, bus, path, &u, error);
387 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
390 if (!unit_get_cgroup_context(u))
397 static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
398 Manager *m = userdata;
409 r = find_unit(m, bus, path, &u, error);
413 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
416 c = unit_get_cgroup_context(u);
424 static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
425 Manager *m = userdata;
436 r = find_unit(m, bus, path, &u, error);
440 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
443 c = unit_get_exec_context(u);
451 static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
452 Manager *m = userdata;
463 r = find_unit(m, bus, path, &u, error);
467 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
470 c = unit_get_kill_context(u);
478 static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
479 _cleanup_free_ char **l = NULL;
480 Manager *m = userdata;
485 l = new0(char*, hashmap_size(m->jobs)+1);
489 HASHMAP_FOREACH(j, m->jobs, i) {
490 l[k] = job_dbus_path(j);
497 assert(hashmap_size(m->jobs) == k);
505 static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
506 _cleanup_free_ char **l = NULL;
507 Manager *m = userdata;
512 l = new0(char*, hashmap_size(m->units)+1);
516 HASHMAP_FOREACH(u, m->units, i) {
517 l[k] = unit_dbus_path(u);
530 static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
537 r = sd_bus_add_filter(bus, selinux_filter, m);
539 log_error("Failed to add SELinux access filter: %s", strerror(-r));
543 r = sd_bus_add_object_vtable(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
545 log_error("Failed to register Manager vtable: %s", strerror(-r));
549 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
551 log_error("Failed to register Job vtable: %s", strerror(-r));
555 r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
557 log_error("Failed to add job enumerator: %s", strerror(-r));
561 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
563 log_error("Failed to register Unit vtable: %s", strerror(-r));
567 r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
569 log_error("Failed to add job enumerator: %s", strerror(-r));
573 for (t = 0; t < _UNIT_TYPE_MAX; t++) {
574 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);
576 log_error("Failed to register type specific vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
580 if (unit_vtable[t]->cgroup_context_offset > 0) {
581 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);
583 log_error("Failed to register control group unit vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
587 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
589 log_error("Failed to register control group vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
594 if (unit_vtable[t]->exec_context_offset > 0) {
595 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
597 log_error("Failed to register execute vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
602 if (unit_vtable[t]->kill_context_offset > 0) {
603 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
605 log_error("Failed to register kill vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
614 static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
620 r = sd_bus_add_match(
623 "path='/org/freedesktop/DBus/Local',"
624 "interface='org.freedesktop.DBus.Local',"
625 "member='Disconnected'",
626 signal_disconnected, m);
629 log_error("Failed to register match for Disconnected message: %s", strerror(-r));
636 static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
637 _cleanup_bus_unref_ sd_bus *bus = NULL;
638 _cleanup_close_ int nfd = -1;
639 Manager *m = userdata;
646 nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
648 log_warning("Failed to accept private connection, ignoring: %m");
652 if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
653 log_warning("Too many concurrent connections, refusing");
657 r = set_ensure_allocated(&m->private_buses, trivial_hash_func, trivial_compare_func);
663 r = sd_bus_new(&bus);
665 log_warning("Failed to allocate new private connection bus: %s", strerror(-r));
669 r = sd_bus_set_fd(bus, nfd, nfd);
671 log_warning("Failed to set fd on new connection bus: %s", strerror(-r));
677 r = bus_check_peercred(bus);
679 log_warning("Incoming private connection from unprivileged client, refusing: %s", strerror(-r));
683 assert_se(sd_id128_randomize(&id) >= 0);
685 r = sd_bus_set_server(bus, 1, id);
687 log_warning("Failed to enable server support for new connection bus: %s", strerror(-r));
691 r = sd_bus_start(bus);
693 log_warning("Failed to start new connection bus: %s", strerror(-r));
697 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
699 log_warning("Failed to attach new connection bus to event loop: %s", strerror(-r));
703 if (m->running_as == SYSTEMD_SYSTEM) {
704 /* When we run as system instance we get the Released
705 * signal via a direct connection */
707 r = sd_bus_add_match(
710 "interface='org.freedesktop.systemd1.Agent',"
712 "path='/org/freedesktop/systemd1/agent'",
713 signal_agent_released, m);
716 log_warning("Failed to register Released match on new connection bus: %s", strerror(-r));
721 r = bus_setup_disconnected_match(m, bus);
725 r = bus_setup_api_vtables(m, bus);
727 log_warning("Failed to set up API vtables on new connection bus: %s", strerror(-r));
731 r = set_put(m->private_buses, bus);
733 log_warning("Failed to add new conenction bus to set: %s", strerror(-r));
739 log_debug("Accepted new private connection.");
744 static int bus_list_names(Manager *m, sd_bus *bus) {
745 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
746 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
753 r = sd_bus_call_method(
755 "org.freedesktop.DBus",
756 "/org/freedesktop/DBus",
757 "org.freedesktop.DBus",
762 log_error("Failed to get initial list of names: %s", bus_error_message(&error, r));
766 r = sd_bus_message_enter_container(reply, 'a', "s");
768 return bus_log_parse_error(r);
770 /* This is a bit hacky, we say the owner of the name is the
771 * name itself, because we don't want the extra traffic to
772 * figure out the real owner. */
773 while ((r = sd_bus_message_read(reply, "s", &name)) > 0)
774 manager_dispatch_bus_name_owner_changed(m, name, NULL, name);
776 return bus_log_parse_error(r);
778 r = sd_bus_message_exit_container(reply);
780 return bus_log_parse_error(r);
785 static int bus_setup_api(Manager *m, sd_bus *bus) {
791 r = bus_setup_api_vtables(m, bus);
795 r = sd_bus_add_match(
798 "sender='org.freedesktop.DBus',"
799 "path='/org/freedesktop/DBus',"
800 "interface='org.freedesktop.DBus',"
801 "member='NameOwnerChanged'",
802 signal_name_owner_changed, m);
804 log_warning("Failed to subscribe to NameOwnerChanged signal: %s", strerror(-r));
806 r = sd_bus_add_match(
809 "sender='org.freedesktop.DBus',"
810 "path='/org/freedesktop/DBus',"
811 "interface='org.freedesktop.systemd1.Activator',"
812 "member='ActivationRequest'",
813 signal_activation_request, m);
815 log_warning("Failed to subscribe to activation signal: %s", strerror(-r));
817 /* Allow replacing of our name, to ease implementation of
818 * reexecution, where we keep the old connection open until
819 * after the new connection is set up and the name installed
820 * to allow clients to synchronously wait for reexecution to
822 r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING);
824 log_error("Failed to register name: %s", strerror(-r));
828 if (r != SD_BUS_NAME_PRIMARY_OWNER) {
829 log_error("Failed to acquire name.");
833 bus_list_names(m, bus);
835 log_debug("Successfully connected to API bus.");
839 static int bus_init_api(Manager *m) {
840 _cleanup_bus_unref_ sd_bus *bus = NULL;
846 /* The API and system bus is the same if we are running in system mode */
847 if (m->running_as == SYSTEMD_SYSTEM && m->system_bus)
848 bus = sd_bus_ref(m->system_bus);
850 if (m->running_as == SYSTEMD_SYSTEM)
851 r = sd_bus_open_system(&bus);
853 r = sd_bus_open_user(&bus);
856 log_debug("Failed to connect to API bus, retrying later...");
860 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
862 log_error("Failed to attach API bus to event loop: %s", strerror(-r));
866 r = bus_setup_disconnected_match(m, bus);
871 r = bus_setup_api(m, bus);
873 log_error("Failed to set up API bus: %s", strerror(-r));
883 static int bus_setup_system(Manager *m, sd_bus *bus) {
889 if (m->running_as == SYSTEMD_SYSTEM)
892 /* If we are a user instance we get the Released message via
894 r = sd_bus_add_match(
897 "interface='org.freedesktop.systemd1.Agent',"
899 "path='/org/freedesktop/systemd1/agent'",
900 signal_agent_released, m);
903 log_warning("Failed to register Released match on system bus: %s", strerror(-r));
905 log_debug("Successfully connected to system bus.");
909 static int bus_init_system(Manager *m) {
910 _cleanup_bus_unref_ sd_bus *bus = NULL;
916 /* The API and system bus is the same if we are running in system mode */
917 if (m->running_as == SYSTEMD_SYSTEM && m->api_bus) {
918 m->system_bus = sd_bus_ref(m->api_bus);
922 r = sd_bus_open_system(&bus);
924 log_debug("Failed to connect to system bus, retrying later...");
928 r = bus_setup_disconnected_match(m, bus);
932 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
934 log_error("Failed to attach system bus to event loop: %s", strerror(-r));
938 r = bus_setup_system(m, bus);
940 log_error("Fauiled to set up system bus: %s", strerror(-r));
950 static int bus_init_private(Manager *m) {
951 _cleanup_close_ int fd = -1;
952 union sockaddr_union sa = {
953 .un.sun_family = AF_UNIX
961 if (m->private_listen_fd >= 0)
964 if (m->running_as == SYSTEMD_SYSTEM) {
966 /* We want the private bus only when running as init */
970 strcpy(sa.un.sun_path, "/run/systemd/private");
971 salen = offsetof(union sockaddr_union, un.sun_path) + sizeof("/run/systemd/private") - 1;
973 size_t left = sizeof(sa.un.sun_path);
974 char *p = sa.un.sun_path;
977 e = secure_getenv("XDG_RUNTIME_DIR");
979 log_error("Failed to determine XDG_RUNTIME_DIR");
983 left = strpcpy(&p, left, e);
984 left = strpcpy(&p, left, "/systemd/private");
986 salen = sizeof(sa.un) - left;
988 mkdir_parents_label(sa.un.sun_path, 0755);
991 unlink(sa.un.sun_path);
993 fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
995 log_error("Failed to allocate private socket: %m");
999 r = bind(fd, &sa.sa, salen);
1001 log_error("Failed to bind private socket: %m");
1005 r = listen(fd, SOMAXCONN);
1007 log_error("Failed to make private socket listening: %m");
1011 r = sd_event_add_io(m->event, fd, EPOLLIN, bus_on_connection, m, &s);
1013 log_error("Failed to allocate event source: %s", strerror(-r));
1017 m->private_listen_fd = fd;
1018 m->private_listen_event_source = s;
1021 log_debug("Successfully created private D-Bus server.");
1026 int bus_init(Manager *m, bool try_bus_connect) {
1029 if (try_bus_connect) {
1030 r = bus_init_system(m);
1034 r = bus_init_api(m);
1039 r = bus_init_private(m);
1046 static void destroy_bus(Manager *m, sd_bus **bus) {
1056 /* Get rid of tracked clients on this bus */
1057 bus_client_untrack_bus(m->subscribed, *bus);
1058 HASHMAP_FOREACH(j, m->jobs, i)
1059 bus_client_untrack_bus(j->subscribed, *bus);
1061 /* Get rid of queued message on this bus */
1062 if (m->queued_message_bus == *bus) {
1063 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
1065 if (m->queued_message)
1066 m->queued_message = sd_bus_message_unref(m->queued_message);
1069 /* Possibly flush unwritten data, but only if we are
1070 * unprivileged, since we don't want to sync here */
1071 if (m->running_as != SYSTEMD_SYSTEM)
1074 /* And destroy the object */
1076 *bus = sd_bus_unref(*bus);
1079 void bus_done(Manager *m) {
1085 destroy_bus(m, &m->api_bus);
1087 destroy_bus(m, &m->system_bus);
1088 while ((b = set_steal_first(m->private_buses)))
1091 set_free(m->private_buses);
1092 set_free(m->subscribed);
1094 if (m->private_listen_event_source)
1095 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1097 if (m->private_listen_fd >= 0) {
1098 close_nointr_nofail(m->private_listen_fd);
1099 m->private_listen_fd = -1;
1103 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1111 /* When we are about to reexecute we add all D-Bus fds to the
1112 * set to pass over to the newly executed systemd. They won't
1113 * be used there however, except thatt they are closed at the
1114 * very end of deserialization, those making it possible for
1115 * clients to synchronously wait for systemd to reexec by
1116 * simply waiting for disconnection */
1119 fd = sd_bus_get_fd(m->api_bus);
1121 fd = fdset_put_dup(fds, fd);
1127 SET_FOREACH(b, m->private_buses, i) {
1128 fd = sd_bus_get_fd(b);
1130 fd = fdset_put_dup(fds, fd);
1136 /* We don't offer any APIs on the system bus (well, unless it
1137 * is the same as the API bus) hence we don't bother with it
1143 void bus_serialize(Manager *m, FILE *f) {
1147 bus_client_track_serialize(m, f, m->subscribed);
1150 int bus_deserialize_item(Manager *m, const char *line) {
1154 return bus_client_track_deserialize_item(m, &m->subscribed, line);