v9fs does not honor open file handles on anonymous files

From: Richard Yao
Date: Tue Dec 31 2013 - 14:22:02 EST


I have a small shell script:

#!/bin/bash
cat <<-EOF
EOF

Running this causes bash to fork via clone(), set fd=0 to point to an
empty file in /tmp, unlink it and then execve cat. Specifically,
something like this;

[pid 3699] open("/tmp/sh-thd-1388524249",
O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600) = 3
[pid 3699] open("/tmp/sh-thd-1388524249", O_RDONLY) = 4
[pid 3699] close(3) = 0
[pid 3699] unlink("/tmp/sh-thd-1388524249") = 0
[pid 3699] dup2(4, 0) = 0
[pid 3699] close(4) = 0
[pid 3699] execve("/bin/cat", ["cat"], [/* 22 vars */]) = 0

One of the first things that cat does is fstat fd=0. This informs cat
that the file is empty and it will quit. If /tmp is on other
filesystems, cat will fstat fd=0, receive a return code of 0 from fstat,
print nothing and then quit normally. If /tmp is on 9pfs, cat will fstat
fd=0, receive ENOENT from fstat, print `cat: -: No such file or
directory` to stderr and die.

It seems that v9fs_vfs_unlink() is killing the file while we still have
open file handles. I have confirmed that this behavior occurs on Linux
3.13.0-rc6. This breaks several things when Gentoo is on a 9p rootfs
(e.g. gcc-config, any emerge command that involves a C compiler,
etcetera) inside QEMU. I have placed /tmp and /var/tmp/portage on a
tmpfs as a hack-fix, but it would be better to get this fixed.

I doubt that I will write a patch to fix this. I am sending the details
to the list so the 9p maintainers or any other interested individual can
fix it.

Attachment: signature.asc
Description: OpenPGP digital signature