Re: open(..., O_CREAT|O_EXCL, 0400) on aufs over nfs4
Hello Pip, I am still considering how to support atomic_open(), but all of my approach are not good. And I am start thinking that your approach is better eventually. Here is what I thought. If you have any comment, please let me know. Support for a branch who has its -atomic_open() -- The filesystems who implement its -atomic_open() are not majority, but surely exist. For example NFSv4 does, and aufs should call NFSv4 -atomic_open, particularly for open(O_CREAT|O_EXCL, 0400). Other than -atomic_open(), NFSv4 returns an error for this case. While I am not sure whether all filesystems who have -atomic_open() behave like this, but NFSv4 surely return an error. Generally speaking, calling -atomic_open() is less important for other open(2) cases. In order to support -atomic_open() for aufs, there are a few approaches. A. Introduce aufs_atomic_open() - calls one of VFS:do_last(), lookup_open() or atomic_open() for branch fs. B. Introduce aufs_atomic_open() calling create, open and chmod, an aufs user Pip Cet's approach - calls aufs_create(), VFS finish_open() and notify_change(). - pass fake-mode to finish_open(), and then correct the mode by notify_change(). C. Extend aufs_open() to call branch fs's -atomic_open() - no aufs_atomic_open(). - aufs_lookup() registers the TID to an internal object. - aufs_create() does nothing when the matching TID is registered, but registers the mode. - aufs_open() calls branch fs's -atomic_open() when the matching TID is registered. D. Extend aufs_open() to re-try branch fs's -open() with superuser's credential - no aufs_atomic_open(). - aufs_create() registers the TID to an internal object. this info represents this process created this file just now. - when aufs gets EACCES from branch fs's -open(), then confirm the registered TID and re-try open() with superuser's credential. Pros and cons for each approach. A. - straightforward but highly depends upon VFS internal. - the atomic behavaiour is kept. - some of parameters such as nameidata are hard to reproduce for branch fs. - large overhead. B. - easy to implement. - the atomic behavaiour is lost. C. - the atomic behavaiour is kept. - dirty and tricky. - VFS checks whether the file is created correctly after calling -create(), which means this approach doesn't work. D. - easy to implement. - the atomic behavaiour is lost. - to open a file with superuser's credential and give it to a user process is a bad idea, since the file object keeps the credential in it. It may affect LSM or something. This approach doesn't work either. J. R. Okajima -- BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT Develop your own process in accordance with the BPMN 2 standard Learn Process modeling best practices with Bonita BPM through live exercises http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_ source=Sourceforge_BPM_Camp_5_6_15utm_medium=emailutm_campaign=VA_SF
Re: open(..., O_CREAT|O_EXCL, 0400) on aufs over nfs4
Pip Cet: I've taken the code from fuse/dir.c and modified it slightly to provide a pretty minimal workaround, by creating the file with read/write permission first and then revoking that permission in a separate call to aufs_setattr if necessary. That's not perfect behavior (there is a window during which the extended preliminary permissions are visible), but it appears to work. From my understanding, such window is problematic. As long as nfs4 has its -atomic_open(), aufs should call it. The sequence of - open(file, O_CREAT|O_WRONLY, 0600); - open(file, O_WRONLY); - chmod(file, 0400); is not atomic at all from nfs4's point of view. My current idea is - At the point where my previous patch prints, aufs creates a small object of {pid, dentry} pair and holds internally. - In aufs_create(), return 0 without processing if given {pid, dentry} matches with the internally stored one. Otherwise, process normally. - In aufs_open(), calls -atomic_open if {pid, dentry} matches. - The exit notifier may be necessary to free the internal pair, if the task can abort in lookup after aufs creates the internal pair. I don't think this idea is good, and still considering how to do it. Anyway, your patch is surely one approach. Thanx. J. R. Okajima -- BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT Develop your own process in accordance with the BPMN 2 standard Learn Process modeling best practices with Bonita BPM through live exercises http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_ source=Sourceforge_BPM_Camp_5_6_15utm_medium=emailutm_campaign=VA_SF
open(..., O_CREAT|O_EXCL, 0400) on aufs over nfs4
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 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/