[systemd-commits] 5 commits - Makefile.am src/activate src/bus-driverd src/libsystemd-bus units/.gitignore units/org.freedesktop.DBus.busname units/systemd-bus-driverd.service.in

Lennart Poettering lennart at kemper.freedesktop.org
Tue Dec 17 06:46:08 PST 2013


 Makefile.am                          |   13 ++
 src/activate/activate.c              |   10 +-
 src/bus-driverd/Makefile             |    1 
 src/bus-driverd/bus-driverd.c        |  154 ++++++++++-------------------------
 src/libsystemd-bus/bus-message.c     |   85 +++++++++++++++++++
 src/libsystemd-bus/bus-message.h     |    2 
 src/libsystemd-bus/busctl.c          |    4 
 src/libsystemd-bus/sd-bus.c          |   43 +++++++--
 units/.gitignore                     |    1 
 units/org.freedesktop.DBus.busname   |   12 ++
 units/systemd-bus-driverd.service.in |   14 +++
 11 files changed, 210 insertions(+), 129 deletions(-)

New commits:
commit 382aa8d036b80ef30ee5cebfbf29ea1136e26df2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Dec 17 15:44:05 2013 +0100

    bus: make driverd code more similar to other daemons, and make it exit on idle among other things

diff --git a/src/bus-driverd/bus-driverd.c b/src/bus-driverd/bus-driverd.c
index d2b3e08..bf448cd 100644
--- a/src/bus-driverd/bus-driverd.c
+++ b/src/bus-driverd/bus-driverd.c
@@ -49,9 +49,7 @@
 #include "sd-id128.h"
 #include "async.h"
 #include "hashmap.h"
-
-#define DBUS_PATH       "/org/freedesktop/DBus"
-#define DBUS_INTERFACE  "org.freedesktop.DBus"
+#include "def.h"
 
 /*
  * TODO:
@@ -61,58 +59,6 @@
  * StartServiceByName
  */
 
-static sd_bus *driver_bus;
-
-static int help(void) {
-
-        printf("%s [OPTIONS...] <bus-path>\n\n"
-               "Driver to provide a org.freedesktop.DBus interface on the given kdbus node.\n\n"
-               "  -h --help              Show this help\n"
-               "     --version           Show package version\n",
-               program_invocation_short_name);
-
-        return 0;
-}
-
-static int parse_argv(int argc, char *argv[]) {
-
-        enum {
-                ARG_VERSION = 0x100,
-        };
-
-        static const struct option options[] = {
-                { "help",            no_argument,       NULL, 'h'         },
-                { "version",         no_argument,       NULL, ARG_VERSION },
-                {}
-        };
-
-        int c;
-
-        assert(argc >= 0);
-        assert(argv);
-
-        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
-                switch (c) {
-
-                case 'h':
-                        help();
-                        return 0;
-
-                case ARG_VERSION:
-                        puts(PACKAGE_STRING);
-                        puts(SYSTEMD_FEATURES);
-                        return 0;
-
-                case '?':
-                        return -EINVAL;
-
-                default:
-                        assert_not_reached("Unknown option");
-                }
-
-        return 1;
-}
-
 static int driver_name_info_error(sd_bus *bus, sd_bus_message *m, const char *name, int error_code) {
 
         if (error_code == -ENXIO || error_code == -ENOENT)
@@ -426,19 +372,11 @@ static int driver_start_service_by_name(sd_bus *bus, sd_bus_message *m, void *us
         return sd_bus_send(bus, reply, NULL);
 }
 
-static int driver_update_env(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-
-        return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_NOT_SUPPORTED,
-                                          "UpdateActivationEnvironment is unsupported");
-}
-
-static int driver_reload_config(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
-
-        return sd_bus_reply_method_errorf(m, SD_BUS_ERROR_NOT_SUPPORTED,
-                                          "ReloadConfig is unsupported");
+static int driver_unsupported(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
+        return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "%s() is not supported", sd_bus_message_get_member(m));
 }
 
