Package: coreutils
Version: 8.20-3
Severity: normal

cp --update --archive can be used to make and maintain backup copies of 
directory 
trees. I am using this in a script with --verbose (I post-process the output in
this script). After upgrading to wheezy (coreutils 8.20) from lenny (coreutils
6.10), the cp output has included a lot of lines like

removed ‘path/to/certain/file’

All the listed files have more than one hard link. The following test case 
illustrates
the behaviour:

$ mkdir x
$ date > x/a
$ ln x/a x/b
$ ls -l x
total 8
-rw-rw-r-- 2 toomas toomas 30 Jun 27 16:36 a
-rw-rw-r-- 2 toomas toomas 30 Jun 27 16:36 b
$ cp --update --archive --verbose  --no-target-directory ./x ./y
‘./x’ -> ‘./y’
‘./x/b’ -> ‘./y/b’
‘./x/a’ -> ‘./y/a’
$ ls -l y
total 8
-rw-rw-r-- 2 toomas toomas 30 Jun 27 16:36 a
-rw-rw-r-- 2 toomas toomas 30 Jun 27 16:36 b
$ # The following command is the one which is showing the problem:
$ cp --update --archive --verbose  --no-target-directory ./x ./y
removed ‘./y/a’
$ # The following listing shows that the link was actually re-created:
$ ls -l y
total 8
-rw-rw-r-- 2 toomas toomas 30 Jun 27 16:36 a
-rw-rw-r-- 2 toomas toomas 30 Jun 27 16:36 b

Doing a "strace" on the last "cp" reveals the following sequence of events:

lstat("./x/b", {st_mode=S_IFREG|0664, st_size=30, ...}) = 0
stat("./y/b", {st_mode=S_IFREG|0664, st_size=30, ...}) = 0
lstat("./x/a", {st_mode=S_IFREG|0664, st_size=30, ...}) = 0
stat("./y/a", {st_mode=S_IFREG|0664, st_size=30, ...}) = 0
linkat(AT_FDCWD, "./y/b", AT_FDCWD, "./y/a", 0) = -1 EEXIST (File exists)
unlink("./y/a")                         = 0
linkat(AT_FDCWD, "./y/b", AT_FDCWD, "./y/a", 0) = 0

So even though the program has stat()ed both y/a and y/b and should "know"
that they already have identical inode numbers, is still tries to link y/a
to y/b, fails, removes y/a, and re-creates the hard link again.

With large directory trees containing numerous hard links this seems like
an unnecessary waste of resources, in addition to creating the initially
very confusing "removed ‘path/to/certain/file’" messages on the verbose
output.

In my opinion, the correct behaviour should omit the linkat(), unlink(),
linkat() sequence after comparing the inode numbers of existing files.

Toomas Tamm

-- System Information:
Debian Release: 7.5
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.2.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.utf-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages coreutils depends on:
ii  dpkg          1.16.15
ii  install-info  4.13a.dfsg.1-10
ii  libacl1       2.2.51-8
ii  libattr1      1:2.4.46-8
ii  libc6         2.13-38+deb7u1
ii  libselinux1   2.1.9-5

coreutils recommends no packages.

coreutils suggests no packages.

-- no debconf information


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to