Application Packaging Developer's Guide
검색에만이 책은
PDF로 이 문서 다운로드 (433 KB)

Chapter 5 Package Creation Case Studies

This chapter provides case studies to show packaging scenarios such as installing objects conditionally, determining at run time how many files to create, and modifying an existing data file during package installation and removal.

Each case study begins with a description, followed by a list of the packaging techniques used, a narrative description of the approach taken when using those techniques, and sample files and scripts associated with the case study.

This is a list of the case studies in this chapter:

Soliciting Input From the Administrator

The package in this case study has three types of objects. The administrator may choose which of the three types to install and where to locate the objects on the installation machine.

Techniques

This case study demonstrates the following techniques:

  • Using parametric path names (variables in object path names) that are used to establish multiple base directories

    For information on parametric path names, see "Parametric Path Names".

  • Using a request script to solicit input from the administrator

    For information on request scripts, see "Writing a request Script".

  • Setting conditional values for an installation parameter

Approach

To set up the selective installation in this case study, you must complete the following tasks:

  • Define a class for each type of object that can be installed.

    In this case study, the three object types are the package executables, the man pages, and the emacs executables. Each type has its own class: bin, man, and emacs, respectively. Notice that in the prototype file all the object files belong to one of these three classes.

  • Initialize the CLASSES parameter in the pkginfo file to null.

    Normally when you define a class, you should list that class in the CLASSES parameter in the pkginfo file. Otherwise, no objects in that class are installed. For this case study, the parameter is initially set to null, which means no objects will get installed. The CLASSES parameter will be changed by the request script, based on the choices of the administrator. This way, the CLASSES parameter is set to only those object types that the administrator wants installed.


    Note -

    Usually it is a good idea to set parameters to a default value. If this package had components common to all three object types, you could assign them to the none class, and then set the CLASSES parameter equal to none.


  • Insert parametric path names into the prototype file.

    The request script sets these environment variables to the value that the administrator provides. Then, the pkgadd command resolves these environment variables at installation time and knows where to install the package.

    The three environment variables used in this example are set to their default in the pkginfo file and serve the following purposes:

    • $NCMPBIN defines the location for object executables

    • $NCMPMAN defines the location for man pages

    • $EMACS defines the location for emacs executables

    The example prototype file shows how to define the object path names with variables.

  • Create a request script to ask the administrator which parts of the package should be installed and where they should be placed.

    The request script for this package asks the administrator two questions:

    • Should this part of the package be installed?

      When the answer is yes, the appropriate class name is added to the CLASSES parameter. For example, when the administrator chooses to install the man pages associated with this package, the class man is added to the CLASSES parameter.

    • If so, where should this part of the package be placed?

      The appropriate environment variable is set to the response to this question. In the man page example, the variable $NCMPMAN is set to the response value.

    These two questions are repeated for each of the three object types.

    At the end of the request script, the parameters are made available to the installation environment for the pkgadd command and any other packaging scripts. The request script does this by writing these definitions to the file provided by the calling utility. For this case study, no other scripts are provided.

    When looking at the request script for this case study, notice that the questions are generated by the data validation tools ckyorn and ckpath. For more information on these tools see the ckyorn(1) and ckpath(1) man pages.

Case Study Files

The pkginfo File

PKG=ncmp
NAME=NCMP Utilities
CATEGORY=application, tools
BASEDIR=/
ARCH=SPARC
VERSION=RELEASE 1.0, Issue 1.0
CLASSES=""
NCMPBIN=/bin
NCMPMAN=/usr/man
EMACS=/usr/emacs

The prototype File

i pkginfo
i request
x bin $NCMPBIN 0755 root other
f bin $NCMPBIN/dired=/usr/ncmp/bin/dired 0755 root other
f bin $NCMPBIN/less=/usr/ncmp/bin/less 0755 root other
f bin $NCMPBIN/ttype=/usr/ncmp/bin/ttype 0755 root other
f emacs $NCMPBIN/emacs=/usr/ncmp/bin/emacs 0755 root other
x emacs $EMACS 0755 root other
f emacs $EMACS/ansii=/usr/ncmp/lib/emacs/macros/ansii 0644 root other
f emacs $EMACS/box=/usr/ncmp/lib/emacs/macros/box 0644 root other
f emacs $EMACS/crypt=/usr/ncmp/lib/emacs/macros/crypt 0644 root other
f emacs $EMACS/draw=/usr/ncmp/lib/emacs/macros/draw 0644 root other
f emacs $EMACS/mail=/usr/ncmp/lib/emacs/macros/mail 0644 root other
f emacs $NCMPMAN/man1/emacs.1=/usr/ncmp/man/man1/emacs.1 0644 root other
d man $NCMPMAN 0755 root other
d man $NCMPMAN/man1 0755 root other
f man $NCMPMAN/man1/dired.1=/usr/ncmp/man/man1/dired.1 0644 root other
f man $NCMPMAN/man1/ttype.1=/usr/ncmp/man/man1/ttype.1 0644 root other
f man $NCMPMAN/man1/less.1=/usr/ncmp/man/man1/less.1 0644 inixmr other

