X-Original-To: alpine-devel@mail.alpinelinux.org Delivered-To: alpine-devel@mail.alpinelinux.org Received: from mail.alpinelinux.org (dallas-a1.alpinelinux.org [127.0.0.1]) by mail.alpinelinux.org (Postfix) with ESMTP id 40027DCE453 for ; Thu, 26 Nov 2015 23:51:16 +0000 (UTC) Received: from lithium.8pit.net (lithium.8pit.net [81.4.121.103]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.alpinelinux.org (Postfix) with ESMTPS id 9AF3BDCF254; Thu, 26 Nov 2015 23:51:15 +0000 (UTC) Received: from localhost (ip5f5ac93e.dynamic.kabel-deutschland.de [95.90.201.62]) by lithium.8pit.net (OpenSMTPD) with ESMTPSA id ffd19abb TLS version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO; Fri, 27 Nov 2015 00:51:11 +0100 (CET) From: =?UTF-8?q?S=C3=B6ren=20Tempel?= To: alpine-devel@lists.alpinelinux.org Subject: [alpine-devel] [PATCH 3/5] abuild: rewrite hardlink handling when compressing man pages Date: Fri, 27 Nov 2015 00:50:45 +0100 Message-Id: <1448581847-30376-3-git-send-email-soeren+git@soeren-tempel.net> X-Mailer: git-send-email 2.6.3 In-Reply-To: <1448581847-30376-1-git-send-email-soeren+git@soeren-tempel.net> References: <1448581847-30376-1-git-send-email-soeren+git@soeren-tempel.net> X-Virus-Scanned: ClamAV using ClamSMTP X-Mailinglist: alpine-devel Precedence: list List-Id: Alpine Development List-Unsubscribe: List-Post: List-Help: List-Subscribe: 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. --- 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 @@ -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 - 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" -- 2.6.3 --- Unsubscribe: alpine-devel+unsubscribe@lists.alpinelinux.org Help: alpine-devel+help@lists.alpinelinux.org ---