summaryrefslogtreecommitdiff
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
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
-rw-r--r--TODO9
-rw-r--r--src/dbus-manager.c4
-rw-r--r--src/dbus.c46
-rw-r--r--src/dbus.h2
-rw-r--r--src/fdset.c2
-rw-r--r--src/manager.c4
-rw-r--r--src/systemctl.c7
7 files changed, 68 insertions, 6 deletions
diff --git a/TODO b/TODO
index be964623cc..3f26e2ea5f 100644
--- a/TODO
+++ b/TODO
@@ -5,6 +5,9 @@ F15:
* 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown
(path: after installing inotify watches, recheck file again to fix race)
+* move systemadm man page to systemd-gtk
+ https://bugzilla.redhat.com/show_bug.cgi?id=699394
+
F15 External:
* NFS, networkmanager ordering issue (PENDING)
@@ -28,6 +31,10 @@ F15 External:
Features:
+* drop /.readahead on bigger upgrades with yum
+
+* add inode stat() check to readahead
+
* plymouth.enable=0
* introduce dbus calls for enabling/disabling a service
@@ -60,8 +67,6 @@ Features:
* rename systemd-logger to systemd-stdio-syslog-bridge
-* introduce /usr/lib/binfmt.d/, /usr/lib/tmpfiles.d/
-
* take BSD file lock on tty devices when using them?
* avoid any flag files, or readahead files in /, we need to support r/o /
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index 9776b0b9de..797e53d10f 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -922,8 +922,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
} else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "Reexecute")) {
- if (!(reply = dbus_message_new_method_return(message)))
- goto oom;
+ /* We don't send a reply back here, the client should
+ * just wait for us disconnecting. */
m->exit_code = MANAGER_REEXECUTE;
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;
+}
diff --git a/src/dbus.h b/src/dbus.h
index 57a2b388ca..8387ffaa72 100644
--- a/src/dbus.h
+++ b/src/dbus.h
@@ -43,6 +43,8 @@ int bus_parse_strv(DBusMessage *m, char ***_l);
bool bus_has_subscriber(Manager *m);
bool bus_connection_has_subscriber(Manager *m, DBusConnection *c);
+int bus_fdset_add_all(Manager *m, FDSet *fds);
+
#define BUS_CONNECTION_SUBSCRIBED(m, c) dbus_connection_get_data((c), (m)->subscribed_data_slot)
#define BUS_PENDING_CALL_NAME(m, p) dbus_pending_call_get_data((p), (m)->name_data_slot)
diff --git a/src/fdset.c b/src/fdset.c
index 29e75a0346..9bf3788849 100644
--- a/src/fdset.c
+++ b/src/fdset.c
@@ -49,7 +49,7 @@ void fdset_free(FDSet *s) {
* here, so that the EBADFD that valgrind will return
* us on close() doesn't influence us */
- /* log_warning("Closing left-over fd %i", PTR_TO_FD(p)); */
+ log_debug("Closing left-over fd %i", PTR_TO_FD(p));
close_nointr(PTR_TO_FD(p));
}
diff --git a/src/manager.c b/src/manager.c
index 084b41f13e..68d43ada44 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -2688,6 +2688,10 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds) {
if (ferror(f))
return -EIO;
+ r = bus_fdset_add_all(m, fds);
+ if (r < 0)
+ return r;
+
return 0;
}
diff --git a/src/systemctl.c b/src/systemctl.c
index 10c6319b4e..99ada38309 100644
--- a/src/systemctl.c
+++ b/src/systemctl.c
@@ -3323,6 +3323,13 @@ static int daemon_reload(DBusConnection *bus, char **args, unsigned n) {
goto finish;
}
+ if (streq(method, "Reexecute") && dbus_error_has_name(&error, DBUS_ERROR_NO_REPLY)) {
+ /* On reexecution, we expect a disconnect, not
+ * a reply */
+ r = 0;
+ goto finish;
+ }
+
log_error("Failed to issue method call: %s", bus_error_message(&error));
r = -EIO;
goto finish;