The request Script

trap 'exit 3' 15
# determine if and where general executables should be placed
ans=`ckyorn -d y \
-p "Should executables included in this package be installed"
` || exit $?
if [ "$ans" = y ]
then
   CLASSES="$CLASSES bin"
   NCMPBIN=`ckpath -d /usr/ncmp/bin -aoy \
   -p "Where should executables be installed"
   ` || exit $?
fi
# determine if emacs editor should be installed, and if it should
# where should the associated macros be placed
ans=`ckyorn -d y \
-p "Should emacs editor included in this package be installed"
` || exit $?
if [ "$ans" = y ]
then
   CLASSES="$CLASSES emacs"
   EMACS=`ckpath -d /usr/ncmp/lib/emacs -aoy \
   -p "Where should emacs macros be installed"
   ` || exit $?
fi

Note that a request script can exit without leaving any files on the file system. For installations on Solaris versions prior to 2.5 (where no checkinstall script may be used) the request script is the correct place to test the file system in any manner necessary to ensure that the installation will succeed. When the request script exits with code 1, the installation will quit cleanly.

These example files show the use of parametric paths to establish multiple base directories. However, the preferred method involves use of the BASEDIR parameter which is managed and validated by the pkgadd command. Whenever multiple base directories are used, take special care to provide for installation of multiple versions and architectures on the same platform.

Creating a File at Installation and Saving It During Removal

This case study creates a database file at installation time and saves a copy of the database when the package is removed.

Techniques

This case study demonstrates the following techniques:

  • Using classes and class action scripts to perform special actions on different sets of objects

    For more information, see "Writing Class Action Scripts".

  • Using the installf command to install a file not defined in the prototype and pkgmap files

Approach

To create a database file at installation and save a copy on removal for this case study, you must complete the following tasks:

  • Define three classes.

    The package in this case study requires the following three classes be defined in the CLASSES parameter:

    • The standard class of none, which contains a set of processes belonging in the subdirectory bin.

    • The admin class, which contains an executable file config and a directory containing data files.

    • The cfgdata class, which contains a directory.

  • Make the package collectively relocatable.

    Notice in the prototype file that none of the path names begins with a slash or an environment variable. This indicates that they are collectively relocatable.

  • Calculate the amount of space the database file requires and create a space file to deliver with the package. This file notifies the pkgadd command that the package requires extra space and specifies how much.

  • Create a class action script for the admin class (i.admin).

    The sample script initializes a database using the data files belonging to the admin class. To perform this task, it does the following:

    • Copies the source data file to its proper destination

    • Creates an empty file named config.data and assigns it to a class of cfgdata

    • Executes the bin/config command (delivered with the package and already installed) to populate the database file config.data using the data files belonging to the admin class

    • Executes the installf -f command to finalize installation of config.data

    No special action is required for the admin class at removal time so no removal class action script is created. This means that all files and directories in the admin class are removed from the system.

  • Create a removal class action script for the cfgdata class (r.cfgdata).

    The removal script makes a copy of the database file before it is deleted. No special action is required for this class at installation time, so no installation class action script is needed.

    Remember that the input to a removal script is a list of path names to remove. Path names always appear in reverse alphabetical order. This removal script copies files to the directory named $PKGSAV. When all the path names have been processed, the script then goes back and removes all directories and files associated with the cfgdata class.

    The outcome of this removal script is to copy config.data to $PKGSAV and then remove the config.data file and the data directory.

Case Study Files

The pkginfo File

PKG=krazy
NAME=KrAzY Applications
CATEGORY=applications
BASEDIR=/opt
ARCH=SPARC
VERSION=Version 1
CLASSES=none cfgdata admin

The prototype File

