severity 642603 serious merge 642603 645009 tags 642603 + patch pending quit
Antti Kultanen wrote: > On Tue, 11 Oct 2011, Jonathan Nieder wrote: >> Do you use btrfs? > > Yes. Yes I do. > > What's going on? See http://bugs.debian.org/642603 for details. How about this patch? -- >8 -- Subject: debian: use symlinks instead of hardlinks for builtin aliases dpkg upgrades a package in three stages: 1. Extract the new version of each file to <foo>.dpkg-new, and link the old version to <foo>.dpkg-tmp so the next step can be backed out if it is interrupted. 2. fsync() and rename() the new files into place. 3. Unlink the backed-up old versions. The git package includes many hardlinks in /usr/lib/git-core. It fails to upgrade in step 1 if this directory is located on a btrfs, which have a limit of links to one inode in one directory: | dpkg: error processing /var/cache/apt/archives/git_1%3a1.7.6.3-1_amd64.deb (--unpack): | unable to make backup link of `./usr/lib/git-core/git-send-pack' before installing new version: Too many links At least within git itself, most uses of builtins use the non-dashed form ("git <command>"), so effort spent optimizing the dashed forms (e.g., by using hardlinks instead of symlinks) is mostly a waste. Let's just use symlinks here. Requested-by: Bastian Blank <[email protected]> Fixes: http://bugs.debian.org/642603 Signed-off-by: Jonathan Nieder <[email protected]> --- debian/changelog | 4 + ...d-a-knob-to-turn-off-hardlinks-within-same.diff | 84 ++++++++++++++++++++ debian/rules | 3 +- 3 files changed, 90 insertions(+), 1 deletions(-) create mode 100644 debian/diff/0018-Makefile-add-a-knob-to-turn-off-hardlinks-within-same.diff diff --git a/debian/changelog b/debian/changelog index 41c3ad7f..8e677616 100644 --- a/debian/changelog +++ b/debian/changelog @@ -15,6 +15,10 @@ git (1:1.7.7-1.1) unstable; urgency=low GNU/kFreeBSD * Makefile: fix permissions of mergetools/ when building from source extracted with permissive umask + * 0018-Makefile-add-a-knob-to-turn-off-hardlinks-...diff: new; + Makefile: add a knob to disable hardlinks within bindir and + gitexecdir. + * debian/rules: add NO_HARDLINKS=1 to OPTS (closes: #642603). [ Simon Chopin ] * debian/git.postinst: fix fresh install contrib/hooks cleaning diff --git a/debian/diff/0018-Makefile-add-a-knob-to-turn-off-hardlinks-within-same.diff b/debian/diff/0018-Makefile-add-a-knob-to-turn-off-hardlinks-within-same.diff new file mode 100644 index 00000000..222dcbf3 --- /dev/null +++ b/debian/diff/0018-Makefile-add-a-knob-to-turn-off-hardlinks-within-same.diff @@ -0,0 +1,84 @@ +From b58698d5c82baa52fb9aaba10c06152ad6b836d1 Mon Sep 17 00:00:00 2001 +From: Jonathan Nieder <[email protected]> +Date: Wed, 12 Oct 2011 03:38:42 -0500 +Subject: Makefile: add a knob to turn off hardlinks within same directory + +The git builtins in $(gitexecdir) are implemented as hard links to a +single git binary by default, so even the overhead of symlink +resolution is not needed to run them. However, the trick can be +harmful, in two cases: + + - on Windows, some tools to estimate directory size hugely + overestimate the size of git (each hardlink counts as taking up the + same amount of space as git.exe) + + - various filesystems have limits on the number of hardlinks that + can be made to a particular file --- Linux's LINK_MAX is 127, + _POSIX_LINK_MAX is 8, and btrfs has a limit of 4096 / + ($len_filename + 8) or so links to a given inode in a single + directory. + +Normally that second case is not a problem (when ln fails, "make +install" falls back to "ln -s"), but if git is tar'ed up on one +filesystem and then extracted on a more limited one, it can result in +"Too many links" errors. + +Nowadays people are encouraged to (and typically do) run builtins +using the "git" command name directly rather than those dashed forms +in scripts, making the use of hardlinks for the dashed forms a +somewhat pointless optimization. Introduce a new knob to allow people +to turn it off with a simple "make install NO_HARDLINKS=YesPlease". + +Typically someone using this setting would want to set +NO_CROSS_DIRECTORY_HARDLINKS, too, but that is not enforced, so you +can make $(bindir)/git and $(gitexecdir)/git into hardlinks to the +same inode and still make sure your tarball avoids the btrfs limits if +you want. + +Requested-by: Bastian Blank <[email protected]> +Signed-off-by: Jonathan Nieder <[email protected]> +--- + Makefile | 7 +++++++ + 1 files changed, 7 insertions(+), 0 deletions(-) + +diff --git a/Makefile b/Makefile +index 9afdcf2..ab64ff4 100644 +--- a/Makefile ++++ b/Makefile +@@ -226,6 +226,10 @@ all:: + # 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. + # ++# Define NO_HARDLINKS if you plan to distribute the installed programs as a tar ++# that might be extracted on a filesystem like btrfs that does not cope well ++# with many links to one inode in one directory. ++# + # Define USE_NED_ALLOCATOR if you want to replace the platforms default + # memory allocators with the nedmalloc allocator written by Niall Douglas. + # +@@ -2326,12 +2330,14 @@ endif + } && \ + for p in $(filter $(install_bindir_programs),$(BUILT_INS)); do \ + $(RM) "$$bindir/$$p" && \ ++ test -z "$(NO_HARDLINKS)" && \ + ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \ + ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \ + cp "$$bindir/git$X" "$$bindir/$$p" || exit; \ + done && \ + for p in $(BUILT_INS); do \ + $(RM) "$$execdir/$$p" && \ ++ test -z "$(NO_HARDLINKS)" && \ + ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \ + ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \ + cp "$$execdir/git$X" "$$execdir/$$p" || exit; \ +@@ -2339,6 +2345,7 @@ endif + remote_curl_aliases="$(REMOTE_CURL_ALIASES)" && \ + for p in $$remote_curl_aliases; do \ + $(RM) "$$execdir/$$p" && \ ++ test -z "$(NO_HARDLINKS)" && \ + ln "$$execdir/git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \ + ln -s "git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \ + cp "$$execdir/git-remote-http$X" "$$execdir/$$p" || exit; \ +-- +1.7.7 + diff --git a/debian/rules b/debian/rules index 243b1335..a18ba26a 100755 --- a/debian/rules +++ b/debian/rules @@ -12,7 +12,8 @@ OPTS =NO_OPENSSL=1 prefix=/usr gitexecdir=/usr/lib/git-core \ INSTALLDIRS=vendor \ NO_PYTHON=1 \ USE_SRV_RR=1 \ - THREADED_DELTA_SEARCH=1 NO_CROSS_DIRECTORY_HARDLINKS=1 \ + THREADED_DELTA_SEARCH=1 \ + NO_CROSS_DIRECTORY_HARDLINKS=1 NO_HARDLINKS=1 \ DEFAULT_PAGER=pager DEFAULT_EDITOR=editor DOC_OPTS =prefix=/usr htmldir=/usr/share/doc/git/html \ ASCIIDOC8=1 ASCIIDOC_NO_ROFF=1 -- 1.7.7 -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected]

