bug#34713: Files vanishing when moving to different FS

2019-03-04 Thread Christoph Michelbach

Hello, Bob

Thank you for your explanation. I understand what's going on and even 
looked at the part of the source code that causes the problem prior to 
filing the bug report.



Even if you don't consider it a bug, it's still unexpected behavior that 
could be avoided. I think that mv's behavior would be more logical if it 
only removed files that it copied prior to removal (simple solution to 
the problem without destroying user data) or also move files that 
appeared in the destination location during the copying process 
(emulating moving a directory within a file system better and not 
destroying user data).



In the first case, it should still try to remove directories after 
removing all files in them but adhere to the rule that non-empty 
directories cannot be deleted instead of simply emptying them of their 
content prior to deletion.



In the second case, it should attempt to delete the directory and if 
this fails because it is non-empty, copy the newly appeared files over 
to the destination.



I think that the second solution is better for the users as it emulates 
the behavior of a move operation within a file system. However, I see 
that the first solution is easier to implement. The current behavior of 
mv destroys user data which I think is highly unexpected behavior.



Christoph






bug#34713: Files vanishing when moving to different FS

2019-03-04 Thread Bob Proulx
tags 34713 notabug
close 34713
thanks

Hello Christoph,

Christoph Michelbach wrote:
> To reproduce this bug, you need two different file systems. Adapt the
> paths to fit your system.

Thank you for making this bug report.  However what you are
experiencing is due to the race condition created by the non-atomic
nature of copying files from one file system to another, removing
files, and renaming files.  This is not a bug in mv but is an
intrinsic behavior.

> Set the experimental file structure up like this:
> 
> mkdir exp
> cd exp
> mkdir a
> cd a
> touch a{1..10}
> cd ..
> mkdir b
> cd b
> touch b{1..1}
> mkdir /t/ae # /t has to be on a different file system

Thank you for the very nice test case.

> Then have two terminals open in the exp directory created above.

This is a clue to the nature of the problem being a race condition.
It describes simultaneous parallel processes.

> In one, execute this command:
> 
> mv a /t/ae

Because /t is on a different file system mv cannot simply rename the
files but must perform the action in two steps.  It copies the file
from source to destination.  It removes source file.  This is
documented in the mv with:

'mv' can move any type of file from one file system to another.
Prior to version '4.0' of the fileutils, 'mv' could move only
regular files between file systems.  For example, now 'mv' can
move an entire directory hierarchy including special device files
from one partition to another.  It first uses some of the same
code that's used by 'cp -a' to copy the requested directories and
files, then (assuming the copy succeeded) it removes the
originals.  If the copy fails, then the part that was copied to
the destination partition is removed.  If you were to copy three
directories from one partition to another and the copy of the
first directory succeeded, but the second didn't, the first would
be left on the destination partition and the second and third
would be left on the original partition.

The mv a /t/ae action is similar to cp -a a t/ae && rm -r a when the
action is successful.  Similar because there are two steps happening.
A first step with the copy and a second step with the removal and
there is a time skew between those actions.

> In the other, execute this one while the one in the first terminal
> still is running (hence the large number of files so you have time to
> do this):
> 
> mv b/* a

This is the second part of the race condition.  It it moving files
into the a directory at the same time that files are being copied out
of the directory and the directory itself being removed.

> You will end up with 100 000 files in /t/ae. The 10 000 files beginning
> with the letter b will be gone.

Look at the two actions explicitly:

Process 1:
  cp -a a /t/ae
  rm -rf a

Process 2:
  mv b/* a

Now it is more obvious that as soon as the first process copy finishes
that it will remove the source location, that is having files moved
into it by the second process, that the directory will be deleted by
the first process.

Does that make it easier to understand what is happening?

The copy and remove two actions do not occur when both the source and
destination are on the same file system.  In that case the file can be
renamed atomically without doing a copy.  But when the action is
across two file systems this is not possible and it is simulated (or
perhaps emulated) by the copy and remove two step action.

Whenever tasks are moving files into and out of the same directory at
the same time this is always something to be aware of regardless
because they may be an overlap of actions in that directory.

In this particular example the problem can be avoided by renaming "a"
first and then transfering the files to the other file system.
Because it was removed then the second process can create it without
collision.  Something like this pseudo-code.  However to safely use
temporary file names will require more code than this.  This is simply
for illustration purposes.

Process 1:
  mv a tmpdirname
  cp -a tmpdirname /t/ae
  rm -rf tmpdirname

Process 2:
  mkdir a
  mv b/* a

I hope this helps.

Since this is not a bug in mv I am going to close the ticket in our
bug database.  But please we would like to hear back from you in this
ticket for any further discussion.

Bob





bug#33644: [PATCH] cp --preserve=xattr: preserve NFSv4 ACL extended attributes

2019-03-04 Thread Kamil Dudka
On Sunday, March 3, 2019 3:07:53 AM CET Pádraig Brady wrote:
> So attr_copy_file() copies all except those defined in /etc/xattr.conf

... which is, however, not how xattr.conf is currently documented:

# /etc/xattr.conf
#
# Format:
#  
#
# Actions:
#   permissions - copy when trying to preserve permissions.
#   skip - do not copy.

> ACL xattrs are listed in that file with the rationale from a comment in
> libattr being:
> 
>  "ACLs are excluded by default because copying them between
>   file systems with and without ACL support needs some
>   additional logic so that no unexpected permissions result."
> 
> So the ACL handling specifically is deferred to libacl.
> Now system.posix_acl_access is handled by libacl,
> but system.nfs4_acl is not.

True.

> So I think the correct fix here is to remove the
> nfs entries from /etc/xattr.conf, and then cp will copy.

OK, I will propose it on the acl-devel mailing list, together with updating 
the documentation of xattr.conf.  We will see what attr/acl upstream thinks 
about it.

> This has the advantage of being configurable,
> and also removes nfs4 specific handling from cp.
> Any nfs4 specific handling should be in libacl.

So you think it should.  Nevertheless, in reality, libacl is not aware
of NFSv4 ACLs at all.  And I am not aware of any plans to change this.

Kamil

> thanks,
> Pádraig