bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: cp(1) fails to copy file from /proc


From: Jim Meyering
Subject: Re: cp(1) fails to copy file from /proc
Date: Thu, 16 Apr 2009 14:54:20 +0200

Jukka Salmi wrote:
> (Please Cc: me on replies since I'm not subscribed to the list.)
> as [1]described on the Debian Users list cp(1) seems to have problems copying
> files from /proc on at least Debian GNU/Linux 5.0 systems (tested on i686 and
> x86_64).  I'm seeing this with coreutils 6.10 (using the Debian binary package
> coreutils-6.10-6), but another list member [2]wrote that he could reproduce it
> with coreutils 7.2.
>
> The following description of the problem is more or less copied from my
> [1]original post.
>
> How I'm able to reproduce the problem:
>
> $ wc -l /proc/cpuinfo
> 200 /proc/cpuinfo
> $ cp /proc/cpuinfo /tmp
> $ echo $?
> 0
> $ wc -l /tmp/cpuinfo
> 125 /tmp/cpuinfo
>
> The first part of the file is copied correctly, but the rest is missing.
> Running strace(1) on cp reveals that cp requests to read 4 kB, receives less
> (but still >0), writes the received data to the destination file and exits:
>
> $ strace cp /proc/cpuinfo /tmp
> [...]
> open("/proc/cpuinfo", O_RDONLY)         = 3
> fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
> open("/tmp/cpuinfo", O_WRONLY|O_CREAT|O_EXCL, 0444) = 4
> fstat(4, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
> read(3, "processor\t: 0\nvendor_id\t: Genuine"..., 4096) = 3535
> write(4, "processor\t: 0\nvendor_id\t: Genuine"..., 3535) = 3535

Thank you for the bug report.
The relevant code from coreutils/src/copy.c is here:

            /* A short read on a regular file means EOF.  */
            if (n_read != buf_size && S_ISREG (src_open_sb.st_mode))
              break;

That optimization was added over three years ago, with this change:

    http://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=25719a33154f0c6

It appears that it is not (no longer?) valid for most mainstream kernels,
at least for files on /proc, so I'll remove it or adjust it.

BTW, while reproducing your particular problem appears to require
a relatively large /proc/cpuinfo file (probably an 8-cpu system),
I can reproduce the failure with other large files in /proc.
I chose /proc/kallsyms:

    $ cp /proc/kallsyms /dev/shm/k
    $ wc -c /proc/kallsyms /dev/shm/k
    1492084 /proc/kallsyms
    4090 /dev/shm/k

I was surprised to see different results when copying to /tmp:

    $ cp /proc/kallsyms /tmp/k
    $ wc -c /proc/kallsyms /tmp/k
    1492084 /proc/kallsyms
    1492084 /tmp/k

That's because the two devices have different fundamental block sizes:

    $ stat -f --format '%S %n' /dev/shm/k /tmp/k
    4096 /dev/shm/k
    1024 /tmp/k

and cp chooses its input buffer size based on that.
With the smaller block size, cp happens to avoid the short read problem.

I've confirmed this on the following kernels:

  debian unstable  2.6.26-2-amd64
  fedora 10        2.6.27.21-170.2.56.fc10.x86_64
  ubuntu           2.6.28-11-generic
  fedora rawhide   2.6.29.1-70.fc11.x86_64




reply via email to

[Prev in Thread] Current Thread [Next in Thread]