Among the methods of setting up dynamic links, rpath
has its own problems, and ld.so.conf
is an OS global configuration that may affect other services because of the dynamic library version of a single service, which is not an elegant method.
So how can we make the target service find the corresponding dynamic library without affecting other services, without using rpath
and ld.so.conf
?
LD_LIBRARY_PATH
For dynamic link library path configuration, in addition to rpath
and ld.so.conf
, there is also LD_LIBRARY_PATH
. As long as the LD_LIBRARY_PATH
variable is set in the binary startup environment, glibc
will use the path configuration in this variable as one of the paths to find the DLLs, allowing the binary executable to link properly to the DLLs it depends on.
LD_LIBRARY_PATH
will take effect “globally” in the current shell session, however, since the author’s service uses systemd to manage its life cycle, according to the above idea, we should only need to inject LD_LIBRARY_PATH
into the startup environment before the service starts. This also enables a certain degree of environmental “isolation” with systemd.
The Environment
field in the systemd service configuration is used to describe the environment variables of the startup environment, so let’s add LD_LIBRARY_PATH
here (below), reload the systemd configuration and restart the service, and observe the effect.
|
|
In fact, for most services, it is sufficient to add environment variables to solve the problem. But unfortunately, since our service needs to listen on ports 1024 and below (e.g. 80, 443), I have performed a setcap
operation on the binary executable to give it the ability to listen on lower ports.
Capability
Because the file contains capability, glibc
ignores LD_LIBRARY_PATH
, and the service is still not linked to the dynamic library correctly.
Once you understand why, the next step is clear: first, remove the capability from the binary executable (chown
can remove it, as can setcap -ep
), and second, use systemd’s service configuration to configure the capability (below).
|
|
Reload the systemd configuration again and restart the service, the problem is solved perfectly.