【问题标题】:How to cause Errno 23 ENFILE on purpose如何故意导致 Errno 23 ENFILE
【发布时间】:2015-09-24 13:53:01
【问题描述】:

有没有办法可以故意导致 errno 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。也许在这些系统中需要进行一些其他设置?

谢谢!

【问题讨论】:

    标签: python linux sockets centos fedora


    【解决方案1】:

    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

    【讨论】:

    • 方法 2) 中的 fs.file-max 不是系统范围的设置吗?它确实在 RHEL 文档中这么说:link 并且在这里也被描述为系统范围:link 但系统似乎无论如何都没有限制。
    【解决方案2】:

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

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

    你可以使用:

    df -i
    

    检查您的 inode 使用情况。

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

    解决方案?

    像 Brtfs 和 XFS 这样的现代文件系统使用动态 inode 来避免 inode 限制 - 如果您有其中之一,则可能无法做到这一点。

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

    但是,如果您想确保从您的帖子中模拟一种情况,您应该创建 googol 文件,每个 1 字节,并且在磁盘用完之前很久就会用完 inode。然后你可以尝试创建socket。

    如果我错了,请纠正我。

    【讨论】:

      猜你喜欢
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-14
      • 2015-11-27
      • 1970-01-01
      • 2016-02-04
      • 2014-09-11
      相关资源
      最近更新 更多