i pkginfo
i request
i i.admin
i r.cfgdata
d none bin 555 root sys
f none bin/process1 555 root other
f none bin/process2 555 root other
f none bin/process3 555 root other
f admin bin/config 500 root sys
d admin cfg 555 root sys
f admin cfg/datafile1 444 root sys
f admin cfg/datafile2 444 root sys
f admin cfg/datafile3 444 root sys
f admin cfg/datafile4 444 root sys
d cfgdata data 555 root sys

The space File

# extra space required by config data which is
# dynamically loaded onto the system
data 500 1

The i.admin Class Action Script

# PKGINST parameter provided by installation service
# BASEDIR parameter provided by installation service
while read src dest
do
   cp $src $dest || exit 2
done
# if this is the last time this script will be executed
# during the installation, do additional processing here.
if [ "$1" = ENDOFCLASS ]
then
# our config process will create a data file based on any changes
# made by installing files in this class; make sure the data file
# is in class `cfgdata' so special rules can apply to it during
# package removal.
   installf -c cfgdata $PKGINST $BASEDIR/data/config.data f 444 root
   sys || exit 2
   $BASEDIR/bin/config > $BASEDIR/data/config.data || exit 2
   installf -f -c cfgdata $PKGINST || exit 2
fi
exit 0

This illustrates a rare instance in which installf is appropriate in a class action script. Because a space file has been used to reserve room on a specific file system, this new file may be safely added even though it is not included in the pkgmap file.

The r.cfgdata Removal Script

# the product manager for this package has suggested that
# the configuration data is so valuable that it should be
# backed up to $PKGSAV before it is removed!
while read path
do
# path names appear in reverse lexical order.
   mv $path $PKGSAV || exit 2
   rm -f $path || exit 2
done
exit 0

Defining Package Compatibilities and Dependencies

The package in this case study uses optional information files to define package compatibilities and dependencies, and to present a copyright message during installation.

Techniques

This case study demonstrates the following techniques:

  • Using the copyright file

  • Using the compver file

  • Using the depend file

For more information on these files, see "Creating Information Files".

Approach

To meet the requirements in the description, you must:

  • Create a copyright file.

    A copyright file contains the ASCII text of a copyright message. The message shown in the sample file is displayed on the screen during package installation.

  • Create a compver file.

    The pkginfo file shown in the next figure defines this package version as version 3.0. The compver file defines version 3.0 as being compatible with versions 2.3, 2.2, 2.1, 2.1.1, 2.1.3 and 1.7.

  • Create a depend file.

    Files listed in a depend file must already be installed on the system when a package is installed. The example file has 11 packages which must already be on the system at installation time.

Case Study Files

The pkginfo File

PKG=case3
NAME=Case Study #3
CATEGORY=application
BASEDIR=/opt
ARCH=SPARC
VERSION=Version 3.0
CLASSES=none

The copyright File

Copyright (c) 1996 company_name
All Rights Reserved.
THIS PACKAGE CONTAINS UNPUBLISHED PROPRIETARY SOURCE CODE OF
company_name.
The copyright notice above does not evidence any
actual or intended publication of such source code

The compver File

Version 3.0
Version 2.3
Version 2.2
Version 2.1
Version 2.1.1
Version 2.1.3
Version 1.7

The depend File

P acu Advanced C Utilities
Issue 4 Version 1
P cc C Programming Language
Issue 4 Version 1
P dfm Directory and File Management Utilities
P ed Editing Utilities
P esg Extended Software Generation Utilities
Issue 4 Version 1
P graph Graphics Utilities
P rfs Remote File Sharing Utilities
Issue 1 Version 1
P rx Remote Execution Utilities
P sgs Software Generation Utilities
Issue 4 Version 1
P shell Shell Programming Utilities
P sys System Header Files
Release 3.1

Modifying a File Using Standard Classes and Class Action Scripts

This case study modifies an existing file during package installation using standard classes and class action scripts. It uses one of three modification methods. The other two methods are described in "Modifying a File Using the sed Class and a postinstall Script" and "Modifying a File Using the build Class". The file modified is /sbin/inittab.

Techniques

This case study demonstrates how to use installation and removal class action scripts. For more information, see "Writing Class Action Scripts".

Approach

