[systemd-commits] 10 commits - .gitignore TODO man/sd_bus_request_name.xml src/core src/hostname src/journal src/libsystemd-bus src/libsystemd-rtnl src/locale src/login src/network src/socket-proxy src/systemd src/test src/timedate tmpfiles.d/tmp.conf

Lennart Poettering lennart at kemper.freedesktop.org
Thu Dec 12 19:06:54 PST 2013


 .gitignore                              |    2 
 TODO                                    |    8 -
 man/sd_bus_request_name.xml             |   23 ++---
 src/core/manager.c                      |    2 
 src/core/namespace.c                    |   12 ++
 src/hostname/hostnamed.c                |    2 
 src/journal/journald-server.c           |    2 
 src/journal/journald-stream.c           |    8 -
 src/libsystemd-bus/bus-control.c        |    4 
 src/libsystemd-bus/bus-match.c          |    8 +
 src/libsystemd-bus/bus-util.c           |   41 +++++++--
 src/libsystemd-bus/bus-util.h           |    2 
 src/libsystemd-bus/libsystemd-bus.sym   |    6 -
 src/libsystemd-bus/sd-bus.c             |    2 
 src/libsystemd-bus/sd-event.c           |  133 ++++++++++++++++++++------------
 src/libsystemd-bus/test-bus-zero-copy.c |    2 
 src/libsystemd-bus/test-event.c         |   32 +++++--
 src/libsystemd-rtnl/rtnl-internal.h     |    2 
 src/libsystemd-rtnl/sd-rtnl.c           |    8 -
 src/locale/localed.c                    |    2 
 src/login/logind-button.c               |   26 +++---
 src/login/logind.c                      |   38 +++------
 src/network/networkd-manager.c          |   11 --
 src/socket-proxy/socket-proxyd.c        |   17 ++--
 src/systemd/sd-event.h                  |    8 -
 src/test/test-namespace.c               |   24 ++++-
 src/timedate/timedated.c                |    2 
 tmpfiles.d/tmp.conf                     |   25 ------
 28 files changed, 256 insertions(+), 196 deletions(-)

New commits:
commit 12179984a38fe74581333fbcdc11c822d81f505f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Dec 13 04:03:30 2013 +0100

    event: when unreffing an event source from its own handler, detach fd from epoll
    
    The pattern of unreffing an IO event source and then closing its fd is
    frequently seen in even source callbacks. Previously this likely
    resultet in us removing the fd from the epoll after it was closed which
    is problematic, since while we were dispatching we always kept an extra
    reference to event source objects because we might still need it later.

diff --git a/TODO b/TODO
index 4274b37..0ea4109 100644
--- a/TODO
+++ b/TODO
@@ -134,8 +134,7 @@ Features:
   - fix sd-event hookup when we connect to multiple servers one after the other
 
 * sd-event
-  - allow multiple signal handlers per signal
-  - when dispatching an event source then _unref() on it should remove it from the epoll
+  - allow multiple signal handlers per signal?
 
 * in the final killing spree, detect processes from the root directory, and
   complain loudly if they have argv[0][0] == '@' set.
diff --git a/src/libsystemd-bus/sd-event.c b/src/libsystemd-bus/sd-event.c
index b396432..6af52ec 100644
--- a/src/libsystemd-bus/sd-event.c
+++ b/src/libsystemd-bus/sd-event.c
@@ -58,6 +58,7 @@ struct sd_event_source {
         EventSourceType type:4;
         int enabled:3;
         bool pending:1;
+        bool dispatching:1;
 
         int priority;
         unsigned pending_index;
@@ -993,8 +994,21 @@ _public_ sd_event_source* sd_event_source_unref(sd_event_source *s) {
         assert(s->n_ref >= 1);
         s->n_ref--;
 
-        if (s->n_ref <= 0)
-                source_free(s);
+        if (s->n_ref <= 0) {
+                /* Here's a special hack: when we are called from a
+                 * dispatch handler we won't free the event source
+                 * immediately, but we will detach the fd from the
+                 * epoll. This way it is safe for the caller to unref
+                 * the event source and immediately close the fd, but
+                 * we still retain a valid event source object after
+                 * the callback. */
+
+                if (s->dispatching) {
+                        if (s->type == SOURCE_IO)
+                                source_io_unregister(s);
+                } else
+                        source_free(s);
+        }
 
         return NULL;
 }
@@ -1689,7 +1703,7 @@ static int source_dispatch(sd_event_source *s) {
                         return r;
         }
 
-        sd_event_source_ref(s);
+        s->dispatching = true;
 
         switch (s->type) {
 
@@ -1734,12 +1748,16 @@ static int source_dispatch(sd_event_source *s) {
                 break;
         }
 
-        if (r < 0) {
+        s->dispatching = false;
+
+        if (r < 0)
                 log_debug("Event source %p returned error, disabling: %s", s, strerror(-r));
+
+        if (s->n_ref == 0)
+                source_free(s);
+        else if (r < 0)
                 sd_event_source_set_enabled(s, SD_EVENT_OFF);
-        }
 
-        sd_event_source_unref(s);
         return 1;
 }
 
@@ -1761,10 +1779,18 @@ static int event_prepare(sd_event *e) {
                         return r;
 
                 assert(s->prepare);
+
+                s->dispatching = true;
                 r = s->prepare(s, s->userdata);
+                s->dispatching = false;
+
                 if (r < 0)
-                        return r;
+                        log_debug("Prepare callback of event source %p returned error, disabling: %s", s, strerror(-r));
 
+                if (s->n_ref == 0)
+                        source_free(s);
+                else if (r < 0)
+                        sd_event_source_set_enabled(s, SD_EVENT_OFF);
         }
 
         return 0;
diff --git a/src/libsystemd-bus/test-event.c b/src/libsystemd-bus/test-event.c
index 5317008..28ef6a3 100644
--- a/src/libsystemd-bus/test-event.c
+++ b/src/libsystemd-bus/test-event.c
@@ -28,9 +28,15 @@ static int prepare_handler(sd_event_source *s, void *userdata) {
         return 1;
 }
 
-static bool got_a, got_b, got_c;
+static bool got_a, got_b, got_c, got_unref;
 static unsigned got_d;
 
+static int unref_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        sd_event_source_unref(s);
+        got_unref = true;
+        return 0;
+}
+
 static int io_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
 
         log_info("got IO on %c", PTR_TO_INT(userdata));
