I’m upgrading the ipfixprobe package in Alpine Linux to 5.6.0 and found a build/installation issue caused by several process plugins linking against the IPFIX output plugin.
Description
Several process plugins are linked against libipfixprobe-output-ipfix.so as if it was a regular shared library:
libipfixprobe-process-bstats.so -> libipfixprobe-output-ipfix.so
libipfixprobe-process-phists.so -> libipfixprobe-output-ipfix.so
libipfixprobe-process-pstats.so -> libipfixprobe-output-ipfix.so
libipfixprobe-process-quic.so -> libipfixprobe-output-ipfix.so
libipfixprobe-process-tls.so -> libipfixprobe-output-ipfix.so
However, libipfixprobe-output-ipfix.so is installed into the private output plugin directory:
/usr/lib/ipfixprobe/output/libipfixprobe-output-ipfix.so
while the process plugins are installed into:
/usr/lib/ipfixprobe/process/
The affected process plugins do not contain a RUNPATH/RPATH pointing to ../output, and /usr/lib/ipfixprobe/output is not part of the standard dynamic linker search path.
As a result, the installed process plugins contain a runtime dependency that cannot be resolved by the dynamic loader.
Why this is a problem
This causes packaging failures in Alpine Linux during automatic shared-library dependency tracing:
>>> ERROR: ipfixprobe*: libipfixprobe-output-ipfix.so: path not found
>>> ERROR: ipfixprobe*: create_apks failed
The issue can be reproduced from the installed package image with:
scanelf -nR pkg | grep libipfixprobe-output-ipfix
which shows:
ET_DYN libipfixprobe-output-ipfix.so,libstdc++.so.6,libgcc_s.so.1,libc.musl-x86_64.so.1 pkg/ipfixprobe/usr/lib/ipfixprobe/process/libipfixprobe-process-bstats.so
ET_DYN libipfixprobe-output-ipfix.so,libstdc++.so.6,libgcc_s.so.1,libc.musl-x86_64.so.1 pkg/ipfixprobe/usr/lib/ipfixprobe/process/libipfixprobe-process-phists.so
ET_DYN libipfixprobe-output-ipfix.so,libstdc++.so.6,libgcc_s.so.1,libc.musl-x86_64.so.1 pkg/ipfixprobe/usr/lib/ipfixprobe/process/libipfixprobe-process-pstats.so
ET_DYN libcrypto.so.3,libipfixprobe-output-ipfix.so,libstdc++.so.6,libgcc_s.so.1,libc.musl-x86_64.so.1 pkg/ipfixprobe/usr/lib/ipfixprobe/process/libipfixprobe-process-quic.so
ET_DYN libipfixprobe-output-ipfix.so,libstdc++.so.6,libgcc_s.so.1,libc.musl-x86_64.so.1 pkg/ipfixprobe/usr/lib/ipfixprobe/process/libipfixprobe-process-tls.so
But the provider is installed here:
pkg/ipfixprobe/usr/lib/ipfixprobe/output/libipfixprobe-output-ipfix.so
This is likely a runtime problem as well, not only a packaging problem, because the dynamic loader will not normally search /usr/lib/ipfixprobe/output when loading modules from /usr/lib/ipfixprobe/process.
Why the current linking looks wrong
libipfixprobe-output-ipfix.so appears to be an ipfixprobe output plugin, not a public/shared support library. Linking process plugins directly against an output plugin creates a cross-plugin dependency that is not represented correctly in the installation layout.
If code from the IPFIX output plugin is needed by process plugins, that shared code should probably live in a common internal library with a well-defined runtime location, rather than requiring process plugins to depend on another plugin from a sibling plugin directory.
Possible solutions
There are a few possible ways to fix this.
Move shared IPFIX helper code into a common internal shared library
The code currently shared through ipfixprobe-output-ipfix should be moved into a separate internal shared library, for example something like:
libipfixprobe-ipfix-common.so
or another appropriately named helper library.
This library should be installed into a location where it can be found by the dynamic loader, either a normal library path or a private library directory with correct RUNPATH.
Then both the IPFIX output plugin and the affected process plugins could link against this common library:
libipfixprobe-process-*.so -> libipfixprobe-ipfix-common.so
libipfixprobe-output-ipfix.so -> libipfixprobe-ipfix-common.so
instead of:
libipfixprobe-process-*.so -> libipfixprobe-output-ipfix.so
This keeps plugins independent and avoids requiring one plugin to act as a shared support library for another plugin.
Alternative: install ipfixprobe-output-ipfix as a real shared library
If libipfixprobe-output-ipfix.so is intentionally meant to provide ABI used by other modules, then it should probably not be installed only as an output plugin under:
/usr/lib/ipfixprobe/output/
It should be installed in a location where the dynamic linker can resolve it, and it should be treated as a real shared library rather than only as a plugin.
However, this seems less clean, because the name and installation path suggest that it is an output plugin, not a general-purpose shared library.
Workaround: add RUNPATH from process plugins to the output plugin directory
Another possible workaround is to set an install RUNPATH on the affected process plugins:
For example:
set_target_properties(ipfixprobe-process-bstats PROPERTIES
INSTALL_RPATH "$ORIGIN/../output"
)
and similarly for:
ipfixprobe-process-phists
ipfixprobe-process-pstats
ipfixprobe-process-quic
ipfixprobe-process-tls
This would fix the immediate runtime lookup problem, but it still leaves the questionable design of one plugin depending directly on another plugin.
Expected result
After installation, process plugins should not contain unresolved dependencies on libraries located only in sibling plugin directories without a valid runtime search path.
In particular, this should either produce no matches:
scanelf -nR "$DESTDIR" | grep libipfixprobe-output-ipfix
or the affected modules should contain a correct RUNPATH that allows libipfixprobe-output-ipfix.so to be resolved at runtime.
Disclaimer: This report was prepared with assistance from an LLM.
I’m upgrading the ipfixprobe package in Alpine Linux to 5.6.0 and found a build/installation issue caused by several process plugins linking against the IPFIX output plugin.
Description
Several process plugins are linked against
libipfixprobe-output-ipfix.soas if it was a regular shared library:However,
libipfixprobe-output-ipfix.sois installed into the private output plugin directory:while the process plugins are installed into:
The affected process plugins do not contain a
RUNPATH/RPATHpointing to../output, and/usr/lib/ipfixprobe/outputis not part of the standard dynamic linker search path.As a result, the installed process plugins contain a runtime dependency that cannot be resolved by the dynamic loader.
Why this is a problem
This causes packaging failures in Alpine Linux during automatic shared-library dependency tracing:
The issue can be reproduced from the installed package image with:
scanelf -nR pkg | grep libipfixprobe-output-ipfixwhich shows:
But the provider is installed here:
This is likely a runtime problem as well, not only a packaging problem, because the dynamic loader will not normally search
/usr/lib/ipfixprobe/outputwhen loading modules from/usr/lib/ipfixprobe/process.Why the current linking looks wrong
libipfixprobe-output-ipfix.soappears to be an ipfixprobe output plugin, not a public/shared support library. Linking process plugins directly against an output plugin creates a cross-plugin dependency that is not represented correctly in the installation layout.If code from the IPFIX output plugin is needed by process plugins, that shared code should probably live in a common internal library with a well-defined runtime location, rather than requiring process plugins to depend on another plugin from a sibling plugin directory.
Possible solutions
There are a few possible ways to fix this.
Move shared IPFIX helper code into a common internal shared library
The code currently shared through
ipfixprobe-output-ipfixshould be moved into a separate internal shared library, for example something like:or another appropriately named helper library.
This library should be installed into a location where it can be found by the dynamic loader, either a normal library path or a private library directory with correct
RUNPATH.Then both the IPFIX output plugin and the affected process plugins could link against this common library:
instead of:
This keeps plugins independent and avoids requiring one plugin to act as a shared support library for another plugin.
Alternative: install
ipfixprobe-output-ipfixas a real shared libraryIf
libipfixprobe-output-ipfix.sois intentionally meant to provide ABI used by other modules, then it should probably not be installed only as an output plugin under:It should be installed in a location where the dynamic linker can resolve it, and it should be treated as a real shared library rather than only as a plugin.
However, this seems less clean, because the name and installation path suggest that it is an output plugin, not a general-purpose shared library.
Workaround: add
RUNPATHfrom process plugins to the output plugin directoryAnother possible workaround is to set an install
RUNPATHon the affected process plugins:For example:
and similarly for:
This would fix the immediate runtime lookup problem, but it still leaves the questionable design of one plugin depending directly on another plugin.
Expected result
After installation, process plugins should not contain unresolved dependencies on libraries located only in sibling plugin directories without a valid runtime search path.
In particular, this should either produce no matches:
or the affected modules should contain a correct
RUNPATHthat allowslibipfixprobe-output-ipfix.soto be resolved at runtime.Disclaimer: This report was prepared with assistance from an LLM.