Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 447370 - FreeBSD: cp -a (-P) fails when encountering broken symlinks
Summary: FreeBSD: cp -a (-P) fails when encountering broken symlinks
Status: RESOLVED OBSOLETE
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Eclasses (show other bugs)
Hardware: All FreeBSD
: Normal normal (vote)
Assignee: Gentoo/BSD Team
URL: http://www.freebsd.org/cgi/query-pr.c...
Whiteboard:
Keywords:
Depends on: 451082
Blocks:
  Show dependency tree
 
Reported: 2012-12-15 15:53 UTC by Yuta SATOH
Modified: 2019-10-11 17:41 UTC (History)
1 user (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
Patch from upstream (cp_dash_n_and_symlinks.patch,1.12 KB, patch)
2012-12-21 09:00 UTC, Michał Górny
Details | Diff
sample patch for distutils-r1.eclass (447370.patch,514 bytes, patch)
2013-01-10 12:36 UTC, Yuta SATOH
Details | Diff
sample patch for multibuild.eclass (447370-multibuild.patch,964 bytes, patch)
2014-04-12 12:32 UTC, Yuta SATOH
Details | Diff
sample patch for multibuild.eclass (use GNU's cp version) (447370-multibuild-alt.patch,1.46 KB, patch)
2014-04-12 13:12 UTC, Yuta SATOH
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Yuta SATOH 2012-12-15 15:53:44 UTC
cp behaves differently on FreeBSD.
Because of it, dev-python/setuptools-0.6.32 will fail to install.


running install_scripts
Installing easy_install script to /var/tmp/portage/dev-python/setuptools-0.6.32/image//_python2.7/usr/bin
cp: symlink: python-exec: File exists
 * ERROR: dev-python/setuptools-0.6.32 failed (install phase):
 *   Merging python2.7 image failed.
 *
 * Call stack:
 *     ebuild.sh, line   93:  Called src_install
 *   environment, line 2954:  Called distutils-r1_src_install
 *   environment, line  912:  Called python_foreach_impl 'distutils-r1_run_phase' 'python_install'
 *   environment, line 2821:  Called distutils-r1_run_phase 'python_install'
 *   environment, line  873:  Called python_install
 *   environment, line 2845:  Called distutils-r1_python_install
 *   environment, line  813:  Called die
 * The specific snippet of code:
 *       cp -a -l -n "${root}"/* "${D}"/ || die "Merging ${EPYTHON} image failed.";


Simple Steps to Reproduce

1. cd /tmp
2. mkdir {1,2,3}
3. ln -s python-exec 1/easy_install
4. ln -s python-exec 2/easy_install
5. cp -a -l -v -n 1/* 3/
6. cp -a -l -v -n 2/* 3/


results on Linux)
# cp -a -l -v -n 1/* 3/
'1/easy_install' -> '3/easy_install'
# cp -a -l -v -n 2/* 3/

results on FreeBSD)
# cp -a -l -v -n 1/* 3/
1/easy_install -> 3/easy_install
# cp -a -l -v -n 2/* 3/
cp: symlink: python-exec: File exists



Reproducible: Always
Comment 1 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2012-12-15 17:32:48 UTC
(In reply to comment #0)
> cp behaves differently on FreeBSD.
> Because of it, dev-python/setuptools-0.6.32 will fail to install.

Err, -n (--no-clobber) handles that on Linux. That looks like a bug in FreeBSD to me.

@ryao, could you help a bit with this one?
Comment 2 Mike Gilbert gentoo-dev 2012-12-15 20:28:58 UTC
Based on reading the cp source code, I agree that this seems to be a bug.

Inside of copy() in cp.c [1], the dne variable is set to 1 based on a call to stat(2). stat(2) attempts to follow symlinks, and returns -1 when called on the easy_install -> python-exec symlink because python-exec doesn't exist in ${D}.

!dne is then passed to copy_link in utils.c [2]. copy_link is supposed to remove the destination if it exists (via unlink), but the bad value in dne causes this to be skipped.

Since the destination file is not removed, the call to symlink then fails, producing the "cp: symlink: python-exec: File exists" message.

I think this could be fixed by changing the stat(2) to lstat(2) in cp.c.
copy_link should probably be changed to obey the "-n" flag (nflag) as well.

[1] http://svnweb.freebsd.org/base/head/bin/cp/cp.c?view=markup
[2] http://svnweb.freebsd.org/base/head/bin/cp/utils.c?view=markup
Comment 3 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2012-12-15 20:55:00 UTC
Thanks for the analysis, Mike. Another thing suggesting that this is a bug is the error message stating the wrong file (link destination).
Comment 4 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2012-12-21 09:00:49 UTC
Created attachment 332902 [details, diff]
Patch from upstream

Could any of you BSD-ers test the attached patch to cp?
Comment 5 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-01-09 22:05:03 UTC
(In reply to comment #4)
> Created attachment 332902 [details, diff] [details, diff]
> Patch from upstream
> 
> Could any of you BSD-ers test the attached patch to cp?

@BSD, could you please test this patch? The OP is not responsive, we don't have any system to test it and the bug is stalled because of lack of it...
Comment 6 Yuta SATOH 2013-01-10 12:36:34 UTC
Created attachment 335060 [details, diff]
sample patch for distutils-r1.eclass

(In reply to comment #5)
> (In reply to comment #4)
> > Created attachment 332902 [details, diff] [details, diff] [details, diff]
> > Patch from upstream
> > 
> > Could any of you BSD-ers test the attached patch to cp?
> 
> @BSD, could you please test this patch? The OP is not responsive, we don't
> have any system to test it and the bug is stalled because of lack of it...

Result of patched cp)

# cp -a -l -v -n 1/* 3/
# cp -a -l -v -n 1/* 3/
3/easy_install not overwritten

I think the results of `cp -a -l -v -n 1/* 3/` is incorrect.
Why copy file will not be displayed ?

@bsd,
BTW, I don't know the status of Gentoo/*BSD projects other than FreeBSD.
Doesn't happen this problem other BSD similarly ?
If problem to occur, what about using tar instead of cp.
Comment 7 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-01-10 12:48:01 UTC
(In reply to comment #6)
> Created attachment 335060 [details, diff] [details, diff]
> sample patch for distutils-r1.eclass
> 
> (In reply to comment #5)
> > (In reply to comment #4)
> > > Created attachment 332902 [details, diff] [details, diff] [details, diff] [details, diff]
> > > Patch from upstream
> > > 
> > > Could any of you BSD-ers test the attached patch to cp?
> > 
> > @BSD, could you please test this patch? The OP is not responsive, we don't
> > have any system to test it and the bug is stalled because of lack of it...
> 
> Result of patched cp)
> 
> # cp -a -l -v -n 1/* 3/
> # cp -a -l -v -n 1/* 3/
> 3/easy_install not overwritten
> 
> I think the results of `cp -a -l -v -n 1/* 3/` is incorrect.
> Why copy file will not be displayed ?

You mean that '-v' works incorrectly?
Comment 8 Yuta SATOH 2013-01-10 13:52:54 UTC
(In reply to comment #7)
> (In reply to comment #6)
> > Created attachment 335060 [details, diff] [details, diff] [details, diff]
> > sample patch for distutils-r1.eclass
> > 
> > (In reply to comment #5)
> > > (In reply to comment #4)
> > > > Created attachment 332902 [details, diff] [details, diff] [details, diff] [details, diff] [details, diff]
> > > > Patch from upstream
> > > > 
> > > > Could any of you BSD-ers test the attached patch to cp?
> > > 
> > > @BSD, could you please test this patch? The OP is not responsive, we don't
> > > have any system to test it and the bug is stalled because of lack of it...
> > 
> > Result of patched cp)
> > 
> > # cp -a -l -v -n 1/* 3/
> > # cp -a -l -v -n 1/* 3/
> > 3/easy_install not overwritten
> > 
> > I think the results of `cp -a -l -v -n 1/* 3/` is incorrect.
> > Why copy file will not be displayed ?
> 
> You mean that '-v' works incorrectly?

Yes.
When the option -n is enabled, the following line is seems to be that it does not displayed.

1/easy_install -> 3/easy_install


Actual Results
# rm 3/*
# cp -a -l -v -n 1/* 3/
# cp -a -l -v -n 1/* 3/
3/easy_install not overwritten


Expected Results
# rm 3/*
# cp -a -l -v -n 1/* 3/
1/easy_install -> 3/easy_install
# cp -a -l -v -n 1/* 3/
3/easy_install not overwritten


FYI,
Option -n is disabled results.
# cp -a -l -v 1/* 3/
1/easy_install -> 3/easy_install
Comment 9 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2013-01-10 22:10:58 UTC
The general issue has been fixed by using tar; I'll leave this bug for the 'cp' bug however.
Comment 10 Yuta SATOH 2014-04-12 12:32:19 UTC
Created attachment 374808 [details, diff]
sample patch for multibuild.eclass

dev-python/{pyelftools-0.21-r4,setuptools-2.2} install fails on Gentoo/FreeBSD...


 * Messages for package dev-python/pyelftools-0.21-r4:

 * ERROR: dev-python/pyelftools-0.21-r4::gentoo failed (install phase):
 *   python3_3: merging image failed.
 *
 * Call stack:
 *     ebuild.sh, line   93:  Called src_install
 *   environment, line 3546:  Called distutils-r1_src_install
 *   environment, line 1211:  Called _distutils-r1_run_foreach_impl 'distutils-r1_python_install'
 *   environment, line  233:  Called python_parallel_foreach_impl 'distutils-r1_run_phase' 'distutils-r1_python_install'
 *   environment, line 3386:  Called multibuild_parallel_foreach_variant '_python_multibuild_wrapper' 'distutils-r1_run_phase' 'distutils-r1_python_install'
 *   environment, line 2529:  Called multibuild_foreach_variant '_multibuild_parallel' '_python_multibuild_wrapper' 'distutils-r1_run_phase' 'distutils-r1_python_install'
 *   environment, line 2478:  Called _multibuild_run '_multibuild_parallel' '_python_multibuild_wrapper' 'distutils-r1_run_phase' 'distutils-r1_python_install'
 *   environment, line 2476:  Called _multibuild_parallel '_python_multibuild_wrapper' 'distutils-r1_run_phase' 'distutils-r1_python_install'
 *   environment, line 2520:  Called _python_multibuild_wrapper 'distutils-r1_run_phase' 'distutils-r1_python_install'
 *   environment, line  664:  Called distutils-r1_run_phase 'distutils-r1_python_install'
 *   environment, line 1179:  Called distutils-r1_python_install
 *   environment, line 1129:  Called multibuild_merge_root '/var/tmp/portage/dev-python/pyelftools-0.21-r4/image//_python3.3' '/var/tmp/portage/dev-python/pyelftools-0.21-r4/image/'
 *   environment, line 2509:  Called die
 * The specific snippet of code:
 *           die "${MULTIBUILD_VARIANT:-(unknown)}: merging image failed.";
 *
 * If you need support, post the output of `emerge --info '=dev-python/pyelftools-0.21-r4::gentoo'`,
 * the complete build log and the output of `emerge -pqv '=dev-python/pyelftools-0.21-r4::gentoo'`.
 * The complete build log is located at '/var/tmp/portage/dev-python/pyelftools-0.21-r4/temp/build.log'.
 * The ebuild environment file is located at '/var/tmp/portage/dev-python/pyelftools-0.21-r4/temp/environment'.
 * Working directory: '/var/tmp/portage/dev-python/pyelftools-0.21-r4/work/pyelftools-0.21'
 * S: '/var/tmp/portage/dev-python/pyelftools-0.21-r4/work/pyelftools-0.21'
 *
 * The following package has failed to build or install:
 *
 *  (dev-python/pyelftools-0.21-r4:0/0::gentoo, ebuild scheduled for merge), Log file:
 *   '/var/tmp/portage/dev-python/pyelftools-0.21-r4/temp/build.log'
 *
Comment 11 Yuta SATOH 2014-04-12 13:12:47 UTC
Created attachment 374810 [details, diff]
sample patch for multibuild.eclass (use GNU's cp version)

Alternative solution...

Add sys-apps/coreutils to DEPEND or @system, use GNU's cp.
On FreeBSD, the name of GNU's cp is gcp.

# equery f coreutils | grep cp
/usr/bin/gcp

However, KEYWORDS of coreutils is not enough.
(Probably, this problem will also occur on prefix but no KEYWORDS...)
http://packages.gentoo.org/package/sys-apps/coreutils?arches=all
Comment 12 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2014-04-13 16:48:07 UTC
We no longer use 'cp -aln' so this bug is obsolete.
Comment 13 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2014-04-14 15:00:49 UTC
Ok, so it's about plain -a as well...
Comment 14 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2014-04-15 15:49:29 UTC
Well, let's make this bug focused purely on weird BSD behavior and not eclasses.
Comment 15 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2015-12-19 14:10:52 UTC
Ok then. Merged just the 'cp -r' -> 'cp -R' change.

commit 7adffa3687e1abf7ee24b096b8ab2f39a7ee32b9
Author: Michał Górny <mgorny@gentoo.org>
Date:   Sat Dec 19 08:57:56 2015

    multibuild.eclass: _copy_sources(), use 'cp -R' for BSD compat, #568692
    
    Use 'cp -R' for multibuild_copy_sources() as the '-r' option triggers
    triggers undesired '-L' behavior wrt symbolic links.
    
    Fixes: https://bugs.gentoo.org/show_bug.cgi?id=568692
Comment 16 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2015-12-19 14:14:17 UTC
Sorry, closed the wrong bug.
Comment 17 Michał Górny archtester Gentoo Infrastructure gentoo-dev Security 2019-10-11 17:41:29 UTC
*-fbsd is gone.