Debian Bug report logs - #532814
coreutils: cp -aL creates hardlinks where none were present before

version graph

Package: coreutils; Maintainer for coreutils is Michael Stone <mstone@debian.org>; Source for coreutils is src:coreutils.

Reported by: "brian m. carlson" <sandals@crustytoothpaste.net>

Date: Thu, 11 Jun 2009 22:24:01 UTC

Severity: normal

Found in version coreutils/7.4-2

Reply or subscribe to this bug.

Toggle useless messages

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to debian-bugs-dist@lists.debian.org, Michael Stone <mstone@debian.org>:
Bug#532814; Package coreutils. (Thu, 11 Jun 2009 22:24:04 GMT) Full text and rfc822 format available.

Acknowledgement sent to "brian m. carlson" <sandals@crustytoothpaste.ath.cx>:
New Bug report received and forwarded. Copy sent to Michael Stone <mstone@debian.org>. (Thu, 11 Jun 2009 22:24:04 GMT) Full text and rfc822 format available.

Message #5 received at submit@bugs.debian.org (full text, mbox):

From: "brian m. carlson" <sandals@crustytoothpaste.ath.cx>
To: Debian Bug Tracking System <submit@bugs.debian.org>
Subject: coreutils: cp -aL creates hardlinks where none were present before
Date: Thu, 11 Jun 2009 21:33:10 +0000
[Message part 1 (text/plain, inline)]
Package: coreutils
Version: 7.4-2
Severity: normal

If I create a directory structure such as the following:

  a:
  total 2
  drwxr-xr-x 2 bmc bmc 1024 2009-06-11 21:06 dir
  lrwxrwxrwx 1 bmc bmc    4 2009-06-11 21:06 link -> ../b
  
  a/dir:
  total 0
  lrwxrwxrwx 1 bmc bmc 7 2009-06-11 21:06 link -> ../../b
  
  b:
  total 2
  -rw-r--r-- 1 bmc bmc 5 2009-06-11 21:06 file

and then run "cp -aL a/* c", then the copies of file (in c) become hard
links to each other.  This behavior is not documented, and it does not
occur if I use -LR instead of -aL.  It appears to be triggered by
--preserve=links.

My opinion is that this behavior is incorrect[0], but I don't care very
much one way or the other.  If this behavior is intentional, it should
be clearly documented in the manual page, at the very least.  Either
changing the behavior or documenting the behavior[1] is satisfactory for
me.

A shell script is attached that demonstrates this problem.

[0] That is, --preserve=links should preserve symlinks as symlinks and
hard links as hard links.  Just because -L forces all symlinks to be
dereferenced does not mean that I want to "preserve" symlinks as hard
links.
[1] This information should be present in the manual page, not just in
the info page (which I almost never read).

