Supporting Relocation in a Heterogeneous Environment
The original concept behind System V packaging assumed one architecture per system. The
concept of a server did not play a role in the design. Now,
of course, a single server may provide support for several architectures, which means
there may be several copies of the same software on a server, each
for a different architecture. While Solaris packages are sequestered within recommended file system
boundaries (for example, / and /usr), with product databases on the server as
well as each client, not all installations necessarily support this division. Certain implementations
support an entirely different structure and imply a common product database. While pointing
the clients to different versions is straightforward, actually installing System V packages to
different base directories can introduce complications for the administrator.
When you design your package, you should also consider the common methods administrators
use for introducing new software versions. Administrators often seek to install and test
the latest version side-by-side with the currently installed version. The procedure involves installing
the new version to a different base directory than the current version and
directing a handful of non-critical clients to the new version as a test.
As confidence builds, the administrator redirects more and more clients to the new
version. Eventually, the administrator retains the old version only for emergencies and then
finally deletes it.
What this means is that packages destined for modern heterogeneous systems must support
true relocation in the sense that the administrator may put them any reasonable
place on the file system and still see full functionality. The Solaris 2.5
and compatible releases provide a number of useful tools which allow multiple architectures
and versions to install cleanly to the same system. Solaris 2.4 and compatible
versions also support true relocation but accomplishing the task is not quite as
obvious.
Traditional Approach
Relocatable Packages
The System V ABI implies that the original intention behind the relocatable package
was to make installing the package more convenient for the administrator. Now the need
for relocatable packages goes much further. Convenience is not the only issue, rather
it is quite possible that during the installation an active software product is
already installed in the default directory. A package that is not designed to
deal with this situation either overwrites the existing product or fails to install.
However, a package designed handle multiple architectures and multiple versions can install smoothly
and offer the administrator a wide range of options that are fully compatible
with existing administrative traditions.
In some ways the problem of multiple architectures and the problem of multiple
versions is the same. It must be possible to install a variant
of the existing package side by side with other variants, and direct clients or
standalone consumers of exported file systems to any one of those variants, without
degraded functionality. While Sun has established methods for dealing with multiple architectures on
a server, the administrator may not adhere to those recommendations. All packages need
to be capable of complying with the administrators' reasonable wishes regarding installation.
Example-A Traditional Relocatable Package
This example shows what a traditional relocatable package may look like. The package
is to be located in /opt/SUNWstuf, and its pkginfo file and pkgmap file might
look like this.
The pkginfo File
# pkginfo file
PKG=SUNWstuf
NAME=software stuff
ARCH=sparc
VERSION=1.0.0,REV=1.0.5
CATEGORY=application
DESC=a set of utilities that do stuff
BASEDIR=/opt
VENDOR=Sun Microsystems, Inc.
HOTLINE=Please contact your local service provider
EMAIL=
MAXINST=1000
CLASSES=none
PSTAMP=hubert990707141632
The pkgmap File
: 1 1758
1 d none SUNWstuf 0775 root bin
1 d none SUNWstuf/EZstuf 0775 root bin
1 f none SUNWstuf/EZstuf/dirdel 0555 bin bin 40 773 751310229
1 f none SUNWstuf/EZstuf/usrdel 0555 bin bin 40 773 751310229
1 f none SUNWstuf/EZstuf/filedel 0555 bin bin 40 773 751310229
1 d none SUNWstuf/HRDstuf 0775 root bin
1 f none SUNWstuf/HRDstuf/mksmart 0555 bin bin 40 773 751310229
1 f none SUNWstuf/HRDstuf/mktall 0555 bin bin 40 773 751310229
1 f none SUNWstuf/HRDstuf/mkcute 0555 bin bin 40 773 751310229
1 f none SUNWstuf/HRDstuf/mkeasy 0555 bin bin 40 773 751310229
1 i pkginfo 348 28411 760740163
1 i postinstall 323 26475 751309908
1 i postremove 402 33179 751309945
1 i preinstall 321 26254 751310019
1 i preremove 320 26114 751309865
This is referred to as the traditional method because every package object is
installed to the base directory defined by the BASEDIR parameter from the pkginfo
file. For example, the first object in the pkgmap file is installed as
the directory /opt/SUNWstuf.
Absolute Packages
An absolute package is one that installs to a particular root (/) file system.
These packages are difficult to deal with from the standpoint of multiple versions
and architectures. As a general rule, all packages should be relocatable. There are,
however very good reasons to include absolute elements in a relocatable package.
Example-A Traditional Absolute Package
If the SUNWstuf package was an absolute package, the BASEDIR parameter should not
be defined in the pkginfo file, and the pkgmap file would look like this.
The pkgmap File
: 1 1758
1 d none /opt ? ? ?
1 d none /opt/SUNWstuf 0775 root bin
1 d none /opt/SUNWstuf/EZstuf 0775 root bin
1 f none /opt/SUNWstuf/EZstuf/dirdel 0555 bin bin 40 773 751310229
1 f none /opt/SUNWstuf/EZstuf/usrdel 0555 bin bin 40 773 751310229
1 f none /opt/SUNWstuf/EZstuf/filedel 0555 bin bin 40 773 751310229
1 d none /opt/SUNWstuf/HRDstuf 0775 root bin
1 f none /opt/SUNWstuf/HRDstuf/mksmart 0555 bin bin 40 773 751310229
1 f none /opt/SUNWstuf/HRDstuf/mktall 0555 bin bin 40 773 751310229
1 f none /opt/SUNWstuf/HRDstuf/mkcute 0555 bin bin 40 773 751310229
1 f none /opt/SUNWstuf/HRDstuf/mkeasy 0555 bin bin 40 773 751310229
1 i pkginfo 348 28411 760740163
1 i postinstall 323 26475 751309908
1 i postremove 402 33179 751309945
1 i preinstall 321 26254 751310019
1 i preremove 320 26114 751309865
In this example, if the administrator specified an alternate base directory during installation,
it would be ignored by the pkgadd command. This package always installs to
/opt/SUNWstuf of the target system.
The -R argument to the pkgadd command works as expected. For example,
pkgadd -d . -R /export/opt/client3 SUNWstuf
installs the objects in /export/opt/client3/opt/SUNWstuf; but that is the closest this package comes
to being relocatable.
Notice the use of the question mark (?) for the /opt directory
in the pkgmap file. This indicates that the existing attributes should not be
changed. It does not mean “create the directory with default attributes,” although under
certain circumstances that may happen. Any directory that is specific to the new
package must specify all attributes explicitly.
Composite Packages
Any package containing relocatable objects is referred to as a relocatable package. This
can be misleading because a relocatable package may contain absolute paths in its
pkgmap file. Using a root (/) entry in a pkgmap file can enhance the
relocatable aspects of the package. Packages that have both relocatable and root entries
are called composite packages.
Example-A Traditional Solution
Assume that one object in the SUNWstuf package is a startup script executed at
run level 2. The file /etc/rc2.d/S70dostuf needs to be installed as a part
of the package, but it cannot be placed into the base directory. Assuming
that a relocatable package is the only solution, the pkginfo and a pkgmap
might look like this.
The pkginfo File
# pkginfo file
PKG=SUNWstuf
NAME=software stuff
ARCH=sparc
VERSION=1.0.0,REV=1.0.5
CATEGORY=application
DESC=a set of utilities that do stuff
BASEDIR=/
VENDOR=Sun Microsystems, Inc.
HOTLINE=Please contact your local service provider
EMAIL=
MAXINST=1000
CLASSES=none
PSTAMP=hubert990707141632
The pkgmap File
: 1 1758
1 d none opt/SUNWstuf/EZstuf 0775 root bin
1 f none opt/SUNWstuf/EZstuf/dirdel 0555 bin bin 40 773 751310229
1 f none opt/SUNWstuf/EZstuf/usrdel 0555 bin bin 40 773 751310229
1 f none opt/SUNWstuf/EZstuf/filedel 0555 bin bin 40 773 751310229
1 d none opt/SUNWstuf/HRDstuf 0775 root bin
1 f none opt/SUNWstuf/HRDstuf/mksmart 0555 bin bin 40 773 751310229
1 f none opt/SUNWstuf/HRDstuf/mktall 0555 bin bin 40 773 751310229
1 f none opt/SUNWstuf/HRDstuf/mkcute 0555 bin bin 40 773 751310229
1 f none opt/SUNWstuf/HRDstuf/mkeasy 0555 bin bin 40 773 751310229
1 d none etc ? ? ?
1 d none etc/rc2.d ? ? ?
1 f none etc/rc2.d/S70dostuf 0744 root sys 450 223443
1 i pkginfo 348 28411 760740163
1 i postinstall 323 26475 751309908
1 i postremove 402 33179 751309945
1 i preinstall 321 26254 751310019
1 i preremove 320 26114 751309865
There is not much difference between this approach and that of the
absolute package. In fact, this would be better off as an absolute package—if the
administrator provided an alternate base directory for this package, it would not work!
In fact, only one file in this package needs to be root-relative,
the rest could be moved anywhere. How to solve this problem through the
use of a composite package is discussed throughout the remainder of this section.
Beyond Tradition
The approach described in this section does not apply to all packages, but
it does result in improved performance during installation to an heterogeneous environment. Very
little of this applies to packages that are delivered as part of the
Solaris operating environment (bundled packages); however, unbundled packages can practice non-traditional packaging.
The reason behind encouraging relocatable packages is to support this requirement:
When a package is added or removed, the existing desirable behaviors of installed software products will be unchanged.
Unbundled packages should reside under /opt so as to assure that the new
package does not interfere with existing products.
Another Look at Composite Packages
There are two rules to follow when constructing a functional composite package:
Establish the base directory based upon where the vast majority of the package objects go.
If a package object goes into a common directory that is not the base directory (for example, /etc), specify it as an absolute path name in the prototype file.
In other words, since “relocatable” means the object can be installed anywhere and
still work, no startup script run by init at boot time can be
considered relocatable! While there is nothing wrong with specifying /etc/passwd as a relative
path in the delivered package, there is only one place it can go.
Making Absolute Path Names Look Relocatable
If you are going to construct a composite package, the absolute paths must
operate in a manner which does not interfere with existing installed software. A
package that can be entirely contained in /opt gets around this problem since
there are no existing files in the way. When a file in /etc
is included in the package, you must ensure that the absolute path names
behave in the same way that is expected from relative path names. Consider
the following two examples.
Example—Modifying a File
Description
An entry is being added to a table, or the object is
a new table which is likely to be modified by other programs or
packages.
Implementation
Define the object as file type e and belonging to the build, awk,
or sed class. The script that performs this task must remove itself as
effectively as it adds itself.
Example
An entry needs to be added to /etc/vfstab in support of the new
solid state hard disk.
The entry in the pkgmap file might be
1 e sed /etc/vfstab ? ? ?
The request script asks the operator if /etc/vfstab should be modified by
the package. If the operator answers “no” then the request script will print
instructions on how to do the job manually and will execute
echo "CLASSES=none" >> $1
If the operator answers “yes” then it executes
echo "CLASSES=none sed" >> $1
which activates the class action script that will make the necessary modifications. The
sed class means that the package file /etc/vfstab is a sed program
which contains both the install and remove operations for the same-named file on
the target system.
Example—Creating a New File
Description
The object is an entirely new file that is unlikely to be
edited at a later time or, it is replacing a file owned by
another package.
Implementation
Define the package object as file type f and install it using a
class action script capable of undoing the change.
Example
A brand new file is required in /etc to provide the necessary information
to support the solid state hard disk, named /etc/shdisk.conf. The entry in
the pkgmap file might look like this:
.
.
.
1 f newetc /etc/shdisk.conf
.
.
.
The class action script i.newetc is responsible for installing this and any other
files that need to go into /etc. It checks to make sure there
is not another file there. If there is not, it will simply copy
the new file into place. If there is already a file in
place, it will back it up before installing the new file. The script
r.newetc removes these files and restores the originals, if required. Here is the
key fragment of the install script.
# i.newetc
while read src dst; do
if [ -f $dst ]; then
dstfile=`basename $dst`
cp $dst $PKGSAV/$dstfile
fi
cp $src $dst
done
if [ "${1}" = "ENDOFCLASS" ]; then
cd $PKGSAV
tar cf SAVE.newetc .
$INST_DATADIR/$PKG/install/squish SAVE.newetc
fi
Notice that this script uses the PKGSAV environment variable to store a backup
of the file to be replaced. When the argument ENDOFCLASS is passed
to the script, that is the pkgadd command informing the script that these
are the last entries in this class, at which point the script archives
and compresses the files that were saved using a private compression program stored
in the install directory of the package.
While the use of the PKGSAV environment variable is not reliable during a package
update; if the package is not updated (through a patch, for instance) the
backup file is secure. The following remove script includes code to deal with
the other issue—the fact that older versions of the pkgrm command do
not pass the scripts the correct path to the PKGSAV environment variable.
The removal script might look like this.
# r.newetc
# make sure we have the correct PKGSAV
if [ -d $PKG_INSTALL_ROOT$PKGSAV ]; then
PKGSAV="$PKG_INSTALL_ROOT$PKGSAV"
fi
# find the unsquish program
UNSQUISH_CMD=`dirname $0`/unsquish
while read file; do
rm $file
done
if [ "${1}" = ENDOFCLASS ]; then
if [ -f $PKGSAV/SAVE.newetc.sq ]; then
$UNSQUISH_CMD $PKGSAV/SAVE.newetc
fi
if [ -f $PKGSAV/SAVE.newetc ]; then
targetdir=dirname $file # get the right directory
cd $targetdir
tar xf $PKGSAV/SAVE.newetc
rm $PKGSAV/SAVE.newetc
fi
fi
This script uses a private uninstalled algorithm (unsquish) which is in the install
directory of the package database. This is done automatically by the pkgadd command
at install time. All scripts not specifically recognized as install-only by the pkgadd
command are left in this directory for use by the pkgrm command. You cannot
count on where that directory is, but you can depend on the
directory being flat and containing all appropriate information files and installation scripts for the
package. This script finds the directory by virtue of the fact that the
class action script is guaranteed to be executing from the directory that contains
the unsquish program.
Notice, also, that this script does not just assume the target directory is
/etc. It may actually be /export/root/client2/etc. The correct directory could be constructed
in one of two ways.
Use the ${PKG_INSTALL_ROOT}/etc construction, or
Take the directory name of a file passed by the pkgadd command (which is what this script does).
By using this approach for each absolute object in the package, you can
be sure that the current desirable behavior is unchanged or at least
recoverable.
Example—A Composite Package
This is an example of the pkginfo and pkgmap files for a composite package.
The pkginfo File
PKG=SUNWstuf
NAME=software stuff
ARCH=sparc
VERSION=1.0.0,REV=1.0.5
CATEGORY=application
DESC=a set of utilities that do stuff
BASEDIR=/opt
VENDOR=Sun Microsystems, Inc.
HOTLINE=Please contact your local service provider
EMAIL=
MAXINST=1000
CLASSES=none daemon
PSTAMP=hubert990707141632
The pkgmap File
: 1 1758
1 d none SUNWstuf/EZstuf 0775 root bin
1 f none SUNWstuf/EZstuf/dirdel 0555 bin bin 40 773 751310229
1 f none SUNWstuf/EZstuf/usrdel 0555 bin bin 40 773 751310229
1 f none SUNWstuf/EZstuf/filedel 0555 bin bin 40 773 751310229
1 d none SUNWstuf/HRDstuf 0775 root bin
1 f none SUNWstuf/HRDstuf/mksmart 0555 bin bin 40 773 751310229
1 f none SUNWstuf/HRDstuf/mktall 0555 bin bin 40 773 751310229
1 f none SUNWstuf/HRDstuf/mkcute 0555 bin bin 40 773 751310229
1 f none SUNWstuf/HRDstuf/mkeasy 0555 bin bin 40 773 751310229
1 d none /etc ? ? ?
1 d none /etc/rc2.d ? ? ?
1 e daemon /etc/rc2.d/S70dostuf 0744 root sys 450 223443
1 i i.daemon 509 39560 752978103
1 i pkginfo 348 28411 760740163
1 i postinstall 323 26475 751309908
1 i postremove 402 33179 751309945
1 i preinstall 321 26254 751310019
1 i preremove 320 26114 751309865
1 i r.daemon 320 24573 742152591
While S70dostuf belongs to the daemon class, the directories that lead up to
it (which are already in place at install time) belong to the none
class. Even if the directories were unique to this package, you should leave
them in the none class. The reason for this is that the directories
need to be created first and deleted last, and this is always true
for the none class. The pkgadd command creates directories; they are not
copied from the package and they are not passed to a class action
script to be created. Instead, they are created by the pkgadd command before
it calls the install class action script, and the pkgrm command deletes directories after
completion of the removal class action script.
This means that if a directory in a special class contains objects in
the class none, when the pkgrm command attempts to remove the directory,
it fails because the directory will not be empty in time. If an
object of class none is to be inserted into a directory of some
special class, that directory will not exist in time to accept the object.
The pkgadd command will create the directory on-the-fly during installation of the object
and may not be able to synchronize the attributes of that directory when
it finally sees the pkgmap definition.
Note - When assigning a directory to a class, always remember the order of creation
and deletion.