chiark / gitweb /
bus: initialize variable, now that we might skip debug logging
[elogind.git] / src / core / dbus.c
index 08aff1fd2b03a64a92e8cac3028b1f58baedca4b..b0ae3e1ae7fd5975d796b1123cd460cfb4b9bedd 100644 (file)
@@ -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"
@@ -203,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;
@@ -365,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 {
@@ -406,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);
@@ -455,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);
@@ -491,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 */
@@ -771,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();
@@ -839,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)));
@@ -978,9 +976,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;
 }
@@ -1054,7 +1051,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
         };
@@ -1139,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 ||
@@ -1159,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;
 
@@ -1176,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);
                         }
                 }
@@ -1184,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;
@@ -1263,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);
@@ -1393,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;
@@ -1459,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);
 
@@ -1479,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;
+        }
+}
+
+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;
         }
 
-finish:
-        if (message)
-                dbus_message_unref(message);
+
+        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;
 }