mv 在我的 fs 上是原子的吗?

mv 在我的 fs 上是原子的吗?

如何检查mv我的 fs (ext4) 是否是原子的?

操作系统是 Red Hat Enterprise Linux Server 版本 6.8。

一般来说,我该如何检查呢?我环顾四周,没有发现我的操作系统是否是标准的 POSIX。

答案1

有趣的是,答案似乎是“这取决于情况”。

需要明确的是,mv已指定

公用事业mv公司应执行相当于rename() 功能

重命名函数规范状态:

对于常规文件,此rename()功能与 ISO C 标准定义的功能等效。此处的包含扩展了该定义,以包括对目录的操作,并指定新参数命名已存在的文件时的行为。该规范要求函数的操作是原子的。

但最新的ISO C 规范对于rename()各州:

7.21.4.2rename函数

概要

#include <stdio.h>
int rename(const char *old, const char *new);

描述

rename函数使名称为 指向的字符串的文件old从此通过 指向的字符串给出的名称来识别new。指定的文件old不再可以通过该名称访问。如果new在调用该函数之前存在由 指向的字符串命名的文件rename,则该行为是实现定义的。

退货

如果操作成功,该rename函数返回零,如果失败,则返回非零,在这种情况下,如果文件以前存在,则仍可以通过其原始名称来识别该文件。

令人惊讶的是,请注意,对于原子性没有明确的要求。最新公开的 C 标准中的其他地方可能需要它,但我还没有找到它。如果有人能找到这样的需求,我们非常欢迎编辑和评论。

也可以看看rename() 是原子的吗?

Linux 手册页

如果newpath已经存在,它将被自动替换,这样尝试访问的另一个进程就不会 newpath发现它丢失了。但是,可能会出现一个窗口,其中oldpath和都newpath引用正在重命名的文件。

Linux 手册页声称替代品文件的内容将是原子的。

测试验证不过,如果您需要做到这一点,原子性可能会非常困难。您不清楚“如何检查 mv 是否是原子的”的含义。您是否想要原子性的需求/规范/文档,或者您实际上需要测试它?

另请注意,上述假设两个操作数文件名位于同一文件系统中。我找不到对mv实用程序执行此操作的标准限制。

答案2

mv基于rename系统调用并且rename()是原子的。您可以查看联机帮助页rename(2)

你可以找到答案rename() 是原子的吗?在堆栈溢出上。

你用的是什么类型的fs?

答案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

相关内容