Bug 11014 - Weird select(2) behaviour with certain files in sysfs
Weird select(2) behaviour with certain files in sysfs
Product: File System
Classification: Unclassified
Component: SysFS
All Linux
: P1 normal
Assigned To: Greg Kroah-Hartman
Depends on:
  Show dependency treegraph
Reported: 2008-06-30 15:22 UTC by Julian Stecklina
Modified: 2009-11-18 01:06 UTC (History)
2 users (show)

See Also:
Kernel Version:
Tree: Mainline
Regression: No

Small program to demonstrate this bug. (1.09 KB, text/plain)
2008-06-30 15:24 UTC, Julian Stecklina

Description Julian Stecklina 2008-06-30 15:22:06 UTC
Latest working kernel version: -
Earliest failing kernel version: 2.6.20 (oldest I could find)
Distribution: Gentoo
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
Problem Description:

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.
Comment 1 Julian Stecklina 2008-06-30 15:24:19 UTC
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.
Comment 2 Greg Kroah-Hartman 2008-06-30 15:40:49 UTC
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...
Comment 3 Greg Kroah-Hartman 2008-06-30 16:08:48 UTC
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.
Comment 4 Julian Stecklina 2008-06-30 17:37:12 UTC
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...  :-/
Comment 5 Greg Kroah-Hartman 2008-07-01 07:45:10 UTC
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.
Comment 6 Julian Stecklina 2009-11-18 00:57:06 UTC
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?
Comment 7 Greg Kroah-Hartman 2009-11-18 01:06:56 UTC
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?

Note You need to log in before you can comment on or make changes to this bug.