Page 1 of 1

AMD64 kernel and sendfile()

Posted: 2007/01/29 23:11:03
by dvadell
I installed proftpd in an AMD64 server with CentOS 4. Everything works fine, except for proftpd. The symptoms were strange: whenever I RETR a file, i would get the contents of the file repeated many times. For example, I tried with a 1302 bytes certificate file and I got a 2604 bytes . Looking it inside, it was the same 1302 bytes, twice.

So I fired my dearest friend: strace . And I got interesting results:

18907 open("/lntsbs_public.cer", O_RDONLY) = 11

And later:

18907 setsockopt(14, SOL_TCP, TCP_CORK, [1], 4) = 0
18907 fcntl(14, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
18907 fcntl(14, F_SETFL, O_RDWR) = 0
18907 sendfile(14, 11, [0], 1302) = -1 EOVERFLOW (Value too large for defined data type)
18907 fcntl(14, F_SETFL, O_RDWR|O_NONBLOCK) = 0
18907 sendto(2, "Jan 29 21:39:34 proftpd[1890"..., 202, 0, NULL, 0) = 202
18907 sendto(2, "Jan 29 21:39:34 proftpd[1890"..., 117, 0, NULL, 0) = 117
18907 read(11, "-----BEGIN CERTIFICATE-----\r\nMII"..., 16384) = 1302
18907 select(15, [], [14], NULL, {1, 0}) = 1 (out [14], left {1, 0})
18907 write(14, "-----BEGIN CERTIFICATE-----\r\nMII"..., 1302) = 1302

Note that it first tries to send it with sendfile() and it gets an EOVERFLOW, so it then sends it with read() and write(). And as read() and write() returns the same 1302 bytes, I suspect that before returning EOVERFLOW, sendfile() will send the file all the same. So, voila, the same file twice.

So I recompiled proftpd with the --disable-sendfile option and now everything works as expected.

I'm using 2.6.9-42.0.3.EL kernel in an up-to-date CentOS installation. Could this be a kernel bug in sendfile()? dmesg doesn't give me a clue.

-- Diego

Re: AMD64 kernel and sendfile()

Posted: 2007/01/30 04:47:27
by pjwelsh
Does this sound like your issue:
There is provided some source diff. However, I would have expected that to be put in mainline proftpd by now...
The other odd part is that the limit and error seem to deal with larger files... your example is not.
Run "yum list proftpd" and just check that you are matching the kernel arch you have. Just a guess at this point, sorry.