Intermittent crashes copying files involving symbolic links
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Python |
Fix Released
|
Unknown
|
|||
python-distutils-extra |
Fix Released
|
Medium
|
Martin Pitt | ||
python-distutils-extra (Ubuntu) |
Fix Released
|
Medium
|
Martin Pitt | ||
python2.7 (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
The approach used by python-
The crash happens while trying to create the debian/tmp/ file tree when apport's make processess calls python-
python setup.py install \
--root=
--install-
--no-compile --install-
For this case I received the following message from pbuilder while trying to build the apport package for ubuntu:
copying data/icons/
error: /tmp/buildd/
make: *** [install/apport] Error 1
dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2
-----------------
There are icon files in two different directories, one a symbolic link to the other.
In particular the source icon files are:
-rw-r--r-- 1 gruber gruber 16628 2011-04-25 12:52:10.493242000 -0400 data/icons/
lrwxrwxrwx 1 gruber gruber 18 2011-04-25 12:52:10.409823944 -0400 data/icons/
these are to be copied by python-distutils to:
lrwxrwxrwx 1 gruber gruber 18 2011-04-25 17:44:10.579475687 -0400 debian/
lrwxrwxrwx 1 gruber gruber 18 2011-04-25 17:44:10.579475687 -0400 debian/
python-
python-distutils then has the responsibility to finish the work on these icons. If the above entries were added by command/
If the two data_file entries are produced in the opposite order file_util.py checks for the existence of destination directory (1) and then tries to find out whether the file is up-to-date. It isn't aware of the symbolic link and doesn't check for the existence of destination directory (2), which doesn't yet exist, so the newer function call fails when the attempt to stat the destination file is made. While python-distutils has functions for producing hard and symbolic links that code is not being accessed for this operation.
On my system the mimetypes directory has always come first and the build always fails. On launchpad the apps directory (target of the symbolic link) is usually listed first and normally the build proceeds without event.
The order of the entries is determined by glob.glob() calls in command/
* There is a second difference in execution between pbuilder and launchpad's build farm. The build farm keeps file modification time in seconds and python-distutils' dep_util.py uses subsecond floating point stat.st_mtime values around line 85 while copy times are preserved in file_util.py using stat[ST_MTIME], an integer value. This doesn't matter on an ext3 file system but causes the destination file to look older than the original on an ext4 file system, which tracks subsecond times (note the file times above). The symbolic-
description: | updated |
Changed in ubuntu: | |
assignee: | nobody → John S. Gruber (jsjgruber) |
Changed in python-distutils-extra: | |
assignee: | nobody → John S. Gruber (jsjgruber) |
affects: | ubuntu → python-distutils-extra (Ubuntu) |
Changed in python-distutils-extra: | |
status: | New → Triaged |
Changed in python-distutils-extra (Ubuntu): | |
status: | New → Triaged |
Changed in python-distutils-extra: | |
importance: | Undecided → Medium |
Changed in python-distutils-extra (Ubuntu): | |
importance: | Undecided → Medium |
Changed in python: | |
status: | Unknown → New |
Changed in python2.7 (Ubuntu): | |
status: | New → Confirmed |
Changed in python: | |
status: | New → Fix Released |
Thanks for the analysis! I can reproduce this by fudging build_icons.run() to reverse() the glob result first.
This seems to be easier to reproduce by installing a broken symlink to a nonexisting directory. I added a test for this to test/auto.py.