chiark / gitweb /
turn kdbus support into a runtime option
[elogind.git] / src / libelogind / sd-bus / bus-util.c
index a30493fb4853349e04f4df802818ed408313ebbd..2e4cd572fe78ca175374a165ac1e6b283f405dd5 100644 (file)
@@ -30,6 +30,7 @@
 #include "path-util.h"
 #include "missing.h"
 #include "set.h"
+#include "signal-util.h"
 #include "unit-name.h"
 
 #include "sd-bus.h"
 #include "bus-util.h"
 #include "bus-internal.h"
 
-static int name_owner_change_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+static int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
         sd_event *e = userdata;
 
-        assert(bus);
         assert(m);
         assert(e);
 
-        sd_bus_close(bus);
+        sd_bus_close(sd_bus_message_get_bus(m));
         sd_event_exit(e, 0);
 
         return 1;
@@ -322,12 +322,11 @@ static void async_polkit_query_free(AsyncPolkitQuery *q) {
         free(q);
 }
 
-static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userdata, sd_bus_error *error) {
+static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
         _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
         AsyncPolkitQuery *q = userdata;
         int r;
 
-        assert(bus);
         assert(reply);
         assert(q);
 
@@ -340,7 +339,7 @@ static int async_polkit_callback(sd_bus *bus, sd_bus_message *reply, void *userd
                 goto finish;
         }
 
-        r = q->callback(bus, q->request, q->userdata, &error_buffer);
+        r = q->callback(q->request, q->userdata, &error_buffer);
         r = bus_maybe_reply_error(q->request, r, &error_buffer);
 
 finish:
@@ -546,7 +545,6 @@ int bus_open_system_systemd(sd_bus **_bus) {
          * directly to the system instance, instead of going via the
          * bus */
 
-#ifdef ENABLE_KDBUS
         r = sd_bus_new(&bus);
         if (r < 0)
                 return r;
@@ -565,7 +563,6 @@ int bus_open_system_systemd(sd_bus **_bus) {
         }
 
         bus = sd_bus_unref(bus);
-#endif
 
         r = sd_bus_new(&bus);
         if (r < 0)
@@ -599,7 +596,6 @@ int bus_open_user_systemd(sd_bus **_bus) {
 
         assert(_bus);
 
-#ifdef ENABLE_KDBUS
         r = sd_bus_new(&bus);
         if (r < 0)
                 return r;
@@ -617,7 +613,6 @@ int bus_open_user_systemd(sd_bus **_bus) {
         }
 
         bus = sd_bus_unref(bus);
-#endif
 
         e = secure_getenv("XDG_RUNTIME_DIR");
         if (!e)
@@ -1037,14 +1032,14 @@ static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_
         return r;
 }
 
-int bus_message_map_all_properties(sd_bus *bus,
-                                   sd_bus_message *m,
-                                   const struct bus_properties_map *map,
-                                   void *userdata) {
+int bus_message_map_all_properties(
+                sd_bus_message *m,
+                const struct bus_properties_map *map,
+                void *userdata) {
+
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         int r;
 
-        assert(bus);
         assert(m);
         assert(map);
 
@@ -1080,9 +1075,9 @@ int bus_message_map_all_properties(sd_bus *bus,
 
                         v = (uint8_t *)userdata + prop->offset;
                         if (map[i].set)
-                                r = prop->set(bus, member, m, &error, v);
+                                r = prop->set(sd_bus_message_get_bus(m), member, m, &error, v);
                         else
-                                r = map_basic(bus, member, m, &error, v);
+                                r = map_basic(sd_bus_message_get_bus(m), member, m, &error, v);
                         if (r < 0)
                                 return r;
 
@@ -1099,22 +1094,24 @@ int bus_message_map_all_properties(sd_bus *bus,
                 if (r < 0)
                         return r;
         }
+        if (r < 0)
+                return r;
 
         return sd_bus_message_exit_container(m);
 }
 
-int bus_message_map_properties_changed(sd_bus *bus,
-                                       sd_bus_message *m,
-                                       const struct bus_properties_map *map,
-                                       void *userdata) {
+int bus_message_map_properties_changed(
+                sd_bus_message *m,
+                const struct bus_properties_map *map,
+                void *userdata) {
+
         const char *member;
         int r, invalidated, i;
 
-        assert(bus);
         assert(m);
         assert(map);
 
-        r = bus_message_map_all_properties(bus, m, map, userdata);
+        r = bus_message_map_all_properties(m, map, userdata);
         if (r < 0)
                 return r;
 
@@ -1129,6 +1126,8 @@ int bus_message_map_properties_changed(sd_bus *bus,
                                 ++invalidated;
                                 break;
                         }
+        if (r < 0)
+                return r;
 
         r = sd_bus_message_exit_container(m);
         if (r < 0)
@@ -1137,11 +1136,13 @@ int bus_message_map_properties_changed(sd_bus *bus,
         return invalidated;
 }
 
-int bus_map_all_properties(sd_bus *bus,
-                           const char *destination,
-                           const char *path,
-                           const struct bus_properties_map *map,
-                           void *userdata) {
+int bus_map_all_properties(
+                sd_bus *bus,
+                const char *destination,
+                const char *path,
+                const struct bus_properties_map *map,
+                void *userdata) {
+
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         int r;
@@ -1163,7 +1164,7 @@ int bus_map_all_properties(sd_bus *bus,
         if (r < 0)
                 return r;
 
-        return bus_message_map_all_properties(bus, m, map, userdata);
+        return bus_message_map_all_properties(m, map, userdata);
 }
 
 int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
@@ -1600,24 +1601,22 @@ typedef struct BusWaitForJobs {
         sd_bus_slot *slot_disconnected;
 } BusWaitForJobs;
 
-static int match_disconnected(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        assert(bus);
+static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
         assert(m);
 
         log_error("Warning! D-Bus connection terminated.");
-        sd_bus_close(bus);
+        sd_bus_close(sd_bus_message_get_bus(m));
 
         return 0;
 }
 
-static int match_job_removed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
+static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
         const char *path, *unit, *result;
         BusWaitForJobs *d = userdata;
         uint32_t id;
         char *found;
         int r;
 
-        assert(bus);
         assert(m);
         assert(d);
 
@@ -1887,7 +1886,7 @@ int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
         return set_put_strdup(d->jobs, path);
 }
 
-int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet) {
+int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
         const char *type, *path, *source;
         int r;
 
@@ -1902,6 +1901,10 @@ int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet) {
                         else
                                 log_info("Removed symlink %s.", path);
                 }
+
+                r = unit_file_changes_add(changes, n_changes, streq(type, "symlink") ? UNIT_FILE_SYMLINK : UNIT_FILE_UNLINK, path, source);
+                if (r < 0)
+                        return r;
         }
         if (r < 0)
                 return bus_log_parse_error(r);
@@ -2039,3 +2042,37 @@ int bus_path_decode_unique(const char *path, const char *prefix, char **ret_send
         *ret_external = external;
         return 1;
 }
+
+bool is_kdbus_wanted(void) {
+        _cleanup_free_ char *value = NULL;
+#ifdef ENABLE_KDBUS
+        const bool configured = true;
+#else
+        const bool configured = false;
+#endif
+
+        int r;
+
+        if (get_proc_cmdline_key("kdbus", NULL) > 0)
+                return true;
+
+        r = get_proc_cmdline_key("kdbus=", &value);
+        if (r <= 0)
+                return configured;
+
+        return parse_boolean(value) == 1;
+}
+
+bool is_kdbus_available(void) {
+        _cleanup_close_ int fd = -1;
+        struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
+
+        if (!is_kdbus_wanted())
+                return false;
+
+        fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
+        if (fd < 0)
+                return false;
+
+        return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;
+}