Nicolas Williams wrote:
On Wed, Aug 19, 2009 at 03:48:06PM -0700, David Pacheco wrote:
Sorry to reply to my own mail, but it's worse than I thought. The man
page is obviously wrong in the most literal reading (we don't return
ETIME if nget is updated...), but after looking at the code, I'm not
even sure what it's supposed to be saying. The code in the kernel
appears to return early with ETIME without consuming events in some
cases, but other times it goes and consumes events even after getting
ETIME. See:

http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/fs/portfs/port.c#1325

Note the check on line 1339. If it falls through because flags = 0
(which it is in the common case for port_getn), we check for events
without modifying error. It's unclear if that's intentional - i.e. is
the code wrong in addition to the man page or just the man page?

To my reading you have these possible conditions:

 - max == 0 and port_getn() returns 0 -> *nget will have been set to the
   number of events available.


Except when you hit 6455223. This unlikely case occurs when some events on the port are not deliverable to the calling thread (e.g., async i/o completion after a fork in the child process). This is not relevant to this discussion, but it's worth noting that there are multiple edge conditions not handled well by the current implementation.


 - port_getn() returns 0, or it returns -1 && errno is one of ETIME,
   EINTR, or EBADFD -> events may have been consumed and placed in
   list[], and *nget will have been set to the number of consumed
   events.


EBADFD can't return with events.

It's unlikely that EINTR would return with events because usually we'll bail out at line 1338, but maybe we can loop through it multiple times having consumed events the first time and gotten EINTR later.


 - port_getn() returns -1 && errno is one of EBADF or EINVAL -> no
   events will have been consumed, list[] and *nget remain untouched.
>
 - port_getn() returns -1 && errno is EFAULT -> events will have been
   consumed, *nget will be set to the number of events consumed, and
   list[] is undefined.


Yep. But really we should fix the implementation and make the man page match the implementation. One shouldn't need to inspect kernel code to know how to handle errors from a syscall. I used to own a few bugs in this area, but I've removed myself as RE since I don't have the time to get to them any time soon.

-- Dave

--
David Pacheco, Sun Microsystems Fishworks.     http://blogs.sun.com/dap/
_______________________________________________
networking-discuss mailing list
[email protected]

Reply via email to