如何检查mv
我的 fs (ext4) 是否是原子的?
操作系统是 Red Hat Enterprise Linux Server 版本 6.8。
一般来说,我该如何检查呢?我环顾四周,没有发现我的操作系统是否是标准的 POSIX。
答案1
有趣的是,答案似乎是“这取决于情况”。
需要明确的是,mv
已指定到
公用事业
mv
公司应执行相当于rename()
功能
这重命名函数规范状态:
对于常规文件,此
rename()
功能与 ISO C 标准定义的功能等效。此处的包含扩展了该定义,以包括对目录的操作,并指定新参数命名已存在的文件时的行为。该规范要求函数的操作是原子的。
但最新的ISO C 规范对于rename()
各州:
7.21.4.2
rename
函数概要
#include <stdio.h> int rename(const char *old, const char *new);
描述
该
rename
函数使名称为 指向的字符串的文件old
从此通过 指向的字符串给出的名称来识别new
。指定的文件old
不再可以通过该名称访问。如果new
在调用该函数之前存在由 指向的字符串命名的文件rename
,则该行为是实现定义的。退货
如果操作成功,该
rename
函数返回零,如果失败,则返回非零,在这种情况下,如果文件以前存在,则仍可以通过其原始名称来识别该文件。
令人惊讶的是,请注意,对于原子性没有明确的要求。最新公开的 C 标准中的其他地方可能需要它,但我还没有找到它。如果有人能找到这样的需求,我们非常欢迎编辑和评论。
也可以看看rename() 是原子的吗?
如果
newpath
已经存在,它将被自动替换,这样尝试访问的另一个进程就不会newpath
发现它丢失了。但是,可能会出现一个窗口,其中oldpath
和都newpath
引用正在重命名的文件。
Linux 手册页声称替代品文件的内容将是原子的。
测试和验证不过,如果您需要做到这一点,原子性可能会非常困难。您不清楚“如何检查 mv 是否是原子的”的含义。您是否想要原子性的需求/规范/文档,或者您实际上需要测试它?
另请注意,上述假设两个操作数文件名位于同一文件系统中。我找不到对mv
实用程序执行此操作的标准限制。
答案2
答案3
除了检查系统调用及其原子性之外,也许inotify-tools
可以作为测试,尽管我不确定这是否是原子性的保证证明。
打开2个贝壳。在其中之一中观察移动的目标目录:
inotifywait -m target/
将文件移动到另一个目录中:
mv foobar target/
应该inotifywait
只显示一行:
target/ MOVED_TO foobar
ls target/
与和的响应相比touch target/a
,它似乎是原子的,它会产生多行消息,例如:
# the response to ls target/
target/ OPEN,ISDIR
target/ ACCESS,ISDIR
target/ CLOSE_NOWRITE,CLOSE,ISDIR
聚苯乙烯
我认为,至少它表明文件上的异步多进程协作是安全的inotify
(实际上是原子的):在任何情况下,您只有inotify
在操作后给出最终信号后才会做出响应。例如,可以使用 轻松安全地实现生产者-消费者设置inotify
。