gpt4 book ai didi

c - 如何确保数据写入物理介质?

转载 作者:行者123 更新时间:2023-12-03 09:52:26 24 4
gpt4 key购买 nike

我有一个由脚本调用的程序。该程序将大量数据写入磁盘上的文件,然后终止。一旦运行完毕,脚本就会切断整个系统的电源。

我遇到的问题是文件没有完整写入。如果它是一个 4GiB 文件,当我稍后查看它时,磁盘上实际上只有大约 2GiB。我能够可靠地确保所有数据都被写入的唯一方法是在退出之前让程序休眠一小段时间,但这是一个非常糟糕且不可靠的 hack,我不想使用。以下是我最近尝试的一些示例代码:

int main () {
FILE *output;
output = fopen("/logs/data", "w");

[fwrite several GiB of data to output]

fflush(output);

int fdo = open("/logs", O_RDONLY);
fsync(fdo);

fclose(output);
close(fdo);

return 0;
}

我最初尝试使用文件描述符构建我的 FILE 并在使用的描述符 (/logs/data) 上调用 fsync() 但这产生了同样的问题。根据 fsync(2) 的规范:

Calling fsync() does not necessarily ensure that the entry in thedirectory containing the file has also reached disk. For that anexplicit fsync() on a file descriptor for the directory is alsoneeded.

这让我找到了上面的代码,为包含我的数据文件的目录创建了一个特定的文件描述符,并在上面调用了 fsync()。然而结果是一样的。我真的不明白为什么会这样,因为 fsync() 应该是阻塞的:

The call blocks until thedevice reports that the transfer has completed.

此外,如您所见,我在 FILE 上添加了一个 fflush(),我认为 fsync() 可能只是同步了之前的数据被冲洗了,但这对情况没有任何影响。

在结束程序之前,我需要以某种方式验证数据是否确实已写入物理介质,但我不确定该怎么做。我看到有一些文件,例如/sys/block/[device]/[partition]/stat 可以告诉我还有多少脏 block 要写入,我可以等待该值达到 0,但这不会这似乎是解决一个简单问题的好方法,此外,如果任何其他程序正在磁盘上运行,那么我不想等待他们也同步他们的数据,因为我只关心的完整性这个特定文件和 stat 文件没有区别。

编辑根据建议,我尝试 fsync() 两次,首先是在文件上,然后是在目录上:

int main () {
FILE *output;
int fd = open("/logs/data", O_WRONLY | O_CREAT, 660);
output = fdopen(fd, "w");

[fwrite several GiB of data to output]

fsync(fd);
int fdo = open("/logs", O_RDONLY);
fsync(fdo);

fclose(output);
close(fd);
close(fdo);

return 0;
}

这产生了一些有趣的输出。对于 4GiB(4294967296 字节)的文件,磁盘上的实际数据大小为 4294963200,恰好与总值相差 1 页文件(4096 字节)。它似乎非常接近可行的解决方案,但它仍然不能保证每个字节的数据。

最佳答案

您是否考虑过将 O_DIRECT 和/或 O_SYNC 标志传递给 open() ?来自 open() 手册:

O_DIRECT
Try to minimize cache effects of the I/O to and from this file. In general this will degrade performance, but it is useful in special situations, such as when applications do their owncaching. File I/O is done directly to/from user-space buffers. The O_DIRECT flag on its own makes an effort to transfer data synchronously, but does not give the guarantees of the O_SYNCflag that data and necessary metadata are transferred. To guarantee synchronous I/O, O_SYNC must be used in addition to O_DIRECT.

O_SYNC
Write operations on the file will complete according to the requirements of synchronized I/O file integrity completion...

article on LWN(现在已经很老了)也提供了一些指南来确保数据的完整性。

关于c - 如何确保数据写入物理介质?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65616577/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com