Re: open(..., O_CREAT|O_EXCL, 0400) on aufs over nfs4

2015-04-22 Thread sfjro

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

2015-04-07 Thread sfjro

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

2015-04-04 Thread Pip Cet

   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/