我在带有磁盘的虚拟机上运行 Apache qcow2
。 Apache 运行一个(编译的 C++)程序,该程序执行以下操作:
它调用
system
运行另一个创建文件的(C++)程序然后它尝试读取并处理该文件
步骤 (2) 尝试使用ifstream::open
.当我在虚拟机上运行该程序时,失败(ifstream::good
返回false
),并errno
表示该文件不存在。但是,如果我打开 shell 并查找该文件,则该文件确实存在。
该程序在未启动时qcow2
(在 3 台不同的 RedHat 和 Ubuntu 计算机上)运行良好,我猜这与此有关。我可以通过两种方式解决这个问题:
- 如果我在 (1) 和 (2) 之间添加另一个步骤,并且调用
system("ls /foo/bar/myfile")
命令ls
失败,返回 2。我可以调用它 100 次,但它仍然失败。但是,步骤 (2) 现在将会成功 - 如果我运行
system("sync")
而不是system("ls")
,则步骤 (2) 成功
知道发生了什么事吗?是否qcow2
有一些不寻常的冲洗要求?
编辑-添加了一些系统信息:
- RHEL 8.5,最新
- 内核4.18.0-348.12.2.el8_5.x86_64
- 模拟 pc-q35-rhel8.2.0
- VM 具有 4GiB RAM、2vCPU (Skylake-Client-IBRS)
- 磁盘:10GB,已使用 35%,virtio,默认缓存,Ubuntu 20.04 映像
我已经使用 Win 7 和 Linux 映像运行此设置多年,以前从未遇到过问题。
$ virsh version
Compiled against library: libvirt 6.0.0
Using library: libvirt 6.0.0
Using API: QEMU 6.0.0
Running hypervisor: QEMU 4.2.0
答案1
我有类似的问题与应用程序图像,(用 Go 编写)在裸机上。通过调用f.Sync()
创建文件的程序解决了这个问题。
我不认为这是 qemu 特定的。我的工作理论是,如果文件尚未同步到存储,则它仅对创建它的进程可见。如果那个人回来了,那么可能只有父母了。来自不同祖先的进程可能必须等待文件同步。
我对此没有明确的资源,只是我在调试上述内容时发现的。