【发布时间】:2015-10-02 10:44:26
【问题描述】:
如何限制父创建的文件大小但对子生成的文件没有限制?
我有一个用例,父进程将 STDOUT 重定向到文件,子进程写入 STDOUT(将被重定向到父进程创建的文件)。
我已将父进程的文件大小限制设置为 50 MB,而对子进程没有限制。
当重定向 STDOUT 的文件的文件大小超过 50 MB 时,如何确保父进程获得 SIGXFSZ。
【问题讨论】:
标签: linux file process limit ulimit
如何限制父创建的文件大小但对子生成的文件没有限制?
我有一个用例,父进程将 STDOUT 重定向到文件,子进程写入 STDOUT(将被重定向到父进程创建的文件)。
我已将父进程的文件大小限制设置为 50 MB,而对子进程没有限制。
当重定向 STDOUT 的文件的文件大小超过 50 MB 时,如何确保父进程获得 SIGXFSZ。
【问题讨论】:
标签: linux file process limit ulimit
文件大小有限,当使用setrlimit(2) 设置RLIMIT_FSIZE 限制时会生成SIGXFSZ。
子进程从父进程继承资源限制:
通过
fork(2)创建的子进程继承其父进程的资源 限制。在execve(2)中保留资源限制。
资源限制是每个进程 属性,不是全局的,也不是每个文件的。具体来说,对于RLIMIT_FSIZE:
RLIMIT_FSIZE进程可以创建的文件的最大大小。 尝试将文件扩展超出此限制会导致传递
SIGXFSZ信号。[...]
当进程更改文件大小时应用此限制。如果文件大小变得大于当前进程的RLIMIT_FSIZE值,则生成SIGXFSZ和EFBIG。
您可以在内核源代码中检查这一点。见mm/filemap.c:
inline ssize_t generic_write_checks(struct kiocb *iocb, struct iov_iter *from)
{
...
unsigned long limit = rlimit(RLIMIT_FSIZE);
...
if (limit != RLIM_INFINITY) {
if (iocb->ki_pos >= limit) {
send_sig(SIGXFSZ, current, 0);
return -EFBIG;
}
...
static inline unsigned long rlimit(unsigned int limit)
{
return task_rlimit(current, limit);
}
注意这里的current是一个指向当前进程的指针。
总结一下:
RLIMIT_FSIZE,则当父级写入任何文件时应用此限制;RLIMIT_FSIZE,则在子级写入任何文件时应用新限制。父进程有一些限制,如果父进程创建的任何文件超过限制,它应该得到
SIGXFSZ。现在孩子只是将数据写入由父母创建的文件,所以不应该在父母限制中考虑文件的大小吗?
不,不应该。当孩子写入文件时,内核检查孩子的RLIMIT_FSIZE 值。内核不关心是哪个进程创建或打开了文件。
【讨论】:
SIGXFSZ,但仅适用于在父级中创建的文件(即每个文件的限制)?