Bug 6734

Summary: evdev does not ensure inotify fd is O_NONBLOCK
Product: xorg Reporter: Philip Langdale <xorgbugs.philipl>
Component: Input/evdevAssignee: Zephaniah E. Hull <warp-spam+fdo>
Status: RESOLVED FIXED QA Contact:
Severity: major    
Priority: high Keywords: patch
Version: git   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
Always set O_NONBLOCK on the inotify fd none

Description Philip Langdale 2006-04-25 13:29:44 UTC
This is with the 1.1.1 driver compiled against Xorg 7.0 and running against 6.9.
if that's a hopeless combination, let me know.

When I plug or unplug an input device, the X server locks up cold, although it
may actually have segfaulted and then stuck in the signal handler.
Comment 1 Zephaniah E. Hull 2006-04-27 00:50:17 UTC
(In reply to comment #0)
> This is with the 1.1.1 driver compiled against Xorg 7.0 and running against 6.9.
> if that's a hopeless combination, let me know.

...

The only way I can think of for that to happen would...  Yeah, it would qualify
as a pretty hopeless situation.

In theory, that ABI should be constant, except that things were subtily broken
when we killed the libc wrapper.

What kernel are you running?
Comment 2 Philip Langdale 2006-04-27 01:14:56 UTC
2.6.16.2

You're saying that there's actually an ABI difference between 6.9 and 7? or does
evdev 1.1.1 actually require a newer server version?
Comment 3 Philip Langdale 2006-05-01 05:12:45 UTC
So, I've investigated more and this is very curious. The X server is not
crashed. It seems to be stuck. And the weirdest part is that if I attach gdb to
the server and then 'continue', the server comes back to life and everything is
good again.

If gdb is reliable, the server gets stuck in:

#0  0xffffe410 in __kernel_vsyscall ()
#1  0xb7e4e543 in read () from /lib/tls/i686/cmov/libc.so.6
#2  0xb79ef760 in evdevReadInput ()
   from /usr/lib/xorg/modules/input/evdev_drv.so
#3  0x080b4be0 in xf86Wakeup ()
#4  0x08089ad7 in WakeupHandler ()
#5  0x0818f96e in WaitForSomething ()
#6  0x08085c16 in Dispatch ()
#7  0x0806e0a8 in main ()

I also note that sending a non-fatal handled signal to the server also unsticks
it. For example USR1 (fake VT switch) or ironically USR2 (Reload input devices).
This kind of behaviour seems really evil.
Comment 4 Philip Langdale 2006-05-01 07:05:40 UTC
Created attachment 5534 [details] [review]
Always set O_NONBLOCK on the inotify fd

Ok, It was simple. The while loop doing the reading on the inotify fd clearly
expects the fd to be O_NONBLOCK but it is not in practice. This is not the case
on Ubuntu Dapper 2.6.15 and with kernel.org 2.6.16. Perhaps your particular
kernel has been tweaked so that it is NONBLOCK by default.

This patch turns on O_NONBLOCK for the fd and now it works as expected.
Comment 5 Zephaniah E. Hull 2006-05-01 07:46:36 UTC
(In reply to comment #4)
> Created an attachment (id=5534) [edit]
> Always set O_NONBLOCK on the inotify fd
> 
> Ok, It was simple. The while loop doing the reading on the inotify fd clearly
> expects the fd to be O_NONBLOCK but it is not in practice. This is not the case
> on Ubuntu Dapper 2.6.15 and with kernel.org 2.6.16. Perhaps your particular
> kernel has been tweaked so that it is NONBLOCK by default.

Interesting, I'm running a stock kernel and I'm not having any problems.

That said, this patch is IMHO obviously correct, and so I've applied it and
released 1.1.2.

Thank you very much for tracking it down.
> 
> This patch turns on O_NONBLOCK for the fd and now it works as expected.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.