-- System Information:
Debian Release: squeeze/sid
  APT prefers unstable
  APT policy: (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.30-rc8-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages coreutils depends on:
ii  libacl1                       2.2.47-2   Access control list shared library
ii  libattr1                      1:2.4.43-2 Extended attribute shared library
ii  libc6                         2.9-13     GNU C Library: Shared libraries
ii  libselinux1                   2.0.71-1   SELinux shared libraries

coreutils recommends no packages.

coreutils suggests no packages.

-- no debconf information

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
+1 713 440 7475 | http://crustytoothpaste.ath.cx/~bmc | My opinion only
OpenPGP: RSA v4 4096b 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187
[testcase (text/plain, attachment)]
[signature.asc (application/pgp-signature, inline)]

Information forwarded to debian-bugs-dist@lists.debian.org, Michael Stone <mstone@debian.org>:
Bug#532814; Package coreutils. (Mon, 15 Jun 2009 07:54:06 GMT) Full text and rfc822 format available.

Acknowledgement sent to Jim Meyering <jim@meyering.net>:
Extra info received and forwarded to list. Copy sent to Michael Stone <mstone@debian.org>. (Mon, 15 Jun 2009 07:54:06 GMT) Full text and rfc822 format available.

Message #10 received at submit@bugs.debian.org (full text, mbox):

From: Jim Meyering <jim@meyering.net>
To: "brian m. carlson" <sandals@crustytoothpaste.ath.cx>
Cc: 532814@bugs.debian.org, Debian Bug Tracking System <submit@bugs.debian.org>
Subject: Re: Bug#532814: coreutils: cp -aL creates hardlinks where none were present before
Date: Mon, 15 Jun 2009 09:34:23 +0200
brian m. carlson wrote:
> Package: coreutils
> Version: 7.4-2

Thanks for taking the time to report that.

> If I create a directory structure such as the following:
>
>   a:
>   total 2
>   drwxr-xr-x 2 bmc bmc 1024 2009-06-11 21:06 dir
>   lrwxrwxrwx 1 bmc bmc    4 2009-06-11 21:06 link -> ../b
>
>   a/dir:
>   total 0
>   lrwxrwxrwx 1 bmc bmc 7 2009-06-11 21:06 link -> ../../b
>
>   b:
>   total 2
>   -rw-r--r-- 1 bmc bmc 5 2009-06-11 21:06 file
>
> and then run "cp -aL a/* c", then the copies of file (in c) become hard
> links to each other.  This behavior is not documented, and it does not
> occur if I use -LR instead of -aL.  It appears to be triggered by
> --preserve=links.

That is correct, and deliberate.
With --preserve=links, when cp detects two source files with the
same inode, it must arrange for the corresponding names to be hard
linked in the destination tree.  That is what "preserve=links" means.

The trick is to realize that when you invoke cp with -L,
that tells cp to use stat (which never sees a symlink) rather
than lstat to determine inode numbers.  So those two symlinks
to the same file appear (to cp -L) as hard links, and it preserves
that attribute because you used -a, which includes --preserve=links.

> My opinion is that this behavior is incorrect[0], but I don't care very
> much one way or the other.  If this behavior is intentional, it should
> be clearly documented in the manual page, at the very least.  Either
> changing the behavior or documenting the behavior[1] is satisfactory for
> me.

I reproduced with this:

    $ mkdir c; touch f; ln -s f a; ln -s f b; cp -aL a b c; ls -i1 c
    74161745 a
    74161745 b

> [0] That is, --preserve=links should preserve symlinks as symlinks and
> hard links as hard links.  Just because -L forces all symlinks to be
> dereferenced does not mean that I want to "preserve" symlinks as hard
> links.

--preserve=links preserves *hard* links.
By definition (POSIX), cp -L can never produce a symlink.

> [1] This information should be present in the manual page, not just in
> the info page (which I almost never read).

Sorry, but this corner is obscure enough that any explanation
belongs in the info documentation.
In fact, there are already comments in the texinfo sources
saying that this deserves explanation.

I wrote a few words on -L and added to the --preserve=links description:

    `links'
          Preserve in the destination files any links between
          corresponding source files.  Note that with `-L' or `-H',
          this option can convert symbolic links to hard links.  For
          example,
               $ mkdir c; : > a; ln -s a b; cp -aH a b c; ls -i1 c
               74161745 a
               74161745 b
          Note the inputs: `b' is a symlink to regular file `a', yet
          the files in destination directory, `c/', are hard-linked.
          Since `-a' implies `--preserve=links', and since `-H' tells
          `cp' to dereference command line arguments, it sees two files
          with the same inode number, and preserves the perceived hard
          link.

          Here is a similar example that exercises `cp''s `-L' option:
               $ mkdir b c; (cd b; : > a; ln -s a b); cp -aL b c; ls -i1 c/b
               74163295 a
               74163295 b

Here's the patch:

From 7d350170ae78e1aca68aff81a08116109dd33be5 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering@redhat.com>
Date: Mon, 15 Jun 2009 09:10:50 +0200
Subject: [PATCH] doc: cp: describe an oddity of combining -H/-L and --preserve=links

* doc/coreutils.texi (cp invocation) [-L]: Elaborate.
[--preserve=links]: Remove comments saying that we need documentation
for just this situation.  Provide more explanation and examples.
Reported by Brian M. Carlson in http://bugs.debian.org/525048.
---
 doc/coreutils.texi |   26 ++++++++++++++++++++++++--
 1 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 155858b..1806295 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -7388,6 +7388,9 @@ cp invocation
 @opindex -L
 @opindex --dereference
 Follow symbolic links when copying from them.
+With this option, @command{cp} cannot create a symbolic link.
+For example, a symlink (to regular file) in the source tree will be copied to
+a regular file in the destination tree.

 @item -n
 @itemx --no-clobber
@@ -7435,8 +7438,27 @@ cp invocation
 @itemx links
 Preserve in the destination files
 any links between corresponding source files.
-@c Give examples illustrating how hard links are preserved.
-@c Also, show how soft links map to hard links with -L and -H.
+Note that with @option{-L} or @option{-H}, this option can convert
+symbolic links to hard links.  For example,
+@example
+$ mkdir c; : > a; ln -s a b; cp -aH a b c; ls -i1 c
+74161745 a
+74161745 b
+@end example
+@noindent
+Note the inputs: @file{b} is a symlink to regular file @file{a},
+yet the files in destination directory, @file{c/}, are hard-linked.
+Since @option{-a} implies @option{--preserve=links}, and since @option{-H}
+tells @command{cp} to dereference command line arguments, it sees two files
+with the same inode number, and preserves the perceived hard link.
+
+Here is a similar example that exercises @command{cp}'s @option{-L} option:
+@smallexample
+$ mkdir b c; (cd b; : > a; ln -s a b); cp -aL b c; ls -i1 c/b
+74163295 a
+74163295 b
+@end smallexample
+
 @itemx context
 Preserve SELinux security context of the file. @command{cp} will fail
 if the preserving of SELinux security context is not succesful.
--
1.6.3.2.406.gd6a466




Information forwarded to debian-bugs-dist@lists.debian.org, Michael Stone <mstone@debian.org>:
Bug#532814; Package coreutils. (Mon, 15 Jun 2009 07:54:18 GMT) Full text and rfc822 format available.

Acknowledgement sent to Jim Meyering <jim@meyering.net>:
Extra info received and forwarded to list. Copy sent to Michael Stone <mstone@debian.org>. (Mon, 15 Jun 2009 07:54:18 GMT) Full text and rfc822 format available.

Changed Bug submitter to '"brian m. carlson" <sandals@crustytoothpaste.net>' from '"brian m. carlson" <sandals@crustytoothpaste.ath.cx>' Request was from "brian m. carlson" <sandals@crustytoothpaste.net> to control@bugs.debian.org. (Thu, 03 Feb 2011 20:51:42 GMT) Full text and rfc822 format available.

Send a report that this bug log contains spam.


Debian bug tracking system administrator <owner@bugs.debian.org>. Last modified: Mon Apr 21 02:35:38 2014; Machine Name: beach.debian.org

Debian Bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.