[PATCH 3/3] systemd-logind: Monitor systemd-logind going away

Hans de Goede hdegoede at redhat.com
Mon Mar 24 08:32:01 PDT 2014


When we're using server managed-fds through systemd-logind, systemd-logind
*must* keep running while we are using it, as it does things like drmSetMaster
and drmDropMaster for us on vt-switch.

On a systemd-logind restart, we cannot simply re-connect since we will then
get a different fd for the /dev/dri/card# node, and we've tied a lot of
state to the old fd. I've discussed this with the systemd people, and in the
future there me be a restart mechanism were systemd-logind passed fds from
the old logind to the new logind. But for now there answer is simply:
"Don't restart systemd-logind", and there never really is a good reason to
restart it.

So to ensure unpleasentness if people do decide to restart systemd-logind
anyways (or when it crashes), monitor logind going away and make this a fatal
error. This avoids getting a hard-hung machine on the next vt-switch and will
hopefully quickly educate users to not restart systemd-logind while they have
an X session using it active.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 hw/xfree86/os-support/linux/systemd-logind.c | 34 ++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/hw/xfree86/os-support/linux/systemd-logind.c b/hw/xfree86/os-support/linux/systemd-logind.c
index 62858b0..d11519b 100644
--- a/hw/xfree86/os-support/linux/systemd-logind.c
+++ b/hw/xfree86/os-support/linux/systemd-logind.c
@@ -310,10 +310,31 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data)
     dbus_int32_t major, minor;
     char *pause_str;
 
-    if (strcmp(dbus_message_get_path(message), info->session) != 0)
+    dbus_error_init(&error);
+
+    if (dbus_message_is_signal(message,
+                               "org.freedesktop.DBus", "NameOwnerChanged")) {
+        char *name, *old_owner, *new_owner;
+
+        dbus_message_get_args(message, &error,
+                              DBUS_TYPE_STRING, &name,
+                              DBUS_TYPE_STRING, &old_owner,
+                              DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID);
+        if (dbus_error_is_set(&error)) {
+            LogMessage(X_ERROR, "systemd-logind: NameOwnerChanged: %s\n",
+                       error.message);
+            dbus_error_free(&error);
+            return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+        }
+
+        if (name && strcmp(name, "org.freedesktop.login1") == 0)
+            FatalError("systemd-logind disappeared (stopped / restarted?)\n");
+
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    }
 
-    dbus_error_init(&error);
+    if (strcmp(dbus_message_get_path(message), info->session) != 0)
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
     if (dbus_message_is_signal(message, "org.freedesktop.login1.Session",
                                "PauseDevice")) {
@@ -472,6 +493,15 @@ connect_hook(DBusConnection *connection, void *data)
         goto cleanup;
     }
 
+    dbus_bus_add_match(connection,
+        "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',path='/org/freedesktop/DBus'",
+        &error);
+    if (dbus_error_is_set(&error)) {
+        LogMessage(X_ERROR, "systemd-logind: could not add match: %s\n",
+                   error.message);
+        goto cleanup;
+    }
+
     /*
      * HdG: This is not useful with systemd <= 208 since the signal only
      * contains invalidated property names there, rather than property, val
-- 
1.9.0



More information about the xorg-devel mailing list