我有一个服务,它将一组文件的硬链接组装到一个临时的临时目录中,但它没有写入访问权限(以及所有父目录树的遍历权限)。
这非常有效,直到我的AWS托管节点重新启动。看来他们现在正在使用更新的内核,而link(2)调用现在返回EACCES。
检查此系统调用的(Linux)手册页:
EACCES - 拒绝对包含newpath的目录的写访问权,或拒绝旧路径或新路径的路径前缀中的一个目录的搜索权限。 (另见path_resolution(7)。)
为了进行比较,BSD版本似乎描述了类似的语义,可能稍微详细一点:
[EACCES]任一路径前缀的组件都会拒绝搜索权限。
[EACCES]请求的链接要求在具有拒绝写入权限的模式的目录中写入。
[EACCES]当前进程无法访问现有文件。
这些情况都不适用:作为运行服务的用户,我可以读取源文件(包括遍历到其目录),并写入临时登台目录(实际上,我创建了该目录);此外,该临时目录位于同一文件系统上(尽管这会导致不同的错误)。
是什么给出了?
答案 0 :(得分:2)
重新启动时,新内核默认启动到集fs.protected_hardlinks=1
。 This was added as default behavior in late 2012.设置此sysctl后,Linux需要对另一个用户创建硬链接才能对文件进行写访问。
这在技术上与the relevant POSIX specification兼容,newer upstream kernels have this off by default, due to its observed ability to break third-party software部分说明:
实现可能要求调用进程有权访问现有文件。
然而,{{3}}。因此,在当前实例中,它可以由供应商重新启用,也可以基于上游内核从引入和稍后禁用之间的时间段开始。