X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fdbus.c;h=b0ae3e1ae7fd5975d796b1123cd460cfb4b9bedd;hp=67ab1ae7f70ba85bf8a3e134fa9433ff7a06d2b1;hb=bd4b5df2cb253f130ecdac604e865e3f832c316a;hpb=b92bea5d2a9481de69bb627a7b442a9f58fca43d diff --git a/src/core/dbus.c b/src/core/dbus.c index 67ab1ae7f..b0ae3e1ae 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -28,7 +28,6 @@ #include "dbus.h" #include "log.h" #include "strv.h" -#include "cgroup.h" #include "mkdir.h" #include "missing.h" #include "dbus-unit.h" @@ -48,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" @@ -363,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 { @@ -453,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); @@ -489,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 */ @@ -769,7 +768,7 @@ static void bus_new_connection( } static int init_registered_system_bus(Manager *m) { - char *id; + char *id = NULL; if (!dbus_connection_add_filter(m->system_bus, system_bus_message_filter, m, NULL)) return log_oom(); @@ -837,7 +836,8 @@ static int init_registered_api_bus(Manager *m) { return r; if (m->running_as == SYSTEMD_USER) { - char *id; + char *id = NULL; + log_debug("Successfully connected to API D-Bus bus %s as %s", strnull((id = dbus_connection_get_server_id(m->api_bus))), strnull(dbus_bus_get_unique_name(m->api_bus))); @@ -1136,19 +1136,19 @@ int bus_init(Manager *m, bool try_bus_connect) { 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) - goto oom; + return log_oom(); if (m->name_data_slot < 0) if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot)) - goto oom; + return log_oom(); if (m->conn_data_slot < 0) if (!dbus_pending_call_allocate_data_slot(&m->conn_data_slot)) - goto oom; + return log_oom(); if (m->subscribed_data_slot < 0) if (!dbus_connection_allocate_data_slot(&m->subscribed_data_slot)) - goto oom; + return log_oom(); if (try_bus_connect) { if ((r = bus_init_system(m)) < 0 || @@ -1156,16 +1156,14 @@ int bus_init(Manager *m, bool try_bus_connect) { return r; } - if ((r = bus_init_private(m)) < 0) + r = bus_init_private(m); + if (r < 0) return r; return 0; -oom: - return log_oom(); } static void shutdown_connection(Manager *m, DBusConnection *c) { - Set *s; Job *j; Iterator i; @@ -1173,7 +1171,7 @@ static void shutdown_connection(Manager *m, DBusConnection *c) { JobBusClient *cl, *nextcl; LIST_FOREACH_SAFE(client, cl, nextcl, j->bus_client_list) { if (cl->bus == c) { - LIST_REMOVE(JobBusClient, client, j->bus_client_list, cl); + LIST_REMOVE(client, j->bus_client_list, cl); free(cl); } } @@ -1181,15 +1179,7 @@ static void shutdown_connection(Manager *m, DBusConnection *c) { set_remove(m->bus_connections, c); set_remove(m->bus_connections_for_dispatch, c); - - if ((s = BUS_CONNECTION_SUBSCRIBED(m, c))) { - char *t; - - while ((t = set_steal_first(s))) - free(t); - - set_free(s); - } + set_free_free(BUS_CONNECTION_SUBSCRIBED(m, c)); if (m->queued_message_connection == c) { m->queued_message_connection = NULL; @@ -1260,10 +1250,10 @@ void bus_done(Manager *m) { set_free(m->bus_connections_for_dispatch); if (m->name_data_slot >= 0) - dbus_pending_call_free_data_slot(&m->name_data_slot); + dbus_pending_call_free_data_slot(&m->name_data_slot); if (m->conn_data_slot >= 0) - dbus_pending_call_free_data_slot(&m->conn_data_slot); + dbus_pending_call_free_data_slot(&m->conn_data_slot); if (m->subscribed_data_slot >= 0) dbus_connection_free_data_slot(&m->subscribed_data_slot); @@ -1390,6 +1380,12 @@ bool bus_has_subscriber(Manager *m) { assert(m); + /* If we are reloading then we might not have deserialized the + subscribers yet, hence let's assume that there are some */ + + if (m->n_reloading > 0) + return true; + SET_FOREACH(c, m->bus_connections_for_dispatch, i) if (bus_connection_has_subscriber(m, c)) return true; @@ -1456,7 +1452,7 @@ void bus_broadcast_finished( usec_t userspace_usec, usec_t total_usec) { - DBusMessage *message; + _cleanup_dbus_message_unref_ DBusMessage *message = NULL; assert(m); @@ -1476,16 +1472,106 @@ void bus_broadcast_finished( DBUS_TYPE_UINT64, &total_usec, DBUS_TYPE_INVALID)) { log_oom(); - goto finish; + return; } if (bus_broadcast(m, message) < 0) { log_oom(); - goto finish; + return; } +} -finish: - if (message) - dbus_message_unref(message); +void bus_broadcast_reloading(Manager *m, bool active) { + + _cleanup_dbus_message_unref_ DBusMessage *message = NULL; + dbus_bool_t b = active; + + assert(m); + + message = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading"); + if (!message) { + log_oom(); + return; + } + + assert_cc(sizeof(usec_t) == sizeof(uint64_t)); + if (!dbus_message_append_args(message, + DBUS_TYPE_BOOLEAN, &b, + DBUS_TYPE_INVALID)) { + log_oom(); + return; + } + + + if (bus_broadcast(m, message) < 0) { + log_oom(); + return; + } +} + +Set *bus_acquire_subscribed(Manager *m, DBusConnection *c) { + Set *s; + + assert(m); + assert(c); + + s = BUS_CONNECTION_SUBSCRIBED(m, c); + if (s) + return s; + + s = set_new(string_hash_func, string_compare_func); + if (!s) + return NULL; + + if (!dbus_connection_set_data(c, m->subscribed_data_slot, s, NULL)) { + set_free(s); + return NULL; + } + + return s; +} + +void bus_serialize(Manager *m, FILE *f) { + char *client; + Iterator i; + Set *s; + + assert(m); + assert(f); + + if (!m->api_bus) + return; + + s = BUS_CONNECTION_SUBSCRIBED(m, m->api_bus); + SET_FOREACH(client, s, i) + fprintf(f, "subscribed=%s\n", client); +} + +int bus_deserialize_item(Manager *m, const char *line) { + const char *e; + char *b; + Set *s; + + assert(m); + assert(line); + + if (!m->api_bus) + return 0; + + e = startswith(line, "subscribed="); + if (!e) + return 0; + + s = bus_acquire_subscribed(m, m->api_bus); + if (!s) + return -ENOMEM; + + b = strdup(e); + if (!b) + return -ENOMEM; + + set_consume(s, b); + + return 1; }