summaryrefslogtreecommitdiff
path: root/src/dbus.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2011-04-28 22:07:01 +0200
committerLennart Poettering <lennart@poettering.net>2011-04-28 22:07:01 +0200
commitb23de6af893c11da4286bc416455cd0926d1532e (patch)
treee2a7e00fcedc9b8314b7035f3a4fdb6eca05bead /src/dbus.c
parentb4bd51448fa8b7574e9a92af50b58da9bb0dfb5e (diff)
dbus: make daemon reexecution synchronous
We simply keep open copies of the dbus connections across the reexecution and close them as last step of it. A client can thus simply wait until its connection is dropped to know when the reexecution is finished. https://bugzilla.redhat.com/show_bug.cgi?id=698198
Diffstat (limited to 'src/dbus.c')
-rw-r--r--src/dbus.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/src/dbus.c b/src/dbus.c
index 1907560bc0..8ea768c5a7 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -598,7 +598,12 @@ static void request_name_pending_cb(DBusPendingCall *pending, void *userdata) {
static int request_name(Manager *m) {
const char *name = "org.freedesktop.systemd1";
- uint32_t flags = 0;
+ /* Allow replacing of our name, to ease implementation of
+ * reexecution, where we keep the old connection open until
+ * after the new connection is set up and the name installed
+ * to allow clients to synchronously wait for reexecution to
+ * finish */
+ uint32_t flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT|DBUS_NAME_FLAG_REPLACE_EXISTING;
DBusMessage *message = NULL;
DBusPendingCall *pending = NULL;
@@ -1305,3 +1310,42 @@ bool bus_connection_has_subscriber(Manager *m, DBusConnection *c) {
return !set_isempty(BUS_CONNECTION_SUBSCRIBED(m, c));
}
+
+int bus_fdset_add_all(Manager *m, FDSet *fds) {
+ Iterator i;
+ DBusConnection *c;
+
+ assert(m);
+ assert(fds);
+
+ /* When we are about to reexecute we add all D-Bus fds to the
+ * set to pass over to the newly executed systemd. They won't
+ * be used there however, except that they are closed at the
+ * very end of deserialization, those making it possible for
+ * clients to synchronously wait for systemd to reexec buy
+ * simply waiting for disconnection */
+
+ SET_FOREACH(c, m->bus_connections_for_dispatch, i) {
+ int fd;
+
+ if (dbus_connection_get_unix_fd(c, &fd)) {
+ fd = fdset_put_dup(fds, fd);
+
+ if (fd < 0)
+ return fd;
+ }
+ }
+
+ SET_FOREACH(c, m->bus_connections, i) {
+ int fd;
+
+ if (dbus_connection_get_unix_fd(c, &fd)) {
+ fd = fdset_put_dup(fds, fd);
+
+ if (fd < 0)
+ return fd;
+ }
+ }
+
+ return 0;
+}