diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 92d588b276..89dbfe840a 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); }