Development/Docs/Core Dependency Sanitization
From Mandriva
The system core comprises the essential set of packages of the Mandriva Linux operating system. Special attention should be given to the core dependencies in order to reduce complexity, keep the system maintenable and prevent inclusion of unnecessary packages.
Contents |
Introduction
Mandriva Linux (Cooker circa Mandriva Linux 2005 release) has a heavily inter-dependent system core which impacts directly on dependency resolution effort for system upgrades. The system core also aggregates elements that should be deemed optional but can't be removed due to dependency chains originating in essential core components. Sanitization of system core dependencies can be applied punctually without affecting the rest of the system (unlike more extreme measures), and the several suspicious dependency links listed in this paper can be applied individually or in any combination in order to disentangle the system core and allow better planning of upgrade strategies.
Intrusive changes mentioned along this paper are marked as so and can be safely bypassed to maintain a conservative approach to the sanitization process.
System core dependencies
Packages in the core
For simplicity, a subset of the packages that are part of the system core has been selected for this study. Selected packages are: glibc, bash, rpm, rpm-helper, perl-base, coreutils, initscripts, unzip, make, cpio, tar, util-linux, libselinux1, udev and the hotplug subsystem. The complete system core contains 117 real packages and 144 virtual packages (1202 total dependencies, which can be optimized to 451 direct dependencies between packages), tied together by the basesystem metapackage. Charting the full core would result in a graph too dense for meaningful analysis.
Packages in the complete core are:
SysVinit basesystem bash bdflush bootloader-utils bzip2 chkconfig common-licenses console-tools coreutils cpio cracklib-dicts crontabs diffutils dmidecode drakxtools-backend e2fsprogs elfutils etcskel ethtool file filesystem findutils gawk gettext-base glibc grep grub gzip hotplug ifmetric ifplugd info-install initscripts iproute2 iputils kernel-i586-up-1GB-2.6.10.3mdk ldconfig ldetect-lst less libbeecrypt6 libbzip2_1 libconsole0 libcrack2 libdb4.2 libelfutils1 libext2fs2 libgcc1 libglib1.2 libglib2.0_0 libintl3 libiw27 libldap2.2_7 libldetect0.6 libmagic1 libncurses5 libopenssl0.9.7 libpam0 libpcre0 libpwdb0 librpm4.2 libsasl2 libselinux1 libslang1 libsysfs1 libtermcap2 libusb0.1_4 libuser libuser1 libutempter0 logrotate losetup make makedev mandriva-release mingetty mkinitrd mktemp module-init-tools modutils mount ncurses net-tools openldap pam passwd perl-MDK-Common perl-base pkgconfig popt procps psmisc pwdb-conf rootfiles rpm rpm-helper sash sed setup shadow-utils sound-scripts sysfsutils sysklogd tar termcap time timezone udev unzip usbutils utempter util-linux vim-minimal vixie-cron which wireless-tools zlib1
Highlighted packages are not referenced directly by the basesystem metapackage and entered de system core via indirect dependencies. Underlined packages should be investigated to see if they're actually essential base system packages:
- kernel: making this package mandatory forces chroot installations to carry its own, unused kernel copy. Additionally, packages shouldn't require kernel (see rationale in the Conclusions section below).
- ldetect-lst: data for hardware autodetection. The hardware autodetection subsystem can be installed by default, but could be optional as a requirement.
- libtermcap2: many distros switched to ncurses, but Luca Berra points that it's small and lean. It's needed by bash in the core system, perhaps bash could use its own internal implementation.
- make: I can't see why this is essential, but it's tied to libusb.
- pkgconfig: This is a development package but it's required by libpcre0 (bug #0000).
- sound_scripts: should be optional, not all systems have sound output (will investigate).
- udev: could be used if available but not mandatory.
- unzip: same case as make, see Development/Docs/Unzip_Dependency.
- usbutils: should be installed only in systems with USB ports.
- vim-minimal: can be replaced by elvis-tiny, see Vi Change Proposal.
- wireless-tools: should be installed only in systems with wireless capabilities.
Some statistics
Top ten real dependencies are:
Symbol | Dependencies |
---|---|
libc.so.6(GLIBC_2.0) | 96 |
libc.so.6 | 96 |
libc.so.6(GLIBC_2.1) | 77 |
libc.so.6(GLIBC_2.3) | 73 |
libc.so.6(GLIBC_2.1.3) | 43 |
libc.so.6(GLIBC_2.2) | 42 |
/bin/sh | 36 |
/sbin/ldconfig | 35 |
glibc | 34 |
bash | 32 |
Package | Dependencies |
---|---|
glibc | 96 |
bash | 49 |
ldconfig | 36 |
coreutils | 13 |
perl-base | 10 |
chkconfig | 9 |
rpm-helper | 9 |
info-install | 9 |
shadow-utils | 7 |
mktemp | 7 |
Dependency chart analysis
Fig. 1: Dependencies of the system core
- Rpm dependencies should be reviewed. Does it really need unzip? And make?
- Coreutils is tied to pam via su(1), apparently /etc/pam.d/su is the reason. If /etc/pam.d could be placed in the filesystem package or su relocated to a different place, this dependency could be eliminated.
- Self-dependencies can be safely removed.
- Glibc shouldn't require bash, as it relies on the static sash.
- Glibc shouldn't require the rpm package. This dependency is critical as it ties the entire distribution to rpm, bash, perl-base and coreutils.
- Pam shouldn't require initscripts.
- Initscripts shouldn't require udev. Udev should be used only if available in the system, and a different constraint could be used to make sure it's installed if it is an essential package. Otherwise, many subsystem will end [[UnzipDependency][requiring USB support]].
- Cpio shouldn't require tar (/sbin/rmt shouldn't be essential for cpio usage).
- Tar shouldn't require cpio.
- Packages shouldn't require kernel (see rules below).
- Does udev really use rpm-helper scripts to create or delete system users and groups?
- Initscripts requires perl-base due to supermount activation and filesystem-monitor. This dependency can be removed if the supermount script is moved to the supermount package and filesystem-monitor is either moved to a more appropriate package or written as a shell script. This is not a unacceptable dependency though, and can be kept as is with little impact in the system dependencies.
- Udev requires perl-base only for /sbin/udev-migrating-devfs-rules.pl. Same case as above.
- [INTRUSIVE] Virtually all packages requiring ldconfig also require glibc. We should consider moving it to the glibc package (as do other distributions such as Debian).
- Rpm shouldn't require cpio, as it uses its own internal implementation.
Conclusions
General rules for system sanitization can be derived from the cases above:
- No packages should require kernel. Rationale: There's no guarantee that the installed kernel is actually the kernel running on the system. Additionally, if a system comes to the point where a package is to be installed, we can safely assume that a kernel is running. If installing a chroot system, it shouldn't require an installed kernel. If it does require a kernel, it can be installed manually.
- Hardware-dependent subsystems such as USB and wireless support should be optional and installed only if the system has the hardware available or by user's request.
- [INTRUSIVE] Pre- and post-install scriptlets should be Bourne-compliant whenever possible and executed using the /bin/bsh interpreter instead of /bin/sh. Rationale: The latter is provided by bash, generating extra dependencies for each package.
Other specific points to investigate:
- Glibc dependencies should be reevaluated (rpm and bash).
- Rpm dependencies should be reevaluated. It possibly doesn't need cpio, make and unzip.
- Bash can use its internal termcap implementation.
- Vi and the Bourne shell can be improved.