Subject: Re: bug#8636: cp -x flag does not work

From: Bob Proulx <[email-masked]>
Date: Thu, 15 Sep 2011 10:33:24 -0600

[email-masked] wrote:
> you are claiming functionality that you do not provide (stay on one file
> system during a potentially recursive copy ) while allowing recursion into
> other file systems if they are mounted beneath the directory you are
> copying. 
> 
> why you think that this constitutes staying  on one filesystem eludes me.

Let me help with this.  You said the command you were using was:

>> copying the root directory ( / ) of a running linux system using cp -xdvpR
>> cp followed a directory that was mounted via NFS under / .

This failure was not reproducible.  More information was requested.
In that follow-up you said the actual command you used was:

>> the command used was cp -xvdpR /*   /newdirectory
>> the guilty party is apparently the wildcard
>> the command as given above copies everything and descends all directories on
>> all mounted file systems under / no matter what they are.

That is correct.  And that is the reason cp is doing the right thing
and this is not a bug in cp.  You have specifically requested that the
mount point be copied.

You may be misunderstanding how how wildcards work.  The shell expands
wildcards before invoking the command.  You can see this using the
echo command.

  $ echo somecommand /*
  
The 'somecommand' does not see the '*' at all.  The shell sees the '*'
and expands it to match files.  The names of the files replace the
string on the command line.  The modified list of arguments is passed
to the command when it is invoked.  The command does not know that a
wildcard was involved.

When you call

  cp -xvdpR /*   /newdirectory

The cp command sees something like (using ... to indicate more files):

  cp -xvdpR /bin /boot /dev /etc ... /mnt ...   /newdirectory

Since cp was asked to recursively copy /mnt it will copy /mnt and that
is regardless of the -x option.  The documentation for -x is:

         Skip subdirectories that are on different file systems from
         the one that the copy started on.

The cp command was told to copy /mnt and relating to this
documentation that is where the copy starts.  If there is a mount
point below that directory then the -x will instruct cp to skip it.
But since /mnt was explicitly stated in the cp command it is not below
anything and will not be skipped.

If you were to remove the wildcard and specify only the root directory
then the -x would skip any mount points below it.

  cp -xvdpR /  /newdirectory

There cp would be given only the / directory and the /mnt mount point
below it would be skipped.

> find does this correctly ( -xdev or -mount switches) and coreutil's cp and
> mv can and should too.

No it does not.  Try 'find' on your mount point.  I will use the
"-maxdepth 2" to limit the amount of runtime only.  But if run find
using the same "/*" you used with cp then find will have the same
behavior.

  find /* -xdev -maxdepth 2 -print

Hope this helps.

Bob