Linux splice()返回EINVAL(“无效参数") [英] Linux splice() returning EINVAL ("Invalid argument")

查看:105
本文介绍了Linux splice()返回EINVAL(“无效参数")的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用拼接(

I'm trying to experiment with using splice (man 2 splice) to copy data from a UDP socket directly to a file. Unfortunately the first call to splice() returns EINVAL.

该手册页指出:

EINVAL Target file system doesn't support splicing; target file is opened in
       append mode; neither of the descriptors refers to a pipe; or offset
       given for nonseekable device.

但是,我认为这些条件均不适用.我正在使用Fedora 15(内核2.6.40-4),因此我相信所有文件系统都支持splice().在第一次调用拼接文件时,目标文件应该无关紧要,但是为了完整起见,我通过open(path, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR)打开它.这两个调用都使用管道,并且两个调用都没有使用NULL以外的偏移量.

However, I believe none of those conditions apply. I'm using Fedora 15 (kernel 2.6.40-4) so I believe splice() is supported on all filesystems. The target file should be irrelevant in the first call to splice, but for completeness I'm opening it via open(path, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR). Both calls use a pipe and neither call uses an offset besides NULL.

这是我的示例代码:

int sz = splice(sock_fd, 0, mPipeFds[1], 0, 8192, SPLICE_F_MORE);
if (-1 == sz)
{
int err = errno;
LOG4CXX_ERROR(spLogger, "splice from: " << strerror(err));
return 0;
}

sz = splice(mPipeFds[0], 0, file_fd, 0, sz, SPLICE_F_MORE);
if (-1 == sz)
{
int err = errno;
LOG4CXX_ERROR(spLogger, "splice to: " << strerror(err));
}

return 0;

sock_fd由以下伪代码初始化:

sock_fd is initialized by the following psuedocode:

int sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK);
bind(sock_fd, ...);

可能与此相关的是,此代码段在libevent循环内运行. libevent使用epoll()来确定UDP套接字是否很热.

Possibly related is that this code snippet is running inside a libevent loop. libevent is using epoll() to determine if the UDP socket is hot.

推荐答案

找到了我的答案. tl; dr-入站端不支持UDP.

Found my answer. tl;dr - UDP isn't supported on the inbound side.

经过足够的Google搜索,我偶然发现了论坛讨论和一些测试代码,其中打印出一张输入/输出fd类型及其支持的表格:

After enough Googling I stumbled upon a forum discussion and some test code which prints out a table of in/out fd types and their support:

$ ./a.out 
in\out     pipe    reg     chr     unix    tcp    udp
pipe       yes     yes     yes     yes     yes    yes
reg        yes     no      no      no      no     no
chr        yes     no      no      no      no     no
unix       no      no      no      no      no     no
tcp        yes     no      no      no      no     no
udp        no      no      no      no      no     no

这篇关于Linux splice()返回EINVAL(“无效参数")的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