Mail archive
alpine-devel

Re: [alpine-devel] [PATCH 3/5] abuild: rewrite hardlink handling when compressing man pages

From: Natanael Copa <ncopa_at_alpinelinux.org>
Date: Mon, 30 Nov 2015 08:21:37 +0100

On Fri, 27 Nov 2015 00:50:45 +0100
Sören Tempel <soeren+git_at_soeren-tempel.net> wrote:

> The problem is that gzip refuses to run if it detects that a file has
> more than 1 link. Our existing solution (removing hardlinks, compressing
> the man page and recreating the hardlinks) made certain assumptions
> about inode order that are only given on Unix v7 like filesystems
> meaning it didn't work properly on 'tree-based' filesystems like BTRFS
> or ZFS.
>
> This patch has a different more bulletproof approach: It simply replaces
> all hardlinks with symlinks. This is way easier because symlinks (unlike
> hardlinks) can point to a file that doesn't exist, therefore we can
> update all links before compressing the file in an easy way.

How well it this tested?

The other approach has build entire world at this point.

I am not very happy about rebuilding world again for this change.

-nc

> ---
> abuild.in | 40 ++++++++++++++++++++++------------------
> 1 file changed, 22 insertions(+), 18 deletions(-)
>
> diff --git a/abuild.in b/abuild.in
> index 4c45504..26b7982 100644
> --- a/abuild.in
> +++ b/abuild.in
> _at_@ -1403,29 +1403,33 @@ default_doc() {
> done
>
> # compress man pages
> - local previnode= prevname= mandir="$subpkgdir"/usr/share/man
> - [ -d "$mandir" ] && find "$subpkgdir"/usr/share/man \
> - -type f \( -name \*.[0-8n] -o -name \*.[0-8][a-z]* \) \
> - -exec stat -c "%i %n" {} \; | sort -n \
> - | while read inode name; do
> -
> - if [ "$inode" = "$previnode" ]; then
> - # update hard link
> - rm "$name"
> - ln "$prevname".gz "$name".gz
> - else
> - gzip -9 "$name"
> - fi
> + local mandir="$subpkgdir"/usr/share/man
> + [ -d "$mandir" ] && find "$mandir" -type f \
> + -a \( -name \*.[0-8n] -o -name \*.[0-8][a-z]* \) \
> + -exec stat -c "%i %n" \{\} \; | while read inode name; do
> +
> + # Skip hardlinks removed in last iteration.
> + [ -f "$name" ] || continue
> +
> + local islink=0
> + find "$mandir" -type f -links +1 \
> + -a \( -name \*.[0-8n] -o -name \*.[0-8][a-z]* \) \
> + -exec stat -c "%i %n" \{\} \; | while read linode lname; do
> + if [ "$linode" = "$inode" -a "$lname" != "$name" ]; then
> + islink=1
> + rm -f "$lname"
> + ln -s "${name##*/}".gz "$lname".gz
> + fi
> + done

How is performance on this? It looks like this can be horribly slow if
$mandir is huge.

Could you try locate the biggest -doc package and run this on armhf and
post a specific number?


>
> - previnode="$inode"
> - prevname="$name"
> + [ $islink -eq 0 ] && gzip -9 "$name"
> done
> - [ -d "$mandir" ] && find "$subpkgdir"/usr/share/man \
> - -type l \( -name \*.[0-8n] -o -name \*.[0-8][a-z]*
> \) \
> + [ -d "$mandir" ] && find "$mandir" -type l \
> + -a \( -name \*.[0-8n] -o -name \*.[0-8][a-z]* \) \
> | while read symlink; do
>
> ln -s $(readlink $symlink).gz "$symlink".gz
> - rm "$symlink"
> + rm -f "$symlink"
> done
>
> rm -f "$subpkgdir/usr/share/info/dir"

-nc


---
Unsubscribe:  alpine-devel+unsubscribe_at_lists.alpinelinux.org
Help:         alpine-devel+help_at_lists.alpinelinux.org
---
Received on Mon Nov 30 2015 - 08:21:37 GMT