@@ -155,18 +161,26 @@ static int exit_handler(sd_event_source *s, void *userdata) {
 
 int main(int argc, char *argv[]) {
         sd_event *e = NULL;
-        sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL;
+        sd_event_source *w = NULL, *x = NULL, *y = NULL, *z = NULL, *q = NULL, *t = NULL;
         static const char ch = 'x';
-        int a[2] = { -1, -1 }, b[2] = { -1, -1}, d[2] = { -1, -1};
+        int a[2] = { -1, -1 }, b[2] = { -1, -1}, d[2] = { -1, -1}, k[2] = { -1, -1 };
 
         assert_se(pipe(a) >= 0);
         assert_se(pipe(b) >= 0);
         assert_se(pipe(d) >= 0);
+        assert_se(pipe(k) >= 0);
 
         assert_se(sd_event_default(&e) >= 0);
 
         assert_se(sd_event_set_watchdog(e, true) >= 0);
 
+        /* Test whether we cleanly can destroy an io event source from its own handler */
+        got_unref = false;
+        assert_se(sd_event_add_io(e, k[0], EPOLLIN, unref_handler, NULL, &t) >= 0);
+        assert_se(write(k[1], &ch, 1) == 1);
+        assert_se(sd_event_run(e, (uint64_t) -1) >= 1);
+        assert_se(got_unref);
+
         got_a = false, got_b = false, got_c = false, got_d = 0;
 
         /* Add a oneshot handler, trigger it, re-enable it, and trigger
@@ -227,6 +241,8 @@ int main(int argc, char *argv[]) {
 
         close_pipe(a);
         close_pipe(b);
+        close_pipe(d);
+        close_pipe(k);
 
         return 0;
 }

commit 7b77ed8cf36e8eca6017791626044b61ae2d68e7
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Dec 13 03:30:42 2013 +0100

    event: be more conservative when returning errors from event handler callbacks
    
    We really should return errors from event handlers if we have a
    continous problem and don't know any other solution.

diff --git a/src/core/manager.c b/src/core/manager.c
index ad4c6e8..a2f3570 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1631,7 +1631,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
         }
 
         if (sigchld)
-                return manager_dispatch_sigchld(m);
+                manager_dispatch_sigchld(m);
 
         return 0;
 }
diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c
index 8958c7f..aba9054 100644
--- a/src/journal/journald-stream.c
+++ b/src/journal/journald-stream.c
@@ -293,7 +293,6 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents,
 
         if ((revents|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
                 log_error("Got invalid event from epoll for stdout stream: %"PRIx32, revents);
-                r = -EIO;
                 goto terminate;
         }
 
@@ -304,12 +303,11 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents,
                         return 0;
 
                 log_warning("Failed to read from stream: %m");
-                r = -errno;
                 goto terminate;
         }
 
         if (l == 0) {
-                r = stdout_stream_scan(s, true);
+                stdout_stream_scan(s, true);
                 goto terminate;
         }
 
@@ -391,7 +389,6 @@ static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revent
         len = sizeof(stream->ucred);
         if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &stream->ucred, &len) < 0) {
                 log_error("Failed to determine peer credentials: %m");
-                r = -errno;
                 goto fail;
         }
 
@@ -404,7 +401,6 @@ static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revent
 
         if (shutdown(fd, SHUT_WR) < 0) {
                 log_error("Failed to shutdown writing side of socket: %m");
-                r = -errno;
                 goto fail;
         }
 
@@ -428,7 +424,7 @@ static int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revent
 
 fail:
         stdout_stream_free(stream);
-        return r;
+        return 0;
 }
 
 int server_open_stdout_socket(Server *s) {
diff --git a/src/login/logind-button.c b/src/login/logind-button.c
index 3dd0829..e29f2c4 100644
--- a/src/login/logind-button.c
+++ b/src/login/logind-button.c
@@ -141,7 +141,9 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
                                    "MESSAGE=Power key pressed.",
                                    MESSAGE_ID(SD_MESSAGE_POWER_KEY),
                                    NULL);
-                        return button_handle(b, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
+
+                        button_handle(b, INHIBIT_HANDLE_POWER_KEY, b->manager->handle_power_key, b->manager->power_key_ignore_inhibited, true);
+                        break;
 
                 /* The kernel is a bit confused here:
 
@@ -154,41 +156,41 @@ static int button_dispatch(sd_event_source *s, int fd, uint32_t revents, void *u
                                    "MESSAGE=Suspend key pressed.",
                                    MESSAGE_ID(SD_MESSAGE_SUSPEND_KEY),
                                    NULL);
-                        return button_handle(b, INHIBIT_HANDLE_SUSPEND_KEY, b->manager->handle_suspend_key, b->manager->suspend_key_ignore_inhibited, true);
+
+                        button_handle(b, INHIBIT_HANDLE_SUSPEND_KEY, b->manager->handle_suspend_key, b->manager->suspend_key_ignore_inhibited, true);
+                        break;
 
                 case KEY_SUSPEND:
                         log_struct(LOG_INFO,
                                    "MESSAGE=Hibernate key pressed.",
                                    MESSAGE_ID(SD_MESSAGE_HIBERNATE_KEY),
                                    NULL);
-                        return button_handle(b, INHIBIT_HANDLE_HIBERNATE_KEY, b->manager->handle_hibernate_key, b->manager->hibernate_key_ignore_inhibited, true);
+
+                        button_handle(b, INHIBIT_HANDLE_HIBERNATE_KEY, b->manager->handle_hibernate_key, b->manager->hibernate_key_ignore_inhibited, true);
+                        break;
                 }
 
         } else if (ev.type == EV_SW && ev.value > 0) {
 
-                switch (ev.code) {
-
-                case SW_LID:
+                if (ev.code == SW_LID) {
                         log_struct(LOG_INFO,
                                    "MESSAGE=Lid closed.",
                                    MESSAGE_ID(SD_MESSAGE_LID_CLOSED),
                                    NULL);
-                        b->lid_close_queued = true;
 
-                        return button_handle(b, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, true);
+                        b->lid_close_queued = true;
+                        button_handle(b, INHIBIT_HANDLE_LID_SWITCH, b->manager->handle_lid_switch, b->manager->lid_switch_ignore_inhibited, true);
                 }
 
         } else if (ev.type == EV_SW && ev.value == 0) {
 
-                switch (ev.code) {
-
-                case SW_LID:
+                if (ev.code == SW_LID) {
                         log_struct(LOG_INFO,
                                    "MESSAGE=Lid opened.",
                                    MESSAGE_ID(SD_MESSAGE_LID_OPENED),
                                    NULL);
+
                         b->lid_close_queued = false;
-                        break;
                 }
         }
 
diff --git a/src/login/logind.c b/src/login/logind.c
index 2226087..b7c8f71 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -34,6 +34,7 @@
 #include "bus-util.h"
 #include "bus-error.h"
 #include "logind.h"
+#include "udev-util.h"
 
 Manager *manager_new(void) {
         Manager *m;
@@ -490,9 +491,8 @@ static int manager_enumerate_inhibitors(Manager *m) {
 }
 
 static int manager_dispatch_seat_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
         Manager *m = userdata;
-        struct udev_device *d;
-        int r;
 
         assert(m);
 
@@ -500,16 +500,13 @@ static int manager_dispatch_seat_udev(sd_event_source *s, int fd, uint32_t reven
         if (!d)
                 return -ENOMEM;
 
-        r = manager_process_seat_device(m, d);
-        udev_device_unref(d);
-
-        return r;
+        manager_process_seat_device(m, d);
+        return 0;
 }
 
 static int manager_dispatch_device_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
         Manager *m = userdata;
-        struct udev_device *d;
-        int r;
 
         assert(m);
 
@@ -517,16 +514,13 @@ static int manager_dispatch_device_udev(sd_event_source *s, int fd, uint32_t rev
         if (!d)
                 return -ENOMEM;
 
-        r = manager_process_seat_device(m, d);
-        udev_device_unref(d);
-
-        return r;
+        manager_process_seat_device(m, d);
+        return 0;
 }
 
 static int manager_dispatch_vcsa_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
         Manager *m = userdata;
-        struct udev_device *d;
-        int r = 0;
         const char *name;
 
         assert(m);
@@ -541,17 +535,14 @@ static int manager_dispatch_vcsa_udev(sd_event_source *s, int fd, uint32_t reven
          * VTs, to make sure our auto VTs never go away. */
 
         if (name && startswith(name, "vcsa") && streq_ptr(udev_device_get_action(d), "remove"))
-                r = seat_preallocate_vts(m->seat0);
+                seat_preallocate_vts(m->seat0);
 
-        udev_device_unref(d);
-
-        return r;
+        return 0;
 }
 
 static int manager_dispatch_button_udev(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
         Manager *m = userdata;
-        struct udev_device *d;
-        int r;
 
         assert(m);
 
@@ -559,10 +550,8 @@ static int manager_dispatch_button_udev(sd_event_source *s, int fd, uint32_t rev
         if (!d)
                 return -ENOMEM;
 
-        r = manager_process_button_device(m, d);
-        udev_device_unref(d);
-
-        return r;
+        manager_process_button_device(m, d);
+        return 0;
 }
 
 static int manager_dispatch_console(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
@@ -573,7 +562,6 @@ static int manager_dispatch_console(sd_event_source *s, int fd, uint32_t revents
         assert(m->console_active_fd == fd);
 
         seat_read_active_vt(m->seat0);
-
         return 0;
 }
 
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index d59b913..1b5837e 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -22,6 +22,7 @@
 #include "path-util.h"
 #include "networkd.h"
 #include "libudev-private.h"
+#include "udev-util.h"
 
 int manager_new(Manager **ret) {
         _cleanup_manager_free_ Manager *m = NULL;
@@ -204,19 +205,13 @@ finish:
 static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
         Manager *m = userdata;
         struct udev_monitor *monitor = m->udev_monitor;
-        struct udev_device *device;
-        int r;
+        _cleanup_udev_device_unref_ struct udev_device *device = NULL;
 
         device = udev_monitor_receive_device(monitor);
         if (!device)
                 return -ENOMEM;
 
-        r = manager_process_link(m, device);
-        if (r < 0)
-                return r;
-
-        udev_device_unref(device);
-
+        manager_process_link(m, device);
         return 0;
 }
 
diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c
index c6f56be..b066633 100644
--- a/src/socket-proxy/socket-proxyd.c
+++ b/src/socket-proxy/socket-proxyd.c
@@ -462,6 +462,7 @@ fail:
 }
 
 static int accept_cb(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        _cleanup_free_ char *peer = NULL;
         Context *context = userdata;
         int nfd = -1, r;
 
@@ -471,24 +472,24 @@ static int accept_cb(sd_event_source *s, int fd, uint32_t revents, void *userdat
         assert(context);
 
         nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
-        if (nfd >= 0) {
-                _cleanup_free_ char *peer = NULL;
-
+        if (nfd < 0) {
+                if (errno != -EAGAIN)
+                        log_warning("Failed to accept() socket: %m");
+        } else {
                 getpeername_pretty(nfd, &peer);
                 log_debug("New connection from %s", strna(peer));
 
                 r = add_connection_socket(context, sd_event_source_get_event(s), nfd);
                 if (r < 0) {
+                        log_error("Failed to accept connection, ignoring: %s", strerror(-r));
                         close_nointr_nofail(fd);
-                        return r;
                 }
-
-        } else if (errno != -EAGAIN)
-                log_warning("Failed to accept() socket: %m");
+        }
 
         r = sd_event_source_set_enabled(s, SD_EVENT_ONESHOT);
         if (r < 0) {
-                log_error("Error %d while re-enabling listener with ONESHOT: %s", r, strerror(-r));
+                log_error("Error while re-enabling listener with ONESHOT: %s", strerror(-r));
+                sd_event_exit(sd_event_source_get_event(s), r);
                 return r;
         }
 

commit c5ef10429a7768e3453f29e8c85cb560ce382649
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Dec 13 02:43:35 2013 +0100

    git: update .gitignore

diff --git a/.gitignore b/.gitignore
index f00cb8e..7dff099 100644
--- a/.gitignore
+++ b/.gitignore
@@ -113,6 +113,8 @@
 /test-daemon
 /test-date
 /test-device-nodes
+/test-dhcp-client
+/test-dhcp-option
 /test-ellipsize
 /test-engine
 /test-env-replace

commit 6b46ea73e3b1d8a1e65f58ac04772821bd4a72fb
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Dec 13 02:05:04 2013 +0100

    namespace: include boot id in private tmp directories
    
    This way it is easy to only exclude directories from the current boot
    from automatic clean up in /var/tmp.
    
    Also, pick a longer name for the directories so that are globs in
    tmp.conf can be simpler yet equally accurate.

diff --git a/src/core/namespace.c b/src/core/namespace.c
index 926ff71..85147be 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -278,12 +278,22 @@ fail:
 
 static int setup_one_tmp_dir(const char *id, const char *prefix, char **path) {
         _cleanup_free_ char *x = NULL;
+        char bid[SD_ID128_STRING_MAX];
+        sd_id128_t boot_id;
+        int r;
 
         assert(id);
         assert(prefix);
         assert(path);
 
-        x = strjoin(prefix, "/systemd-", id, "-XXXXXX", NULL);
+        /* We include the boot id in the directory so that after a
+         * reboot we can easily identify obsolete directories. */
+
+        r = sd_id128_get_boot(&boot_id);
+        if (r < 0)
+                return r;
+
+        x = strjoin(prefix, "/systemd-private-", sd_id128_to_string(boot_id, bid), "-", id, "-XXXXXX", NULL);
         if (!x)
                 return -ENOMEM;
 
diff --git a/src/test/test-namespace.c b/src/test/test-namespace.c
index 6454a1b..5b76b9e 100644
--- a/src/test/test-namespace.c
+++ b/src/test/test-namespace.c
@@ -119,13 +119,25 @@ static void test_netns(void) {
 }
 
 int main(int argc, char *argv[]) {
-        test_tmpdir("abcd.service",
-                    "/tmp/systemd-abcd.service-",
-                    "/var/tmp/systemd-abcd.service-");
+        sd_id128_t bid;
+        char boot_id[SD_ID128_STRING_MAX];
+        _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *zz = NULL;
 
-        test_tmpdir("sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device",
-                    "/tmp/systemd-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-",
-                    "/var/tmp/systemd-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-");
+        assert_se(sd_id128_get_boot(&bid) >= 0);
+        sd_id128_to_string(bid, boot_id);
+
+        x = strjoin("/tmp/systemd-private-", boot_id, "-abcd.service-", NULL);
+        y = strjoin("/var/tmp/systemd-private-", boot_id, "-abcd.service-", NULL);
+        assert_se(x && y);
+
+        test_tmpdir("abcd.service", x, y);
+
+        z = strjoin("/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-", NULL);
+        zz = strjoin("/var/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-", NULL);
+
+        assert_se(z && zz);
+
+        test_tmpdir("sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device", z, zz);
 
         test_netns();
 
diff --git a/tmpfiles.d/tmp.conf b/tmpfiles.d/tmp.conf
index f0312ef..b80dab4 100644
--- a/tmpfiles.d/tmp.conf
+++ b/tmpfiles.d/tmp.conf
@@ -12,24 +12,7 @@ d /tmp 1777 root root 10d
 d /var/tmp 1777 root root 30d
 
 # Exclude namespace mountpoints created with PrivateTmp=yes
-x /tmp/systemd-*.service-*
-x /var/tmp/systemd-*.service-*
-X /tmp/systemd-*.service-*/tmp
-X /var/tmp/systemd-*.service-*/tmp
-x /tmp/systemd-*.socket-*
-x /var/tmp/systemd-*.socket-*
-X /tmp/systemd-*.socket-*/tmp
-X /var/tmp/systemd-*.socket-*/tmp
-x /tmp/systemd-*.mount-*
-x /var/tmp/systemd-*.mount-*
-X /tmp/systemd-*.mount-*/tmp
-X /var/tmp/systemd-*.mount-*/tmp
-x /tmp/systemd-*.swap-*
-x /var/tmp/systemd-*.swap-*
-X /tmp/systemd-*.swap-*/tmp
-X /var/tmp/systemd-*.swap-*/tmp
-# keep those for compatibility during upgrades
-x /tmp/systemd-private-*
-x /var/tmp/systemd-private-*
-X /tmp/systemd-private-*/tmp
-X /var/tmp/systemd-private-*/tmp
+x /tmp/systemd-private-%b-*
+X /tmp/systemd-private-%b-*/tmp
+x /var/tmp/systemd-private-%b-*
+X /var/tmp/systemd-private-%b-*/tmp

commit 6203e07a83214a55bb1f88508fcda2005c601dea
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Dec 12 22:21:25 2013 +0100

    event: rework sd-event exit logic
    
    With this change a failing event source handler will not cause the
    entire event loop to fail. Instead, we just disable the specific event
    source, log a message at debug level and go on.
    
    This also introduces a new concept of "exit code" which can be stored in
    the event loop and is returned by sd_event_loop(). We also rename "quit"
    to "exit" everywhere else.
    
    Altogether this should make things more robus and keep errors local
    while still providing a way to return event loop errors in a clear way.

diff --git a/TODO b/TODO
index dad55c4..4274b37 100644
--- a/TODO
+++ b/TODO
@@ -131,13 +131,10 @@ Features:
   - longer term:
     * priority queues
     * priority inheritance
+  - fix sd-event hookup when we connect to multiple servers one after the other
 
 * sd-event
   - allow multiple signal handlers per signal
-  - when a handler returns an error, just turn off its event source,
-    but do not return anything up to the event loop caller. Instead
-    add parameter to sd_event_request_quit() to take retval. This way
-    errors rippling upwards are the option, not the default
   - when dispatching an event source then _unref() on it should remove it from the epoll
 
 * in the final killing spree, detect processes from the root directory, and
diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
index 3f08d1c..eb2b35f 100644
--- a/src/hostname/hostnamed.c
+++ b/src/hostname/hostnamed.c
@@ -645,8 +645,6 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        r = 0;
-
 finish:
         context_free(&context, bus);
 
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 0f67fb8..3f8b95d 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1243,7 +1243,7 @@ static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *
 
         log_info("Received SIG%s", signal_to_string(si->ssi_signo));
 
-        sd_event_request_quit(s->event);
+        sd_event_exit(s->event, 0);
         return 0;
 }
 
diff --git a/src/libsystemd-bus/bus-util.c b/src/libsystemd-bus/bus-util.c
index 3afcb82..30ee67e 100644
--- a/src/libsystemd-bus/bus-util.c
+++ b/src/libsystemd-bus/bus-util.c
@@ -35,18 +35,18 @@
 #include "bus-util.h"
 #include "bus-internal.h"
 
-static int quit_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+static int name_owner_change_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
         sd_event *e = userdata;
 
         assert(bus);
         assert(m);
         assert(e);
 
-        sd_event_request_quit(e);
+        sd_event_exit(e, 0);
         return 1;
 }
 
-int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name) {
+int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) {
         _cleanup_free_ char *match = NULL;
         const char *unique;
         int r;
@@ -55,6 +55,11 @@ int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name) {
         assert(bus);
         assert(name);
 
+        /* We unregister the name here and then wait for the
+         * NameOwnerChanged signal for this event to arrive before we
+         * quit. We do this in order to make sure that any queued
+         * requests are still processed before we really exit. */
+
         r = sd_bus_get_unique_name(bus, &unique);
         if (r < 0)
                 return r;
@@ -71,7 +76,7 @@ int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name) {
         if (r < 0)
                 return -ENOMEM;
 
-        r = sd_bus_add_match(bus, match, quit_callback, e);
+        r = sd_bus_add_match(bus, match, name_owner_change_callback, e);
         if (r < 0)
                 return r;
 
@@ -84,7 +89,7 @@ int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name) {
 
 int bus_event_loop_with_idle(sd_event *e, sd_bus *bus, const char *name, usec_t timeout) {
         bool exiting = false;
-        int r;
+        int r, code;
 
         assert(e);
         assert(bus);
@@ -103,7 +108,7 @@ int bus_event_loop_with_idle(sd_event *e, sd_bus *bus, const char *name, usec_t
                         return r;
 
                 if (r == 0 && !exiting) {
-                        r = bus_async_unregister_and_quit(e, bus, name);
+                        r = bus_async_unregister_and_exit(e, bus, name);
                         if (r < 0)
                                 return r;
 
@@ -111,7 +116,11 @@ int bus_event_loop_with_idle(sd_event *e, sd_bus *bus, const char *name, usec_t
                 }
         }
 
-        return 0;
+        r = sd_event_get_exit_code(e, &code);
+        if (r < 0)
+                return r;
+
+        return code;
 }
 
 int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
diff --git a/src/libsystemd-bus/bus-util.h b/src/libsystemd-bus/bus-util.h
index 9d49237..9a90c2a 100644
--- a/src/libsystemd-bus/bus-util.h
+++ b/src/libsystemd-bus/bus-util.h
@@ -52,7 +52,7 @@ int bus_map_all_properties(sd_bus *bus,
                            const struct bus_properties_map *map,
                            void *userdata);
 
-int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name);
+int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name);
 
 int bus_event_loop_with_idle(sd_event *e, sd_bus *bus, const char *name, usec_t timeout);
 
diff --git a/src/libsystemd-bus/libsystemd-bus.sym b/src/libsystemd-bus/libsystemd-bus.sym
index 4a849b3..f3dbb76 100644
--- a/src/libsystemd-bus/libsystemd-bus.sym
+++ b/src/libsystemd-bus/libsystemd-bus.sym
@@ -227,15 +227,15 @@ global:
         sd_event_add_signal;
         sd_event_add_child;
         sd_event_add_defer;
-        sd_event_add_quit;
+        sd_event_add_exit;
 
         sd_event_run;
         sd_event_loop;
+        sd_event_exit;
 
         sd_event_get_state;
         sd_event_get_tid;
-        sd_event_get_quit;
-        sd_event_request_quit;
+        sd_event_get_exit_code;
         sd_event_get_now_realtime;
         sd_event_get_now_monotonic;
         sd_event_set_watchdog;
diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 060dcc1..a4709a1 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -2646,7 +2646,7 @@ _public_ int sd_bus_attach_event(sd_bus *bus, sd_event *event, int priority) {
         if (r < 0)
                 goto fail;
 
-        r = sd_event_add_quit(bus->event, quit_callback, bus, &bus->quit_event_source);
+        r = sd_event_add_exit(bus->event, quit_callback, bus, &bus->quit_event_source);
         if (r < 0)
                 goto fail;
 
diff --git a/src/libsystemd-bus/sd-event.c b/src/libsystemd-bus/sd-event.c
index 462dd41..b396432 100644
--- a/src/libsystemd-bus/sd-event.c
+++ b/src/libsystemd-bus/sd-event.c
@@ -44,7 +44,7 @@ typedef enum EventSourceType {
         SOURCE_SIGNAL,
         SOURCE_CHILD,
         SOURCE_DEFER,
-        SOURCE_QUIT,
+        SOURCE_EXIT,
         SOURCE_WATCHDOG
 } EventSourceType;
 
@@ -96,7 +96,7 @@ struct sd_event_source {
                 struct {
                         sd_event_handler_t callback;
                         unsigned prioq_index;
-                } quit;
+                } exit;
         };
 };
 
@@ -132,7 +132,7 @@ struct sd_event {
         Hashmap *child_sources;
         unsigned n_enabled_child_sources;
 
-        Prioq *quit;
+        Prioq *exit;
 
         pid_t original_pid;
 
@@ -140,10 +140,12 @@ struct sd_event {
         dual_timestamp timestamp;
         int state;
 
-        bool quit_requested:1;
+        bool exit_requested:1;
         bool need_process_child:1;
         bool watchdog:1;
 
+        int exit_code;
+
         pid_t tid;
         sd_event **default_event_ptr;
 
@@ -284,11 +286,11 @@ static int latest_time_prioq_compare(const void *a, const void *b) {
         return 0;
 }
 
-static int quit_prioq_compare(const void *a, const void *b) {
+static int exit_prioq_compare(const void *a, const void *b) {
         const sd_event_source *x = a, *y = b;
 
-        assert(x->type == SOURCE_QUIT);
-        assert(y->type == SOURCE_QUIT);
+        assert(x->type == SOURCE_EXIT);
+        assert(y->type == SOURCE_EXIT);
 
         /* Enabled ones first */
         if (x->enabled != SD_EVENT_OFF && y->enabled == SD_EVENT_OFF)
@@ -338,7 +340,7 @@ static void event_free(sd_event *e) {
         prioq_free(e->monotonic_latest);
         prioq_free(e->realtime_earliest);
         prioq_free(e->realtime_latest);
-        prioq_free(e->quit);
+        prioq_free(e->exit);
 
         free(e->signal_sources);
 
@@ -515,8 +517,8 @@ static void source_free(sd_event_source *s) {
                         /* nothing */
                         break;
 
-                case SOURCE_QUIT:
-                        prioq_remove(s->event->quit, s, &s->quit.prioq_index);
+                case SOURCE_EXIT:
+                        prioq_remove(s->event->exit, s, &s->exit.prioq_index);
                         break;
                 }
 
@@ -536,7 +538,7 @@ static int source_set_pending(sd_event_source *s, bool b) {
         int r;
 
         assert(s);
-        assert(s->type != SOURCE_QUIT);
+        assert(s->type != SOURCE_EXIT);
 
         if (s->pending == b)
                 return 0;
@@ -934,7 +936,7 @@ _public_ int sd_event_add_defer(
         return 0;
 }
 
-_public_ int sd_event_add_quit(
+_public_ int sd_event_add_exit(
                 sd_event *e,
                 sd_event_handler_t callback,
                 void *userdata,
@@ -949,22 +951,22 @@ _public_ int sd_event_add_quit(
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
-        if (!e->quit) {
-                e->quit = prioq_new(quit_prioq_compare);
-                if (!e->quit)
+        if (!e->exit) {
+                e->exit = prioq_new(exit_prioq_compare);
+                if (!e->exit)
                         return -ENOMEM;
         }
 
-        s = source_new(e, SOURCE_QUIT);
+        s = source_new(e, SOURCE_EXIT);
         if (!s)
                 return -ENOMEM;
 
-        s->quit.callback = callback;
+        s->exit.callback = callback;
         s->userdata = userdata;
-        s->quit.prioq_index = PRIOQ_IDX_NULL;
+        s->exit.prioq_index = PRIOQ_IDX_NULL;
         s->enabled = SD_EVENT_ONESHOT;
 
-        r = prioq_put(s->event->quit, s, &s->quit.prioq_index);
+        r = prioq_put(s->event->exit, s, &s->exit.prioq_index);
         if (r < 0) {
                 source_free(s);
                 return r;
@@ -1005,7 +1007,7 @@ _public_ sd_event *sd_event_source_get_event(sd_event_source *s) {
 
 _public_ int sd_event_source_get_pending(sd_event_source *s) {
         assert_return(s, -EINVAL);
-        assert_return(s->type != SOURCE_QUIT, -EDOM);
+        assert_return(s->type != SOURCE_EXIT, -EDOM);
         assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
@@ -1096,8 +1098,8 @@ _public_ int sd_event_source_set_priority(sd_event_source *s, int priority) {
         if (s->prepare)
                 prioq_reshuffle(s->event->prepare, s, &s->prepare_index);
 
-        if (s->type == SOURCE_QUIT)
-                prioq_reshuffle(s->event->quit, s, &s->quit.prioq_index);
+        if (s->type == SOURCE_EXIT)
+                prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
 
         return 0;
 }
@@ -1168,9 +1170,9 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
 
                         break;
 
-                case SOURCE_QUIT:
+                case SOURCE_EXIT:
                         s->enabled = m;
-                        prioq_reshuffle(s->event->quit, s, &s->quit.prioq_index);
+                        prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
                         break;
 
                 case SOURCE_DEFER:
@@ -1223,9 +1225,9 @@ _public_ int sd_event_source_set_enabled(sd_event_source *s, int m) {
                         }
                         break;
 
-                case SOURCE_QUIT:
+                case SOURCE_EXIT:
                         s->enabled = m;
-                        prioq_reshuffle(s->event->quit, s, &s->quit.prioq_index);
+                        prioq_reshuffle(s->event->exit, s, &s->exit.prioq_index);
                         break;
 
                 case SOURCE_DEFER:
@@ -1321,7 +1323,7 @@ _public_ int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t
         int r;
 
         assert_return(s, -EINVAL);
-        assert_return(s->type != SOURCE_QUIT, -EDOM);
+        assert_return(s->type != SOURCE_EXIT, -EDOM);
         assert_return(s->event->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(s->event), -ECHILD);
 
@@ -1673,9 +1675,9 @@ static int source_dispatch(sd_event_source *s) {
         int r = 0;
 
         assert(s);
-        assert(s->pending || s->type == SOURCE_QUIT);
+        assert(s->pending || s->type == SOURCE_EXIT);
 
-        if (s->type != SOURCE_DEFER && s->type != SOURCE_QUIT) {
+        if (s->type != SOURCE_DEFER && s->type != SOURCE_EXIT) {
                 r = source_set_pending(s, false);
                 if (r < 0)
                         return r;
@@ -1727,14 +1729,18 @@ static int source_dispatch(sd_event_source *s) {
                 r = s->defer.callback(s, s->userdata);
                 break;
 
-        case SOURCE_QUIT:
-                r = s->quit.callback(s, s->userdata);
+        case SOURCE_EXIT:
+                r = s->exit.callback(s, s->userdata);
                 break;
         }
 
-        sd_event_source_unref(s);
+        if (r < 0) {
+                log_debug("Event source %p returned error, disabling: %s", s, strerror(-r));
+                sd_event_source_set_enabled(s, SD_EVENT_OFF);
+        }
 
-        return r;
+        sd_event_source_unref(s);
+        return 1;
 }
 
 static int event_prepare(sd_event *e) {
@@ -1764,13 +1770,13 @@ static int event_prepare(sd_event *e) {
         return 0;
 }
 
-static int dispatch_quit(sd_event *e) {
+static int dispatch_exit(sd_event *e) {
         sd_event_source *p;
         int r;
 
         assert(e);
 
-        p = prioq_peek(e->quit);
+        p = prioq_peek(e->exit);
         if (!p || p->enabled == SD_EVENT_OFF) {
                 e->state = SD_EVENT_FINISHED;
                 return 0;
@@ -1778,7 +1784,7 @@ static int dispatch_quit(sd_event *e) {
 
         sd_event_ref(e);
         e->iteration++;
-        e->state = SD_EVENT_QUITTING;
+        e->state = SD_EVENT_EXITING;
 
         r = source_dispatch(p);
 
@@ -1850,8 +1856,8 @@ _public_ int sd_event_run(sd_event *e, uint64_t timeout) {
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(e->state == SD_EVENT_PASSIVE, -EBUSY);
 
-        if (e->quit_requested)
-                return dispatch_quit(e);
+        if (e->exit_requested)
+                return dispatch_exit(e);
 
         sd_event_ref(e);
         e->iteration++;
@@ -1946,7 +1952,7 @@ _public_ int sd_event_loop(sd_event *e) {
                         goto finish;
         }
 
-        r = 0;
+        r = e->exit_code;
 
 finish:
         sd_event_unref(e);
@@ -1960,19 +1966,26 @@ _public_ int sd_event_get_state(sd_event *e) {
         return e->state;
 }
 
-_public_ int sd_event_get_quit(sd_event *e) {
+_public_ int sd_event_get_exit_code(sd_event *e, int *code) {
         assert_return(e, -EINVAL);
+        assert_return(code, -EINVAL);
         assert_return(!event_pid_changed(e), -ECHILD);
 
-        return e->quit_requested;
+        if (!e->exit_requested)
+                return -ENODATA;
+
+        *code = e->exit_code;
+        return 0;
 }
 
-_public_ int sd_event_request_quit(sd_event *e) {
+_public_ int sd_event_exit(sd_event *e, int code) {
         assert_return(e, -EINVAL);
         assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
         assert_return(!event_pid_changed(e), -ECHILD);
 
-        e->quit_requested = true;
+        e->exit_requested = true;
+        e->exit_code = code;
+
         return 0;
 }
 
diff --git a/src/libsystemd-bus/test-event.c b/src/libsystemd-bus/test-event.c
index 2b91eb0..5317008 100644
--- a/src/libsystemd-bus/test-event.c
+++ b/src/libsystemd-bus/test-event.c
@@ -63,7 +63,7 @@ static int child_handler(sd_event_source *s, const siginfo_t *si, void *userdata
 
         assert(userdata == INT_TO_PTR('f'));
 
-        assert_se(sd_event_request_quit(sd_event_source_get_event(s)) >= 0);
+        assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0);
         sd_event_source_unref(s);
 
         return 1;
@@ -143,12 +143,12 @@ static int time_handler(sd_event_source *s, uint64_t usec, void *userdata) {
         return 2;
 }
 
-static bool got_quit = false;
+static bool got_exit = false;
 
-static int quit_handler(sd_event_source *s, void *userdata) {
+static int exit_handler(sd_event_source *s, void *userdata) {
         log_info("got quit handler on %c", PTR_TO_INT(userdata));
 
-        got_quit = true;
+        got_exit = true;
 
         return 3;
 }
@@ -183,7 +183,7 @@ int main(int argc, char *argv[]) {
         assert_se(sd_event_add_io(e, a[0], EPOLLIN, io_handler, INT_TO_PTR('a'), &x) >= 0);
         assert_se(sd_event_add_io(e, b[0], EPOLLIN, io_handler, INT_TO_PTR('b'), &y) >= 0);
         assert_se(sd_event_add_monotonic(e, 0, 0, time_handler, INT_TO_PTR('c'), &z) >= 0);
-        assert_se(sd_event_add_quit(e, quit_handler, INT_TO_PTR('g'), &q) >= 0);
+        assert_se(sd_event_add_exit(e, exit_handler, INT_TO_PTR('g'), &q) >= 0);
 
         assert_se(sd_event_source_set_priority(x, 99) >= 0);
         assert_se(sd_event_source_set_enabled(y, SD_EVENT_ONESHOT) >= 0);
diff --git a/src/libsystemd-rtnl/rtnl-internal.h b/src/libsystemd-rtnl/rtnl-internal.h
index dabf12d..a1050a0 100644
--- a/src/libsystemd-rtnl/rtnl-internal.h
+++ b/src/libsystemd-rtnl/rtnl-internal.h
@@ -74,7 +74,7 @@ struct sd_rtnl {
 
         sd_event_source *io_event_source;
         sd_event_source *time_event_source;
-        sd_event_source *quit_event_source;
+        sd_event_source *exit_event_source;
         sd_event *event;
 };
 
diff --git a/src/libsystemd-rtnl/sd-rtnl.c b/src/libsystemd-rtnl/sd-rtnl.c
index 57d0b76..98d0f89 100644
--- a/src/libsystemd-rtnl/sd-rtnl.c
+++ b/src/libsystemd-rtnl/sd-rtnl.c
@@ -743,7 +743,7 @@ static int prepare_callback(sd_event_source *s, void *userdata) {
         return 1;
 }
 
-static int quit_callback(sd_event_source *event, void *userdata) {
+static int exit_callback(sd_event_source *event, void *userdata) {
         sd_rtnl *rtnl = userdata;
 
         assert(event);
@@ -790,7 +790,7 @@ int sd_rtnl_attach_event(sd_rtnl *rtnl, sd_event *event, int priority) {
         if (r < 0)
                 goto fail;
 
-        r = sd_event_add_quit(rtnl->event, quit_callback, rtnl, &rtnl->quit_event_source);
+        r = sd_event_add_exit(rtnl->event, exit_callback, rtnl, &rtnl->exit_event_source);
         if (r < 0)
                 goto fail;
 
@@ -811,8 +811,8 @@ int sd_rtnl_detach_event(sd_rtnl *rtnl) {
         if (rtnl->time_event_source)
                 rtnl->time_event_source = sd_event_source_unref(rtnl->time_event_source);
 
-        if (rtnl->quit_event_source)
-                rtnl->quit_event_source = sd_event_source_unref(rtnl->quit_event_source);
+        if (rtnl->exit_event_source)
+                rtnl->exit_event_source = sd_event_source_unref(rtnl->exit_event_source);
 
         if (rtnl->event)
                 rtnl->event = sd_event_unref(rtnl->event);
diff --git a/src/locale/localed.c b/src/locale/localed.c
index 65318b6..2c90180 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -1155,8 +1155,6 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        r = 0;
-
 finish:
         context_free(&context, bus);
 
diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h
index 3551077..c7c4506 100644
--- a/src/systemd/sd-event.h
+++ b/src/systemd/sd-event.h
@@ -53,7 +53,7 @@ enum {
 enum {
         SD_EVENT_PASSIVE,
         SD_EVENT_RUNNING,
-        SD_EVENT_QUITTING,
+        SD_EVENT_EXITING,
         SD_EVENT_FINISHED
 };
 
@@ -82,15 +82,15 @@ int sd_event_add_realtime(sd_event *e, uint64_t usec, uint64_t accuracy, sd_even
 int sd_event_add_signal(sd_event *e, int sig, sd_event_signal_handler_t callback, void *userdata, sd_event_source **s);
 int sd_event_add_child(sd_event *e, pid_t pid, int options, sd_event_child_handler_t callback, void *userdata, sd_event_source **s);
 int sd_event_add_defer(sd_event *e, sd_event_handler_t callback, void *userdata, sd_event_source **s);
-int sd_event_add_quit(sd_event *e, sd_event_handler_t callback, void *userdata, sd_event_source **s);
+int sd_event_add_exit(sd_event *e, sd_event_handler_t callback, void *userdata, sd_event_source **s);
 
 int sd_event_run(sd_event *e, uint64_t timeout);
 int sd_event_loop(sd_event *e);
+int sd_event_exit(sd_event *e, int code);
 
 int sd_event_get_state(sd_event *e);
 int sd_event_get_tid(sd_event *e, pid_t *tid);
-int sd_event_get_quit(sd_event *e);
-int sd_event_request_quit(sd_event *e);
+int sd_event_get_exit_code(sd_event *e, int *code);
 int sd_event_get_now_realtime(sd_event *e, uint64_t *usec);
 int sd_event_get_now_monotonic(sd_event *e, uint64_t *usec);
 int sd_event_set_watchdog(sd_event *e, int b);
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
index 37173a2..8ac933c 100644
--- a/src/timedate/timedated.c
+++ b/src/timedate/timedated.c
@@ -863,8 +863,6 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        r = 0;
-
 finish:
         context_free(&context, bus);
 

commit 6e41a3e53d858f30e131c62350f51465558ca55c
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Dec 12 22:18:09 2013 +0100

    bus: fix make check

diff --git a/src/libsystemd-bus/test-bus-zero-copy.c b/src/libsystemd-bus/test-bus-zero-copy.c
index 07ccbc3..054c4c7 100644
--- a/src/libsystemd-bus/test-bus-zero-copy.c
+++ b/src/libsystemd-bus/test-bus-zero-copy.c
@@ -133,7 +133,7 @@ int main(int argc, char *argv[]) {
         r = sd_bus_message_append(m, "u", 4711);
         assert_se(r >= 0);
 
-        r = bus_message_seal(m, 55, 0);
+        r = bus_message_seal(m, 55, 99*USEC_PER_SEC);
         assert_se(r >= 0);
 
         bus_message_dump(m, stdout, true);

commit 33cb6e7934a57f508a164eb6d33a044efad75ab7
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Dec 12 22:17:38 2013 +0100

    bus: properly parse NameOwnerChanged messages when caller explicitly wants to match against names coming/going

diff --git a/src/libsystemd-bus/bus-control.c b/src/libsystemd-bus/bus-control.c
index db7263f..5125fd9 100644
--- a/src/libsystemd-bus/bus-control.c
+++ b/src/libsystemd-bus/bus-control.c
@@ -741,7 +741,7 @@ static int add_name_change_match(sd_bus *bus,
                         return 0;
         }
 
-        if (old_owner) {
+        if (!isempty(old_owner)) {
                 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
                 if (r < 0)
                         return 0;
@@ -751,7 +751,7 @@ static int add_name_change_match(sd_bus *bus,
                         return 0;
         }
 
-        if (new_owner) {
+        if (!isempty(new_owner)) {
                 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
                 if (r < 0)
                         return r;

commit b408e2a8be6b87fd1796c45a767d00bbb00d7148
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Dec 12 22:01:40 2013 +0100

    man: update sd_bus_request_name() man page

diff --git a/man/sd_bus_request_name.xml b/man/sd_bus_request_name.xml
index 6e61a88..039b962 100644
--- a/man/sd_bus_request_name.xml
+++ b/man/sd_bus_request_name.xml
@@ -106,9 +106,9 @@
                         </varlistentry>
 
                         <varlistentry>
-                                <term><varname>SD_BUS_NAME_DO_NOT_QUEUE</varname></term>
+                                <term><varname>SD_BUS_NAME_QUEUE</varname></term>
 
-                                <listitem><para>Do not queue name
+                                <listitem><para>Queue name
                                 acquisition when the name is already
                                 taken.</para></listitem>
                         </varlistentry>
@@ -126,16 +126,15 @@
                 integer. On failure, these calls return a negative
                 errno-style error code.</para>
 
-                <para><function>sd_bus_request_name()</function> will
-                return 0 when the name is already taken by another
-                peer and the client has been added to the queue for
-                the name, unless
-                <varname>SD_BUS_NAME_DO_NOT_QUEUE</varname> has been
-                set. The caller can subscribe to
-                <literal>NameOwnerChanged</literal> signals to be
-                notified when the name is successfully
-                acquired. <function>sd_bus_request_name()</function> returns
-                > 0 when the name has been
+                <para>If <varname>SD_BUS_NAME_QUEUE</varname> is
+                specified <function>sd_bus_request_name()</function>
+                will return 0 when the name is already taken by
+                another peer and the client has been added to the
+                queue for the name. In that case the caller can
+                subscribe to <literal>NameOwnerChanged</literal>
+                signals to be notified when the name is successfully
+                acquired. <function>sd_bus_request_name()</function>
+                returns > 0 when the name has immediately been
                 acquired successfully.</para>
         </refsect1>
 

commit 11846aa74680bab65711427b1e7702e783b2894c
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Dec 12 21:25:47 2013 +0100

    bus: make sure exit-on-idle logic works on kdbus systems that do not generate NameLost

diff --git a/src/libsystemd-bus/bus-util.c b/src/libsystemd-bus/bus-util.c
index 9a42b05..3afcb82 100644
--- a/src/libsystemd-bus/bus-util.c
+++ b/src/libsystemd-bus/bus-util.c
@@ -48,16 +48,29 @@ static int quit_callback(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_
 
 int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name) {
         _cleanup_free_ char *match = NULL;
+        const char *unique;
         int r;
 
         assert(e);
         assert(bus);
         assert(name);
 
-        r = asprintf(&match, "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameLost',arg0='%s'", name);
+        r = sd_bus_get_unique_name(bus, &unique);
         if (r < 0)
                 return r;
 
+        r = asprintf(&match,
+                     "sender='org.freedesktop.DBus',"
+                     "type='signal',"
+                     "interface='org.freedesktop.DBus',"
+                     "member='NameOwnerChanged',"
+                     "path='/org/freedesktop/DBus',"
+                     "arg0='%s',"
+                     "arg1='%s',"
+                     "arg2=''", name, unique);
+        if (r < 0)
+                return -ENOMEM;
+
         r = sd_bus_add_match(bus, match, quit_callback, e);
         if (r < 0)
                 return r;
@@ -66,9 +79,6 @@ int bus_async_unregister_and_quit(sd_event *e, sd_bus *bus, const char *name) {
         if (r < 0)
                 return r;
 
-        if (r != BUS_NAME_RELEASED)
-                return -EIO;
-
         return 0;
 }
 

commit 2c8d477a01cd154bbaab6c46a5ffeed3e55f1a6b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Dec 12 21:25:31 2013 +0100

    bus: fix parsing of matches against empty strings

diff --git a/src/libsystemd-bus/bus-match.c b/src/libsystemd-bus/bus-match.c
index f7fca5f..342819d 100644
--- a/src/libsystemd-bus/bus-match.c
+++ b/src/libsystemd-bus/bus-match.c
@@ -755,6 +755,14 @@ int bus_match_parse(
                         escaped = false;
                 }
 
+                if (!value) {
+                        value = strdup("");
+                        if (!value) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+                }
+
                 if (t == BUS_MATCH_MESSAGE_TYPE) {
                         r = bus_message_type_from_string(value, &u);
                         if (r < 0)



More information about the systemd-commits mailing list