如何故意引起Errno 23 ENFILE

时间:2015-09-24 13:53:01

标签: python linux sockets centos fedora

有没有办法可以故意导致错误23(ENFILE文件表溢出)?

我正在进行套接字编程,我想检查创建太多套接字是否会导致此错误。据我了解 - 创建的socked被视为文件描述符,因此它应该计入打开文件的系统限制。

这是我的python脚本的一部分,它创建了套接字

def enfile():

nofile_soft_limit = 10000
nofile_hard_limit = 20000

resource.setrlimit(resource.RLIMIT_NOFILE, (nofile_soft_limit,nofile_hard_limit))

sock_table = []
for i in range(0, 10000):
    print "Creating socket number {0}".format(i)
    try:
        temp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.SOL_UDP)
    except socket.error as msg:
        print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
        print msg[0]
    sock_table.append(temp)

使用setrlimit()我将打开文件的进程限制更改为高值,这样我就不会得到Errno24(EMFILE)。

我尝试了两种方法: 1)每用户限制  通过更改/etc/security/limits.conf

root      hard    nofile      5000
root      soft    nofile      5000

(之后用新会话登录)

2)全系统限制 通过更改/etc/sysctl.conf

fs.file-max = 5000
and then run sysctl -p to apply the changes.

尽管每个用户和系统范围的限制,我的脚本轻松创建10k套接字,并以errno 24(EMFILE)结束。

有可能实现我的目标吗?我正在使用两个操作系统 - CentOS 6.7和Fedora 20.也许在这些系统中还有其他一些设置?

谢谢!

2 个答案:

答案 0 :(得分:2)

ENFILE只有在达到系统范围限制时才会发生,而您到目前为止尝试的设置是按进程进行的,因此仅与EMFILE.有关。有关详细信息,包括哪个系统 - 要更改为触发ENFILE的广泛设置,请参阅以下答案:https://stackoverflow.com/a/24862823/4323以及https://serverfault.com/questions/122679/how-do-ulimit-n-and-proc-sys-fs-file-max-differ

答案 1 :(得分:1)

您应该在内核源代码中寻找答案。

当sock_alloc()返回NULL时,套接字调用在__sock_create()中返回 ENFILE 。只有在它无法分配新的inode时才会发生这种情况。

您可以使用:

df -i

检查您的inode使用情况。

不幸的是,无法动态更改inode限制。 通常,首次创建文件系统时,将设置inode的总数和为这些inode保留的空间。

<强>解决方案吗

像Brtfs和XFS这样的现代文件系统使用动态inode来避免inode限制 - 如果你有其中一个,那么就不可能做到这一点。

如果您有LVM磁盘,减小卷的大小可能有所帮助。

但是如果你想确保从你的帖子中模拟一个情况,你应该创建googol文件,每个1个字节,你将在磁盘用完之前用完inode。然后你可以尝试创建套接字。

如果我错了,请纠正我。