在Linux上进行原子文件保存,同时不丢失元数据。

9
我正在开发一个基于Perl的文件同步工具。它将文件下载到一个临时目录中(保证与实际文件在同一文件系统上),然后将临时文件移动到原来的位置,保留权限、所有权和ACL等元数据。我想知道如何在Linux上完成最后一步。
在Mac OS X上,至少在C语言中,我会使用exchangedata函数。它接受两个文件名作为参数并交换它们的内容,保留除mtime之外的所有元数据。它保证操作是原子的——所有读取器将只看到旧文件或新文件,永远不会看到其间的内容。不幸的是,我认为它在Linux上不可用。
我知道rename可以原子地移动,但它不能保存元数据。另一方面,我可以打开文件并用新文件的内容覆盖数据,这将保留所有元数据,但不是一个原子操作。有什么建议解决这个问题吗?

2
你正在努力保留哪种元数据?在Unix中,所有的都是拥有者/组和拥有者/组/所有人的权限。这会发生很大的变化吗?这对你来说是个问题吗? - Carl Smotricz
许多Linux文件系统也支持扩展属性和ACL,而一个非特权用户可能没有必要的权限来更改临时文件的用户和组为旧的那个。基本上,这里涉及到很多微妙之处,我想知道是否已经存在处理它的东西。 - Becca Royal-Gordon
2个回答

6

我这里唯一能想到的方法是从你要替换的文件中读取元数据,将其应用于临时文件,然后将临时文件重命名为旧文件。(rename显然会保留源文件属性。)


虽然很难知道所有正确的元数据是什么。有文件属性、扩展属性、ACL、安全标签、文件功能和其他特定于文件系统或系统的东西... - ephemient
2
这听起来是一个不错的开始清单。“好的敌人是更好。” - jrockway
是的,如果没有完整的解决方案(目前似乎没有),那么至少部分正确地解决问题总比什么都不做好。即使rsync也只知道/关心有限的元数据。 - ephemient

4

这是与文件系统相关的内容,但...

XFS_IOC_SWAPEXT ioctl 命令可以在 XFS 文件系统上交换两个文件描述符的范围。

#include <xfs/xfs.h>
#include <xfs/xfs_dfrag.h>

xfs_swapext_t sx = {
    ...,
    .sx_fdtarget = fd1,
    .sx_fdtmp    = fd2,
    ...
};
xfs_swapext(fd1, &sx);

参见xfs_fsr的源代码,以获取示例用法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接