Kernel Bug Tracker – Bug 11014
Weird select(2) behaviour with certain files in sysfs
Last modified: 2009-11-18 01:06:56 UTC
Latest working kernel version: -
Earliest failing kernel version: 2.6.20 (oldest I could find)
Hardware Environment: Thinkpad X60s (see http://thinkwiki.org/wiki/Category:X60s ), but also reproducible on PPC64 box.
Software Environment: Gentoo Linux 2008.0, GCC 4.1.2
The select man page states that select returns, once one of the file descriptors it is passed is "ready". Where ready means that the requested I/O operation can be done without blocking. Files in sysfs seem to violate this property, specifically in the case where a file descriptor is at the EOF.
Consider reading a complete file via non-blocking I/O. In pseudo code this would look like:
fd = open_nonblocking(filename)
test for data on fd via select
bytes_read = read(fd)
while bytes_read > 0
In particular, EOF means that select returns immediately and the following read returns 0 to indicate the EOF condition.
If you try that on files in sysfs (e.g. /sys/class/input/input0/name or /sys/class/power_supply/AC/type ), select will block permanently (or timeout, if you set one) instead of returning immediately when the EOF is reached. This violates the sentence in the man page, since the requested read operation wouldn't block.
SBCL (Steel Bank Common Lisp, see sbcl.org) does file I/O in more or less this way and thus cannot read these files in sysfs.
Steps to reproduce:
Get http://www1.inf.tu-dresden.de/~s1054849/kernbug.c which is a small C program implementing the pseudo code above. Compile it via cc -o kernbug kernbug.c. Now you can try it out. First a positive example:
% ./kernbug /proc/cpuinfo
Read 512 bytes.
Read 512 bytes.
Read 126 bytes.
Read 0 bytes.
Now a negative one:
% ./kernbug /sys/class/input/input0/name
Read 18 bytes.
and another one:
% ./kernbug /sys/class/power_supply/AC/type
Read 6 bytes.
Created attachment 16664 [details]
Small program to demonstrate this bug.
This is the same as the program at http://www1.inf.tu-dresden.de/~s1054849/kernbug.c . I attached it in case it disappears on my webspace.
select/poll is not allowed on all sysfs files, only specific ones.
It is weird that lisp has such a strange file io implementation.
I'll play around with your sample application to see if I can get a simple fix for this...
In looking at this further, it's just not going to work, sorry.
The majority of sysfs files do not support poll/select, and we can't
tell userspace this either (select/poll don't let us return an error
So, for sysfs files, this isn't going to be able to work properly, and
it has never worked before, sorry.
According to stat the files in question are regular files. Reading man 3p select: "The pselect() and select() functions shall support regular files, terminal and pseudo-terminal devices, STREAMS-based files, FIFOs, pipes, and sockets."
Perhaps I sound pedantic, but it still looks like a bug which forces applications to jump through hoops to determine whether a file has b0rken select semantics... :-/
Yes, but the sysfs files are "virtual files", not "regular files" or any of the other things the man page states.
This is the way that sysfs has always worked.
Also, there are other virtual files that the kernel exports that also operate the same way. /proc/bus/usb/devices is one example that also fails your test program here.
If you know of a way that we can easily fix this within the kernel to make your application work, for all ram-based virtual file systems in the kernel, I would love to see it, but as of right now, I really don't know of a way to solve this, sorry.
You marked this bug as DOCUMENTED. May I asked, where it's documented? Shouldn't it be in the BUGS section of the select and poll man pages?
Wow, over a year since the last response, that's a long time :)
Anyway, this should probably be documented somewhere, how about sending the
man pages maintainer a patch for them?