From: msizanoen Date: Thu, 24 Aug 2023 09:42:37 +0000 (+0700) Subject: login: Properly handle -EIO in session_leave_vt X-Git-Tag: v255-rc1~631 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=99d4ad71b72045d6352ba221105843fc6b600717;p=thirdparty%2Fsystemd.git login: Properly handle -EIO in session_leave_vt session_leave_vt may be called after the VT device was hung up, which will cause vt_release to fail with -EIO. This is known to cause an issue with GNOME 44 on Fedora where gdm-session-worker sometimes freezes when trying to switch to VT 1 after a `loginctl terminate-user` operation. Fix this by reopening the VT in session_leave_vt if we get an -EIO. --- diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 92d588b2764..89dbfe840ad 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -1415,6 +1415,23 @@ void session_leave_vt(Session *s) { session_device_pause_all(s); r = vt_release(s->vtfd, false); + if (r == -EIO) { + int vt, old_fd; + + /* It might happen if the controlling process exited before or while we were + * restoring the VT as it would leave the old file-descriptor in a hung-up + * state. In this case let's retry with a fresh handle to the virtual terminal. */ + + /* We do a little dance to avoid having the terminal be available + * for reuse before we've cleaned it up. */ + old_fd = TAKE_FD(s->vtfd); + + vt = session_open_vt(s); + safe_close(old_fd); + + if (vt >= 0) + r = vt_release(vt, false); + } if (r < 0) log_debug_errno(r, "Cannot release VT of session %s: %m", s->id); }