From: Omar Sandoval <osan...@fb.com> QEMU's local 9pfs server passes through O_NOATIME from the client. If the QEMU process doesn't have permissions to use O_NOATIME (namely, it does not own the file nor have the CAP_FOWNER capability), the open will fail. This causes issues when from the client's point of view, it believes it has permissions to use O_NOATIME (e.g., a process running as root in the virtual machine). Additionally, overlayfs on Linux opens files on the lower layer using O_NOATIME, so in this case a 9pfs mount can't be used as a lower layer for overlayfs (cf. https://github.com/osandov/drgn/blob/dabfe1971951701da13863dbe6d8a1d172ad9650/vmtest/onoatimehack.c and https://github.com/NixOS/nixpkgs/issues/54509).
Luckily, O_NOATIME is effectively a hint, and is often ignored by, e.g., network filesystems. open(2) notes that O_NOATIME "may not be effective on all filesystems. One example is NFS, where the server maintains the access time." This means that we can honor it when possible but fall back to ignoring it. Signed-off-by: Omar Sandoval <osan...@fb.com> --- hw/9pfs/9p-util.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h index 79ed6b233e..50842d540f 100644 --- a/hw/9pfs/9p-util.h +++ b/hw/9pfs/9p-util.h @@ -37,9 +37,14 @@ static inline int openat_file(int dirfd, const char *name, int flags, { int fd, serrno, ret; +again: fd = openat(dirfd, name, flags | O_NOFOLLOW | O_NOCTTY | O_NONBLOCK, mode); if (fd == -1) { + if (errno == EPERM && (flags & O_NOATIME)) { + flags &= ~O_NOATIME; + goto again; + } return -1; } -- 2.26.1