Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build-system: add option to revert back to classic shared library deps instread of dlopen(), for downstreams where minimal, runtime-combined OS images are a non-issue #17769

Open
mikhailnov opened this issue Nov 28, 2020 · 15 comments
Labels
build-system RFE 🎁 Request for Enhancement, i.e. a feature request

Comments

@mikhailnov
Copy link
Contributor

mikhailnov commented Nov 28, 2020

Hello,
systemd-247 started using dlopen()

The runtime dependencies on libqrencode, libpcre2, libidn/libidn2, libpwquality and libcryptsetup have been changed to be based on dlopen()

as a package maintainer I would very much like to avoid adding dependencies manually. It will require:

  • manual checking of the list of dlopened libraries
  • detecting build-time soname and adding it to dependencies by scripts (we in ROSA do not name package like foo-libs, we name packages like lib64foo2 for /usr/lib64/libfoo.so.2)

Is it possible to make a configure option to off dlopen and return to old behaviour?

@mbiebl
Copy link
Contributor

mbiebl commented Nov 28, 2020

you might be interested in #17416

@mikhailnov
Copy link
Contributor Author

mikhailnov commented Nov 28, 2020

Also some distros, e.g. ALT Linux (cc @shaba ), make RPM dependencies from real ABI symbols used (they create a hash of used symbols in Requires and hash of available ones in Provides), so they track not only the soname, but also real ABI. Using dlopen will break this mechanics of guaranteeing ABI consistency.

@mbiebl
Copy link
Contributor

mbiebl commented Nov 28, 2020

I have the same problem in Debian as you. We don't have any tooling to handle dlopenend dependencies automatically. I suggested a different approach in #17416 (comment) but @poettering doesn't like it.

@mikhailnov
Copy link
Contributor Author

mikhailnov commented Nov 28, 2020

We in RPM can do sth like the following build-time automation of adding dependencies which is probably impossible in Debian:

<...>
%define soname_libidn2 %(patchelf --print-soname %{_libdir}/libidn2.so || echo 0)
<...>
BuildRequires: patchelf
<...>
Requires: %{soname_libidn2}%{_arch_tag_suffix}

But:

  • it does not version symbols
  • it does not allow to track symbols
  • some libraries may be forgotten
  • and in general looks like a not needed complication

@mikhailnov
Copy link
Contributor Author

Also, the list of dlopen'ed libraries is, I would say, very partial, for example, I encountered problems with ABI of libseccomp, so this solution with dlopen does not fully solve existing problems and creates new problems.

@mikhailnov
Copy link
Contributor Author

dl = dlopen("libcryptsetup.so.12", RTLD_LAZY);

dl = dlopen("libcryptsetup.so.12", RTLD_LAZY);

What if soname is different at build time?! Nobody will notice it, the package will be build successfully, but dlopenning may not work out of the box! that is a complete crap, I believe, for a distro package. Or am I wrong?

@DemiMarie
Copy link

One advantage of dlopen() is that it allows for dependencies to be optional.

@poettering
Copy link
Member

What if soname is different at build time?! Nobody will notice it, the package will be build successfully, but dlopenning may not work out of the box! that is a complete crap, I believe, for a distro package. Or am I wrong?

If the name changes (i.e. the number after the .so.), then that's am ABI break, it's absolutely intended that we don't attempt to use the library then, as that can end up in all kinds of code corruptions. We load the exact versions of the libraries we support. If a library's ABI changes, then this always means some developer needs to look into that, and possibly update code for the new ABI.

@poettering poettering added build-system RFE 🎁 Request for Enhancement, i.e. a feature request labels Dec 2, 2020
@poettering poettering changed the title off dlopen() build-system: add option to revert back to classic shared library deps instread of dlopen(), for downstreams where minimal, runtime-combined OS images are a non-issue Dec 2, 2020
@mikhailnov
Copy link
Contributor Author

What if soname is different at build time?! Nobody will notice it, the package will be build successfully, but dlopenning may not work out of the box! that is a complete crap, I believe, for a distro package. Or am I wrong?

If the name changes (i.e. the number after the .so.), then that's am ABI break, it's absolutely intended that we don't attempt to use the library then, as that can end up in all kinds of code corruptions. We load the exact versions of the libraries we support. If a library's ABI changes, then this always means some developer needs to look into that, and possibly update code for the new ABI.

The problem is that it is not detected at build time and cannot be detected as a requirement by existing tools.
You write about hiding head in sand in #17416 , I do understand what you mean and why you do this, but the main problem that currently it is a regression of stability of systemd inside a distro, a big regression to my mind. I try to avoid hiding my head into sand, but the price of trying to solve not urgent problems must not be so high and require to loose in predictionability and stability, I believe.

@poettering
Copy link
Member

regression of stability? What do you mean by that? The builds are as stable as before? There are no memory corruptions or anything introduced by that, even if the shared libraries are updated. So not sure what you mean by "stability".

If you want we can add a test case that tries to load all shared libs we open once, which will fail if they aren't installed. This way you'll catch failure of missing .so during build time at least. Which isn#t the same as runtime, but close enough, no?

@mikhailnov
Copy link
Contributor Author

mikhailnov commented Dec 7, 2020 via email

@poettering
Copy link
Member

07.12.2020 16:00, Lennart Poettering пишет:
regression of /stability/? What do you mean by that?
When I build systemd RPM without dlopen(), I am sure that:

  • all dependencies are resolved automatically and are installed

Hmm, that's what meson and pkg-config are actually responsible for: managing deps at build time.

  • I know that everything will work not differently on different systems

Uh, what? The ELF shared library dep header actually list the very same .so names as we do. You could argue that listing them explicitly in our code is a lot safer, since we pin the library versions explicitly.

  • if e.g. libcryptsetup soname changes, I will find out that systemd has to be rebuilt by e.g. dnf repoquery --qf '%{sourcerpm}' --whatrequires 'libcryptsetup.so.N()(64bit)', but in case of dlopen() it will start to fail loading libcryptsetup at runtime SILENTLY for the distribution build system. It is a repository-wide standard process of ensuring that packages are not broken. At this moment distros cannot deal with dlopen() in terms of ensuring consistency. Do you see my point?

Yeah, distro build tools currently have no nice way to automatically deal with such deps. Something to fix though. In those distro build tools.

Such soft dependencies are very common, much more common than you might assume btw. The libxkbcommon dep in systemd has been like this for many many years, and plenty other packages use dlopen() like this too to minimize dep trees.

@poettering
Copy link
Member

Yes, ensuring dlopenability and ABI consistency at build time is much better than nothing!

See #17884

@DemiMarie
Copy link

DemiMarie commented Dec 7, 2020

Yeah, distro build tools currently have no nice way to automatically deal with such deps. Something to fix though. In those distro build tools.

I agree that distro build tools should be able to deal with them, but I am having trouble figuring out how they should do so. Is there a way to extract them from the compiled binary, without resorting to strings or similar?

@poettering
Copy link
Member

@DemiMarie see #17416, wich uses objcopy to extract them from an ELF binary, after they have been declared in sources.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build-system RFE 🎁 Request for Enhancement, i.e. a feature request
Development

No branches or pull requests

4 participants