[PATCH] drm: retry opening input_source indefinitely

Anisse Astier anisse at astier.eu
Mon Dec 17 03:30:00 PST 2012


Because since commit 89097d735f78 "we no longer can guarantee the
terminal is reopened by the time on_input_source_disconnected is called"
(Ray Strode), what would happen before this patch is the following:

 -> tty gets closed by kernel (see
    https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245)
 -> plymouth core tries to reopen the console using main loop facility
    ply_event_loop_watch_for_timeout.
 -> After the first attempt fails, and before the second attempt, drm
    plugin is also notified with on_input_source_disconnected (if we use the
    same tty, which is the case on debian with /dev/tty7) and calls
    open_input_source
 -> open_input source 'reopens' by calling ply_terminal_get_fd, which
		will return an invalid fd (-1). But it isn't checked, and then it
    watches this fd with ply_event_loop_watch_fd
 -> which has an assert (fd >= 0); that causes plymouth to stop itself.
 -> plymouth stops itself without calling ply_terminal_unlock, which
		leaves a TIOCSLCKTRMIOS type lock on the tty, making Xorg unable to
    modify its parameters (for example ISIG, which kills it once you press
    enter...)

This was reproduced reliably on a Toshiba C660D-10L (PSC0WE) laptop,
with an AMD V140/RS880M CPU/GPU combo, on a debian squeeze based system.

What this patch does is modify drm plugin so it keeps trying to get a
valid fd for the console. This way it doesn't interfere with
ply-terminal's reopening loop. If it can never reopen it, it also
doesn't prevent plymouth to stop itsefl properly when it receives the
quit command.

This patch isn't ideal, to quote Ray Strode:
"What we really need is a way to have the terminal tell us when its
opened and closed directly, rather than relying on the event loop
callback. And then call open_input_source in response to the terminal
telling us it's opened"

I hope this can be a good base, and at least a good explanation for the bug.
---
 src/plugins/renderers/drm/plugin.c |   22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c
index db953e6..f0b3a30 100644
--- a/src/plugins/renderers/drm/plugin.c
+++ b/src/plugins/renderers/drm/plugin.c
@@ -1244,11 +1244,31 @@ on_key_event (ply_renderer_input_source_t *input_source,
 }
 
 static void
+reopen_input_source (ply_renderer_input_source_t *input_source)
+{
+  int terminal_fd = ply_terminal_get_fd (input_source->backend->terminal);
+  if (terminal_fd < 0)
+    {
+     ply_trace ("Terminal fd is invalid. Retrying in 0.1 seconds");
+      /* Keep trying. There's no hurry */
+     ply_event_loop_watch_for_timeout (input_source->backend->loop,
+                                       0.1,
+                                       (ply_event_loop_timeout_handler_t)
+                                       reopen_input_source,
+                                       input_source);
+    }
+  else
+    {
+      open_input_source (input_source->backend, input_source);
+    }
+}
+
+static void
 on_input_source_disconnected (ply_renderer_input_source_t *input_source)
 {
   ply_trace ("input source disconnected, reopening");
 
-  open_input_source (input_source->backend, input_source);
+  reopen_input_source (input_source);
 }
 
 static bool
-- 
1.7.10.5



More information about the plymouth mailing list