To modify /sbin/inittab during installation, using classes and class action scripts, you must complete the following tasks:

  • Create a class.

    Create a class called inittab. You must provide an installation and a removal class action script for this class. Define the inittab class in the CLASSES parameter in the pkginfo file.

  • Create an inittab file.

    This file contains the information for the entry that you will add to /sbin/inittab. Notice in the prototype file figure that inittab is a member of the inittab class and has a file type of e for editable.

  • Create an installation class action script (i.inittab).

    Remember that class action scripts must produce the same results each time they are executed. The class action script performs the following procedures:

    • Checks if this entry has been added before

    • If it has, removes any previous versions of the entry

    • Edits the inittab file and adds the comment lines so you know where the entry is from

    • Moves the temporary file back into /sbin/inittab

    • Executes the init q command when it receives the ENDOFCLASS indicator

    Note that the init q command can be performed by this installation script. A one-line postinstall script is not needed by this approach.

  • Create a removal class action script (r.inittab).

    The removal script is very similar to the installation script. The information added by the installation script is removed and the init q command is executed.

This case study is more complicated than the next one; see "Modifying a File Using the sed Class and a postinstall Script". Instead of providing two files, three are needed and the delivered /sbin/inittab file is actually just a place holder containing a fragment of the entry to be inserted. This could have been placed into the i.inittab file except that the pkgadd command must have a file to pass to the i.inittab file. Also, the removal procedure must be placed into a separate file (r.inittab). While this method works fine, it is best reserved for cases involving very complicated installations of multiple files. See "Modifying crontab Files During Installation".

The sed program used in "Modifying a File Using the sed Class and a postinstall Script" supports multiple package instances since the comment at the end of the inittab entry is based on package instance. The case study in "Modifying a File Using the build Class" shows a more streamlined approach to editing /sbin/inittab during installation.

Case Study Files

The pkginfo File

PKG=case5
NAME=Case Study #5
CATEGORY=applications
BASEDIR=/opt
ARCH=SPARC
VERSION=Version 1d05
CLASSES=inittab

The prototype File

i pkginfo
i i.inittab
i r.inittab
e inittab /sbin/inittab ? ? ?

The i.inittab Installation Class Action Script

# PKGINST parameter provided by installation service
while read src dest
do
# remove all entries from the table that
# associated with this PKGINST
sed -e "/^[^:]*:[^:]*:[^:]*:[^#]*#$PKGINST$/d" $dest >
/tmp/$$itab ||
exit 2
sed -e "s/$/#$PKGINST" $src >> /tmp/$$itab ||
exit 2
mv /tmp/$$itab $dest ||
exit 2
done
if [ "$1" = ENDOFCLASS ]
then
/sbin/init q ||
exit 2
fi
exit 0

The r.inittab Removal Class Action Script

# PKGINST parameter provided by installation service
while read src dest
do
# remove all entries from the table that
# are associated with this PKGINST
sed -e "/^[^:]*:[^:]*:[^:]*:[^#]*#$PKGINST$/d" $dest >
/tmp/$$itab ||
exit 2
mv /tmp/$$itab $dest ||
exit 2
done
/sbin/init q ||
exit 2
exit 0

The inittab File

rb:023456:wait:/usr/robot/bin/setup

Modifying a File Using the sed Class and a postinstall Script

This case study modifies a file which exists on the installation machine during package installation. It uses one of three modification methods. The other two methods are described in "Modifying a File Using Standard Classes and Class Action Scripts" and "Modifying a File Using the build Class". The file modified is /sbin/inittab.

Techniques

This case study demonstrates the following techniques:

Approach

To modify /sbin/inittab at the time of installation, using the sed class, you must complete the following tasks:

  • Add the sed class script to the prototype file.

    The name of a script must be the name of the file that will be edited. In this case, the file to be edited is /sbin/inittab and so the sed script is named /sbin/inittab. There are no requirements for the mode, owner, and group of a sed script (represented in the sample prototype by question marks). The file type of the sed script must be e (indicating that it is editable).

  • Set the CLASSES parameter to include the sed class.

    As shown in the example file, sed is the only class being installed. However, it could be one of any number of classes.

  • Create a sed class action script.

    Your package cannot deliver a copy of /sbin/inittab that looks the way you need it to, since /sbin/inittab is a dynamic file and you have no way of knowing how it will look at the time of package installation. However, using a sed script allows you to modify the /sbin/inittab file during package installation.

  • Create a postinstall script.

    You need to execute the init q command to inform the system that /sbin/inittab has been modified. The only place you can perform that action in this example is in a postinstall script. Looking at the example postinstall script, you will see that its only purpose is to execute the init q command.

