]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind: stop managing VT switches if no sessions are registered on that VT 9961/head
authorFranck Bui <fbui@suse.com>
Mon, 27 Aug 2018 21:16:10 +0000 (23:16 +0200)
committerFranck Bui <fbui@suse.com>
Wed, 21 Nov 2018 13:29:01 +0000 (14:29 +0100)
When no sessions are registered on a given VT (anymore), we should always let
the kernel processes VT switching (instead of simply emitting a warning)
otherwise the requests sent by the kernel are simply ignored making the VT
switch requested by users simply impossible.

Even if it shouldn't happen, this case was encountered in issue #9754, so
better to be safe than sorry.

src/login/logind.c

index f419186506f23e404cb4fcf6f4e593c658bf17f7..b8530520efef973d9e901b2e50522dd92270a722 100644 (file)
@@ -25,6 +25,7 @@
 #include "selinux-util.h"
 #include "signal-util.h"
 #include "strv.h"
+#include "terminal-util.h"
 
 static Manager* manager_unref(Manager *m);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_unref);
@@ -747,7 +748,29 @@ static int manager_vt_switch(sd_event_source *src, const struct signalfd_siginfo
 
         active = m->seat0->active;
         if (!active || active->vtnr < 1) {
-                log_warning("Received VT_PROCESS signal without a registered session on that VT.");
+                _cleanup_close_ int fd = -1;
+                int r;
+
+                /* We are requested to acknowledge the VT-switch signal by the kernel but
+                 * there's no registered sessions for the current VT. Normally this
+                 * shouldn't happen but something wrong might have happened when we tried
+                 * to release the VT. Better be safe than sorry, and try to release the VT
+                 * one more time otherwise the user will be locked with the current VT. */
+
+                log_warning("Received VT_PROCESS signal without a registered session, restoring VT.");
+
+                /* At this point we only have the kernel mapping for referring to the
+                 * current VT. */
+                fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
+                if (fd < 0) {
+                        log_warning_errno(fd, "Failed to open, ignoring: %m");
+                        return 0;
+                }
+
+                r = vt_release(fd, true);
+                if (r < 0)
+                        log_warning_errno(r, "Failed to release VT, ignoring: %m");
+
                 return 0;
         }