0

I'm running Apache on a VM with a qcow2 disk. Apache runs a (compiled C++) program which does the following:

  1. It calls system to run another (C++) program which creates a file

  2. It then attempts to read and process that file

Step (2) attempts to open the new file with ifstream::open. When I run this program on the VM, this fails (ifstream::good returns false), with errno saying that the file doesn't exist. However, the file does actually exist if I open a shell and look for it.

This program works fine when it's not on qcow2 (on 3 different RedHat and Ubuntu computers), which I'm guessing is implicated. I can fix this in two ways:

  1. If I add another step between (1) and (2), and call system("ls /foo/bar/myfile") the ls command fails, returning 2. I can call it 100 times and it still fails. However, step (2) will now succeed
  2. If I run system("sync") instead of system("ls"), step (2) succeeds

Any idea what's going on? Does qcow2 have some unusual flush requirements?

Edit - added some sys info:

  • RHEL 8.5, up-to-date
  • kernel 4.18.0-348.12.2.el8_5.x86_64
  • emulating pc-q35-rhel8.2.0
  • VM has 4GiB RAM, 2vCPUs (Skylake-Client-IBRS)
  • disk: 10GB, 35% used, virtio, default cache, Ubuntu 20.04 image

I've run this setup for years with Win 7 and Linux images and never seen an issue before.

$ 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
5
  • The only time I have seen something like that is when using a network drive that gets out of sync when writing on the client and server at the same time and usually "sync" doesn't fix it. What version of QEMU(?) are you using? What is the host OS? It would be helpful to see how you're connecting the qcow2 drive as well (scsi, ide, sata, etc).
    – CR.
    Commented Mar 8, 2022 at 22:06
  • @CR. - added sys info above
    – EML
    Commented Mar 9, 2022 at 9:57
  • Is the "other" C++ program properly closing the file it creates?
    – CR.
    Commented Mar 9, 2022 at 16:19
  • @CR. - just checked, thx - the other program is trivial, and does an open (checking that the open succeeds), and one write (checking the number of chars written), followed immediately by a close. In fact, the only interesting thing about it is that it uses C-style fopen/fwrite/fclose, while the other code is C++.
    – EML
    Commented Mar 9, 2022 at 16:57
  • If you run the programs outside of Apache does it work? How is Apache invoking the binaries? I tried to recreate this but don't see any problems. Can you post some code snippets?
    – CR.
    Commented Mar 9, 2022 at 18:20

1 Answer 1

0

I had a similar issue with appImage, (written in Go) on a baremetal machine. This got fixed by calling f.Sync() in the program that created the files.

I don't think this is qemu specific. My working theory is that if a file is not synced yet to storage, it is only visible to the proces that created it. If that one returns, then probably only the parent. Processes from a different ancestry will probably have to wait until the file is synced.

I don't have a definite resource on this, just what I found when debugging the above.

1
  • Very curious, ta. I'll have a go with more debug over the w/end as @CR. suggests.
    – EML
    Commented Mar 11, 2022 at 9:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .