Unbound daemon linking bug?

Hi,

It seems the unbound daemon binary "unbound" does not actually
link in the libunbound.so dynamically.

This means packagers did not find the dependancies, so unbound
does not depend on unbound-libs. When upgrading the "unbound"
package this does not update the libunbond pacakge.

I don't think there is a valid reason for the unbound daemon not
to link against the unbound library instead of including a static
copy.

I confirmed this to be a problem for unbound packaged on fedora/rhel/centos.
It might also be an issue for other distributions that mistakenly
assumed the unbound daemon uses a shared linbound.so library.

Paul

Note that unbound-host seems fine:

[paul@bofh trunk]$ ldd /usr/sbin/unbound|grep unbound
[paul@bofh trunk]$ ldd /usr/sbin/unbound-host|grep unbound
   libunbound.so.2 => /usr/lib64/libunbound.so.2 (0x0000003263200000)

Paul

Hi Paul,

I don't fully grasp your problem: if unbound does not link against
libunbound, upgrading the unbound package would not need to update the
libunbound package.

It is of course possible to use the library dynamically, but probably
unbound links statically for performance optimization reasons.

Best regards,

Matthijs

I don't fully grasp your problem: if unbound does not link against
libunbound, upgrading the unbound package would not need to update the
libunbound package.

But if a fix is applied to unbound-libs, the unbound daemon will still
be using an old copy. Also, the results of unbound vs unbound-host could
then be different.

As a rule, it is always bad to have duplicatated staticly linked code
from a dynamic library into any executable - it becomes unmanagable.

To avoid this, I will make unbound depend on unbound-libs of the identical
version so that we keep the daemon and libraries in sync with each other.

It is of course possible to use the library dynamically, but probably
unbound links statically for performance optimization reasons.

Can you explain those to me?

Paul

Try passing --enable-allsymbols to configure.

Hi Paul,

I don't fully grasp your problem: if unbound does not link against
libunbound, upgrading the unbound package would not need to update the
libunbound package.

But if a fix is applied to unbound-libs, the unbound daemon will still
be using an old copy. Also, the results of unbound vs unbound-host could
then be different.

Seems to me that this is a thing that the package maintainer should
maintain.

As a rule, it is always bad to have duplicatated staticly linked code
from a dynamic library into any executable - it becomes unmanagable.

To avoid this, I will make unbound depend on unbound-libs of the identical
version so that we keep the daemon and libraries in sync with each other.

It is of course possible to use the library dynamically, but probably
unbound links statically for performance optimization reasons.

Can you explain those to me?

Dynamic linking *may* increase paging thus decreasing performance.

Paul

- --enable-allsymbols is indeed what you want.

Best regards,

Matthijs

I don't fully grasp your problem: if unbound does not link against
libunbound, upgrading the unbound package would not need to update the
libunbound package.

But if a fix is applied to unbound-libs, the unbound daemon will still
be using an old copy. Also, the results of unbound vs unbound-host could
then be different.

Seems to me that this is a thing that the package maintainer should
maintain.

Dynamic linking *may* increase paging thus decreasing performance.

The package maintainer thinks upstream should reconsider their view, or
perhaps back these up with actual numbers instead of hypothesis :slight_smile:

- --enable-allsymbols is indeed what you want.

I tested this, and it works indeed. I'll add it to the new releases
of unbound. Thanks!

Paul

I don't fully grasp your problem: if unbound does not link against
libunbound, upgrading the unbound package would not need to update the
libunbound package.

But if a fix is applied to unbound-libs, the unbound daemon will still
be using an old copy. Also, the results of unbound vs unbound-host could
then be different.

Seems to me that this is a thing that the package maintainer should
maintain.

Dynamic linking *may* increase paging thus decreasing performance.

The package maintainer thinks upstream should reconsider their view, or
perhaps back these up with actual numbers instead of hypothesis :slight_smile:

Yes I do not think this is a big issue. Dynamic linking and chroot
feature (on not wonderfully packaged environments) can be painful.

- --enable-allsymbols is indeed what you want.

I tested this, and it works indeed. I'll add it to the new releases
of unbound. Thanks!

Note that this means libunbound exports internal symbols, not just the
'libunbound API'. Those symbols 'pollute' the linking environment of
the user program, i.e. conflict if they also use dns_cache_store() and
so on.

This is why the option is not enabled by default. We could get around
this by having libunbound-internal and libunbound (that links to
libunbound-internal again). And so on, but it gets more complicated,
static binaries can be very nice for system critical services in some
situations, so this option we have to also keep around...

Best regards,
   Wouter

Seems to me that this is a thing that the package maintainer should
maintain.

Dynamic linking *may* increase paging thus decreasing performance.

The package maintainer thinks upstream should reconsider their view, or
perhaps back these up with actual numbers instead of hypothesis :slight_smile:

Yes I do not think this is a big issue. Dynamic linking and chroot
feature (on not wonderfully packaged environments) can be painful.

- --enable-allsymbols is indeed what you want.

I tested this, and it works indeed. I'll add it to the new releases
of unbound. Thanks!

Note that this means libunbound exports internal symbols, not just the
'libunbound API'. Those symbols 'pollute' the linking environment of
the user program, i.e. conflict if they also use dns_cache_store() and
so on.

Hmm, that's not the best either.

This is why the option is not enabled by default. We could get around
this by having libunbound-internal and libunbound (that links to
libunbound-internal again). And so on, but it gets more complicated,
static binaries can be very nice for system critical services in some
situations, so this option we have to also keep around...

I'm not sure I understood it fully. If some things are internal only,
and some things are libunbound API, then why are the internal only
functions not 'static' and the API functions are the only ones visible?
Then either dynamically or staticly link libunbound into unbound?

Paul

Paul Wouters wrote:

I don't think there is a valid reason for the unbound daemon not
to link against the unbound library instead of including a static
copy.

actually, i can think of a reason: so that the unbound daemon can use
more "advanced" options (external event library, python integration)
while the libunbound library doesn't. in fact, i've just uploaded a new
version of the debian unbound package that minimizes the library
dependencies of libunbound while leaving unbound unchanged.

e.g., if libunbound dynamically links against libev, you cannot
dynamically link an executable against libunbound and libevent, since
the symbols in libev and libevent would conflict. (i think there is
also a similar possibility with libpython2.6 / libpython2.7, but i
believe libssl0.9.8 / libssl1.0.0 aren't affected because libssl uses
versioned symbols.)

I see your point, but I'm not sure how packaging would deal with that,
other then maintaining two different compiles of libunbound on the same
system - and maintaining the "static" copy inside the daemon.

For Fedora/RHEL, I've added a hard Requires: so that the libs and the
daemon package will never be of a different version.

Paul