diff options
author | Lennart Poettering <lennart@poettering.net> | 2011-04-28 22:07:01 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2011-04-28 22:07:01 +0200 |
commit | b23de6af893c11da4286bc416455cd0926d1532e (patch) | |
tree | e2a7e00fcedc9b8314b7035f3a4fdb6eca05bead /src/dbus.c | |
parent | b4bd51448fa8b7574e9a92af50b58da9bb0dfb5e (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.c | 46 |
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; +} |