diff --git a/lxd.changes b/lxd.changes index 099fed8..80d5aab 100644 --- a/lxd.changes +++ b/lxd.changes @@ -1,8 +1,10 @@ ------------------------------------------------------------------- Thu Mar 28 01:54:01 UTC 2019 - Aleksa Sarai -- Make sqlite+dqlite both shared libs to avoid bloating RSS -- which requires - having a separate RPATH for them. +- Make sqlite+dqlite both shared libs to avoid bloating RSS. In order to avoid + issues with packaging new versions of libsqlite3 there are a bunch of + DT_SONAME and DT_NEEDED hacks to ensure that rpm doesn't cause false-positive + conflicts or other issues. ------------------------------------------------------------------- Tue Mar 26 02:44:05 UTC 2019 - Aleksa Sarai diff --git a/lxd.spec b/lxd.spec index da8f44e..daf2dba 100644 --- a/lxd.spec +++ b/lxd.spec @@ -46,15 +46,16 @@ BuildRequires: libtool BuildRequires: tcl-devel BuildRequires: libuv-devel >= 1.8.0 # Bits required for images and other things at runtime. +Requires: ebtables Requires: acl BuildRequires: dnsmasq Requires: dnsmasq -Requires: tar -Requires: xz +Requires: lxcfs Requires: rsync Requires: squashfs -Requires: criu -Requires: lxcfs +Requires: tar +Requires: xz +Requires: criu >= 2.0 # Storage backends -- we don't recommend ZFS since it's not *technically* a # blessed configuration. Recommends: lvm2 @@ -149,12 +150,42 @@ do ) done -# We want to set r(un)path for lxd (*and* libs) to our fake _libdir. We don't -# pass it as part of ldflags, as we've seen some cases where the RPATH gets -# messed up during compilation. -patchelf --set-rpath '%{_libdir}/%{name}' bin/lxd -patchelf --set-rpath '%{_libdir}/%{name}' "$PKGDIR/dist/sqlite/.libs/libsqlite3.so" -patchelf --set-rpath '%{_libdir}/%{name}' "$PKGDIR/dist/dqlite/.libs/libdqlite.so" +# This part is quite ugly, so I apologise upfront. +# +# We want to have our dist/* libraries be dylibs so that we don't bloat our lxd +# binary. Unfortunately, we are presented with a few challenges: +# +# * Doing this naively (put it in {_libdir}) results in sqlite3 package +# conflicts -- and we aren't going to maintain sqlite3 for all of openSUSE +# here. +# +# * Putting everything in a hidden {_libdir}/{name} with RUNPATH configured +# accordingly works a little better, but still results in lxd ending up with +# {Provides,Requires}: libsqlite3.so.0. This results in more esoteric +# conflicts but is still an issue (we'd need to add Prefer: libsqlite3-0 +# everywhere). +# +# So, the only reasonable choice left is to use absolute paths as DT_NEEDED +# entries -- which bypasses the need for RUNPATH and allows us to set garbage +# sonames for our dist/* libraries. Absolute paths for DT_NEEDED is *slightly* +# undefined behaviour, but glibc has had this behaviour for a very long time -- +# and others have considered using it in a similar manner[1]. +# +# What F U N. +# +# [1]: https://github.com/NixOS/nixpkgs/issues/24844 + +# Give our libraries unrecognisable DT_SONAME entries. +patchelf --set-soname '_lxd-libsqlite3.so.0' "$PKGDIR/dist/sqlite/.libs/libsqlite3.so.0" +patchelf --set-soname '_lxd-libdqlite.so.0' "$PKGDIR/dist/dqlite/.libs/libdqlite.so.0" + +# Switch to absolute DT_NEEDED for the lxd binary. +patchelf --remove-rpath bin/lxd +patchelf --replace-needed {,%{_libdir}/%{name}/}'libsqlite3.so.0' bin/lxd +patchelf --replace-needed {,%{_libdir}/%{name}/}'libdqlite.so.0' bin/lxd +# Just to be sure, fix libdqlite.so as well. +patchelf --remove-rpath "$PKGDIR/dist/dqlite/.libs/libdqlite.so" +patchelf --replace-needed {,%{_libdir}/%{name}/}'libsqlite3.so.0' "$PKGDIR/dist/dqlite/.libs/libdqlite.so" # Generate man pages. mkdir man @@ -165,7 +196,7 @@ export GOPATH="$PWD/.gopath" export PKGDIR="$GOPATH/src/%{import_path}" install -d -m 0755 %{buildroot}%{_libdir}/%{name} -pushd .gopath/src/%{import_path} +pushd "$PKGDIR" # We can't use install because *.so.$n are symlinks. cp -avt %{buildroot}%{_libdir}/%{name}/ dist/sqlite/.libs/libsqlite3.so.* cp -avt %{buildroot}%{_libdir}/%{name}/ dist/dqlite/.libs/libdqlite.so.*