Hello,
I have a sheevaplug and I've found that several versions of linux kernel from cbxbiker (
http://sheeva.with-linux.com/sheeva) corrupts data sent using sendfile from an USB harddrive: One byte each 100MB (aprox) is modified.
I've found that both lighttpd and cherokee corrupts files when downloading them at high speed (> 10MBps), but works correctly at low speed (dsl, 100KBps). I've developed an small C program which reproduces the problem. I've checked several versions of linux (2.6.34 to 2.6.35.7) and all exhibits this bug.
Did anyone also reproduce this problem? Any clue about the bug source?
This night I will try to reproduce it using a ram disk to discard a USB driver bug and I will try to get an USB2 ethernet adaptor to try to discard the ethernet driver.
test-sendfile.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/sendfile.h>
int main(void)
{
struct sockaddr_in stSockAddr;
int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(-1 == SocketFD)
{
perror("can not create socket");
exit(EXIT_FAILURE);
}
memset(&stSockAddr, 0, sizeof stSockAddr);
stSockAddr.sin_family = AF_INET;
stSockAddr.sin_port = htons(1100);
stSockAddr.sin_addr.s_addr = INADDR_ANY;
if(-1 == bind(SocketFD,(struct sockaddr *)&stSockAddr, sizeof stSockAddr))
{
perror("error bind failed");
close(SocketFD);
exit(EXIT_FAILURE);
}
if(-1 == listen(SocketFD, 10))
{
perror("error listen failed");
close(SocketFD);
exit(EXIT_FAILURE);
}
for(;;)
{
off_t pos = 0;
int ConnectFD = accept(SocketFD, NULL, NULL);
if(0 > ConnectFD)
{
perror("error accept failed");
close(SocketFD);
exit(EXIT_FAILURE);
}
printf("Sent a file of %d bytes\n", sendfile(ConnectFD, 0, &pos, 0x7FFFFFFF));
shutdown(ConnectFD, SHUT_RDWR);
close(ConnectFD);
}
close(SocketFD);
return 0;
}