X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fdbus.c;h=c2097a4dbffb629c1274d1ed1915623b11d05141;hp=1bc83a2c2aa98e1423cd91922f6506e156e3e7de;hb=4ad490007b70e6ac18d3cb04fa2ed92eba1451fa;hpb=d2e54fae5ca7a0f71b5ac8b356a589ff0a09ea0a diff --git a/src/core/dbus.c b/src/core/dbus.c index 1bc83a2c2..c2097a4db 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -28,8 +28,8 @@ #include "dbus.h" #include "log.h" #include "strv.h" -#include "cgroup.h" #include "mkdir.h" +#include "missing.h" #include "dbus-unit.h" #include "dbus-job.h" #include "dbus-manager.h" @@ -47,7 +47,7 @@ #include "special.h" #include "dbus-common.h" -#define CONNECTIONS_MAX 52 +#define CONNECTIONS_MAX 512 /* Well-known address (http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-types) */ #define DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=/var/run/dbus/system_bus_socket" @@ -202,13 +202,11 @@ static void bus_toggle_watch(DBusWatch *bus_watch, void *data) { } static int bus_timeout_arm(Manager *m, Watch *w) { - struct itimerspec its; + struct itimerspec its = {}; assert(m); assert(w); - zero(its); - if (dbus_timeout_get_enabled(w->data.bus_timeout)) { timespec_store(&its.it_value, dbus_timeout_get_interval(w->data.bus_timeout) * USEC_PER_MSEC); its.it_interval = its.it_value; @@ -364,8 +362,8 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBus log_debug("Got D-Bus activation request for %s", name); - if (manager_unit_pending_inactive(m, SPECIAL_DBUS_SERVICE) || - manager_unit_pending_inactive(m, SPECIAL_DBUS_SOCKET)) { + if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) || + manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET)) { r = -EADDRNOTAVAIL; dbus_set_error(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down."); } else { @@ -405,7 +403,7 @@ static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBus dbus_error_free(&error); if (reply) { - if (!dbus_connection_send(connection, reply, NULL)) + if (!bus_maybe_send_reply(connection, message, reply)) goto oom; dbus_message_unref(reply); @@ -444,7 +442,7 @@ static DBusHandlerResult system_bus_message_filter(DBusConnection *connection, D log_debug("System D-Bus connection terminated."); bus_done_system(m); - } else if (m->running_as != MANAGER_SYSTEM && + } else if (m->running_as != SYSTEMD_SYSTEM && dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { const char *cgroup; @@ -454,7 +452,7 @@ static DBusHandlerResult system_bus_message_filter(DBusConnection *connection, D DBUS_TYPE_INVALID)) log_error("Failed to parse Released message: %s", bus_error_message(&error)); else - cgroup_notify_empty(m, cgroup); + manager_notify_cgroup_empty(m, cgroup); } dbus_error_free(&error); @@ -480,7 +478,7 @@ static DBusHandlerResult private_bus_message_filter(DBusConnection *connection, if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) shutdown_connection(m, connection); - else if (m->running_as == MANAGER_SYSTEM && + else if (m->running_as == SYSTEMD_SYSTEM && dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) { const char *cgroup; @@ -490,7 +488,7 @@ static DBusHandlerResult private_bus_message_filter(DBusConnection *connection, DBUS_TYPE_INVALID)) log_error("Failed to parse Released message: %s", bus_error_message(&error)); else - cgroup_notify_empty(m, cgroup); + manager_notify_cgroup_empty(m, cgroup); /* Forward the message to the system bus, so that user * instances are notified as well */ @@ -723,15 +721,11 @@ 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)) { - log_error("Not enough memory"); - return -ENOMEM; - } + !dbus_connection_set_timeout_functions(bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL)) + return log_oom(); - if (set_put(m->bus_connections_for_dispatch, bus) < 0) { - log_error("Not enough memory"); - return -ENOMEM; - } + if (set_put(m->bus_connections_for_dispatch, bus) < 0) + return log_oom(); dbus_connection_set_dispatch_status_function(bus, bus_dispatch_status, m, NULL); return 0; @@ -764,7 +758,7 @@ static void bus_new_connection( !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."); + log_oom(); return; } @@ -776,12 +770,10 @@ static void bus_new_connection( static int init_registered_system_bus(Manager *m) { char *id; - if (!dbus_connection_add_filter(m->system_bus, system_bus_message_filter, m, NULL)) { - log_error("Not enough memory"); - return -ENOMEM; - } + if (!dbus_connection_add_filter(m->system_bus, system_bus_message_filter, m, NULL)) + return log_oom(); - if (m->running_as != MANAGER_SYSTEM) { + if (m->running_as != SYSTEMD_SYSTEM) { DBusError error; dbus_error_init(&error); @@ -814,10 +806,8 @@ static int init_registered_api_bus(Manager *m) { 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)) { - log_error("Not enough memory"); - return -ENOMEM; - } + !dbus_connection_add_filter(m->api_bus, api_bus_message_filter, m, NULL)) + return log_oom(); /* Get NameOwnerChange messages */ dbus_bus_add_match(m->api_bus, @@ -845,7 +835,7 @@ static int init_registered_api_bus(Manager *m) { if (r < 0) return r; - if (m->running_as == MANAGER_USER) { + if (m->running_as == SYSTEMD_USER) { char *id; log_debug("Successfully connected to API D-Bus bus %s as %s", strnull((id = dbus_connection_get_server_id(m->api_bus))), @@ -896,7 +886,7 @@ static void bus_register_cb(DBusPendingCall *pending, void *userdata) { if (conn == &m->system_bus) { r = init_registered_system_bus(m); - if (r == 0 && m->running_as == MANAGER_SYSTEM) + if (r == 0 && m->running_as == SYSTEMD_SYSTEM) r = init_registered_api_bus(m); } else r = init_registered_api_bus(m); @@ -963,12 +953,12 @@ static DBusConnection* manager_bus_connect_private(Manager *m, DBusBusType type) switch (type) { case DBUS_BUS_SYSTEM: - address = getenv("DBUS_SYSTEM_BUS_ADDRESS"); + address = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS"); if (!address || !address[0]) address = DBUS_SYSTEM_BUS_DEFAULT_ADDRESS; break; case DBUS_BUS_SESSION: - address = getenv("DBUS_SESSION_BUS_ADDRESS"); + address = secure_getenv("DBUS_SESSION_BUS_ADDRESS"); if (!address || !address[0]) address = DBUS_SESSION_BUS_DEFAULT_ADDRESS; break; @@ -985,9 +975,8 @@ static DBusConnection* manager_bus_connect_private(Manager *m, DBusBusType type) } return connection; + fail: - if (connection) - dbus_connection_close(connection); dbus_error_free(&error); return NULL; } @@ -1026,7 +1015,7 @@ static int bus_init_api(Manager *m) { if (m->api_bus) return 0; - if (m->running_as == MANAGER_SYSTEM) { + if (m->running_as == SYSTEMD_SYSTEM) { m->api_bus = m->system_bus; /* In this mode there is no distinct connection to the API bus, * the API is published on the system bus. @@ -1061,7 +1050,7 @@ fail: static int bus_init_private(Manager *m) { DBusError error; int r; - const char *const external_only[] = { + static const char *const external_only[] = { "EXTERNAL", NULL }; @@ -1073,7 +1062,7 @@ static int bus_init_private(Manager *m) { if (m->private_bus) return 0; - if (m->running_as == MANAGER_SYSTEM) { + if (m->running_as == SYSTEMD_SYSTEM) { /* We want the private bus only when running as init */ if (getpid() != 1) @@ -1084,19 +1073,33 @@ static int bus_init_private(Manager *m) { } else { const char *e; char *p; + char *escaped; - e = getenv("XDG_RUNTIME_DIR"); + e = secure_getenv("XDG_RUNTIME_DIR"); if (!e) return 0; - if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0) { - log_error("Not enough memory"); - r = -ENOMEM; + if (asprintf(&p, "%s/systemd/private", e) < 0) { + r = log_oom(); + goto fail; + } + + mkdir_parents_label(p, 0755); + unlink(p); + free(p); + + escaped = dbus_address_escape_value(e); + if (!escaped) { + r = log_oom(); goto fail; } + if (asprintf(&p, "unix:path=%s/systemd/private", escaped) < 0) { + dbus_free(escaped); + r = log_oom(); + goto fail; + } + dbus_free(escaped); - mkdir_parents_label(p+10, 0755); - unlink(p+10); m->private_bus = dbus_server_listen(p, &error); free(p); } @@ -1110,8 +1113,7 @@ static int bus_init_private(Manager *m) { 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; + r = log_oom(); goto fail; } @@ -1158,8 +1160,7 @@ int bus_init(Manager *m, bool try_bus_connect) { return 0; oom: - log_error("Not enough memory"); - return -ENOMEM; + return log_oom(); } static void shutdown_connection(Manager *m, DBusConnection *c) { @@ -1200,7 +1201,7 @@ static void shutdown_connection(Manager *m, DBusConnection *c) { dbus_connection_set_dispatch_status_function(c, NULL, NULL, NULL); /* system manager cannot afford to block on DBus */ - if (m->running_as != MANAGER_SYSTEM) + if (m->running_as != SYSTEMD_SYSTEM) dbus_connection_flush(c); dbus_connection_close(c); dbus_connection_unref(c); @@ -1210,7 +1211,7 @@ static void bus_done_api(Manager *m) { if (!m->api_bus) return; - if (m->running_as == MANAGER_USER) + if (m->running_as == SYSTEMD_USER) shutdown_connection(m, m->api_bus); m->api_bus = NULL; @@ -1225,7 +1226,7 @@ static void bus_done_system(Manager *m) { if (!m->system_bus) return; - if (m->running_as == MANAGER_SYSTEM) + if (m->running_as == SYSTEMD_SYSTEM) bus_done_api(m); shutdown_connection(m, m->system_bus); @@ -1372,11 +1373,11 @@ int bus_broadcast(Manager *m, DBusMessage *message) { assert(message); SET_FOREACH(c, m->bus_connections_for_dispatch, i) - if (c != m->system_bus || m->running_as == MANAGER_SYSTEM) + if (c != m->system_bus || m->running_as == SYSTEMD_SYSTEM) oom = !dbus_connection_send(c, message, NULL); SET_FOREACH(c, m->bus_connections, i) - if (c != m->system_bus || m->running_as == MANAGER_SYSTEM) + if (c != m->system_bus || m->running_as == SYSTEMD_SYSTEM) oom = !dbus_connection_send(c, message, NULL); return oom ? -ENOMEM : 0; @@ -1447,6 +1448,8 @@ int bus_fdset_add_all(Manager *m, FDSet *fds) { void bus_broadcast_finished( Manager *m, + usec_t firmware_usec, + usec_t loader_usec, usec_t kernel_usec, usec_t initrd_usec, usec_t userspace_usec, @@ -1458,24 +1461,26 @@ void bus_broadcast_finished( message = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished"); if (!message) { - log_error("Out of memory."); + log_oom(); return; } assert_cc(sizeof(usec_t) == sizeof(uint64_t)); if (!dbus_message_append_args(message, + DBUS_TYPE_UINT64, &firmware_usec, + DBUS_TYPE_UINT64, &loader_usec, DBUS_TYPE_UINT64, &kernel_usec, DBUS_TYPE_UINT64, &initrd_usec, DBUS_TYPE_UINT64, &userspace_usec, DBUS_TYPE_UINT64, &total_usec, DBUS_TYPE_INVALID)) { - log_error("Out of memory."); + log_oom(); goto finish; } if (bus_broadcast(m, message) < 0) { - log_error("Out of memory."); + log_oom(); goto finish; }