Hi,
Bastian Blank wrote:
> The git package includes many hardlinks in /usr/lib/git-core. It fails
> to upgrade 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
Yuck. As a reminder to myself: 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.
This report is about a consequence of step 1 --- it doubles the number
of links to each file. This makes it easy to run into filesystem
limits.
Unfortunately, it's not clear to me what that limit actually _is_ for
btrfs. Here's what I know.
i. "stat $(git --exec-path)git" informs me it has 106 links at the
moment (so 212 in the middle of an upgrade).
i. _POSIX_LINK_MAX is 8. If we care about that level of portability
(and we shouldn't), then Debian packages would have at most
four links to each file.
ii. LINK_MAX in linux/limits.h is 127. UFS_LINK_MAX and EXT2_LINK_MAX
are 32000.
iii. btrfs's limit is on number of links to a file in a single
directory. Spreading links over multiple directories avoids it.
Whatever the actual limit _is_ (I couldn't find clear numbers),
upstream seems to consider it a problem and would probably be
open to patches fixing it.
http://thread.gmane.org/gmane.comp.file-systems.btrfs/6285/focus=6354
iv. Git's "make install" punts and falls back to "ln -s" when
attempts to make a hard link fail. Maybe the git packaging
should have been doing the same, by writing the links in
postinst instead of asking dpkg to take care of it. This would
also allow some minor space savings since /usr/bin/git and
/usr/lib/git-core/git-add could be links to the same inode on
installations where they happen to be on the same filesystem.
v. dpkg could learn to cap the number of links at (<packaged number
of links> + 1) instead of (<packaged number> * 2) by making only
one backup link for each old inode, but I doubt that is worth it
(it would require a new data structure to maintain the inode ->
paths mapping, to tell which paths are linked).
Corrections? What do you think?
Thanks,
Jonathan
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]