The pmcheck framework is extensible, as the set of known components is defined by the names of the
component scripts in the $PCP_SHARE_DIR/lib/pmcheck directory.
Each component script needs to abide by the following rules for correct integration with pmcheck:
• The script will be run with sh(1), if you need some other scripting language then you must provide a
sh(1) wrapper.
• Since each script is responsible for one component, the name of the component is implied, however the
name of the component is also passed from pmcheck as the sole argument after the options. This allows
generic component scripts to be implemented as hard links below $PCP_SHARE_DIR/lib/pmcheck.
• When called with a -l, --list option the script does nothing, unless it is also called with a -v option
in which case a short description of the component is displayed on standard output.
• When called with a -s, --state option, the script must exit with the an exit code that indicates the
component's state, namely 0 (active), 1 (inactive, but could be activated by pmcheck), 2 (inactive and
cannot be activated by pmcheck). The distinction between exit codes 1 and 2 is based on many factors,
but 1 usually means all of the required software packages (PCP and other) are installed, required
prerequisite services are running or could be safely started, and any component configuration can
assume default settings or can be reliably deduced, e.g. a port number for communications. Conversely,
2 means automatic activation of the component is not possible and some end-user intervention is
required.
• When called with a -a, --activate option the script must activate the component. This means making any
required configuration change so that it is restarted at the next system reboot or pmcd(1) restart, and
starting the component if it is currently inactive,
• When called with a -d, --deactivate option the script must deactivate the component. This means
stopping the component if it is currently active, and making any required configuration change so that
it isnot restarted at the next system reboot or pmcd(1) restart.
• When called with a -n, --show-me option the script must perform a dry run and echo any required
commands on standard output as per the rules described above for the -n option of pmcheck.
• If a -v, --verbose option is also specified, the script should provide explanatory text on standard
output to help explain, particularly in cases where the component is not active or the reconfiguration
failed.
To assist with component script development, the file $PCP_SHARE_DIR/lib/checkproc.sh may be sourced
(after sourcing $PCP_DIR/etc/pcp.env). checkproc.sh provides the following services:
• A temporary directory is created and the shell variable $tmp is assigned to the full pathname of the
directory.
• The shell variable $status is used to return the exit status from the script [defaults to 0].
• The shell variable $component is assigned to the associated component name.
• The shell variable $prog is assigned to the script's basename (so the component name in the default
case).
• A trap is installed to cleanup $tmp and exit with $status.
• A _do_args shell procedure that handles all command argument parsing.
• Shell variables $aflag, $dflag, $lflag or $sflag have default values of false and are set to true by
_do_args when the -a, -d, -l or -s options are parsed.
• The shell variable $show_me has the default value of false and is set to true by _do_args when the -n
option is parsed.
• The shell variable $verbose counts number of -v options parsed by _do_args.
• A _ctl_svc shell procedure that handles status requests and all reconfiguration operations for services
that are managed by systemctl(1) or init(1) or similar infrastructure layers. _ctl_svc takes 2
arguments, the first is an action (one of state, start, stop, activate (enable and start), or
deactivate (stop and disable), and the second is the name of the component; for systemctl(1) managed
components, name should be the basename of the service, e.g. pmcd for the pmcd.servicesystemd(1)
unit, otherwise name is the name of the init(1) or similar ``rc'' script.
• _ctl_svc will return a value (via $? when called from a shell script) that matches the exit codes
defined above for each action.
• A _ctl_pmda shell procedure that handles status requests and all reconfiguration operations for a PMDA
that is connected to pmcd(1). _ctl_pmda takes at least 2 arguments, the first is an action (one of
state, activate or deactivate, and the second argument is the name of the PMDA. For the install
action, there is a third argument for the name of the PMDA's executable or DSO and an optional fourth
argument is the name of a file providing the input required for the PMDA's Install script (defaults to
/dev/null).
• _ctl_pmda will return a value (via $? when called from a shell script) that matches the exit codes
defined above for each action.
So the following is the simplest possible component script for a system service.
#!/bin/sh
. $PCP_DIR/etc/pcp.env || exit 1
. $PCP_SHARE_DIR/lib/checkproc.sh
_do_args "$@"
if $lflag
then
[ $verbose -gt 0 ] && echo "my description"
elif $sflag
then
_ctl_svc state $component
status=$?
elif $aflag
then
_ctl_svc activate $component || status=1
elif $dflag
then
_ctl_svc deactivate $component || status=1
fi
And the following is the simplest possible component script for a PMDA.
#!/bin/sh
. $PCP_DIR/etc/pcp.env || exit 1
. $PCP_SHARE_DIR/lib/checkproc.sh
_do_args "$@"
if $lflag
then
[ $verbose -gt 0 ] && echo "my description"
elif $sflag
then
_ctl_pmda state $component
status=$?
elif $aflag
then
_ctl_pmda activate $component || status=1
elif $dflag
then
_ctl_pmda deactivate $component || status=1
fi