diff options
author | Zac Medico <zmedico@gentoo.org> | 2012-11-04 18:51:20 -0800 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2012-11-04 18:51:20 -0800 |
commit | 74b7c9d452c97a948852416e1456a3117deec2dc (patch) | |
tree | a5f77751410ba7e0d635c4789466b13edb256141 | |
parent | 658c0fd5940b9547cbdf09d4d4ea6552cfbd542a (diff) | |
download | portage-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-x | bin/ebuild-helpers/prepstrip | 60 |
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 |