From 5e8d1c9a9f15b7453474dc4879bdb4021c3f50a1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 19 Jun 2010 03:04:04 +0200 Subject: [PATCH] dbus: to make sure that systemd stays controllable during early bootup, register our services on our own micro usb server in addition to the bus --- fixme | 4 +- src/dbus-automount.c | 4 +- src/dbus-automount.h | 2 +- src/dbus-device.c | 4 +- src/dbus-device.h | 2 +- src/dbus-job.c | 17 +- src/dbus-manager.c | 40 ++--- src/dbus-mount.c | 4 +- src/dbus-mount.h | 2 +- src/dbus-path.c | 4 +- src/dbus-path.h | 2 +- src/dbus-service.c | 4 +- src/dbus-service.h | 2 +- src/dbus-snapshot.c | 6 +- src/dbus-snapshot.h | 2 +- src/dbus-socket.c | 4 +- src/dbus-socket.h | 2 +- src/dbus-swap.c | 4 +- src/dbus-swap.h | 2 +- src/dbus-target.c | 4 +- src/dbus-target.h | 2 +- src/dbus-timer.c | 4 +- src/dbus-timer.h | 2 +- src/dbus-unit.c | 24 +-- src/dbus.c | 367 +++++++++++++++++++++++++++++++------------ src/dbus.h | 11 +- src/manager.c | 9 +- src/manager.h | 6 +- src/systemctl.c | 9 +- src/unit.c | 3 +- src/unit.h | 2 +- 31 files changed, 360 insertions(+), 194 deletions(-) diff --git a/fixme b/fixme index b5b8e632..15e3ef6b 100644 --- a/fixme +++ b/fixme @@ -59,12 +59,12 @@ * systemd-sysvinit as package -* abstract namespace dbus socket - * patch /etc/init.d/functions with: if [ $PPID -ne 1 && mountpoint /cgroup/systemd ] ; then echo "You suck!" ; fi +* remove MANAGER_SYSTEM + Regularly: * look for close() vs. close_nointr() vs. close_nointr_nofail() diff --git a/src/dbus-automount.c b/src/dbus-automount.c index 285f666d..61732f98 100644 --- a/src/dbus-automount.c +++ b/src/dbus-automount.c @@ -38,12 +38,12 @@ const char bus_automount_interface[] = BUS_AUTOMOUNT_INTERFACE; -DBusHandlerResult bus_automount_message_handler(Unit *u, DBusMessage *message) { +DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { const BusProperty properties[] = { BUS_UNIT_PROPERTIES, { "org.freedesktop.systemd1.Automount", "Where", bus_property_append_string, "s", u->automount.where }, { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); } diff --git a/src/dbus-automount.h b/src/dbus-automount.h index 5e0ee510..77c887e8 100644 --- a/src/dbus-automount.h +++ b/src/dbus-automount.h @@ -26,7 +26,7 @@ #include "unit.h" -DBusHandlerResult bus_automount_message_handler(Unit *u, DBusMessage *message); +DBusHandlerResult bus_automount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); extern const char bus_automount_interface[]; diff --git a/src/dbus-device.c b/src/dbus-device.c index 0610ab87..168c8c8c 100644 --- a/src/dbus-device.c +++ b/src/dbus-device.c @@ -38,12 +38,12 @@ const char bus_device_interface[] = BUS_DEVICE_INTERFACE; -DBusHandlerResult bus_device_message_handler(Unit *u, DBusMessage *message) { +DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { const BusProperty properties[] = { BUS_UNIT_PROPERTIES, { "org.freedesktop.systemd1.Device", "SysFSPath", bus_property_append_string, "s", u->device.sysfs }, { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); } diff --git a/src/dbus-device.h b/src/dbus-device.h index 55bb8f55..dc717f17 100644 --- a/src/dbus-device.h +++ b/src/dbus-device.h @@ -26,7 +26,7 @@ #include "unit.h" -DBusHandlerResult bus_device_message_handler(Unit *u, DBusMessage *message); +DBusHandlerResult bus_device_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); extern const char bus_device_interface[]; diff --git a/src/dbus-job.c b/src/dbus-job.c index 7346252a..48b1588d 100644 --- a/src/dbus-job.c +++ b/src/dbus-job.c @@ -78,7 +78,7 @@ static int bus_job_append_unit(Manager *m, DBusMessageIter *i, const char *prope return 0; } -static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusMessage *message) { +static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusConnection *connection, DBusMessage *message) { const BusProperty properties[] = { { "org.freedesktop.systemd1.Job", "Id", bus_property_append_uint32, "u", &j->id }, { "org.freedesktop.systemd1.Job", "State", bus_job_append_state, "s", &j->state }, @@ -88,7 +88,6 @@ static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusMessage *message) }; DBusMessage *reply = NULL; - Manager *m = j->manager; if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Job", "Cancel")) { if (!(reply = dbus_message_new_method_return(message))) @@ -97,10 +96,10 @@ static DBusHandlerResult bus_job_message_dispatch(Job *j, DBusMessage *message) job_free(j); } else - return bus_default_message_handler(j->manager, message, INTROSPECTION, properties); + return bus_default_message_handler(j->manager, connection, message, INTROSPECTION, properties); if (reply) { - if (!dbus_connection_send(m->api_bus, reply, NULL)) + if (!dbus_connection_send(connection, reply, NULL)) goto oom; dbus_message_unref(reply); @@ -115,7 +114,7 @@ oom: return DBUS_HANDLER_RESULT_NEED_MEMORY; } -static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { +static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { Manager *m = data; Job *j; int r; @@ -137,10 +136,10 @@ static DBusHandlerResult bus_job_message_handler(DBusConnection *connection, DB if (r == -ENOENT) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - return bus_send_error_reply(m, message, NULL, r); + return bus_send_error_reply(m, connection, message, NULL, r); } - return bus_job_message_dispatch(j, message); + return bus_job_message_dispatch(j, connection, message); } const DBusObjectPathVTable bus_job_vtable = { @@ -183,7 +182,7 @@ void bus_job_send_change_signal(Job *j) { goto oom; } - if (!dbus_connection_send(j->manager->api_bus, m, NULL)) + if (bus_broadcast(j->manager, m) < 0) goto oom; free(p); @@ -228,7 +227,7 @@ void bus_job_send_removed_signal(Job *j, bool success) { DBUS_TYPE_INVALID)) goto oom; - if (!dbus_connection_send(j->manager->api_bus, m, NULL)) + if (bus_broadcast(j->manager, m) < 0) goto oom; free(p); diff --git a/src/dbus-manager.c b/src/dbus-manager.c index d4c9e8f0..78182578 100644 --- a/src/dbus-manager.c +++ b/src/dbus-manager.c @@ -185,7 +185,7 @@ static int bus_manager_append_n_jobs(Manager *m, DBusMessageIter *i, const char return 0; } -static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { +static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { Manager *m = data; const BusProperty properties[] = { @@ -226,10 +226,10 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) - return bus_send_error_reply(m, message, &error, -EINVAL); + return bus_send_error_reply(m, connection, message, &error, -EINVAL); if (!(u = manager_get_unit(m, name))) - return bus_send_error_reply(m, message, NULL, -ENOENT); + return bus_send_error_reply(m, connection, message, NULL, -ENOENT); if (!(reply = dbus_message_new_method_return(message))) goto oom; @@ -252,10 +252,10 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) - return bus_send_error_reply(m, message, &error, -EINVAL); + return bus_send_error_reply(m, connection, message, &error, -EINVAL); if ((r = manager_load_unit(m, name, NULL, &u)) < 0) - return bus_send_error_reply(m, message, NULL, r); + return bus_send_error_reply(m, connection, message, NULL, r); if (!(reply = dbus_message_new_method_return(message))) goto oom; @@ -286,10 +286,10 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection &error, DBUS_TYPE_UINT32, &id, DBUS_TYPE_INVALID)) - return bus_send_error_reply(m, message, &error, -EINVAL); + return bus_send_error_reply(m, connection, message, &error, -EINVAL); if (!(j = manager_get_job(m, id))) - return bus_send_error_reply(m, message, NULL, -ENOENT); + return bus_send_error_reply(m, connection, message, NULL, -ENOENT); if (!(reply = dbus_message_new_method_return(message))) goto oom; @@ -449,7 +449,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection r = set_put(m->subscribed, client); if (r < 0) - return bus_send_error_reply(m, message, NULL, r); + return bus_send_error_reply(m, connection, message, NULL, r); if (!(reply = dbus_message_new_method_return(message))) goto oom; @@ -458,7 +458,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection char *client; if (!(client = set_remove(m->subscribed, (char*) dbus_message_get_sender(message)))) - return bus_send_error_reply(m, message, NULL, -ENOENT); + return bus_send_error_reply(m, connection, message, NULL, -ENOENT); free(client); @@ -504,13 +504,13 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection DBUS_TYPE_STRING, &name, DBUS_TYPE_BOOLEAN, &cleanup, DBUS_TYPE_INVALID)) - return bus_send_error_reply(m, message, &error, -EINVAL); + return bus_send_error_reply(m, connection, message, &error, -EINVAL); if (name && name[0] == 0) name = NULL; if ((r = snapshot_create(m, name, cleanup, &s)) < 0) - return bus_send_error_reply(m, message, NULL, r); + return bus_send_error_reply(m, connection, message, NULL, r); if (!(reply = dbus_message_new_method_return(message))) goto oom; @@ -609,7 +609,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Exit")) { if (m->running_as == MANAGER_INIT) - return bus_send_error_reply(m, message, NULL, -ENOTSUP); + return bus_send_error_reply(m, connection, message, NULL, -ENOTSUP); if (!(reply = dbus_message_new_method_return(message))) goto oom; @@ -623,7 +623,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection if (r == -ENOMEM) goto oom; - return bus_send_error_reply(m, message, NULL, r); + return bus_send_error_reply(m, connection, message, NULL, r); } e = strv_env_merge(2, m->environment, l); @@ -647,7 +647,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection if (r == -ENOMEM) goto oom; - return bus_send_error_reply(m, message, NULL, r); + return bus_send_error_reply(m, connection, message, NULL, r); } e = strv_env_delete(m->environment, 1, l); @@ -663,7 +663,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection m->environment = e; } else - return bus_default_message_handler(m, message, NULL, properties); + return bus_default_message_handler(m, connection, message, NULL, properties); if (job_type != _JOB_TYPE_INVALID) { @@ -678,19 +678,19 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &smode, DBUS_TYPE_INVALID)) - return bus_send_error_reply(m, message, &error, -EINVAL); + return bus_send_error_reply(m, connection, message, &error, -EINVAL); if ((mode = job_mode_from_string(smode)) == _JOB_MODE_INVALID) - return bus_send_error_reply(m, message, NULL, -EINVAL); + return bus_send_error_reply(m, connection, message, NULL, -EINVAL); if ((r = manager_load_unit(m, name, NULL, &u)) < 0) - return bus_send_error_reply(m, message, NULL, r); + return bus_send_error_reply(m, connection, message, NULL, r); if (job_type == JOB_START && u->meta.only_by_dependency) - return bus_send_error_reply(m, message, NULL, -EPERM); + return bus_send_error_reply(m, connection, message, NULL, -EPERM); if ((r = manager_add_job(m, job_type, u, mode, true, &j)) < 0) - return bus_send_error_reply(m, message, NULL, r); + return bus_send_error_reply(m, connection, message, NULL, r); if (!(reply = dbus_message_new_method_return(message))) goto oom; diff --git a/src/dbus-mount.c b/src/dbus-mount.c index cccfa60e..0f417e76 100644 --- a/src/dbus-mount.c +++ b/src/dbus-mount.c @@ -120,7 +120,7 @@ static int bus_mount_append_type(Manager *n, DBusMessageIter *i, const char *pro return 0; } -DBusHandlerResult bus_mount_message_handler(Unit *u, DBusMessage *message) { +DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { const BusProperty properties[] = { BUS_UNIT_PROPERTIES, { "org.freedesktop.systemd1.Mount", "Where", bus_property_append_string, "s", u->mount.where }, @@ -135,5 +135,5 @@ DBusHandlerResult bus_mount_message_handler(Unit *u, DBusMessage *message) { { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); } diff --git a/src/dbus-mount.h b/src/dbus-mount.h index 6d8d1a96..53522f70 100644 --- a/src/dbus-mount.h +++ b/src/dbus-mount.h @@ -26,7 +26,7 @@ #include "unit.h" -DBusHandlerResult bus_mount_message_handler(Unit *u, DBusMessage *message); +DBusHandlerResult bus_mount_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); extern const char bus_mount_interface[]; diff --git a/src/dbus-path.c b/src/dbus-path.c index ed1dc265..7589f5bc 100644 --- a/src/dbus-path.c +++ b/src/dbus-path.c @@ -41,12 +41,12 @@ const char bus_path_interface[] = BUS_PATH_INTERFACE; -DBusHandlerResult bus_path_message_handler(Unit *u, DBusMessage *message) { +DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { const BusProperty properties[] = { BUS_UNIT_PROPERTIES, { "org.freedesktop.systemd1.Path", "Unit", bus_property_append_string, "s", &u->path.unit->meta.id }, { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); } diff --git a/src/dbus-path.h b/src/dbus-path.h index 15f58698..261d8451 100644 --- a/src/dbus-path.h +++ b/src/dbus-path.h @@ -26,7 +26,7 @@ #include "unit.h" -DBusHandlerResult bus_path_message_handler(Unit *u, DBusMessage *message); +DBusHandlerResult bus_path_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); extern const char bus_path_interface[]; diff --git a/src/dbus-service.c b/src/dbus-service.c index f70a7721..283932c5 100644 --- a/src/dbus-service.c +++ b/src/dbus-service.c @@ -58,7 +58,7 @@ const char bus_service_interface[] = BUS_SERVICE_INTERFACE; static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_type, service_type, ServiceType); static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_service_append_restart, service_restart, ServiceRestart); -DBusHandlerResult bus_service_message_handler(Unit *u, DBusMessage *message) { +DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *connection, DBusMessage *message) { const BusProperty properties[] = { BUS_UNIT_PROPERTIES, { "org.freedesktop.systemd1.Service", "Type", bus_service_append_type, "s", &u->service.type }, @@ -81,5 +81,5 @@ DBusHandlerResult bus_service_message_handler(Unit *u, DBusMessage *message) { { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, connection, message, INTROSPECTION, properties); } diff --git a/src/dbus-service.h b/src/dbus-service.h index ab1e02f3..cfbdab38 100644 --- a/src/dbus-service.h +++ b/src/dbus-service.h @@ -26,7 +26,7 @@ #include "unit.h" -DBusHandlerResult bus_service_message_handler(Unit *u, DBusMessage *message); +DBusHandlerResult bus_service_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); extern const char bus_service_interface[]; diff --git a/src/dbus-snapshot.c b/src/dbus-snapshot.c index 15e51f03..5ba5d7c8 100644 --- a/src/dbus-snapshot.c +++ b/src/dbus-snapshot.c @@ -39,7 +39,7 @@ const char bus_snapshot_interface[] = BUS_SNAPSHOT_INTERFACE; -DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusMessage *message) { +DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { const BusProperty properties[] = { BUS_UNIT_PROPERTIES, { "org.freedesktop.systemd1.Snapshot", "Cleanup", bus_property_append_bool, "b", &u->snapshot.cleanup }, @@ -59,10 +59,10 @@ DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusMessage *message) { goto oom; } else - return bus_default_message_handler(u->meta.manager, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); if (reply) { - if (!dbus_connection_send(u->meta.manager->api_bus, reply, NULL)) + if (!dbus_connection_send(c, reply, NULL)) goto oom; dbus_message_unref(reply); diff --git a/src/dbus-snapshot.h b/src/dbus-snapshot.h index bf5a4d4b..60b3720d 100644 --- a/src/dbus-snapshot.h +++ b/src/dbus-snapshot.h @@ -26,7 +26,7 @@ #include "unit.h" -DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusMessage *message); +DBusHandlerResult bus_snapshot_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); extern const char bus_snapshot_interface[]; diff --git a/src/dbus-socket.c b/src/dbus-socket.c index 426af2b4..a5474c9f 100644 --- a/src/dbus-socket.c +++ b/src/dbus-socket.c @@ -52,7 +52,7 @@ const char bus_socket_interface[] = BUS_SOCKET_INTERFACE; static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_socket_append_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only); -DBusHandlerResult bus_socket_message_handler(Unit *u, DBusMessage *message) { +DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { const BusProperty properties[] = { BUS_UNIT_PROPERTIES, { "org.freedesktop.systemd1.Socket", "BindIPv6Only", bus_socket_append_bind_ipv6_only, "s", &u->socket.bind_ipv6_only }, @@ -69,5 +69,5 @@ DBusHandlerResult bus_socket_message_handler(Unit *u, DBusMessage *message) { { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); } diff --git a/src/dbus-socket.h b/src/dbus-socket.h index ab063220..79a1546d 100644 --- a/src/dbus-socket.h +++ b/src/dbus-socket.h @@ -26,7 +26,7 @@ #include "unit.h" -DBusHandlerResult bus_socket_message_handler(Unit *u, DBusMessage *message); +DBusHandlerResult bus_socket_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); extern const char bus_socket_interface[]; diff --git a/src/dbus-swap.c b/src/dbus-swap.c index f6f8685d..676ec5cc 100644 --- a/src/dbus-swap.c +++ b/src/dbus-swap.c @@ -66,7 +66,7 @@ static int bus_swap_append_priority(Manager *m, DBusMessageIter *i, const char * return 0; } -DBusHandlerResult bus_swap_message_handler(Unit *u, DBusMessage *message) { +DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { const BusProperty properties[] = { BUS_UNIT_PROPERTIES, { "org.freedesktop.systemd1.Swap", "What", bus_property_append_string, "s", u->swap.what }, @@ -74,5 +74,5 @@ DBusHandlerResult bus_swap_message_handler(Unit *u, DBusMessage *message) { { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); } diff --git a/src/dbus-swap.h b/src/dbus-swap.h index cbd15919..a3d418c2 100644 --- a/src/dbus-swap.h +++ b/src/dbus-swap.h @@ -27,7 +27,7 @@ #include "unit.h" -DBusHandlerResult bus_swap_message_handler(Unit *u, DBusMessage *message); +DBusHandlerResult bus_swap_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); extern const char bus_swap_interface[]; diff --git a/src/dbus-target.c b/src/dbus-target.c index 45f0d31f..fb84430b 100644 --- a/src/dbus-target.c +++ b/src/dbus-target.c @@ -37,11 +37,11 @@ const char bus_target_interface[] = BUS_TARGET_INTERFACE; -DBusHandlerResult bus_target_message_handler(Unit *u, DBusMessage *message) { +DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { const BusProperty properties[] = { BUS_UNIT_PROPERTIES, { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); } diff --git a/src/dbus-target.h b/src/dbus-target.h index d118441a..af2dc62b 100644 --- a/src/dbus-target.h +++ b/src/dbus-target.h @@ -26,7 +26,7 @@ #include "unit.h" -DBusHandlerResult bus_target_message_handler(Unit *u, DBusMessage *message); +DBusHandlerResult bus_target_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); extern const char bus_target_interface[]; diff --git a/src/dbus-timer.c b/src/dbus-timer.c index d5729078..68bd8a44 100644 --- a/src/dbus-timer.c +++ b/src/dbus-timer.c @@ -41,12 +41,12 @@ const char bus_timer_interface[] = BUS_TIMER_INTERFACE; -DBusHandlerResult bus_timer_message_handler(Unit *u, DBusMessage *message) { +DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message) { const BusProperty properties[] = { BUS_UNIT_PROPERTIES, { "org.freedesktop.systemd1.Timer", "Unit", bus_property_append_string, "s", &u->timer.unit->meta.id }, { NULL, NULL, NULL, NULL, NULL } }; - return bus_default_message_handler(u->meta.manager, message, INTROSPECTION, properties); + return bus_default_message_handler(u->meta.manager, c, message, INTROSPECTION, properties); } diff --git a/src/dbus-timer.h b/src/dbus-timer.h index 250e8186..562d4498 100644 --- a/src/dbus-timer.h +++ b/src/dbus-timer.h @@ -26,7 +26,7 @@ #include "unit.h" -DBusHandlerResult bus_timer_message_handler(Unit *u, DBusMessage *message); +DBusHandlerResult bus_timer_message_handler(Unit *u, DBusConnection *c, DBusMessage *message); extern const char bus_timer_interface[]; diff --git a/src/dbus-unit.c b/src/dbus-unit.c index 8e35377d..17ca7bdd 100644 --- a/src/dbus-unit.c +++ b/src/dbus-unit.c @@ -255,7 +255,7 @@ int bus_unit_append_cgroups(Manager *m, DBusMessageIter *i, const char *property DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_unit_append_kill_mode, kill_mode, KillMode); -static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message) { +static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusConnection *connection, DBusMessage *message) { DBusMessage *reply = NULL; Manager *m = u->meta.manager; DBusError error; @@ -273,7 +273,7 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Unit", "Restart")) job_type = JOB_RESTART; else if (UNIT_VTABLE(u)->bus_message_handler) - return UNIT_VTABLE(u)->bus_message_handler(u, message); + return UNIT_VTABLE(u)->bus_message_handler(u, connection, message); else return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -284,20 +284,20 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message int r; if (job_type == JOB_START && u->meta.only_by_dependency) - return bus_send_error_reply(m, message, NULL, -EPERM); + return bus_send_error_reply(m, connection, message, NULL, -EPERM); if (!dbus_message_get_args( message, &error, DBUS_TYPE_STRING, &smode, DBUS_TYPE_INVALID)) - return bus_send_error_reply(m, message, &error, -EINVAL); + return bus_send_error_reply(m, connection, message, &error, -EINVAL); if ((mode = job_mode_from_string(smode)) == _JOB_MODE_INVALID) - return bus_send_error_reply(m, message, NULL, -EINVAL); + return bus_send_error_reply(m, connection, message, NULL, -EINVAL); if ((r = manager_add_job(m, job_type, u, mode, true, &j)) < 0) - return bus_send_error_reply(m, message, NULL, r); + return bus_send_error_reply(m, connection, message, NULL, r); if (!(reply = dbus_message_new_method_return(message))) goto oom; @@ -315,7 +315,7 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message free(path); if (reply) { - if (!dbus_connection_send(m->api_bus, reply, NULL)) + if (!dbus_connection_send(connection, reply, NULL)) goto oom; dbus_message_unref(reply); @@ -334,7 +334,7 @@ oom: return DBUS_HANDLER_RESULT_NEED_MEMORY; } -static DBusHandlerResult bus_unit_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { +static DBusHandlerResult bus_unit_message_handler(DBusConnection *connection, DBusMessage *message, void *data) { Manager *m = data; Unit *u; int r; @@ -356,10 +356,10 @@ static DBusHandlerResult bus_unit_message_handler(DBusConnection *connection, D if (r == -ENOENT) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - return bus_send_error_reply(m, message, NULL, r); + return bus_send_error_reply(m, connection, message, NULL, r); } - return bus_unit_message_dispatch(u, message); + return bus_unit_message_dispatch(u, connection, message); } const DBusObjectPathVTable bus_unit_vtable = { @@ -402,7 +402,7 @@ void bus_unit_send_change_signal(Unit *u) { goto oom; } - if (!dbus_connection_send(u->meta.manager->api_bus, m, NULL)) + if (bus_broadcast(u->meta.manager, m) < 0) goto oom; free(p); @@ -445,7 +445,7 @@ void bus_unit_send_removed_signal(Unit *u) { DBUS_TYPE_INVALID)) goto oom; - if (!dbus_connection_send(u->meta.manager->api_bus, m, NULL)) + if (bus_broadcast(u->meta.manager, m) < 0) goto oom; free(p); diff --git a/src/dbus.c b/src/dbus.c index a4e350c3..a34c7dc1 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -43,6 +43,8 @@ #include "dbus-timer.h" #include "dbus-path.h" +#define CONNECTIONS_MAX 52 + static const char bus_properties_interface[] = BUS_PROPERTIES_INTERFACE; static const char bus_introspectable_interface[] = BUS_INTROSPECTABLE_INTERFACE; @@ -66,33 +68,24 @@ const char *const bus_interface_table[] = { }; static const char *error_to_dbus(int error); +static void bus_done_api(Manager *m); +static void bus_done_system(Manager *m); +static void bus_done_private(Manager *m); -static void api_bus_dispatch_status(DBusConnection *bus, DBusDispatchStatus status, void *data) { - Manager *m = data; - - assert(bus); - assert(m); - - if (!m->api_bus) - return; - - assert(m->api_bus == bus); - - m->request_api_bus_dispatch = status != DBUS_DISPATCH_COMPLETE; -} - -static void system_bus_dispatch_status(DBusConnection *bus, DBusDispatchStatus status, void *data) { +static void bus_dispatch_status(DBusConnection *bus, DBusDispatchStatus status, void *data) { Manager *m = data; assert(bus); assert(m); - if (!m->system_bus) - return; - - assert(m->system_bus == bus); + /* We maintain two sets, one for those connections where we + * requested a dispatch, and another where we didn't. And then, + * we move the connections between the two sets. */ - m->request_system_bus_dispatch = status != DBUS_DISPATCH_COMPLETE; + if (status == DBUS_DISPATCH_COMPLETE) + set_move_one(m->bus_connections, m->bus_connections_for_dispatch, bus); + else + set_move_one(m->bus_connections_for_dispatch, m->bus_connections, bus); } static uint32_t bus_flags_to_events(DBusWatch *bus_watch) { @@ -472,7 +465,30 @@ static DBusHandlerResult system_bus_message_filter(DBusConnection *connection, D return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } +static DBusHandlerResult private_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) { + Manager *m = data; + + assert(connection); + assert(message); + assert(m); + + /* log_debug("Got D-Bus request: %s.%s() on %s", */ + /* dbus_message_get_interface(message), */ + /* dbus_message_get_member(message), */ + /* dbus_message_get_path(message)); */ + + if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) { + set_remove(m->bus_connections, connection); + set_remove(m->bus_connections_for_dispatch, connection); + dbus_connection_unref(connection); + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + unsigned bus_dispatch(Manager *m) { + DBusConnection *c; + assert(m); if (m->queued_message) { @@ -480,23 +496,17 @@ unsigned bus_dispatch(Manager *m) { * dispatch any D-Bus messages, so that we won't end * up wanting to queue another message. */ - if (!dbus_connection_send(m->api_bus, m->queued_message, NULL)) - return 0; + if (m->api_bus) + if (!dbus_connection_send(m->api_bus, m->queued_message, NULL)) + return 0; dbus_message_unref(m->queued_message); m->queued_message = NULL; } - if (m->request_api_bus_dispatch) { - if (dbus_connection_dispatch(m->api_bus) == DBUS_DISPATCH_COMPLETE) - m->request_api_bus_dispatch = false; - - return 1; - } - - if (m->request_system_bus_dispatch) { - if (dbus_connection_dispatch(m->system_bus) == DBUS_DISPATCH_COMPLETE) - m->request_system_bus_dispatch = false; + if ((c = set_first(m->bus_connections_for_dispatch))) { + if (dbus_connection_dispatch(c) == DBUS_DISPATCH_COMPLETE) + set_move_one(m->bus_connections, m->bus_connections_for_dispatch, c); return 1; } @@ -689,13 +699,57 @@ static int bus_setup_loop(Manager *m, DBusConnection *bus) { dbus_connection_set_exit_on_disconnect(bus, FALSE); if (!dbus_connection_set_watch_functions(bus, bus_add_watch, bus_remove_watch, bus_toggle_watch, m, NULL) || - !dbus_connection_set_timeout_functions(bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL)) + !dbus_connection_set_timeout_functions(bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL)) { + log_error("Not enough memory"); return -ENOMEM; + } + if (set_put(m->bus_connections_for_dispatch, bus) < 0) { + log_error("Not enough memory"); + return -ENOMEM; + } + + dbus_connection_set_dispatch_status_function(bus, bus_dispatch_status, m, NULL); return 0; } -int bus_init_system(Manager *m) { +static dbus_bool_t allow_only_root(DBusConnection *connection, unsigned long uid, void *data) { + return uid == 0; +} + +static void bus_new_connection( + DBusServer *server, + DBusConnection *new_connection, + void *data) { + + Manager *m = data; + + assert(m); + + if (set_size(m->bus_connections) >= CONNECTIONS_MAX) { + log_error("Too many concurrent connections."); + return; + } + + dbus_connection_set_unix_user_function(new_connection, allow_only_root, NULL, NULL); + + if (bus_setup_loop(m, new_connection) < 0) + return; + + if (!dbus_connection_register_object_path(new_connection, "/org/freedesktop/systemd1", &bus_manager_vtable, m) || + !dbus_connection_register_fallback(new_connection, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) || + !dbus_connection_register_fallback(new_connection, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) || + !dbus_connection_add_filter(new_connection, private_bus_message_filter, m, NULL)) { + log_error("Not enough memory."); + return; + } + + log_debug("Accepted connection on private bus."); + + dbus_connection_ref(new_connection); +} + +static int bus_init_system(Manager *m) { DBusError error; char *id; int r; @@ -712,22 +766,18 @@ int bus_init_system(Manager *m) { else { if (!(m->system_bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error))) { log_debug("Failed to get system D-Bus connection, retrying later: %s", error.message); - dbus_error_free(&error); - return 0; + r = 0; + goto fail; } - dbus_connection_set_dispatch_status_function(m->system_bus, system_bus_dispatch_status, m, NULL); - m->request_system_bus_dispatch = true; - - if ((r = bus_setup_loop(m, m->system_bus)) < 0) { - bus_done_system(m); - return r; - } + if ((r = bus_setup_loop(m, m->system_bus)) < 0) + goto fail; } if (!dbus_connection_add_filter(m->system_bus, system_bus_message_filter, m, NULL)) { - bus_done_system(m); - return -ENOMEM; + log_error("Not enough memory"); + r = -EIO; + goto fail; } dbus_bus_add_match(m->system_bus, @@ -739,9 +789,8 @@ int bus_init_system(Manager *m) { if (dbus_error_is_set(&error)) { log_error("Failed to register match: %s", error.message); - dbus_error_free(&error); - bus_done_system(m); - return -ENOMEM; + r = -EIO; + goto fail; } log_debug("Successfully connected to system D-Bus bus %s as %s", @@ -750,9 +799,15 @@ int bus_init_system(Manager *m) { dbus_free(id); return 0; + +fail: + bus_done_system(m); + dbus_error_free(&error); + + return r; } -int bus_init_api(Manager *m) { +static int bus_init_api(Manager *m) { DBusError error; char *id; int r; @@ -764,34 +819,26 @@ int bus_init_api(Manager *m) { if (m->api_bus) return 0; - if (m->name_data_slot < 0) - if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot)) - return -ENOMEM; - if (m->running_as != MANAGER_SESSION && m->system_bus) m->api_bus = m->system_bus; else { if (!(m->api_bus = dbus_bus_get_private(m->running_as == MANAGER_SESSION ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &error))) { log_debug("Failed to get API D-Bus connection, retrying later: %s", error.message); - dbus_error_free(&error); - return 0; + r = 0; + goto fail; } - dbus_connection_set_dispatch_status_function(m->api_bus, api_bus_dispatch_status, m, NULL); - m->request_api_bus_dispatch = true; - - if ((r = bus_setup_loop(m, m->api_bus)) < 0) { - bus_done_api(m); - return r; - } + if ((r = bus_setup_loop(m, m->api_bus)) < 0) + goto fail; } if (!dbus_connection_register_object_path(m->api_bus, "/org/freedesktop/systemd1", &bus_manager_vtable, m) || !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) || !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) || !dbus_connection_add_filter(m->api_bus, api_bus_message_filter, m, NULL)) { - bus_done_api(m); - return -ENOMEM; + log_error("Not enough memory"); + r = -ENOMEM; + goto fail; } /* Get NameOwnerChange messages */ @@ -805,9 +852,8 @@ int bus_init_api(Manager *m) { if (dbus_error_is_set(&error)) { log_error("Failed to register match: %s", error.message); - dbus_error_free(&error); - bus_done_api(m); - return -ENOMEM; + r = -EIO; + goto fail; } /* Get activation requests */ @@ -821,20 +867,15 @@ int bus_init_api(Manager *m) { if (dbus_error_is_set(&error)) { log_error("Failed to register match: %s", error.message); - dbus_error_free(&error); - bus_done_api(m); - return -ENOMEM; + r = -EIO; + goto fail; } - if ((r = request_name(m)) < 0) { - bus_done_api(m); - return r; - } + if ((r = request_name(m)) < 0) + goto fail; - if ((r = query_name_list(m)) < 0) { - bus_done_api(m); - return r; - } + if ((r = query_name_list(m)) < 0) + goto fail; log_debug("Successfully connected to API D-Bus bus %s as %s", strnull((id = dbus_connection_get_server_id(m->api_bus))), @@ -842,23 +883,106 @@ int bus_init_api(Manager *m) { dbus_free(id); if (!m->subscribed) - if (!(m->subscribed = set_new(string_hash_func, string_compare_func))) + if (!(m->subscribed = set_new(string_hash_func, string_compare_func))) { + log_error("Not enough memory"); + r = -ENOMEM; + goto fail; + } + + return 0; + +fail: + bus_done_api(m); + dbus_error_free(&error); + + return r; +} + +static int bus_init_private(Manager *m) { + DBusError error; + int r; + const char *const external_only[] = { + "EXTERNAL", + NULL + }; + + assert(m); + + dbus_error_init(&error); + + if (m->private_bus) + return 0; + + /* We want the private bus only when running as init */ + if (m->running_as != MANAGER_INIT) + return 0; + + if (!(m->private_bus = dbus_server_listen("unix:abstract=/org/freedesktop/systemd1/private", &error))) { + log_error("Failed to create private D-Bus server: %s", error.message); + r = -EIO; + goto fail; + } + + if (!dbus_server_set_auth_mechanisms(m->private_bus, (const char**) external_only) || + !dbus_server_set_watch_functions(m->private_bus, bus_add_watch, bus_remove_watch, bus_toggle_watch, m, NULL) || + !dbus_server_set_timeout_functions(m->private_bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL)) { + log_error("Not enough memory"); + r = -ENOMEM; + goto fail; + } + + dbus_server_set_new_connection_function(m->private_bus, bus_new_connection, m, NULL); + + log_debug("Successfully create private D-Bus server."); + + return 0; + +fail: + bus_done_private(m); + dbus_error_free(&error); + + return r; +} + +int bus_init(Manager *m) { + int r; + + if (set_ensure_allocated(&m->bus_connections, trivial_hash_func, trivial_compare_func) < 0 || + set_ensure_allocated(&m->bus_connections_for_dispatch, trivial_hash_func, trivial_compare_func) < 0) { + log_error("Not enough memory"); + return -ENOMEM; + } + + if (m->name_data_slot < 0) + if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot)) { + log_error("Not enough memory"); return -ENOMEM; + } + + if ((r = bus_init_system(m)) < 0 || + (r = bus_init_api(m)) < 0 || + (r = bus_init_private(m)) < 0) + return r; return 0; } -void bus_done_api(Manager *m) { +static void shutdown_connection(DBusConnection *c) { + dbus_connection_set_dispatch_status_function(c, NULL, NULL, NULL); + dbus_connection_flush(c); + dbus_connection_close(c); + dbus_connection_unref(c); +} + +static void bus_done_api(Manager *m) { assert(m); if (m->api_bus) { if (m->system_bus == m->api_bus) m->system_bus = NULL; - dbus_connection_set_dispatch_status_function(m->api_bus, NULL, NULL, NULL); - dbus_connection_flush(m->api_bus); - dbus_connection_close(m->api_bus); - dbus_connection_unref(m->api_bus); + set_remove(m->bus_connections, m->api_bus); + shutdown_connection(m->api_bus); m->api_bus = NULL; } @@ -872,30 +996,54 @@ void bus_done_api(Manager *m) { m->subscribed = NULL; } - if (m->name_data_slot >= 0) - dbus_pending_call_free_data_slot(&m->name_data_slot); - if (m->queued_message) { dbus_message_unref(m->queued_message); m->queued_message = NULL; } } -void bus_done_system(Manager *m) { +static void bus_done_system(Manager *m) { assert(m); if (m->system_bus == m->api_bus) bus_done_api(m); if (m->system_bus) { - dbus_connection_set_dispatch_status_function(m->system_bus, NULL, NULL, NULL); - dbus_connection_flush(m->system_bus); - dbus_connection_close(m->system_bus); - dbus_connection_unref(m->system_bus); + set_remove(m->bus_connections, m->system_bus); + shutdown_connection(m->system_bus); m->system_bus = NULL; } } +static void bus_done_private(Manager *m) { + + if (m->private_bus) { + dbus_server_disconnect(m->private_bus); + dbus_server_unref(m->private_bus); + m->private_bus = NULL; + } +} + +void bus_done(Manager *m) { + DBusConnection *c; + + bus_done_api(m); + bus_done_system(m); + bus_done_private(m); + + while ((c = set_steal_first(m->bus_connections))) + shutdown_connection(c); + + while ((c = set_steal_first(m->bus_connections_for_dispatch))) + shutdown_connection(c); + + set_free(m->bus_connections); + set_free(m->bus_connections_for_dispatch); + + if (m->name_data_slot >= 0) + dbus_pending_call_free_data_slot(&m->name_data_slot); +} + static void query_pid_pending_cb(DBusPendingCall *pending, void *userdata) { Manager *m = userdata; DBusMessage *reply; @@ -992,7 +1140,7 @@ oom: return -ENOMEM; } -DBusHandlerResult bus_default_message_handler(Manager *m, DBusMessage *message, const char*introspection, const BusProperty *properties) { +DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBusMessage *message, const char*introspection, const BusProperty *properties) { DBusError error; DBusMessage *reply = NULL; int r; @@ -1020,7 +1168,7 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusMessage *message, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID)) - return bus_send_error_reply(m, message, &error, -EINVAL); + return bus_send_error_reply(m, c, message, &error, -EINVAL); for (p = properties; p->property; p++) if (streq(p->interface, interface) && streq(p->property, property)) @@ -1043,7 +1191,7 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusMessage *message, goto oom; dbus_message_unref(reply); - return bus_send_error_reply(m, message, NULL, r); + return bus_send_error_reply(m, c, message, NULL, r); } if (!dbus_message_iter_close_container(&iter, &sub)) @@ -1060,7 +1208,7 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusMessage *message, &error, DBUS_TYPE_STRING, &interface, DBUS_TYPE_INVALID)) - return bus_send_error_reply(m, message, &error, -EINVAL); + return bus_send_error_reply(m, c, message, &error, -EINVAL); if (!(reply = dbus_message_new_method_return(message))) goto oom; @@ -1085,7 +1233,7 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusMessage *message, goto oom; dbus_message_unref(reply); - return bus_send_error_reply(m, message, NULL, r); + return bus_send_error_reply(m, c, message, NULL, r); } if (!dbus_message_iter_close_container(&sub2, &sub3) || @@ -1100,7 +1248,7 @@ DBusHandlerResult bus_default_message_handler(Manager *m, DBusMessage *message, } if (reply) { - if (!dbus_connection_send(m->api_bus, reply, NULL)) + if (!dbus_connection_send(c, reply, NULL)) goto oom; dbus_message_unref(reply); @@ -1156,7 +1304,7 @@ static const char *error_to_dbus(int error) { return DBUS_ERROR_FAILED; } -DBusHandlerResult bus_send_error_reply(Manager *m, DBusMessage *message, DBusError *bus_error, int error) { +DBusHandlerResult bus_send_error_reply(Manager *m, DBusConnection *c, DBusMessage *message, DBusError *bus_error, int error) { DBusMessage *reply = NULL; const char *name, *text; @@ -1171,7 +1319,7 @@ DBusHandlerResult bus_send_error_reply(Manager *m, DBusMessage *message, DBusErr if (!(reply = dbus_message_new_error(message, name, text))) goto oom; - if (!dbus_connection_send(m->api_bus, reply, NULL)) + if (!dbus_connection_send(c, reply, NULL)) goto oom; dbus_message_unref(reply); @@ -1191,6 +1339,25 @@ oom: return DBUS_HANDLER_RESULT_NEED_MEMORY; } +int bus_broadcast(Manager *m, DBusMessage *message) { + bool oom = false; + Iterator i; + DBusConnection *c; + + assert(m); + assert(message); + + SET_FOREACH(c, m->bus_connections_for_dispatch, i) + if (c != m->system_bus || m->running_as != MANAGER_SESSION) + oom = !dbus_connection_send(c, message, NULL); + + SET_FOREACH(c, m->bus_connections, i) + if (c != m->system_bus || m->running_as != MANAGER_SESSION) + oom = !dbus_connection_send(c, message, NULL); + + return oom ? -ENOMEM : 0; +} + int bus_property_append_string(Manager *m, DBusMessageIter *i, const char *property, void *data) { const char *t = data; diff --git a/src/dbus.h b/src/dbus.h index 264bdff6..af837f28 100644 --- a/src/dbus.h +++ b/src/dbus.h @@ -56,10 +56,8 @@ typedef struct BusProperty { " \n" \ " \n" -int bus_init_system(Manager *m); -int bus_init_api(Manager *m); -void bus_done_system(Manager *m); -void bus_done_api(Manager *m); +int bus_init(Manager *m); +void bus_done(Manager *m); unsigned bus_dispatch(Manager *m); @@ -68,9 +66,10 @@ void bus_timeout_event(Manager *m, Watch *w, int events); int bus_query_pid(Manager *m, const char *name); -DBusHandlerResult bus_default_message_handler(Manager *m, DBusMessage *message, const char* introspection, const BusProperty *properties); +DBusHandlerResult bus_default_message_handler(Manager *m, DBusConnection *c, DBusMessage *message, const char* introspection, const BusProperty *properties); +DBusHandlerResult bus_send_error_reply(Manager *m, DBusConnection *c, DBusMessage *message, DBusError *bus_error, int error); -DBusHandlerResult bus_send_error_reply(Manager *m, DBusMessage *message, DBusError *bus_error, int error); +int bus_broadcast(Manager *m, DBusMessage *message); int bus_property_append_string(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_property_append_strv(Manager *m, DBusMessageIter *i, const char *property, void *data); diff --git a/src/manager.c b/src/manager.c index dee6109c..456241f6 100644 --- a/src/manager.c +++ b/src/manager.c @@ -243,8 +243,7 @@ int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) { goto fail; /* Try to connect to the busses, if possible. */ - if ((r = bus_init_system(m)) < 0 || - (r = bus_init_api(m)) < 0) + if ((r = bus_init(m)) < 0) goto fail; if (asprintf(&p, "%s/%s", m->cgroup_mount_point, m->cgroup_hierarchy) < 0) { @@ -424,8 +423,7 @@ void manager_free(Manager *m) { * around */ manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE); - bus_done_api(m); - bus_done_system(m); + bus_done(m); hashmap_free(m->units); hashmap_free(m->jobs); @@ -1826,8 +1824,7 @@ static int manager_process_signal_fd(Manager *m) { if (!u || UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) { log_info("Trying to reconnect to bus..."); - bus_init_system(m); - bus_init_api(m); + bus_init(m); } if (!u || !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u))) { diff --git a/src/manager.h b/src/manager.h index 6c3434e5..2a04bc7d 100644 --- a/src/manager.h +++ b/src/manager.h @@ -154,6 +154,9 @@ struct Manager { /* Data specific to the D-Bus subsystem */ DBusConnection *api_bus, *system_bus; + DBusServer *private_bus; + Set *bus_connections, *bus_connections_for_dispatch; + Set *subscribed; DBusMessage *queued_message; /* This is used during reloading: * before the reload we queue the @@ -188,9 +191,6 @@ struct Manager { bool dispatching_run_queue:1; bool dispatching_dbus_queue:1; - bool request_api_bus_dispatch:1; - bool request_system_bus_dispatch:1; - bool utmp_reboot_written:1; bool confirm_spawn:1; diff --git a/src/systemctl.c b/src/systemctl.c index 444ddf37..429d6a7a 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -1751,7 +1751,6 @@ static int shutdown_parse_argv(int argc, char *argv[]) { optind = argc; return 1; - } static int telinit_parse_argv(int argc, char *argv[]) { @@ -2262,7 +2261,13 @@ int main(int argc, char*argv[]) { goto finish; } - if ((bus = dbus_bus_get(arg_session ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &error))) + /* If we are root, then let's not go via the bus */ + if (geteuid() == 0 && !arg_session) + bus = dbus_connection_open("unix:abstract=/org/freedesktop/systemd1/private", &error); + else + bus = dbus_bus_get(arg_session ? DBUS_BUS_SESSION : DBUS_BUS_SYSTEM, &error); + + if (bus) dbus_connection_set_exit_on_disconnect(bus, FALSE); switch (arg_action) { diff --git a/src/unit.c b/src/unit.c index 327444bb..c12c2a7d 100644 --- a/src/unit.c +++ b/src/unit.c @@ -1030,8 +1030,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { /* The bus just might have become available, * hence try to connect to it, if we aren't * yet connected. */ - bus_init_system(u->meta.manager); - bus_init_api(u->meta.manager); + bus_init(u->meta.manager); } if (unit_has_name(u, SPECIAL_SYSLOG_SERVICE)) diff --git a/src/unit.h b/src/unit.h index 3397d472..c5be8589 100644 --- a/src/unit.h +++ b/src/unit.h @@ -296,7 +296,7 @@ struct UnitVTable { void (*bus_query_pid_done)(Unit *u, const char *name, pid_t pid); /* Called for each message received on the bus */ - DBusHandlerResult (*bus_message_handler)(Unit *u, DBusMessage *message); + DBusHandlerResult (*bus_message_handler)(Unit *u, DBusConnection *c, DBusMessage *message); /* This is called for each unit type and should be used to * enumerate existing devices and load them. However, -- 2.39.5