I'm running into a problem using tar(1) to create a read-only file on an
   aufs file system with two nfs4 branches.
   ----
   test@sivtar-8e3b7f91b4ed:~/test$ ls
   test@sivtar-8e3b7f91b4ed:~/test$ echo test > x
   test@sivtar-8e3b7f91b4ed:~/test$ chmod 0400 x
   test@sivtar-8e3b7f91b4ed:~/test$ tar cvf x.tar x
   x
   test@sivtar-8e3b7f91b4ed:~/test$ rm x
   rm: remove write-protected regular file ?x?? y
   test@sivtar-8e3b7f91b4ed:~/test$ tar xvf x.tar
   x
   tar: x: Cannot open: Permission denied
   tar: Exiting with failure status due to previous errors
   test@sivtar-8e3b7f91b4ed:~/test$ ls -l
   total 12
   -r-------- 1 test test     0 Apr  5 04:03 x
   -rw-r--r-- 1 test test 10240 Apr  5 04:03 x.tar
   test@sivtar-8e3b7f91b4ed:~/test$
   ----
   I've narrowed it down to this test case:
   ----
   #include <sys/types.h>
   #include <sys/stat.h>
   #include <fcntl.h>
   int main(void)
   {
   Â  int fd = open("x", O_WRONLY|O_CREAT, 0400);
   Â  if (fd < 0)
   Â Â Â  return 1;
   Â  write(fd, "test\n", 5);
   Â  return 0;
   }
   ----
   which wrongly fails on aufs with nfs4 branches. The correct behavior is for
   the open() call to succeed and for the resulting file descriptor to be
   writable; instead, the file is created but -EACCES is returned by open().
   The open(2) man page documents this behavior, and tar(1) relies on it.
   The relevant strace when running on aufs:
   ----
   open("x",  O_WRONLY|O_CREAT, 0400)Â Â Â Â Â Â  = -1 EACCES (Permission
   denied)
   ----
   The strace when running directly on nfs4:
   ----
   open("x", O_WRONLY|O_CREAT, 0400)Â Â Â Â Â Â  = 3
   write(3, "test\n", 5)Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â  = 5
   ----
   This  error  seems to affect multiple or all versions of aufs, but the
   specific data for the version that produced the above traces is:
   aufs version: [Â Â Â  1.060148] aufs 3.x-rcN-20150330
   I'm using kernel 4.0.0-rc6 in qemu.
   I've attached a shell log that I believe contains all the information you
   request for bug reports; please do let me know if I've missed something.
   I've had a look at the relevant code in fs/namei.c, and it appears to me the
   problem is that lookup_open(), in the absence of an ->atomic_open method,
   falls  back  to  creating a file with vfs_create, then opening it with
   vfs_open, which fails in this case. It's not clear to me what a good fix
   would be, though implementing ->atomic_open should work.
   As an experiment, I've disabled nfs4's ->atomic_open method, and the result
   was that with the modified kernel, my test program fails even directly on
   the nfs file system. It still succeeds both directly on a ramfs and on an
   aufs using said ramfs, but that appears to be because ramfs has no ->open at
   all

Attachment: aufs-data
Description: Binary data

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/

Reply via email to