- Overview
- Enhancing Security
- Recommendations and Methodologies for Minimization
- Background
- Qualifying a Solaris Configuration
- Automating Domain Installations
- Using Scripts to Qualify a Solaris Configuration
- Minimization Methodology
- About the Authors
- Acknowledgements
- Related Resources
- Ordering Sun Documents
- Accessing Sun Documentation Online
Using Scripts to Qualify a Solaris Configuration
The general strategy for producing a minimized configuration for an application requires examining all files that make up the application installation. The idea is to identify dependencies these files have in Solaris OE such that only the required parts of Solaris OE are kept. The reason for this is that applications do not uniformly specify the packages in Solaris OE that they have dependencies on, so these have to be determined manually. Even Solaris OE packages suffer from this deficiency.
This operation uses packages because they are the units by which an installed Solaris system is defined and controlled. Removing individual files from a Solaris OE package is not a supported method of minimization.
To reduce the burden of finding the needed Solaris OE packages, several Perl and Korn shell scripts were developed. This section describes these scripts. (See the "Related Resources" on page 39 for the Web address from which to obtain these scripts.)
These scripts use techniques for finding packages by identifying the dynamic dependencies an executable or dynamic library has. A dynamic library can have dependencies on other dynamic libraries. The scripts make use of these properties to provide a systematic way of identifying the packages that executables and dynamic libraries have dependencies on, and which packages these dynamic libraries are in.
This section contains the following topics:
"Find Dependent Files Using truss Command" on page 17
"Find Dynamic Library Dependencies Using ldd Command" on page 18
"Find Package Dependencies" on page 18
"Find Multiple Packages and Files" on page 19
Find Dependent Files Using truss Command
Run all executables in an application with truss to find all dynamic libraries, configuration files, and data files opened successfully. When an executable command from the application is run, various libraries are opened by the runtime linker at startup. Additionally, configuration and data files are opened as the process is in execution. An executable is made up of dynamic libraries that are members of Solaris OE packages. Configuration and data files are members of Solaris OE packages. These relationships are captured by using the truss command to track system calls.
The scan.pl script takes the output of running truss on an executable and analyzes the output to find which dynamic libraries, configuration files, and data files were successfully opened at runtime.
These files are then cross-referenced with the Solaris OE package management system to find which packages these files belong to.
The following is an example of running the truss command on an executable to produce output, and scan.pl processing the output to find required Solaris OE packages.
# truss -f -o /tmp/truss.out -topen,open64,stat,exec /bin/ls \ /tmp/truss.out # scan.pl -p < /tmp/truss.out Needed packages: SUNWcsl SUNWcsu SUNWkvm
NOTE
The truss command is used here instead of pldd because pldd can only provide a snapshot of the process in execution at a given time. Because the process must be running, processes that execute for short durations, such as /bin/ls, would not be guaranteed to return correct results. Additionally, there is an issue when the snapshot is taken pldd would not know that a dlopen and dlclose might have occurred. The truss command overcomes these limitations by logging the calls over the lifetime of the process from startup to termination.
Find Dynamic Library Dependencies Using ldd Command
Run ldd against all executables in the application to find dynamic library dependencies that the runtime linker links in when running the executable. Next, find the packages that the dynamic libraries are in. An application often has its own dynamic libraries. These libraries reference other dynamic libraries in Solaris OE. Normally, dynamic libraries are linked in at runtime when an application executable starts up. This process is not always guaranteed to happen because the application might dlopen the library instead, and only when it's required.
The ldd.ksh script takes one or more executables or libraries and finds which packages contain the dynamic libraries. It does this by cross-referencing the ldd command output with a call to pkgchk to identify the package a dynamic library is in.
The ldd.ksh script also finds libraries that might be missing from an installation by processing ldd output. The truss command has limited ability to achieve this task, and provides incomplete information.
The following is an example of running ldd.ksh on an executable. The -s flag suppresses detailed output.
# ldd.ksh -s /opt/SUNWsrspx/bin/srsproxy Couldn't find package for libaio.so.1 => (file not found) SUNWcsl SUNWlibC SUNWlibms
Find Package Dependencies
An executable (or dynamic library) typically requires multiple dynamic libraries to be able to execute. The chances of all the dynamic libraries being contained in the same package as the executable is small, which means there is a relationship (a dependency) between the packages containing the dynamic libraries and the package containing the executable. Solaris OE tracks this dependency relationship using dependency lists in the Solaris OE package management system.
Any package normally has a relationship back to mandatory core Solaris OE packages. The depend-tree.pl script constructs these dependencies from a starting package all the way back to the core Solaris OE packages.
It is always important to maintain dependencies among packages, because these are critical to Solaris OE. Also, it reduces the risk of packaging problems that might occur when patching a system.
Minimization has some requirements that do not fit well when following dependency links. The main ones are from following dependencies for SUNWnamos and SUNWdtdst. Issues arising from these are covered in the next section and in "Removing Unneeded Dependent Packages" on page 24.
The depend-tree.pl script works out the dependency tree that a package has. The depend-tree.pl script pulls details of dependencies all the way to the root packages. Root packages do not depend on anything else. This dependency information is kept in the Solaris OE package management system.
The following is an example of running depend-tree.pl to find package dependencies that it has on other Solaris OE packages.
# depend-tree.pl -HuN SUNWesu SUNWcar SUNWkvm SUNWcsr SUNWcsu SUNWcsd SUNWcsl SUNWpl5u SUNWpl5v
The command line argument -HuN means suppress the header; display unique packages only (no duplicates); and ignore SUNWnamos package dependencies.
The -N option is supplied because some executables open locales in SUNWnamos, despite LANG_ALL being set to C. This action causes the dependencies for SUNWnamos to be included. This action is undesirable because a lot of these are X fonts packages and are simply not needed. Without the -N option, the output for SUNWnamos would be as follows.
# depend-tree.pl -Hu SUNWnamos SUNWcar SUNWkvm SUNWcsr SUNWcsu SUNWcsd SUNWi15cs SUNWi15rf SUNWeurf SUNWi1cs SUNWxwplt SUNWesu SUNWcsl SUNWpl5u SUNWpl5v SUNWxwdv SUNWxwfnt SUNWxwice SUNWdtcor SUNWlibms SUNWcpp SUNWzlib
Find Multiple Packages and Files
The scripts described in previous sections all operate on a single executable, a dynamic library, or a package. To maximize the ability to operate at a more granular level, two wrapper functions, meta.ksh and pkg.ksh, are used to operate on multiple packages and files. This operation allows a list of packages or directories to be given to pkg.ksh.
meta.ksh
This script is a wrapper around scan.pl, ldd.ksh, and depend-tree.pl. It takes an executable or a shared library as an argument and executes the first two scripts to get the Solaris OE packages required. These are then passed into depend-tree.pl to get dependencies, and formatted for output.
The -q option tells the script to suppress detailed output. An example of running meta.ksh is as follows.
# meta.ksh -q /usr/openwin/bin/xterm Package: SUNWxwopt truss: SUNWcsd SUNWcsl SUNWcsr SUNWcsu SUNWkvm SUNWlccom SUNWlibms SUNWxwice SUNWxwopt SUNWxwplt ldd: SUNWcsl SUNWlibms SUNWxwice SUNWxwplt depend: SUNWcar SUNWkvm SUNWcsr SUNWcsu SUNWcsd SUNWxwplt SUNWesu SUNWcsl SUNWpl5u SUNWpl5v SUNWxwdv SUNWxwfnt SUNWxwice SUNWdtcor SUNWlibms SUNWcpp SUNWzlib SUNWzlib
The meta.ksh script will kill -9 the executable within a few seconds after it has the information it requires, if the executable does not gracefully exit.
pkg.ksh
This script is the top-level script that operates on packages. If the -d option is specified, it operates on directories.
It takes a package or a directory and iterates over its contents to find all executables and shared libraries. When it finds one, it calls meta.ksh and processes the output. It produces a list of package dependencies as output.
Specifying the -t option takes a profile template, merges in application packages needed from Solaris OE, and writes the merged file to stdout. Adding the -o option writes the template to the specified file.
If the -s option is specified, pkg.ksh searches the directories specified by the -d option or the packages specified by the -s option for dynamic libraries and configures the system to point to their location temporarily.
See the Case Study in Part II of this article for examples of pkg.ksh in use.
At this time, the usage template for pkg.ksh is as follows.
# pkg.ksh Usage: pkg.ksh [-s] [-t <profile template>] [-o <new profile>] [[-d <dir>...<dir>] [-p <pkg>...<pkg>] | [<pkg>...<pkg>]] -s means search for *.so* dynamic libraries and set LD_LIBRARY_PATH and LD_LIBRARY_PATH_64 as appropriate.