连接时没有可用的缓冲空间

当进程在Linux虚拟机上调用“connect”时,我看到错误消息“No buffer space available”。 我无法追查原因 – 希望有人可以帮忙!

我检查了以下内容:

(1)文件句柄:

cat /proc/sys/fs/file-nr 4672 0 810707 

我读这(分配,未使用,可用),所以这看起来不错。

(2)套接字或TCP内存:

 cat /proc/sys/net/ipv4/tcp_mem 191889 255854 383778 cat /proc/net/sockstat sockets: used 579 TCP: inuse 169 orphan 0 tw 245 alloc 187 mem 5 UDP: inuse 31 mem 4 UDPLITE: inuse 0 RAW: inuse 0 FRAG: inuse 0 memory 0 

阅读这个总共只有579套使用中,总页数低于最大值。

在Google上显示了很多随机的TCP调整 – 我希望在答案中是(1)我用尽的资源,(2)如何确定当前值和(3)如何调整天花板。 我find的大部分网页都没有,除了(3)!

**更新#1 **

在Flup的build议,我做了一个systrace发生(使用ping):

 socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 4 connect(4, {sa_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("10.140.0.65")}, 16) = -1 ENOBUFS (No buffer space available) 

**更新#2 **

我不太了解linux内核源码,但是我有一个挖掘周围,唯一的地方在connect()path,我可以看到ENOBUFS在这里: http : //lxr.free-electrons.com/source/net /ipv4/af_inet.c?v=3.11#L353

这看起来像是在内核中分配的东西,尽pipe与kmem_cache_allocsecurity_sk_alloc …?

那么,我不知道究竟是什么问题,但我会试图找出解决这个问题的正确方向。

sk_alloc()dst_alloc()失败时,将返回ENOBUFS代码。 在与套接字相关的源代码中我找不到任何其他的ENOBUFS

另外我找不到从SYSCALL_DEFINE3(connect)sk_alloc()任何path,我认为在connect()调用期间不应该分配套接字,在那里你得到错误,所以我认为这不可能是sk_alloc()造成了这个问题。

dst_alloc()很可能用于在connect()期间检查路由,我找不到确切的path,它必须在里面的某个地方: SYSCALL_DEFINE3(connect) .connect() – > ip4_datagram_connect() – > ip4_datagram_connect() – > ip_route_connect()

dst_alloc()在相应的SLABcaching中分配一个条目,如果caching已满,则实际上可能会失败。 实际上,如果发生这种情况,应该清除旧的条目,但是也可能有时会返回错误。

所以我认为你可以朝这个方向前进。 dstcaching大小可以通过/proc/sys/net/ipv4/route/max_size更改。 首先,检查设置(或sys.net.ipv4.route任何其他设置)是否被“Google上显示的随机TCP调整”更改。