This reverts commit 698b72b5018868df6a839d08fd24c642db97ffcd.
Using patchelf can cause build-ids to be missing from core files
(issue #4983).
This is as clean a revert as possible. Followup patches will introduce
an alternative fix for #4673.
Fixes #4983
Signed-off-by: Rafael Ávila de Espíndola <
espi...@scylladb.com>
---
dist/debian/rules.mustache | 4 +--
install.sh | 34 ++++--------------
scripts/create-relocatable-package.py | 50 +++++++++++++++++++++++++--
3 files changed, 56 insertions(+), 32 deletions(-)
diff --git a/dist/debian/rules.mustache b/dist/debian/rules.mustache
index 6a1b41f06..0a8934192 100755
--- a/dist/debian/rules.mustache
+++ b/dist/debian/rules.mustache
@@ -34,9 +34,7 @@ override_dh_installinit:
dh_installinit --no-start --name node-exporter
override_dh_strip:
- # The binaries (ethtool...patchelf) don't pass dh_strip after going through patchelf. Since they are
- # already stripped, nothing is lost if we exclude them, so that's what we do.
- dh_strip -Xlibprotobuf.so.15 -Xld.so -Xethtool -Xgawk -Xgzip -Xhwloc-calc -Xhwloc-distrib -Xifconfig -Xlscpu -Xnetstat -Xpatchelf --dbg-package={{product}}-server-dbg
+ dh_strip -Xlibprotobuf.so.15 -Xld.so --dbg-package={{product}}-server-dbg
override_dh_makeshlibs:
diff --git a/install.sh b/install.sh
index 3ea1a073d..bb2516852 100755
--- a/install.sh
+++ b/install.sh
@@ -80,29 +80,6 @@ while [ $# -gt 0 ]; do
esac
done
-patchelf() {
- # patchelf comes from the build system, so it needs the build system's ld.so and
- # shared libraries. We can't use patchelf on patchelf itself, so invoke it via
- # ld.so.
- LD_LIBRARY_PATH="$PWD/libreloc" libreloc/ld.so libexec/patchelf "$@"
-}
-
-adjust_bin() {
- local bin="$1"
- # We could add --set-rpath too, but then debugedit (called by rpmbuild) barfs
- # on the result. So use LD_LIBRARY_PATH in the thunk, below.
- patchelf \
- --set-interpreter "$prefix/libreloc/ld.so" \
- "$root/$prefix/libexec/$bin"
- cat > "$root/$prefix/bin/$bin" <<EOF
-#!/bin/bash -e
-export GNUTLS_SYSTEM_PRIORITY_FILE="\${GNUTLS_SYSTEM_PRIORITY_FILE-$prefix/libreloc/gnutls.config}"
-export LD_LIBRARY_PATH="$prefix/libreloc"
-exec -a "\$0" "$prefix/libexec/$bin" "\$@"
-EOF
- chmod +x "$root/$prefix/bin/$bin"
-}
-
if [ -z "$prefix" ]; then
if $nonroot; then
prefix=~/scylladb
@@ -158,13 +135,16 @@ install -m644 dist/common/systemd/*.slice -Dt "$rsystemd"
install -m644 dist/common/systemd/*.timer -Dt "$rsystemd"
install -m755 seastar/scripts/seastar-cpu-map.sh -Dt "$rprefix"/scripts
install -m755 seastar/dpdk/usertools/dpdk-devbind.py -Dt "$rprefix"/scripts
-install -m755 libreloc/* -Dt "$rprefix/libreloc"
+install -m755 bin/* -Dt "$rprefix/bin"
# some files in libexec are symlinks, which "install" dereferences
# use cp -P for the symlinks instead.
-install -m755 libexec/* -Dt "$rprefix/libexec"
-for bin in libexec/*; do
- adjust_bin "${bin#libexec/}"
+install -m755 libexec/*.bin -Dt "$rprefix/libexec"
+for f in libexec/*; do
+ if [[ "$f" != *.bin ]]; then
+ cp -P "$f" "$rprefix/libexec"
+ fi
done
+install -m755 libreloc/* -Dt "$rprefix/libreloc"
install -d -m755 "$rdoc"/scylla
install -m644 README.md -Dt "$rdoc"/scylla/
diff --git a/scripts/create-relocatable-package.py b/scripts/create-relocatable-package.py
index 0bdd95b95..179d56541 100755
--- a/scripts/create-relocatable-package.py
+++ b/scripts/create-relocatable-package.py
@@ -61,7 +61,6 @@ args = ap.parse_args()
executables = ['build/{}/scylla'.format(args.mode),
'build/{}/iotune'.format(args.mode),
- '/usr/bin/patchelf',
'/usr/bin/lscpu',
'/usr/bin/gawk',
'/usr/bin/gzip',
@@ -97,9 +96,56 @@ ar = tarfile.open(fileobj=gzip_process.stdin, mode='w|')
pathlib.Path('build/SCYLLA-RELOCATABLE-FILE').touch()
ar.add('build/SCYLLA-RELOCATABLE-FILE', arcname='SCYLLA-RELOCATABLE-FILE')
+# This thunk is a shell script that arranges for the executable to be invoked,
+# under the following conditions:
+#
+# - the same argument vector is passed to the executable, including argv[0]
+# - the executable name (/proc/pid/comm, shown in top(1)) is the same
+# - the dynamic linker is taken from this package rather than the executable's
+# default (which is hardcoded to point to /lib64/ld-linux-x86_64.so or similar)
+# - LD_LIBRARY_PATH points to the lib/ directory so shared library dependencies
+# are satisified from there rather than the system default (e.g. /lib64)
+
+# To do that, the dynamic linker is invoked using a symbolic link named after the
+# executable, not its standard name. We use "bash -a" to set argv[0].
+
+# The full tangled web looks like:
+#
+# foobar/bin/scylla a shell script invoking everything
+# foobar/libexec/scylla.bin the real binary
+# foobar/libexec/scylla a symlink to ../lib/ld.so
+# foobar/libreloc/ld.so the dynamic linker
+# foobar/libreloc/lib... all the other libraries
+
+# the transformations (done by the thunk and symlinks) are:
+#
+# bin/scylla args -> libexec/scylla libexec/scylla.bin args -> lib/ld.so libexec/scylla.bin args
+
+thunk = b'''\
+#!/bin/bash
+
+x="$(readlink -f "$0")"
+b="$(basename "$x")"
+d="$(dirname "$x")/.."
+ldso="$d/libexec/$b"
+realexe="$d/libexec/$b.bin"
+export GNUTLS_SYSTEM_PRIORITY_FILE="${GNUTLS_SYSTEM_PRIORITY_FILE-$d/libreloc/gnutls.config}"
+LD_LIBRARY_PATH="$d/libreloc" exec -a "$0" "$ldso" "$realexe" "$@"
+'''
+
for exe in executables:
basename = os.path.basename(exe)
- ar.add(exe, arcname='libexec/' + basename)
+ ar.add(exe, arcname='libexec/' + basename + '.bin')
+ ti = tarfile.TarInfo(name='bin/' + basename)
+ ti.size = len(thunk)
+ ti.mode = 0o755
+ ti.mtime = os.stat(exe).st_mtime
+ ar.addfile(ti, fileobj=io.BytesIO(thunk))
+ ti = tarfile.TarInfo(name='libexec/' + basename)
+ ti.type = tarfile.SYMTYPE
+ ti.linkname = '../libreloc/ld.so'
+ ti.mtime = os.stat(exe).st_mtime
+ ar.addfile(ti)
for lib, libfile in libs.items():
ar.add(libfile, arcname='libreloc/' + lib)
if have_gnutls:
--
2.23.0