This approach to editing /sbin/inittab during installation has one drawback; you have to deliver a full script (the postinstall script) simply to perform the init q command.

Case Study Files

The pkginfo File

PKG=case4
NAME=Case Study #4
CATEGORY=applications
BASEDIR=/opt
ARCH=SPARC
VERSION=Version 1d05
CLASSES=sed

The prototype File

i pkginfo
i postinstall
e sed /sbin/inittab ? ? ?

The sed Class Action Script (/sbin/inittab)

!remove
# remove all entries from the table that are associated
# with this package, though not necessarily just
# with this package instance
/^[^:]*:[^:]*:[^:]*:[^#]*#ROBOT$/d
!install
# remove any previous entry added to the table
# for this particular change
/^[^:]*:[^:]*:[^:]*:[^#]*#ROBOT$/d
# add the needed entry at the end of the table;
# sed(1) does not properly interpret the '$a'
# construct if you previously deleted the last
# line, so the command
# $a\
# rb:023456:wait:/usr/robot/bin/setup #ROBOT
# will not work here if the file already contained
# the modification. Instead, you will settle for
# inserting the entry before the last line!
$i\
rb:023456:wait:/usr/robot/bin/setup #ROBOT

The postinstall Script

# make init re-read inittab
/sbin/init q ||
exit 2
exit 0

Modifying a File Using the build Class

This case study modifies a file which exists on the installation machine during package installation. It uses one of three modification methods. The other two methods are described in "Modifying a File Using Standard Classes and Class Action Scripts" and "Modifying a File Using the sed Class and a postinstall Script". The file modified is /sbin/inittab.

Techniques

This case study demonstrates how to use the build class. For more information on the build class, see "The build Class Script ".

Approach

This approach to modifying /sbin/inittab uses the build class. A build class script is executed as a shell script and its output becomes the new version of the file being executed. In other words, the data file /sbin/inittab that is delivered with this package will be executed and the output of that execution will become /sbin/inittab.

The build class script is executed during package installation and package removal. The argument install is passed to the file if it is being executed at installation time. Notice in the sample build class script that installation actions are defined by testing for this argument.

To edit /sbin/inittab using the build class, you must complete the following tasks:

  • Define the build file in the prototype file.

    The entry for the build file in the prototype file should place it in the build class and define its file type as e. Be certain that the CLASSES parameter in the pkginfo file is defined as build.

  • Create the build class script.

    The sample build class script performs the following procedures:

    • Edits the /sbin/inittab file to remove any existing changes for this package. Notice that the file name /sbin/inittab is hardcoded into the sed command.

    • If the package is being installed, adds the new line to the end of /sbin/inittab. A comment tag is included in this new entry to describe where that entry came from.

    • Executes the init q command.

This solution addresses the drawbacks described in the case studies in "Modifying a File Using Standard Classes and Class Action Scripts" and "Modifying a File Using the sed Class and a postinstall Script". Only one short file is needed (beyond the pkginfo and prototype files). The file works with multiple instances of a package since the PKGINST parameter is used, and no postinstall script is required since the init q command can be executed from the build class script.

Case Study Files

The pkginfo File

PKG=case6
NAME=Case Study #6
CATEGORY=applications
BASEDIR=/opt
ARCH=SPARC
VERSION=Version 1d05
CLASSES=build

The prototype File

i pkginfo
e build /sbin/inittab ? ? ?

The Build File

# PKGINST parameter provided by installation service
# remove all entries from the existing table that
# are associated with this PKGINST
sed -e "/^[^:]*:[^:]*:[^:]*:[^#]*#$PKGINST$/d" /sbin/inittab ||
exit 2
if [ "$1" = install ]
then
# add the following entry to the table
echo "rb:023456:wait:/usr/robot/bin/setup #$PKGINST" ||
exit 2
fi
/sbin/init q ||
exit 2
exit 0

Modifying crontab Files During Installation

This case study modifies crontab files during package installation.

Techniques

This case study demonstrates the following techniques:

  • Using the crontab command within a class action script

Approach

The most efficient way to edit more than one file during installation is to define a class and provide a class action script. If you used the build class approach, you would need to deliver one build class script for each crontab file edited. Defining a cron class provides a more general approach. To edit crontab files with this approach, you must:

  • Define the crontab files that are to be edited in the prototype file.

    Create an entry in the prototype file for each crontab file that will be edited. Define the class as cron and the file type as e for each file. Use the actual name of the file to be edited.

  • Create the crontab files for the package.

    These files contain the information you want added to the existing crontab files of the same name.

  • Create an installation class action script for the cron class.

    The sample i.cron script performs the following procedures:

    • Determines the user ID (UID).

      The i.cron script sets the variable user to the base name of the cron class script being processed. That name is the UID. For example, the base name of /var/spool/cron/crontabs/root is root, which is also the UID.

    • Executes crontab using the UID and the -l option.

      Using the -l option tells crontab to send the contents of the crontab file for the defined user to the standard output.

    • Pipes the output of the crontab command to a sed script that removes any previous entries added with this installation technique.

    • Puts the edited output into a temporary file.

    • Adds the data file for the root UID (that was delivered with the package) to the temporary file and adds a tag so you will know where these entries came from.

    • Executes crontab with the same UID and gives it the temporary file as input.

  • Create a removal class action script for the cron class.

    The r.cron script is the same as the installation script except there is no procedure to add information to the crontab file.

    These procedures are performed for every file in the cron class.

Case Study Files

The pkginfo Command

PKG=case7
NAME=Case Study #7
CATEGORY=application
BASEDIR=/opt
ARCH=SPARC
VERSION=Version 1.0
CLASSES=cron

The prototype File

i pkginfo
i i.cron
i r.cron
e cron /var/spool/cron/crontabs/root ? ? ?
e cron /var/spool/cron/crontabs/sys ? ? ?

The i.cron Installation Class Action Script

# PKGINST parameter provided by installation service
while read src dest
do
user=`basename $dest` ||
exit 2
(crontab -l $user |
sed -e "/#$PKGINST$/d" > /tmp/$$crontab) ||
exit 2
sed -e "s/$/#$PKGINST/" $src >> /tmp/$$crontab ||
exit 2
crontab $user < /tmp/$$crontab ||
exit 2
rm -f /tmp/$$crontab
done
exit 0

The r.cron Removal Class Action Script

# PKGINST parameter provided by installation service
while read path
do
user=`basename $path` ||
exit 2
(crontab -l $user |
sed -e "/#$PKGINST$/d" > /tmp/$$crontab) ||
exit 2
crontab $user < /tmp/$$crontab ||
exit 2
rm -f /tmp/$$crontab
done
exit 

crontab File #1

41,1,21 * * * * /usr/lib/uucp/uudemon.hour > /dev/null
45 23 * * * ulimit 5000; /usr/bin/su uucp -c
"/usr/lib/uucp/uudemon.cleanup" >
/dev/null 2>&1
11,31,51 * * * * /usr/lib/uucp/uudemon.poll > /dev/null

crontab File #2

0 * * * 0-6 /usr/lib/sa/sa1
20,40 8-17 * * 1-5 /usr/lib/sa/sa1
5 18 * * 1-5 /usr/lib/sa/sa2 -s 8:00 -e 18:01 -i 1200 -A

Note -

If editing of a group of files will increase total file size by more than 10K, supply a space file so the pkgadd command can allow for this increase. For more information on the space file, see "Reserving Additional Space on a Target System".


Installing and Removing a Driver With Procedure Scripts

This package installs a driver.

Techniques

This case study demonstrates the following techniques:

  • Installing and loading a driver with a postinstall script

  • Unloading a driver with a preremove script

For more information on these scripts, see "Writing Procedure Scripts".

Approach

  • Create a request script.

    The request script determines where the administrator wants the driver objects to be installed, by questioning the administrator and assigning the answer to the $KERNDIR parameter.

    The script ends with a routine to make the two parameters CLASSES and KERNDIR available to the installation environment and the postinstall script.

  • Create a postinstall script.

    The postinstall script actually performs the driver installation. It is executed after the two files buffer and buffer.conf have been installed. The postinstall file shown for this example performs the following actions:

    • Uses the add_drv command to load the driver into the system

    • Creates a link for the device using the installf command

    • Finalizes the installation using the installf -f command

  • Create a preremove script.

    The preremove script uses the rem_drv command to unload the driver from the system, and then removes the link /dev/buffer0.

Case Study Files

The pkginfo File

PKG=bufdev
NAME=Buffer Device
CATEGORY=system
BASEDIR=/
ARCH=INTEL
VERSION=Software Issue #19
CLASSES=none

The prototype File

To install a driver at the time of installation, you must include the object and configuration files for the driver in the prototype file.

In this example, the executable module for the driver is named buffer; the add_drv command operates on this file. The kernel uses the configuration file, buffer.conf, to help configure the driver.

i pkginfo
i request
i postinstall
i preremove
f none $KERNDIR/buffer 444 root root
f none $KERNDIR/buffer.conf 444 root root

Looking at the prototype file for this example, notice the following:

  • Since no special treatment is required for the package objects, you can put them into the standard none class. The CLASSES parameter is set to none in the pkginfo file.

  • The path names for buffer and buffer.conf begin with the variable $KERNDIR. This variable is set in the request script and allows the administrator to decide where the driver files should be installed. The default directory is /kernel/drv.

  • There is an entry for the postinstall script (the script that will perform the driver installation).

  • Note that a BASEDIR is specified even though this is an absolute package. This is because the pkgadd command does not know that $KERNDIR is going to resolve to an absolute path until after the BASEDIR has been evaluated.

The request Script

trap 'exit 3' 15
# determine where driver object should be placed; location
# must be an absolute path name that is an existing directory
KERNDIR=`ckpath -aoy -d /kernel/drv -p \
"Where do you want the driver object installed"` || exit $?

# make parameters available to installation service, and
# so to any other packaging scripts
cat >$1 <<!

CLASSES='$CLASSES'
KERNDIR='$KERNDIR'
!
exit 0

The postinstall Script

# KERNDIR parameter provided by `request' script
err_code=1                    # an error is considered fatal
# Load the module into the system
cd $KERNDIR
add_drv -m '* 0666 root sys' buffer || exit $err_code
# Create a /dev entry for the character node
installf $PKGINST /dev/buffer0=/devices/eisa/buffer*:0 s
installf -f $PKGINST

The preremove Script

err_code=1                    # an error is considered fatal
# Unload the driver
rem_drv buffer || exit $err_code
# remove /dev file
removef $PKGINST /dev/buffer0 ; rm /dev/buffer0
removef -f $PKGINST

Installing a Driver Using the sed Class and Procedure Scripts

This case study describes how to install a driver using the sed class and procedure scripts. It is also different from the previous case study (see "Installing and Removing a Driver With Procedure Scripts") because this package is made up of both absolute and relocatable objects.

Techniques

This case study demonstrates the following techniques:

  • Building a prototype file with both absolute and relocatable objects

    For more information on building a prototype file, see "Creating a prototype File".

Approach

  • Create a prototype file containing both absolute and relocatable package objects.

    This is discussed in detail in "The prototype File".

  • Add the sed class script to the prototype file.

    The name of a script must be the name of the file that will be edited. In this case, the file to be edited is /etc/devlink.tab and so the sed script is named /etc/devlink.tab. There are no requirements for the mode, owner, and group of a sed script (represented in the sample prototype by question marks). The file type of the sed script must be e (indicating that it is editable).

  • Set the CLASSES parameter to include the sed class.

  • Create a sed class action script (/etc/devlink.tab).

  • Create a postinstall script.

    The postinstall script needs to execute the add_drv command to add the device driver to the system.

  • Create a preremove script.

    The preremove script needs to execute the rem_drv command to remove the device driver from the system, prior to the package being removed.

  • Create a copyright file.

    A copyright file contains the ASCII text of a copyright message. The message shown in the sample file is displayed on the screen during package installation.

Case Study Files

The pkginfo File

PKG=SUNWsst
NAME=Simple SCSI Target Driver
VERSION=1
CATEGORY=system
ARCH=sparc
VENDOR=Sun Microsystems
BASEDIR=/opt
CLASSES=sed

The prototype File

For example, this case study uses the hierarchical layout of the package objects shown in Figure 5-1.

Figure 5-1 Hierarchical Package Directory Structure

그래픽

The package objects are installed in the same places as they are in the pkg directory above. The driver modules (sst and sst.conf) are installed into /usr/kernel/drv and the include file is installed into /usr/include/sys/scsi/targets. The sst, sst.conf, and sst_def.h files are absolute objects. The test program, sstest.c, and its directory SUNWsst are relocatable; their installation location is set by the BASEDIR parameter.

The remaining components of the package (all the control files) go in the top directory of the package on the development machine, except the sed class script. This is called devlink.tab after the file it modifies, and goes into etc, the directory containing the real devlink.tab file.

From the pkg directory, run the pkgproto command as follows:


find usr SUNWsst -print | pkgproto > prototype

The output from the above command looks like this:

d none usr 0775 pms mts
d none usr/include 0775 pms mts
d none usr/include/sys 0775 pms mts
d none usr/include/sys/scsi 0775 pms mts
d none usr/include/sys/scsi/targets 0775 pms mts
f none usr/include/sys/scsi/targets/sst_def.h 0444 pms mts
d none usr/kernel 0775 pms mts
d none usr/kernel/drv 0775 pms mts
f none usr/kernel/drv/sst 0664 pms mts
f none usr/kernel/drv/sst.conf 0444 pms mts
d none SUNWsst 0775 pms mts
f none SUNWsst/sstest.c 0664 pms mts

This prototype file is not yet complete. To complete this file, you need to make the following modifications:

  • Insert the entries for the control files (file type i), because they have a different format than the other package objects.

  • Remove entries for directories that already exist on the target system.

  • Change the access permission and ownership for each entry.

  • Prepend a slash to the absolute package objects.

This is the final prototype file:

i pkginfo
i postinstall
i preremove
i copyright
e sed /etc/devlink.tab ? ? ?
f none /usr/include/sys/scsi/targets/sst_def.h 0644 bin bin
f none /usr/kernel/drv/sst 0755 root sys
f none /usr/kernel/drv/sst.conf 0644 root sys
d none SUNWsst 0775 root sys
f none SUNWsst/sstest.c 0664 root sys

The questions marks in the entry for the sed script indicate that the access permissions and ownership of the existing file on the installation machine should not be changed.

The sed Class Action Script (/etc/devlink.tab)

In the driver example, a sed class script is used to add an entry for the driver to the file /etc/devlink.tab. This file is used by the devlinks command to create symbolic links from /dev into /devices. This is the sed script:

# sed class script to modify /etc/devlink.tab
!install
/name=sst;/d
$i\
type=ddi_pseudo;name=sst;minor=character	rsst\\A1

!remove
/name=sst;/d

The pkgrm command does not run the removal part of the script. You may need to add a line to the preremove script to run sed directly to remove the entry from /etc/devlink.tab.

The postinstall Installation Script

In this example, all the script needs to do is run the add_drv command.

# Postinstallation script for SUNWsst
# This does not apply to a client.
if [$PKG_INSTALL_ROOT = "/" -o -z $PKG_INSTALL_ROOT]; then
   SAVEBASE=$BASEDIR
   BASEDIR=""; export BASEDIR
   /usr/sbin/add_drv sst
   STATUS=$?
   BASEDIR=$SAVEBASE; export BASEDIR
   if [ $STATUS -eq 0 ]
   then
	     exit 20
   else
	     exit 2
   fi
else
   echo "This cannot be installed onto a client."
   exit 2
fi

Note -

This example will probably not work correctly if you install it onto a diskless client from a server, since there is no reliable way to run the add_drv and rem_drv commands on that client from the pkgadd command executing on the server. You may be better off splitting the package on the root (/) and /usr boundaries.


The add_drv command uses the BASEDIR parameter, so the script has to unset BASEDIR before running the command, and restore it afterwards.

One of the actions of the add_drv command is to run devlinks, which uses the entry placed in /etc/devlink.tab by the sed class script to create the /dev entries for the driver.

The exit code from the postinstall script is significant. The exit code 20 tells the pkgadd command to tell the user to reboot the system (necessary after installing a driver), and the exit code 2 tells the pkgadd command to tell the user that the installation partially failed.

The preremove Removal Script

In the case of this driver example, it removes the links in /dev and runs the rem_drv command on the driver.

# Pre removal script for the sst driver
echo "Removing /dev entries"
/usr/bin/rm -f /dev/rsst*

echo "Deinstalling driver from the kernel"
SAVEBASE=$BASEDIR
BASEDIR=""; export BASEDIR
/usr/sbin/rem_drv sst
BASEDIR=$SAVEBASE; export BASEDIR

exit 

The script removes the /dev entries itself; the /devices entries are removed by the rem_drv command.

The copyright File

This is a simple ASCII file containing the text of a copyright notice. The notice is displayed at the beginning of package installation exactly as it appears in the file.


	Copyright (c) 1996 Drivers-R-Us, Inc.
	10 Device Drive, Thebus, IO 80586

All rights reserved. This product and related documentation is
protected by copyright and distributed under licenses 
restricting its use, copying, distribution and decompilation. 
No part of this product or related documentation may be 
reproduced in any form by any means without prior written 
authorization of Drivers-R-Us and its licensors, if any.