]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/dbus.c
shared: split out polkit stuff from bus-util.c → bus-polkit.c
[thirdparty/systemd.git] / src / core / dbus.c
index 74b1c51c1d00222b54c11a923e9da2880c81767f..c86e049c78b0b9235b544ecf9d9296449773bca7 100644 (file)
@@ -10,7 +10,7 @@
 #include "bus-common-errors.h"
 #include "bus-error.h"
 #include "bus-internal.h"
-#include "bus-util.h"
+#include "bus-polkit.h"
 #include "dbus-automount.h"
 #include "dbus-cgroup.h"
 #include "dbus-device.h"
@@ -32,7 +32,6 @@
 #include "fd-util.h"
 #include "fs-util.h"
 #include "log.h"
-#include "missing.h"
 #include "mkdir.h"
 #include "process-util.h"
 #include "selinux-access.h"
@@ -622,6 +621,9 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void
 
         nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
         if (nfd < 0) {
+                if (ERRNO_IS_ACCEPT_AGAIN(errno))
+                        return 0;
+
                 log_warning_errno(errno, "Failed to accept private connection, ignoring: %m");
                 return 0;
         }
@@ -717,114 +719,6 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void
         return 0;
 }
 
-static int manager_dispatch_sync_bus_names(sd_event_source *es, void *userdata) {
-        _cleanup_strv_free_ char **names = NULL;
-        Manager *m = userdata;
-        const char *name;
-        Iterator i;
-        Unit *u;
-        int r;
-
-        assert(es);
-        assert(m);
-        assert(m->sync_bus_names_event_source == es);
-
-        /* First things first, destroy the defer event so that we aren't triggered again */
-        m->sync_bus_names_event_source = sd_event_source_unref(m->sync_bus_names_event_source);
-
-        /* Let's see if there's anything to do still? */
-        if (!m->api_bus)
-                return 0;
-        if (hashmap_isempty(m->watch_bus))
-                return 0;
-
-        /* OK, let's sync up the names. Let's see which names are currently on the bus. */
-        r = sd_bus_list_names(m->api_bus, &names, NULL);
-        if (r < 0)
-                return log_error_errno(r, "Failed to get initial list of names: %m");
-
-        /* We have to synchronize the current bus names with the
-         * list of active services. To do this, walk the list of
-         * all units with bus names. */
-        HASHMAP_FOREACH_KEY(u, name, m->watch_bus, i) {
-                Service *s = SERVICE(u);
-
-                assert(s);
-
-                if (!streq_ptr(s->bus_name, name)) {
-                        log_unit_warning(u, "Bus name has changed from %s → %s, ignoring.", s->bus_name, name);
-                        continue;
-                }
-
-                /* Check if a service's bus name is in the list of currently
-                 * active names */
-                if (strv_contains(names, name)) {
-                        _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
-                        const char *unique;
-
-                        /* If it is, determine its current owner */
-                        r = sd_bus_get_name_creds(m->api_bus, name, SD_BUS_CREDS_UNIQUE_NAME, &creds);
-                        if (r < 0) {
-                                log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to get bus name owner %s: %m", name);
-                                continue;
-                        }
-
-                        r = sd_bus_creds_get_unique_name(creds, &unique);
-                        if (r < 0) {
-                                log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to get unique name for %s: %m", name);
-                                continue;
-                        }
-
-                        /* Now, let's compare that to the previous bus owner, and
-                         * if it's still the same, all is fine, so just don't
-                         * bother the service. Otherwise, the name has apparently
-                         * changed, so synthesize a name owner changed signal. */
-
-                        if (!streq_ptr(unique, s->bus_name_owner))
-                                UNIT_VTABLE(u)->bus_name_owner_change(u, name, s->bus_name_owner, unique);
-                } else {
-                        /* So, the name we're watching is not on the bus.
-                         * This either means it simply hasn't appeared yet,
-                         * or it was lost during the daemon reload.
-                         * Check if the service has a stored name owner,
-                         * and synthesize a name loss signal in this case. */
-
-                        if (s->bus_name_owner)
-                                UNIT_VTABLE(u)->bus_name_owner_change(u, name, s->bus_name_owner, NULL);
-                }
-        }
-
-        return 0;
-}
-
-int manager_enqueue_sync_bus_names(Manager *m) {
-        int r;
-
-        assert(m);
-
-        /* Enqueues a request to synchronize the bus names in a later event loop iteration. The callers generally don't
-         * want us to invoke ->bus_name_owner_change() unit calls from their stack frames as this might result in event
-         * dispatching on its own creating loops, hence we simply create a defer event for the event loop and exit. */
-
-        if (m->sync_bus_names_event_source)
-                return 0;
-
-        r = sd_event_add_defer(m->event, &m->sync_bus_names_event_source, manager_dispatch_sync_bus_names, m);
-        if (r < 0)
-                return log_error_errno(r, "Failed to create bus name synchronization event: %m");
-
-        r = sd_event_source_set_priority(m->sync_bus_names_event_source, SD_EVENT_PRIORITY_IDLE);
-        if (r < 0)
-                return log_error_errno(r, "Failed to set event priority: %m");
-
-        r = sd_event_source_set_enabled(m->sync_bus_names_event_source, SD_EVENT_ONESHOT);
-        if (r < 0)
-                return log_error_errno(r, "Failed to set even to oneshot: %m");
-
-        (void) sd_event_source_set_description(m->sync_bus_names_event_source, "manager-sync-bus-names");
-        return 0;
-}
-
 static int bus_setup_api(Manager *m, sd_bus *bus) {
         Iterator i;
         char *name;
@@ -908,10 +802,6 @@ int bus_init_api(Manager *m) {
 
         m->api_bus = TAKE_PTR(bus);
 
-        r = manager_enqueue_sync_bus_names(m);
-        if (r < 0)
-                return r;
-
         return 0;
 }
 
@@ -1049,13 +939,10 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
 
         /* Make sure all bus slots watching names are released. */
         HASHMAP_FOREACH(u, m->watch_bus, i) {
-                if (!u->match_bus_slot)
-                        continue;
-
-                if (sd_bus_slot_get_bus(u->match_bus_slot) != *bus)
-                        continue;
-
-                u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
+                if (u->match_bus_slot && sd_bus_slot_get_bus(u->match_bus_slot) == *bus)
+                        u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
+                if (u->get_name_owner_slot && sd_bus_slot_get_bus(u->get_name_owner_slot) == *bus)
+                        u->get_name_owner_slot = sd_bus_slot_unref(u->get_name_owner_slot);
         }
 
         /* Get rid of tracked clients on this bus */
@@ -1254,7 +1141,7 @@ uint64_t manager_bus_n_queued_write(Manager *m) {
         sd_bus *b;
         int r;
 
-        /* Returns the total number of messages queued for writing on all our direct and API busses. */
+        /* Returns the total number of messages queued for writing on all our direct and API buses. */
 
         SET_FOREACH(b, m->private_buses, i) {
                 uint64_t k;