Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 03 Mar 2003 18:36:33 -0800
From:      Terry Lambert <tlambert2@mindspring.com>
To:        Sean Chittenden <sean@chittenden.org>
Cc:        Hiten Pandya <hiten@unixdaemons.com>, arch@FreeBSD.ORG
Subject:   Re: Should sendfile() to return ENOBUFS?
Message-ID:  <3E641131.431A0BA8@mindspring.com>
References:  <20030303224418.GU79234@perrin.int.nxad.com> <20030304001230.GC36475@unixdaemons.com> <20030304002218.GY79234@perrin.int.nxad.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Sean Chittenden wrote:
> > FWIW, there are many other parts of the sys/ tree where ENOBUFS or
> > any error code is not returned in the case of mbuf allocation, or
> > something on those lines, best candidate for this is the
> > sys/nfsserver code.
> 
> Are you suggesting that the parts of the sys/ tree that don't return
> ENOBUFS should?
> 
> FWIW, all I'm advocating right now is to get sendfile() fixed up and
> taken care of just because it's biting me in the arse and making life
> hell at the moment.  -sc

sendfile:

     When using a socket marked for non-blocking I/O, sendfile() may send
     fewer bytes than requested.  In this case, the number of bytes success-
     fully written is returned in *sbytes (if specified), and the error EAGAIN
     is returned.

This seems to indicate several things:

1)	The correct error is EAGAIN, *not* ENOBUFS

2)	You need to be damn sure you can guarantee a correct update
	of *sbytes; I believe this is very difficult in the case in
	question, which is why it blocks

3)	If sbytes is NULL, you should probably block, even on a
	non-blocking call.  The reason for this is that there is
	no way for the application to restart without *sbytes

4)	If you get rid of the blocking with (sbytes == NULL), you
	better add a BUGS section to the manual page.

Frankly I'm really surprised that you are blocking in this place; it
indicates an inability to get a page in the kernel map in the sf zone,
which, in turn, indicates that your NSFBUFS is improperly tuned; if
you are using sendfile, and tune up your other kernel parameters for
your system, don't forget NSFBUFS.

While you could *technically* make sf_buf_alloc() non-blocking, in
general this would be a bad idea, given that the one place it's called
is in in interior loop that can be the subject of a "goto" (so it's an
embedded interior loop) in sendfile() itself.  I think it would be very
hard to satisfy #2, to allow it to be restartable by the application,
in the face of failure, and since *sbytes is not a mandatory parameter,
likely your application will end up barfing (e.g. sending partial FTP
files or HTML documents down, with no way to recover from a failure,
other than closing the client socket, and hoping the client can recover).

In a "flash crowd" case on an HTTP server, this basically means that
you will continuously get retries, and the situation will worsen,
exponentially, as people retry getting the same page.  In the FTP
case, or some other protocol without automatic retry on session
abandonment, of course, it will be fatal.

-- Terry

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3E641131.431A0BA8>