FS#13683 - [git] 1.6.2-1 contains empty binary

Attached to Project: Arch Linux
Opened by xduugu (xduugu) - Friday, 06 March 2009, 14:18 GMT
Last edited by Dan McGee (toofishes) - Saturday, 06 June 2009, 01:19 GMT
Task Type Bug Report
Category Packages: Extra
Status Closed
Assigned To Dan McGee (toofishes)
Architecture All
Severity High
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 0
Private No

Details

Description:
the new git package contains a git binary of size 0 which is not installed by pacman. Because of the missing local file (it's contained in the package) you get an error

$ git
bash: git: command not found

if you try to use git.

Additional info:
* git-1.6.2-1

Steps to reproduce:
Upgrade to newest git and invoke it.
This task depends upon

Closed by  Dan McGee (toofishes)
Saturday, 06 June 2009, 01:19 GMT
Reason for closing:  Fixed
Additional comments about closing:  Fixed in git 1.6.3.2-1
Comment by Alessandro Doro (adoroo) - Friday, 06 March 2009, 14:39 GMT
i686
$ pacman -Q git; ls -l /usr/bin/git
git 1.6.2-1
-rwxr-xr-x 92 root root 846744 6 mar 2009 /usr/bin/git

Have you noticed any pacman error?
Comment by Greg (dolby) - Friday, 06 March 2009, 14:42 GMT
It works fine here
ls -al /usr/bin/git
-rwxr-xr-x 92 root root 846744 2009-03-06 18:41 /usr/bin/git
git --version
git version 1.6.2
Comment by xduugu (xduugu) - Friday, 06 March 2009, 15:20 GMT
No pacman errors at all and actually there aren't any files of size 0 but lots of symlinks in the packages. ;)
Probably it's a local problem with resolving these symlinks.
Comment by Eric Belanger (Snowman) - Friday, 06 March 2009, 19:45 GMT
Try reinstalling git.
Comment by xduugu (xduugu) - Friday, 06 March 2009, 20:18 GMT
I already did but there was no change. Besides, I tried to install the package using pacman-git and to build it manually. The manually built package installs the /usr/bin/git binary because it's no symlink in the package and all the other files link to it but I'm still missing several copies in /usr/lib/git-core like git-merge.

Honestly, I have no idea what else I can do to find the cause since I can install the older git package which also contains several symlinks without any problems.
Comment by xduugu (xduugu) - Friday, 06 March 2009, 21:14 GMT
I think I found it. Installing with pacman's debug option enabled is really helpful:

debug: warning extracting usr/bin/git (Can't create '/usr/bin/git': Invalid cross-device link)

The new git package contains a symlink from /usr/bin/git to /usr/lib/git-core/git-diff which is a real file in the old one and because my /usr/lib sits on a separate partition, the git binary can not be extracted.

Now I know what the problem is but I don't know how to fix it. It seems that bsdtar introduces the symlinks and probably one can disable this behavior but this would greatly increase the package size. Fixing this limitation in libalpm if possible is in my opinion the best solution.
Comment by Alessandro Doro (adoroo) - Friday, 06 March 2009, 23:17 GMT
$ tar tzvf git-1.6.2-1-i686.pkg.tar.gz
$ tar tzvf git-1.6.1.1-1-i686.pkg.tar.gz
show that usr/bin/git (like other binaries) is a hard link to usr/lib/git-core/git-diff, not a symbolic link.

Idem for git-1.6.0.* packages.

Is this the right behaviuor or a packaging issue?
Comment by Alessandro Doro (adoroo) - Saturday, 07 March 2009, 00:19 GMT
It isn't a packaging issue; the git Makefile prefers hard links:

install: all
[...]
bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
{ $(RM) "$$execdir/git-add$X" && \
ln "$$bindir/git$X" "$$execdir/git-add$X" 2>/dev/null || \
cp "$$bindir/git$X" "$$execdir/git-add$X"; } && \
{ for p in $(filter-out git-add$X,$(BUILT_INS)); do \
$(RM) "$$execdir/$$p" && \
ln "$$execdir/git-add$X" "$$execdir/$$p" 2>/dev/null || \
ln -s "git-add$X" "$$execdir/$$p" 2>/dev/null || \
cp "$$execdir/git-add$X" "$$execdir/$$p" || exit; \
done } && \
./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X"

It is fine to patch the Makefile for the Arch Linux package?
Comment by Alessandro Doro (adoroo) - Saturday, 07 March 2009, 01:59 GMT
Sorry. My previous post http://bugs.archlinux.org/task/13683#comment40800 was very inaccurate.

· git-1.6.2-1-i686.pkg.tar.gz
usr/lib/git-core/git-diff is the destination link of many binaries (including usr/bin/git)

Same package, built by me
usr/bin/git is the destination link of many binaries

In previous packages (I don't -Scc) the stored links are different and inconsistent between packages.

· git-1.6.1.1-1-i686.pkg.tar.gz
· git-1.6.0.5-1-i686.pkg.tar.gz
usr/lib/git-core/git-format-patch is the destination link of many binaries (usr/bin/git is a regular file)

· git-1.6.1-1-i686.pkg.tar.gz
· git-1.6.0.6-1-i686.pkg.tar.gz
usr/lib/git-core/git-diff is the destination link of many binaries (usr/bin/git is a regular file)


Anyway we have a pacman bug:
debug: warning extracting usr/bin/git (Can't create '/usr/bin/git': Invalid cross-device link)
It silently gives a warning while it should throw an error or try a fallback procedure.
Comment by Dan McGee (toofishes) - Sunday, 08 March 2009, 21:31 GMT
There is really no fallback pacman can do here- it isn't going to relink the files on the fly or something; I really don't think that would be a great idea.

Just to clear this up for me, this could have been an issue for some time, right? We just had different tar behavior in previous packages, and the hard link here resolved to a different location.

Does anyone use all these hard links anyways? They seem a bit silly to me; in the worst case we could just turn them into symlinks.
Comment by Xavier (shining) - Monday, 09 March 2009, 10:15 GMT
> In previous packages (I don't -Scc) the stored links are different and inconsistent between packages.

Well they are hard links, so there is not really one pointing to another, is there?

> Does anyone use all these hard links anyways? They seem a bit silly to me; in the worst case we could just turn them into symlinks.

If I understood correctly, the problem is when hard links are in different directories, because different directories can lie on different partitions.
However, it looks quite strange to have /usr/lib and /usr/bin separated, afaik a much more common setup is to only have the whole /usr on a separate partition.

In any cases, only /usr/bin/git is affected and so only this one needs to be converted to a symlink to support this exotic setup.
Comment by Alessandro Doro (adoroo) - Monday, 09 March 2009, 12:04 GMT
> There is really no fallback pacman can do here- it isn't going to relink the files on the fly or something; I really don't think that would be a great idea.
Agree, I can't remember what I was thinking about.
Comment by Alessandro Doro (adoroo) - Monday, 09 March 2009, 12:06 GMT
> Well they are hard links, so there is not really one pointing to another, is there?

Sure, but I was talking about the way they are archived:
$ tar tzvf git-1.6.2-1-i686.pkg.tar.gz
-rwxr-xr-x root/root 846744 2009-03-06 17:41 usr/lib/git-core/git-diff
hrwxr-xr-x root/root 0 2009-03-06 17:41 usr/bin/git link to usr/lib/git-core/git-diff

So pacman first extracts git-diff, then tries the hard link. In the other packages I observed the git binary is always a regular file and the hard links reside in usr/lib/git-core/ only.

> In any cases, only /usr/bin/git is affected and so only this one needs to be converted to a symlink to support this exotic setup.
It's not sure that in another build the archive structure remains the same. e.g. my build of git-1.6.2-1-i686.pkg.tar.gz is different from the official build.

The only feasible fix (if a fix is desired!) for me is to patch the git Makefile forcing the symbolic link.

... and file a bug report for pacman which failed to extract a file without a single warning.
Comment by Xavier (shining) - Monday, 09 March 2009, 12:33 GMT
Dan already has a commit for this (with a reference to another bug report) :
http://code.toofishes.net/cgit/dan/pacman.git/commit/?h=working&id=3e4cd88c528de750f7c04c0a7221f92badd45eda
So I guess we now have a second reason for this patch.

There is a second commit which will even make pacman stop in case of a warning during extraction :
http://code.toofishes.net/cgit/dan/pacman.git/commit/?h=working&id=9e9feabd4bf49277fbab5766a2ac15ba1e506470
This seems a good idea in the case of "no space left", but less in the case of "Invalid cross-device link".
Comment by Dan McGee (toofishes) - Tuesday, 10 March 2009, 01:18 GMT
Please add the architecture to the original report next time; I see now this doesn't affect the i686 version. I actually didn't build that for this release, I built only the x86_64 version. Giovanni's setup must differ from mine just enough that this was the first "broken" version of the package we have encountered.

I will agree with Xavier that your filesystem mount point layout is quite exotic, and I guessing a lot of other programs with hard links would bomb out as well. It is unfortunate that pacman doesn't show this to the user, so that should be fixed, but the chance of me fixing this GIT package is pretty slim. I would really recommend posting to the GIT mailing list (git_at_vger.kernel.org) describing your problem and seeing if they offer any advice or ways to fix the build script from a distribution, package it up, standpoint (note that the Makefile would "correctly" handle your setup if you installed directly to your system by doing a cp operation instead).
Comment by xduugu (xduugu) - Tuesday, 10 March 2009, 01:27 GMT
@alessandro
It was just a guess that "link to" in bsdtar's output means symlink, but the warning makes much more sense now that I know it's actually a hard link. Thanks for your effort.

@dan
> There is really no fallback pacman can do here- it isn't going to relink the files on the fly or something; I really don't think that would be a great idea.

I don't think it's necessary since there shouldn't be much packages which use hard links. Besides git I've got only two other in my cache.

> Just to clear this up for me, this could have been an issue for some time, right? We just had different tar behavior in previous packages, and the hard link here resolved to a different location.

No, the point is, like alessandro already said, that /usr/bin/git is a hard link in the new package while it was a regular file before so that there were no 'cross-directory' links in the old packages. I suspect the git people changed their Makefile, but I don't understand why they made git a hard link and didn't replaced git-upload-archive and git-receive-pack by hard links, too. The tar behavior is not interesting in this case.

@thread
My setup might be very exotic and I don't know how many others are affected, therefore there is no need to fix the package only for me. It's no problem that I fix it by myself but a pacman warning in non-debug mode would be great.

But one questions still bothers me: Does anybody know what's the advantage of hard links over symlinks in this scenario? The thing I can imagine is that the files can possibly be accessed faster.
Comment by xduugu (xduugu) - Tuesday, 10 March 2009, 01:35 GMT
> Please add the architecture to the original report next time; I see now this doesn't affect the i686 version. I actually didn't build that for this release, I built only the x86_64 version. Giovanni's setup must differ from mine just enough that this was the first "broken" version of the package we have encountered.

The 'affected' architecture was i686 but I didn't add the architecture to the bug report because the x86_64 package contains this 'evil' hard link, too
Comment by Dan McGee (toofishes) - Tuesday, 10 March 2009, 01:43 GMT
Yes, a hard link is quicker than a symlink as you never need to do path resolution and traversal. It also ensures you can never leave a dead symlink on your system, as a hard link points to data and not another file location.

By the way, the last major build file change involving linking was last August:
commit 3e073dc561185d5ad2325cb012943020e068801e
Author: Andreas Färber <andreas.faerber@web.de>
Date: Mon Aug 25 17:33:03 2008 +0200

Makefile: always provide a fallback when hardlinks fail
Comment by xduugu (xduugu) - Tuesday, 10 March 2009, 02:12 GMT
Thanks for your explanation concerning the hard links.

@Makefile change
I found the Makefile change which made /usr/bin/git a hard link:

commit 6a0861a8a3295395238c8126c6e74c66b715c595
Author: Gerrit Pape <pape@smarden.org>
Date: Tue Feb 24 08:58:16 2009 +0000

Install builtins with the user and group of the installing personality
Comment by Dan McGee (toofishes) - Tuesday, 10 March 2009, 02:40 GMT
Please send this upstream and let them know it causes problems for certain installs.
Comment by xduugu (xduugu) - Saturday, 23 May 2009, 11:46 GMT
Sorry for the delay, Dan. A patch which handles cross-directory hardlinks was just pushed upstream. It introduced a new make (install) option:

# Define NO_CROSS_DIRECTORY_HARDLINKS if you plan to distribute the installed
# programs as a tar, where bin/ and libexec/ might be on different file systems.

If this is set in the PKGBUILD, the future git packages won't be affected by this 'bug' anymore.

--- PKGBUILD.old
+++ PKGBUILD
@@ -23,7 +23,7 @@
cd $srcdir/$pkgname-$pkgver
make prefix=/usr gitexecdir=/usr/lib/git-core || return 1
make prefix=/usr gitexecdir=/usr/lib/git-core \
- INSTALLDIRS=vendor DESTDIR=${pkgdir} install || return 1
+ NO_CROSS_DIRECTORY_HARDLINKS=1 INSTALLDIRS=vendor DESTDIR=${pkgdir} install || return 1

# let's plop gitweb in /usr/share
mkdir -p $pkgdir/usr/share/
Comment by Dan McGee (toofishes) - Saturday, 23 May 2009, 17:30 GMT
Nice. I'll add this on the next rebuild of git.

Loading...