-const sd_bus_vtable dbus_vtable[] = {
+static const sd_bus_vtable driver_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_METHOD("AddMatch", "s", NULL, driver_add_match, 0),
         SD_BUS_METHOD("GetConnectionSELinuxSecurityContext", "s", "ay", driver_get_security_ctx, 0),
@@ -451,92 +389,88 @@ const sd_bus_vtable dbus_vtable[] = {
         SD_BUS_METHOD("ListNames", NULL, "as", driver_list_names, 0),
         SD_BUS_METHOD("ListQueuedOwners", "s", "as", driver_list_queued_owners, 0),
         SD_BUS_METHOD("NameHasOwner", "s", "b", driver_name_has_owner, 0),
-        SD_BUS_METHOD("ReloadConfig", NULL, NULL, driver_reload_config, 0),
+        SD_BUS_METHOD("ReloadConfig", NULL, NULL, driver_unsupported, 0),
         SD_BUS_METHOD("RemoveMatch", "s", NULL, driver_remove_match, 0),
         SD_BUS_METHOD("RequestName", "su", "u", driver_request_name, 0),
         SD_BUS_METHOD("StartServiceByName", "su", "u", driver_start_service_by_name, 0),
-        SD_BUS_METHOD("UpdateActivationEnvironment", "a{ss}", NULL, driver_update_env, 0),
+        SD_BUS_METHOD("UpdateActivationEnvironment", "a{ss}", NULL, driver_unsupported, 0),
         SD_BUS_SIGNAL("NameAcquired", "s", 0),
         SD_BUS_SIGNAL("NameLost", "s", 0),
         SD_BUS_SIGNAL("NameOwnerChanged", "sss", 0),
         SD_BUS_VTABLE_END
 };
 
-static int driver_main(const char *bus_name) {
-
-        _cleanup_event_source_unref_ sd_event_source *w_accept = NULL;
-        _cleanup_event_source_unref_ sd_event_source *w_root_service = NULL;
-        _cleanup_event_unref_ sd_event *e = NULL;
+static int connect_bus(sd_event *event, sd_bus **_bus) {
+        _cleanup_bus_unref_ sd_bus *bus = NULL;
         int r;
 
-        r = sd_event_new(&e);
-        if (r < 0) {
-                log_error("Failed to allocate event loop: %s", strerror(-r));
-                return r;
-        }
+        assert(event);
+        assert(_bus);
 
-        /* set up kernel bus connection */
-        r = sd_bus_new(&driver_bus);
+        r = sd_bus_default_system(&bus);
         if (r < 0) {
                 log_error("Failed to create bus: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_set_address(driver_bus, bus_name);
+        r = sd_bus_add_object_vtable(bus, "/org/freedesktop/DBus", "org.freedesktop.DBus", driver_vtable, NULL);
         if (r < 0) {
-                log_error("Failed to create bus: %s", strerror(-r));
-                return r;
-        }
-
-        r = sd_bus_start(driver_bus);
-        if (r < 0) {
-                log_error("Failed to start kernel bus: %s", strerror(-r));
+                log_error("Failed to add manager object vtable: %s", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_request_name(driver_bus, DBUS_INTERFACE, 0);
+        r = sd_bus_request_name(bus, "org.freedesktop.DBus", 0);
         if (r < 0) {
-                log_error("Unable to request name '%s': %s\n", DBUS_INTERFACE, strerror(-r));
+                log_error("Unable to request name: %s\n", strerror(-r));
                 return r;
         }
 
-        r = sd_bus_add_object_vtable(driver_bus, DBUS_PATH, DBUS_INTERFACE, dbus_vtable, NULL);
-        if (r < 0) {
-                log_error("Failed to add manager object vtable: %s", strerror(-r));
-                return r;
-        }
-
-        r = sd_bus_attach_event(driver_bus, e, 0);
+        r = sd_bus_attach_event(bus, event, 0);
         if (r < 0) {
                 log_error("Error %d while adding bus to even: %s", r, strerror(-r));
                 return r;
         }
 
-        log_debug("Entering main loop.");
+        *_bus = bus;
+        bus = NULL;
 
-        return sd_event_loop(e);
+        return 0;
 }
 
 int main(int argc, char *argv[]) {
-        char *bus_name;
+        _cleanup_event_unref_ sd_event *event = NULL;
+        _cleanup_bus_unref_ sd_bus *bus = NULL;
         int r;
 
-        setlocale(LC_ALL, "");
+        log_set_target(LOG_TARGET_AUTO);
         log_parse_environment();
         log_open();
 
-        r = parse_argv(argc, argv);
-        if (r <= 0)
-                return r;
+        if (argc != 1) {
+                log_error("This program takes no arguments.");
+                r = -EINVAL;
+                goto finish;
+        }
 
-        if (argc <= optind) {
-                help();
-                return -EINVAL;
+        r = sd_event_default(&event);
+        if (r < 0) {
+                log_error("Failed to allocate event loop: %s", strerror(-r));
+                goto finish;
         }
 
-        r = asprintf(&bus_name, "kernel:path=%s", argv[optind]);
+        sd_event_set_watchdog(event, true);
+
+        r = connect_bus(event, &bus);
         if (r < 0)
-                return r;
+                goto finish;
+
+        r = bus_event_loop_with_idle(event, bus, "org.freedesktop.DBus", DEFAULT_EXIT_USEC);
+        if (r < 0) {
+                log_error("Failed to run event loop: %s", strerror(-r));
+                goto finish;
+        }
+
+finish:
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 
-        return driver_main(bus_name);
 }

commit f83f897489eb5286ea52a71cfd1a66a52b3ae51f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Dec 17 03:55:59 2013 +0100

    busctl: on kdbus the bus driver is a service like any other, hence don't skip it

diff --git a/src/libsystemd-bus/busctl.c b/src/libsystemd-bus/busctl.c
index 57bc83d..4e2e6af 100644
--- a/src/libsystemd-bus/busctl.c
+++ b/src/libsystemd-bus/busctl.c
@@ -108,10 +108,6 @@ static int list_bus_names(sd_bus *bus, char **argv) {
                 if (arg_no_unique && (*i)[0] == ':')
                         continue;
 
-                /* Skip the bus driver */
-                if (streq(*i, "org.freedesktop.DBus"))
-                        continue;
-
                 printf("%-*s", (int) max_i, *i);
 
                 r = sd_bus_get_owner(bus, *i, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM|SD_BUS_CREDS_UNIQUE_NAME, &creds);

commit e1c433c6218b3e3bcc2621bdfa575a77017bb9ae
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Dec 17 02:43:45 2013 +0100

    bus: remarshal messages when necessary before sending

diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index 3f70f6f..1a461e6 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -35,6 +35,7 @@
 #include "bus-type.h"
 #include "bus-signature.h"
 #include "bus-gvariant.h"
+#include "bus-util.h"
 
 static int message_append_basic(sd_bus_message *m, char type, const void *p, const void **stored);
 
@@ -5407,3 +5408,87 @@ _public_ sd_bus *sd_bus_message_get_bus(sd_bus_message *m) {
 
         return m->bus;
 }
+
+int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) {
+        _cleanup_bus_message_unref_ sd_bus_message *n = NULL;
+        usec_t timeout;
+        int r;
+
+        assert(bus);
+        assert(m);
+        assert(*m);
+
+        switch ((*m)->header->type) {
+
+        case SD_BUS_MESSAGE_SIGNAL:
+                r = sd_bus_message_new_signal(bus, (*m)->path, (*m)->interface, (*m)->member, &n);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case SD_BUS_MESSAGE_METHOD_CALL:
+                r = sd_bus_message_new_method_call(bus, (*m)->destination, (*m)->path, (*m)->interface, (*m)->member, &n);
+                if (r < 0)
+                        return r;
+
+                break;
+
+        case SD_BUS_MESSAGE_METHOD_RETURN:
+        case SD_BUS_MESSAGE_METHOD_ERROR:
+
+                n = message_new(bus, (*m)->header->type);
+                if (!n)
+                        return -ENOMEM;
+
+                n->reply_serial = (*m)->reply_serial;
+                r = message_append_field_uint32(n, BUS_MESSAGE_HEADER_REPLY_SERIAL, n->reply_serial);
+                if (r < 0)
+                        return r;
+
+                if ((*m)->header->type == SD_BUS_MESSAGE_METHOD_ERROR && (*m)->error.name) {
+                        r = message_append_field_string(n, BUS_MESSAGE_HEADER_ERROR_NAME, SD_BUS_TYPE_STRING, (*m)->error.name, &n->error.message);
+                        if (r < 0)
+                                return r;
+
+                        n->error._need_free = -1;
+                }
+
+                break;
+
+        default:
+                return -EINVAL;
+        }
+
+        if ((*m)->destination && !n->destination) {
+                r = message_append_field_string(n, BUS_MESSAGE_HEADER_DESTINATION, SD_BUS_TYPE_STRING, (*m)->destination, &n->destination);
+                if (r < 0)
+                        return r;
+        }
+
+        if ((*m)->sender && !n->sender) {
+                r = message_append_field_string(n, BUS_MESSAGE_HEADER_SENDER, SD_BUS_TYPE_STRING, (*m)->sender, &n->sender);
+                if (r < 0)
+                        return r;
+        }
+
+        n->header->flags |= (*m)->header->flags & (BUS_MESSAGE_NO_REPLY_EXPECTED|BUS_MESSAGE_NO_AUTO_START);
+
+        r = sd_bus_message_copy(n, *m, true);
+        if (r < 0)
+                return r;
+
+        timeout = (*m)->timeout;
+        if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED))
+                timeout = BUS_DEFAULT_TIMEOUT;
+
+        r = bus_message_seal(n, (*m)->header->serial, timeout);
+        if (r < 0)
+                return r;
+
+        sd_bus_message_unref(*m);
+        *m = n;
+        n = NULL;
+
+        return 0;
+}
diff --git a/src/libsystemd-bus/bus-message.h b/src/libsystemd-bus/bus-message.h
index 9ef92cf..a9d42c3 100644
--- a/src/libsystemd-bus/bus-message.h
+++ b/src/libsystemd-bus/bus-message.h
@@ -231,3 +231,5 @@ void bus_body_part_unmap(struct bus_body_part *part);
 int bus_message_to_errno(sd_bus_message *m);
 
 int bus_message_new_synthetic_error(sd_bus *bus, uint64_t serial, const sd_bus_error *e, sd_bus_message **m);
+
+int bus_message_remarshal(sd_bus *bus, sd_bus_message **m);
diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 76a27ec..338ce06 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -1319,14 +1319,6 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
         assert(b);
         assert(m);
 
-        if (b->message_version != 0 &&
-            m->header->version != b->message_version)
-                return -EPERM;
-
-        if (b->message_endian != 0 &&
-            m->header->endian != b->message_endian)
-                return -EPERM;
-
         if (m->sealed) {
                 /* If we copy the same message to multiple
                  * destinations, avoid using the same serial
@@ -1341,6 +1333,18 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
         return bus_message_seal(m, ++b->serial, timeout);
 }
 
+static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) {
+        assert(b);
+
+        /* Do packet version and endianess already match? */
+        if ((b->message_version == 0 || b->message_version == (*m)->header->version) &&
+            (b->message_endian == 0 || b->message_endian == (*m)->header->endian))
+                return 0;
+
+        /* No? Then remarshal! */
+        return bus_message_remarshal(b, m);
+}
+
 int bus_seal_synthetic_message(sd_bus *b, sd_bus_message *m) {
         assert(b);
         assert(m);
@@ -1452,7 +1456,8 @@ static int dispatch_rqueue(sd_bus *bus, sd_bus_message **m) {
         }
 }
 
-_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) {
+_public_ int sd_bus_send(sd_bus *bus, sd_bus_message *_m, uint64_t *serial) {
+        _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
         int r;
 
         assert_return(bus, -EINVAL);
@@ -1477,6 +1482,12 @@ _public_ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) {
         if (r < 0)
                 return r;
 
+        /* Remarshall if we have to. This will possible unref the
+         * message and place a replacement in m */
+        r = bus_remarshal_message(bus, &m);
+        if (r < 0)
+                return r;
+
         /* If this is a reply and no reply was requested, then let's
          * suppress this, if we can */
         if (m->dont_send && !serial)
@@ -1567,12 +1578,13 @@ static int timeout_compare(const void *a, const void *b) {
 
 _public_ int sd_bus_call_async(
                 sd_bus *bus,
-                sd_bus_message *m,
+                sd_bus_message *_m,
                 sd_bus_message_handler_t callback,
                 void *userdata,
                 uint64_t usec,
                 uint64_t *serial) {
 
+        _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
         struct reply_callback *c;
         int r;
 
@@ -1596,6 +1608,10 @@ _public_ int sd_bus_call_async(
         if (r < 0)
                 return r;
 
+        r = bus_remarshal_message(bus, &m);
+        if (r < 0)
+                return r;
+
         c = new0(struct reply_callback, 1);
         if (!c)
                 return -ENOMEM;
@@ -1674,11 +1690,12 @@ int bus_ensure_running(sd_bus *bus) {
 
 _public_ int sd_bus_call(
                 sd_bus *bus,
-                sd_bus_message *m,
+                sd_bus_message *_m,
                 uint64_t usec,
                 sd_bus_error *error,
                 sd_bus_message **reply) {
 
+        _cleanup_bus_message_unref_ sd_bus_message *m = sd_bus_message_ref(_m);
         usec_t timeout;
         uint64_t serial;
         unsigned i;
@@ -1702,6 +1719,10 @@ _public_ int sd_bus_call(
         if (r < 0)
                 return r;
 
+        r = bus_remarshal_message(bus, &m);
+        if (r < 0)
+                return r;
+
         r = sd_bus_send(bus, m, &serial);
         if (r < 0)
                 return r;

commit 603938e0a9b5379984d7397e3cf81683c0037a53
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Dec 17 03:14:20 2013 +0100

    activate: fix error checking on epoll_ctl()

diff --git a/src/activate/activate.c b/src/activate/activate.c
index d73c16e..cf545d6 100644
--- a/src/activate/activate.c
+++ b/src/activate/activate.c
@@ -51,10 +51,12 @@ static int add_epoll(int epoll_fd, int fd) {
 
         ev.data.fd = fd;
         r = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev);
-        if (r < 0)
-                log_error("Failed to add event on epoll fd:%d for fd:%d: %m",
-                          epoll_fd, fd);
-        return -errno;
+        if (r < 0) {
+                log_error("Failed to add event on epoll fd:%d for fd:%d: %m", epoll_fd, fd);
+                return -errno;
+        }
+
+        return 0;
 }
 
 static int make_socket_fd(const char* address, int flags) {

commit 15e913230c652ace36abfbf2b6fed0c1f56b8711
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Dec 17 02:43:38 2013 +0100

    bus: install unit files for new driver service

diff --git a/Makefile.am b/Makefile.am
index de63054..8bef21b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3728,8 +3728,21 @@ systemd_bus_driverd_LDADD = \
 
 rootlibexec_PROGRAMS += \
 	systemd-bus-driverd
+
+nodist_systemunit_DATA += \
+	units/systemd-bus-driverd.service
+
+dist_systemunit_DATA += \
+	units/org.freedesktop.DBus.busname
+
+BUSNAMES_TARGET_WANTS += \
+	org.freedesktop.DBus.busname
+
 endif
 
+EXTRA_DIST += \
+	units/systemd-bus-driverd.service.in
+
 # ------------------------------------------------------------------------------
 if ENABLE_LOCALED
 systemd_localed_SOURCES = \
diff --git a/src/bus-driverd/Makefile b/src/bus-driverd/Makefile
new file mode 120000
index 0000000..d0b0e8e
--- /dev/null
+++ b/src/bus-driverd/Makefile
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/units/.gitignore b/units/.gitignore
index 94876ed..76c4cb3 100644
--- a/units/.gitignore
+++ b/units/.gitignore
@@ -22,6 +22,7 @@
 /systemd-ask-password-wall.service
 /systemd-backlight at .service
 /systemd-binfmt.service
+/systemd-bus-driverd.service
 /systemd-bus-proxyd at .service
 /systemd-fsck-root.service
 /systemd-fsck at .service
diff --git a/units/org.freedesktop.DBus.busname b/units/org.freedesktop.DBus.busname
new file mode 100644
index 0000000..68c649d
--- /dev/null
+++ b/units/org.freedesktop.DBus.busname
@@ -0,0 +1,12 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Bus Driver Service Bus Name
+
+[BusName]
+Service=systemd-bus-driverd.service
diff --git a/units/systemd-bus-driverd.service.in b/units/systemd-bus-driverd.service.in
new file mode 100644
index 0000000..575bddc
--- /dev/null
+++ b/units/systemd-bus-driverd.service.in
@@ -0,0 +1,14 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Bus Driver Service
+
+[Service]
+ExecStart=@rootlibexecdir@/systemd-bus-driverd
+BusName=org.freedesktop.DBus
+WatchdogSec=1min



More information about the systemd-commits mailing list