Our goal is to get used to the tools available to find out information about package dependencies on an RPM based system.
Operating System and Software Versions
- Operating system: Red Hat Enterprise Linux 7.5
- Software: rpm 4.11, yum 3.4.3
Privileged access to the system.
- # – requires given linux commands to be executed with root privileges either directly as a root user or by use of
- $ – given linux commands to be executed as a regular non-privileged user
RPM, which stands for Red Hat Package Manager, is a well-known and mature package manager used by all Red Hat flavor distributions, as well as SuSE. With RPM the packager can define relations between packages, and even with versions of packages – for example, an Apache Tomcat server needs proper Java environment present to be able to run.
On the other hand, to install a Java environment, you don’t need a Tomcat server – you may decide to run some different Java based application, maybe one written by yourself started by hand when needed to do it’s job. In other words, the Tomcat server depends on Java.
RPM can make a sysadmin’s life a lot easier by presenting these dependencies – and tools relying on RPM such as the
rpm utility, or
yum can automatically solve these dependencies, and install all additional packages needed for a new component to run properly.
To find out the list of packages that foo.bar package depends on, simply run:
# yum deplist foo.bar
And to find the list of packages that require (depend on) package foo.bar:
rpm -q --whatrequires foo.bar
A real life example with a generic package:
bash. Let’s see what packages needed by the bash package:
# yum deplist bash package: bash.x86_64 4.2.46-30.el7 dependency: libc.so.6()(64bit) provider: glibc.x86_64 2.17-222.el7 dependency: libc.so.6(GLIBC_2.11)(64bit) provider: glibc.x86_64 2.17-222.el7 dependency: libc.so.6(GLIBC_2.14)(64bit) provider: glibc.x86_64 2.17-222.el7 dependency: libc.so.6(GLIBC_2.15)(64bit) provider: glibc.x86_64 2.17-222.el7 dependency: libc.so.6(GLIBC_2.2.5)(64bit) provider: glibc.x86_64 2.17-222.el7 dependency: libc.so.6(GLIBC_2.3)(64bit) provider: glibc.x86_64 2.17-222.el7 dependency: libc.so.6(GLIBC_2.3.4)(64bit) provider: glibc.x86_64 2.17-222.el7 dependency: libc.so.6(GLIBC_2.4)(64bit) provider: glibc.x86_64 2.17-222.el7 dependency: libc.so.6(GLIBC_2.8)(64bit) provider: glibc.x86_64 2.17-222.el7 dependency: libdl.so.2()(64bit) provider: glibc.x86_64 2.17-222.el7 dependency: libdl.so.2(GLIBC_2.2.5)(64bit) provider: glibc.x86_64 2.17-222.el7 dependency: libtinfo.so.5()(64bit) provider: ncurses-libs.x86_64 5.9-14.20130511.el7_4 dependency: rtld(GNU_HASH) provider: glibc.x86_64 2.17-222.el7 provider: glibc.i686 2.17-222.el7
From the package perspective,
bash is a very generic one, and as seen above, depends on a few core package. But if we’d like to install something much more dependent, say, the
konzole KDE terminal emulator on a Red Hat Linux with a Gnome desktop manager, we may get more than one page long dependency list. And with
konzole, the case is even more complicated, as it relies on QT and KDE packages, so in order to install it, you will need to install the whole KDE environment beside Gnome (what you can certainly do) to provide everything
To get a more insight of what packages will be installed, check the list provided by yum before starting the installation:
# yum install konsole Resolving Dependencies --> Running transaction check ---> Package konsole.x86_64 0:4.10.5-4.el7 will be installed --> Processing Dependency: konsole-part = [...]
In the case of a Red Hat system with Gnome, it may take quite some time to resolve a KDE application’s dependencies for the first time, and when that is finished, yum will present the one sole package we asked for, with a nice small size. Followed by more than hundred packages installed for dependencies:
[...] --> Running transaction check ---> Package boost-system.x86_64 0:1.53.0-27.el7 will be installed ---> Package boost-thread.x86_64 0:1.53.0-27.el7 will be installed --> Finished Dependency Resolution Dependencies Resolved ============================================================================================================================== Package Arch Version Repository Size ============================================================================================================================== Installing: konsole x86_64 4.10.5-4.el7 rhel-7-server-rpms 78 k Installing for dependencies: OpenEXR-libs [...]
And in the summary we can see that the installation will use a lot more space on disk in the end, then the size of the package we need:
[...] Transaction Summary ============================================================================================================================== Install 1 Package (+120 Dependent packages) Total download size: 108 M Installed size: 307 M
This is a lot, but we got a useful information on how much space will be used. This is especially useful if we install many packages in one transaction.
While in this case the transaction is wasteful, the goal of dependencies is ultimately about saving resources: if someone implements some functionality in his/her code, and that can be called on the system, the next developer may not need to implement the same functionality again, but use the already existing implementation. For the
konzole example, if you want to install
akregator next time, the system will have many dependencies solved already, as
kdepim package containing
akregator also relies on
kdelibs, and such.
We can use
rpm utility the get the information the other way around: let’s list the installed packages that require the
# rpm -q --whatrequires bash dracut-033-535.el7.x86_64 initscripts-9.49.41-1.el7.x86_64 autofs-5.0.7-83.el7.x86_64 lvm2-2.02.177-4.el7.x86_64 rsyslog-8.24.0-16.el7.x86_64
Cleaning unneeded packages
If we keep our systems up to date, and change or extend their roles, “junk” packages will inevitably appear. In the package sense junk means no longer needed and/or deprecated packages. To follow the above example, we no longer need
akregator, because we moved the “service” of RSS handling to a hypothetical central RSS concentrator within our system, so after migrating our feeds to the central place, we uninstall the local RSS handling application. That will not remove all the KDE packages, as many other packages may depend on them. But if not, those packages are junk, and will consume resources, including longer update times, as
yum by default will update everything blindly it finds new packages/errata for.
Spending resources on upgrading a few unneeded packages on a laptop with broadband connection and SSD may not seem to be an issue, but imagine a datacenter with hundreds or thousands of computers, and you get the picture. It is generally a good idea to keep all systems simple, and resource management is only one point. The more complex a system, the more error prone it is. More components mean more possible bugs.
To get an overview on unneeded packages installed on the system, we can use yum and package-cleanup the same way as on CentOS, or another feature of yum,
The packages these tools mark as unneeded are not identical.
When using any of these tools it is advised to double-check what
yum is going to remove, and possibly test what the cleaning will result in on testing machines with identical package content before cleaning up the production systems.
These tools are indeed clever, but not all-knowing: for example, there will be no entry in the rpm database about a custom PHP application running on top of a webserver that calls
cups to print out incoming orders on a printer connected to the server. That is, there can be an entry if the application is packaged with the right dependencies included, and installed properly with
yum – but that takes effort, and all services need to be packaged the same way if you want to feel safe with yum-based automatic cleanups.
Solving dependency problems
Especially in large environments, there can be dependency issues while installing or upgrading systems.
The below screenshot shows a simple issue:
In the above terminal screen we try to install the
nrpe package, the client needed to monitor many aspects of the system with Nagios. We downloaded the client for the distribution, but both
yum fails with the same error: the
nrpe package requires (depends on) the
nagios-common package. In this example we can obtain the needed package from the same source, and when installing both of them the
rpm utility sees that the dependency we failed on earlier will be satisfied by the end of the transaction and installs both packages, exiting silently with success.
Yum and rpm are essential tools when working with distributions using the RPM package manager. By knowing the toolset it is much easier, and usually safer to solve install, upgrade and modify tasks on the software environment of a given system.