chiark / gitweb /
bus: process AddMatch/RemoveMatch driver call in proxy
authorLennart Poettering <lennart@poettering.net>
Mon, 14 Apr 2014 01:25:10 +0000 (18:25 -0700)
committerLennart Poettering <lennart@poettering.net>
Mon, 14 Apr 2014 01:34:55 +0000 (18:34 -0700)
Previously, AddMatch/RemoveMatch calls where processed exclusively in
the proxy. That's racy however, since subscribing to a signal might not
complete before the signal is sent due to some subsequent method call.
Hence, in order to expose the same ordering guarantees as dbus1 process
the AddMatch/RemoveMatch calls from the proxy, so that they are
dispatched synchronously to all following messages, thus fixing the
race.

Ultimately, we should probabably dissolve the driver entirely into the
proxy, as it is purely a compatibility feature anyway...

src/bus-driverd/bus-driverd.c
src/bus-proxyd/bus-proxyd.c

index 4756c481bd60b15709da35a892c21c26598d2aed..0b5c9b51f3facb624f9c51d8b72d665d0915e90c 100644 (file)
@@ -800,6 +800,7 @@ static int driver_unsupported(sd_bus *bus, sd_bus_message *m, void *userdata, sd
 static const sd_bus_vtable driver_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_METHOD("AddMatch", "s", NULL, driver_add_match, SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD("RemoveMatch", "s", NULL, driver_remove_match, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("GetConnectionSELinuxSecurityContext", "s", "ay", driver_get_security_context, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("GetConnectionUnixProcessID", "s", "u", driver_get_pid, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("GetConnectionUnixUser", "s", "u", driver_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
@@ -812,7 +813,6 @@ static const sd_bus_vtable driver_vtable[] = {
         SD_BUS_METHOD("NameHasOwner", "s", "b", driver_name_has_owner, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("ReleaseName", "s", "u", driver_release_name, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("ReloadConfig", NULL, NULL, driver_unsupported, SD_BUS_VTABLE_DEPRECATED),
-        SD_BUS_METHOD("RemoveMatch", "s", NULL, driver_remove_match, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("RequestName", "su", "u", driver_request_name, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("StartServiceByName", "su", "u", driver_start_service_by_name, SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD("UpdateActivationEnvironment", "a{ss}", NULL, driver_update_environment, 0),
index 80f83e777fee9fc9bb66dc5e908016ad8d68e7d0..5511ee49de805f01531d02ee41f41f0056bc1926 100644 (file)
@@ -289,6 +289,47 @@ static int process_policy(sd_bus *a, sd_bus *b, sd_bus_message *m) {
         return 1;
 }
 
+static int process_driver(sd_bus *a, sd_bus *b, sd_bus_message *m) {
+        int r;
+
+        assert(a);
+        assert(b);
+        assert(m);
+
+        if (!streq_ptr(sd_bus_message_get_destination(m), "org.freedesktop.DBus"))
+                return 0;
+
+        if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "AddMatch")) {
+                const char *match;
+
+                r = sd_bus_message_read(m, "s", &match);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_add_match(a, match, NULL, NULL);
+                if (r < 0)
+                        return r;
+
+                return sd_bus_reply_method_return(m, NULL);
+
+        } else if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus", "RemoveMatch")) {
+                const char *match;
+
+                r = sd_bus_message_read(m, "s", &match);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_remove_match(a, match, NULL, NULL);
+                if (r < 0)
+                        return r;
+
+                return sd_bus_reply_method_return(m, NULL);
+        } else
+                return 0;
+
+        return r;
+}
+
 static int process_hello(sd_bus *a, sd_bus *b, sd_bus_message *m, bool *got_hello) {
         _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
         bool is_hello;
@@ -696,17 +737,28 @@ int main(int argc, char *argv[]) {
                                         goto finish;
                                 }
 
-                                k = sd_bus_send(a, m, NULL);
+                                k = process_driver(a, b, m);
                                 if (k < 0) {
-                                        if (r == -ECONNRESET)
-                                                r = 0;
-                                        else {
-                                                r = k;
-                                                log_error("Failed to send message: %s", strerror(-r));
-                                        }
-
+                                        r = k;
+                                        log_error("Failed to process driver calls: %s", strerror(-r));
                                         goto finish;
                                 }
+
+                                if (k > 0)
+                                        r = k;
+                                else {
+                                        k = sd_bus_send(a, m, NULL);
+                                        if (k < 0) {
+                                                if (r == -ECONNRESET)
+                                                        r = 0;
+                                                else {
+                                                        r = k;
+                                                        log_error("Failed to send message: %s", strerror(-r));
+                                                }
+
+                                                goto finish;
+                                        }
+                                }
                         }
                 }