From 4a1e58fd29c7cdf48dea879191a45db2cfcca0d1 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 20 Nov 2010 17:57:22 +0100 Subject: Retry opening console device on EIO As reported in https://launchpad.net/bugs/544139, ConsoleKit sometimes fails to track the active VT. This particular case was tracked down to a race condition that happens if you try to open /dev/console while the current TTY is currently being closed. This yields an -EIO error, in which case CK should just try again. For a more detailled summary of the problem from a kernel perspective, please see https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245 . https://bugs.freedesktop.org/show_bug.cgi?id=31790 --- src/ck-sysdeps-unix.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/ck-sysdeps-unix.c b/src/ck-sysdeps-unix.c index e4ab16b..4a1736c 100644 --- a/src/ck-sysdeps-unix.c +++ b/src/ck-sysdeps-unix.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -150,9 +151,25 @@ open_a_console (char *fnam) { int fd; +again: fd = open (fnam, O_RDONLY | O_NOCTTY); if (fd < 0 && errno == EACCES) fd = open (fnam, O_WRONLY | O_NOCTTY); +#ifdef __linux__ + if (fd < 0 && errno == EIO) { + /* Linux can return EIO if the tty is currently closing, + * which can happen if multiple processes are opening and + * closing the console in parallel. Unfortunately it can + * also return EIO in more serious situations too (see + * https://bugs.launchpad.net/bugs/554172), but there isn't + * much we can do about that since we really need a console + * fd. + */ + struct timespec ts = { 0, 100000000 }; /* 0.1 seconds */ + nanosleep (&ts, NULL); + goto again; + } +#endif if (fd < 0) return -1; -- cgit v1.2.3