aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2012-11-04 18:51:20 -0800
committerZac Medico <zmedico@gentoo.org>2012-11-04 18:51:20 -0800
commit74b7c9d452c97a948852416e1456a3117deec2dc (patch)
treea5f77751410ba7e0d635c4789466b13edb256141
parentrepoman: add check for deprecated licenses, bug 440638 (diff)
downloadportage-74b7c9d452c97a948852416e1456a3117deec2dc.tar.gz
portage-74b7c9d452c97a948852416e1456a3117deec2dc.tar.bz2
portage-74b7c9d452c97a948852416e1456a3117deec2dc.zip
prepstrip: account for new inode created by strip
Since strip creates a new inode, we need to know the initial set of inodes in advance, so that we can avoid interference due to trying to strip the same (hardlinked) file multiple times in parallel. See bug #421099.
-rwxr-xr-xbin/ebuild-helpers/prepstrip60
1 files changed, 43 insertions, 17 deletions
diff --git a/bin/ebuild-helpers/prepstrip b/bin/ebuild-helpers/prepstrip
index 0d1ce5a09..c6bf60e1d 100755
--- a/bin/ebuild-helpers/prepstrip
+++ b/bin/ebuild-helpers/prepstrip
@@ -94,7 +94,6 @@ save_elf_sources() {
fi
local x=$1
- [[ -f $(inode_file_link "${x}") ]] && return 0
# since we're editing the ELF here, we should recompute the build-id
# (the -i flag below). save that output so we don't need to recompute
@@ -115,7 +114,8 @@ save_elf_debug() {
# twice in this path) in order for gdb's debug-file-directory
# lookup to work correctly.
local x=$1
- local splitdebug=$2
+ local inode_debug=$2
+ local splitdebug=$3
local y=${ED}usr/lib/debug/${x:${#D}}.debug
# dont save debug info twice
@@ -123,9 +123,8 @@ save_elf_debug() {
mkdir -p "${y%/*}"
- local inode=$(inode_file_link "${x}")
- if [[ -f ${inode} ]] ; then
- ln "${inode}" "${y}"
+ if [ -f "${inode_debug}" ] ; then
+ ln "${inode_debug}" "${y}" || die "ln failed unexpectedly"
else
if [[ -n ${splitdebug} ]] ; then
mv "${splitdebug}" "${y}"
@@ -138,7 +137,7 @@ save_elf_debug() {
local args="a-x,o-w"
[[ -g ${x} || -u ${x} ]] && args+=",go-r"
chmod ${args} "${y}"
- ln "${y}" "${inode}"
+ ln "${y}" "${inode_debug}" || die "ln failed unexpectedly"
fi
# if we don't already have build-id from debugedit, look it up
@@ -158,7 +157,8 @@ save_elf_debug() {
# Usage: process_elf <elf>
process_elf() {
- local x=$1 strip_flags=${*:2}
+ local x=$1 inode_link=$2 strip_flags=${*:3}
+ local already_stripped lockfile
__vecho " ${x:${#ED}}"
@@ -167,15 +167,17 @@ process_elf() {
# So, use a lockfile to prevent interference (easily observed with
# dev-vcs/git which creates ~111 hardlinks to one file in
# /usr/libexec/git-core).
- local lockfile=$(inode_file_link "${x}")_lockfile
- if ! ln "${x}" "${lockfile}" 2>/dev/null ; then
+ lockfile=${inode_link}_lockfile
+ if ! ln "${inode_link}" "${lockfile}" 2>/dev/null ; then
while [[ -f ${lockfile} ]] ; do
sleep 1
done
unset lockfile
fi
- save_elf_sources "${x}"
+ [ -f "${inode_link}_stripped" ] && already_stripped=true || already_stripped=false
+
+ ${already_stripped} || save_elf_sources "${x}"
if ${strip_this} ; then
@@ -183,17 +185,26 @@ process_elf() {
if [[ -n ${SPLIT_STRIP_FLAGS} ]] ; then
local shortname="${x##*/}.debug"
local splitdebug="${tmpdir}/splitdebug/${shortname}.${BASHPID}"
+ ${already_stripped} || \
${STRIP} ${strip_flags} \
-f "${splitdebug}" \
-F "${shortname}" \
"${x}"
- save_elf_debug "${x}" "${splitdebug}"
+ save_elf_debug "${x}" "${inode_link}_debug" "${splitdebug}"
else
- save_elf_debug "${x}"
+ save_elf_debug "${x}" "${inode_link}_debug"
+ ${already_stripped} || \
${STRIP} ${strip_flags} "${x}"
fi
fi
+ if ${already_stripped} ; then
+ rm -f "${x}" || die "rm failed unexpectedly"
+ ln "${inode_link}_stripped" "${x}" || die "ln failed unexpectedly"
+ else
+ ln "${x}" "${inode_link}_stripped" || die "ln failed unexpectedly"
+ fi
+
[[ -n ${lockfile} ]] && rm -f "${lockfile}"
}
@@ -232,11 +243,24 @@ if ! ${RESTRICT_binchecks} && ! ${RESTRICT_strip} ; then
__multijob_post_fork
fi
+# Since strip creates a new inode, we need to know the initial set of
+# inodes in advance, so that we can avoid interference due to trying
+# to strip the same (hardlinked) file multiple times in parallel.
+# See bug #421099.
+while read -r x ; do
+ inode_link=$(inode_file_link "${x}")
+ echo "${x}" >> "${inode_link}" || die "echo failed"
+done < <(
+ scanelf -yqRBF '#k%F' -k '.symtab' "$@"
+ find "$@" -type f ! -type l -name '*.a'
+)
+
# Now we look for unstripped binaries.
-for x in \
- $(scanelf -yqRBF '#k%F' -k '.symtab' "$@") \
- $(find "$@" -type f -name '*.a')
+cd "${tmpdir}/inodes" || die "cd failed"
+for inode_link in * ; do
+while read -r x
do
+
if ! ${banner} ; then
__vecho "strip: ${STRIP} ${PORTAGE_STRIP_FLAGS}"
banner=true
@@ -284,9 +308,9 @@ do
${STRIP} -g "${x}"
fi
elif [[ ${f} == *"SB executable"* || ${f} == *"SB shared object"* ]] ; then
- process_elf "${x}" ${PORTAGE_STRIP_FLAGS}
+ process_elf "${x}" "${inode_link}" ${PORTAGE_STRIP_FLAGS}
elif [[ ${f} == *"SB relocatable"* ]] ; then
- process_elf "${x}" ${SAFE_STRIP_FLAGS}
+ process_elf "${x}" "${inode_link}" ${SAFE_STRIP_FLAGS}
fi
if ${was_not_writable} ; then
@@ -294,6 +318,8 @@ do
fi
) &
__multijob_post_fork
+
+done < "${inode_link}"
done
# With a bit more work, we could run the rsync processes below in