O_TRUNC 写入 /proc 文件系统时被忽略
O_TRUNC ignored when writing to the /proc filesystem
尝试通过使用
清除/proc/sys/kernel/core_pattern
来摆脱Ubuntu的apport
sh -c ': > /proc/sys/kernel/core_pattern'
无效。
看起来 O_TRUNC
标志在写入 /proc
文件系统时被忽略了:
echo nonsense >| /proc/sys/kernel/core_pattern
strace sh -c ': > /proc/sys/kernel/core_pattern # do not call apport'
...
openat(AT_FDCWD, "/proc/sys/kernel/core_pattern", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
...
close(3) = 0
cat /proc/sys/kernel/core_pattern
nonsense
在常规文件系统而不是 /proc
文件系统中执行此操作时,我得到一个空文件。
这是内核错误还是功能,甚至可能是有文档记录的错误?
编辑: 通过 sysctl
清除此设置不起作用:
sysctl kernel.core_pattern=""
sysctl: malformed setting "kernel.core_pattern="
似乎 sysctl 程序无法清除任何内核参数,而 man core
明确描述了使用空值来禁用该机制。
是的,echo >| /proc/sys/kernel/core_pattern
可以代替,但是这个问题的目的是找出这是否是内核错误,而不是寻找解决方法。
这是因为 open*
系列系统调用的 O_TRUNC
标志仅更新与打开的文件关联的 inode 的大小。此更改是在找到 inode 之后和最终确定由任何内核 module/driver/subsystem(例如 sysctl 子系统)实现的 struct file
that is then used by the kernel for any actual operation on the opened file. Truncation is performed before the call to any ->open()
file_operations
处理程序之前执行的,因此对处理程序是透明的。
换句话说,虚拟 sysctl files (e.g. /proc/sys/kernel/*
) merely see a file with a 0 (zero) size (->i_size
field of struct inode
) 的 file_operations
处理程序不知道这是截断的结果还是“正常”open
,也不知道他们应该需要这样的信息。
由于 sysctl 文件(就像几乎所有的 procfs 文件一样)出于可以理解的原因并没有真正打扰跟踪大小,它们的功能仅根据 read
和 write
系统调用(也不会以任何方式更新大小)。
确实,使用: > PATH
只会做open
+ close
,而简单的echo > PATH
会在打开后write
一个换行符,因此你观察两种不同的结果。您会观察到与使用 truncate -s 0 PATH
: > PATH
相同的行为,尽管这次截断是在通过 ftruncate
打开后明确完成的(至少在我的系统上是这样)。
man core
explicitly describes that an empty value is used to disable the mechanism[...]
Is that a kernel bug or a feature, perhaps even a documented one?
procfs 下的人类 readable/writable 文件通常被设计为以面向行的方式工作,所以我假设这里的术语“空”仅仅意味着选项的值因此为空向文件写入一个空行。如果有的话,我会将其称为未记录的功能而不是错误。
这是我系统上的一些示例跟踪:
root@xxx:~# cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport %p %s %c %d %P %E
root@xxx:~# strace -f -e openat,write,close,dup2 sh -c ': > /proc/sys/kernel/core_pattern'
...
openat(AT_FDCWD, "/proc/sys/kernel/core_pattern", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
close(1) = 0
dup2(3, 1) = 1
close(3) = 0
...
+++ exited with 0 +++
root@xxx:~# cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport %p %s %c %d %P %E
root@xxx:~#
root@xxx:~# cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport %p %s %c %d %P %E
root@xxx:~# strace -f -e openat,write,close,dup2 sh -c 'echo > /proc/sys/kernel/core_pattern'
...
openat(AT_FDCWD, "/proc/sys/kernel/core_pattern", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
close(1) = 0
dup2(3, 1) = 1
close(3) = 0
write(1, "\n", 1) = 1
...
+++ exited with 0 +++
root@xxx:~# cat /proc/sys/kernel/core_pattern
root@xxx:~#
如果您想查看 sysfs 文件的 open
/read
/write
/close
的实际实现,您可以查看 /kernel/sysctl.c
. There are different tables present for different sysctl facilities e.g. kernel
, vm
,等等