Skip to content

Instantly share code, notes, and snippets.

@jschwinger233
Last active April 21, 2020 04:34
Show Gist options
  • Save jschwinger233/5ab5a083938b15f9dde342ae2891d476 to your computer and use it in GitHub Desktop.
Save jschwinger233/5ab5a083938b15f9dde342ae2891d476 to your computer and use it in GitHub Desktop.

没想到一个 open files limit 都能让我有这么多惊喜.

  1. ulimitrlimit 是一个东西, 有些文章说 ulimit 代表的是 user limit, 限制的是一个 effective user 的总资源, 而 rlimit 限制的是一个进程的资源, 这是错的.
  2. strace -fT ulimit -n 是不行的, 因为 ulimit 是 shell builtins, 所以 strace ulimit 直接报错说找不到命令; 同理 which ulimit 也没有输出(我第一次知道 builtins 是不能 which 的)
  3. man 3 ulimitThis routine is obsolete. Use getrlimit(2), setrlimit(2), and sysconf(3) instead, 有理由相信 ulimit 就是 rlimit
  4. 直接看 bash 源码, 在 builtins/ulimit.def 里可以清楚看到 ulimit 就是调用 rlimit, 第一个问题解决了, 以下讨论 rlimit.
  5. rlimit 是限制用户 / 会话 / 进程组的吗? 只有 RLIMIT_NPROC, RLIMIT_MSGQUEUE, RLIMIT_SIGPENDING 是按照 real user ID 限制的多个进程的, 分别限制的是进程数, POSIX 消息队列字节数, 排队信号数, 其他都是限制单进程.
  6. /proc/$PID/limitulimit 的关系是对应的, 但是如果你在 shell 里 ulimit -a 看到的东西和一个进程的 /proc/$PID/limit 是不一样的, 不要慌, rlimit 是继承的, 所以看看父进程, 看看不同用户的 rlimit 是否不一样, 看看进程自己是否修改了.
  7. docker run --ulimit 是在 docker 层做的! 我意思是, 这不是交给 containerd 和 runc 做的, runc 对此一无所知. 不过具体在哪一步设置的我还不清楚, 我的 docker 解剖计划已经拖延很久了.
  8. 进程出现了 accept4: too many open files in system 之类的日志, 但是 lsof -p 或者 /proc/$PID/fd/ 数出来的 fd 都明显没有超过 rlimit, 那么可以考虑全局 fd 限制.
  9. cat /proc/sys/fs/file-max 定义了 the maximum number of file-handles that the Linux kernel will allocate, 而超过这个限制的话可以在内核日志里看到 VFS: file-max limit <number> reached.
  10. 查看一个进程使用的 open files number, 如果想通过 syscall 的话, 只有一个 getrusage(2) 可以用, 不过只能查看自己或者子进程的 rlimit usage, 所以如果我作为 sibling 也是无法查看的...
  11. 回到上面说的全局内核 file-handles, cat /proc/sys/fs/file-nr 记录了 the number of allocated file handles, the number of allocated but unused file handles, and the maximum number of file handles, 不过我自己试了一下, 第一个数不是即时修改的, 所以参考价值不大.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment