Documentation

SourceForge.net Logo

Support This Project

Home
Project page
Download

Documentation

License

Index

Introduction

This document describes the standard application framework 'appctl' including login, environment and application control.

Purpose

The document provides information for developers as well as for application integrators and users. It provides information about each step of the default login-procedure as well as an overview about application handling.

Scope

This document provides information useful to integrate software into the default framework. It does not describe guidelines for application developing, system setup or OS configuration.

Target readership, requirements of the reader

Information provided by this document can be important for developers, application integrators and users. Developers will have to create start and stop scripts for an application and users will probably need to know how to use ctl.

General Information

The original location of the framework is:

http://appctl.sourceforge.net/

The Sourceforge project page is located at:

http://www.sourceforge.net/projects/appctl/

Login procedure

This chapter describes what happens when an application user is logging in to the system.
The following picture gives an overview about the steps executed at logon time. Each step is described in the following sub-chapters.

  1. .profile is sourced. See chapter "default .profile" for more Information.
  2. Custom interactive profile is sourced. See chapter "custom profiles" for more information.
  3. .profile.default is sourced. See chapter ".profile.default" for more information.
  4. setenv.ora is sourced. See chapter "setenv.ora" for more information
  5. envsetup is sourced. See chapter "envsetup" for more information
  6. Application-specific user-profile is sourced. See chapter "application user profile" for more information.

Default .profile

Object .profile
Location

$HOME

Access Do not modify!
Severity Mandatory
Purpose Basic application environment setup entry point

The default .profile is sourced like all user .profile files at login time. Its purpose is to allow execution of common tasks, setting environment and settings for the user who logs in.
The .profile should not be modified directly by the user. To allow customisation of the users environment refer to chapter "customer profiles". Modifying the default .profile can prevent the application from working properly or even prevent using it at all.
The .profile has an interface to allow custom modifications. It simply sources custom profiles if they exist. Therefore every custom modifications to the user-environment should be done in those fules.

Custom profiles

Object

.profile.custom.interactive
.profile.custom.noninteractive

Location

$HOME

Access Modifiable
Severity Optional
Purpose Custom environment - user preferences

If somebody likes to define his own aliases, variables, prompts and similar things the settings have to be placed here. The files are sourced by the initial .profile.
The files are split into two parts to allow to distinguish between interactive and non-interactive logons. For example .profile.custom.noninteractive is sourced when a cronjob logs in as the application user. Therefore it should not contain any interactive prompts or similar things.
If these files only contain non-interactive commands such as variable exporting or alias settings there is no need to split them. In this cases .profile.custom.interactive can simply be a link to .profile.custom.noninteractive where the settings are stored.
.profile will check weather one of these files exists or not. It will not print any error messages if they are not in place since the files are entirely optional.

.profile.default

Object

.profile.default

Location

$HOME

Access Do not modify!
Severity Mandatory
Purpose Setup of default application environment at logon

.profile.default assures that the all environment variables are set correctly. It verifies PATH variables as well as the LD_LIBRARY_PATH and MANPATH.
In addition it will source envsetup which is setting application-specific variables. Please refer to chapter for more details.
Another functionality of .profile.default is to set the application BASEDIR and version number if It cannot be determined correctly by envsetup.
If the application is installed somewhere else than in /opt/[application_name] then the default BASEDIR variable has to be uncommented and set correctly in this file. This will help envsetup to set the correct environment variables.

setenv.ora

Object

setenv.ora

Location

/opt/oracle/admin/$USER/setenv.ora

Access Do not modify!
Severity Optional
Purpose Setup of oracle environment

Setenv.ora is located at /opt/oracle/admin/$USER/setenv.ora where $USER is the users logon-name in capital letters. This file has to be installed by the database administrator.
The file is optional so if the application doesn’t use any DB connection it is not needed at all. The location of the setenv.ora file /opt/oracle/admin/$SID can be a simple symbolic link to the directory whare setenv.ora is stored.

envsetup

Object

envsetup

Location

$BASEDIR

Access Do not modify!
Severity Mandatory
Purpose Setup application environment variables

Envsetup will setup all application environment variables needed by control scripts and the application itself.

List of variables:

Variable Purpose Example
HOME_BASE Application installation directory (/opt/[application]/[version]/) /opt/tomcat/5.0
RUN Binary directory ($HOME_BASE/bin/). /opt/tomcat/5.0/bin/
LIB Library directory ($HOME_BASE/lib/).Used to store shared application libraries. /opt/tomcat/5.0/lib/
CONF Configuration directory ($HOME_BASE/conf/). Used to store application configuration. /opt/tomcat/5.0/conf/
TOOLS Application support tools ($HOME_BASE/tools/). /opt/tomcat/5.0/tools/
TEST Application tests ($HOME_BASE/test/). /opt/tomcat/5.0/test/
MIGRATION Migration scripts ($HOME_BASE/migration/). /opt/tomcat/5.0/migration/
PID_BASE Storage for PID-files (/var/$BASEDIR/pid/). /var/opt/tomcat/pid/
VAR_BASE Variable processing information (/var/$HOME_BASE/). /var/opt/tomcat/5.0/
LOG_BASE Log file storage ($VAR_BASE/log/). /var/opt/tomcat/5.0/log/
LOG_OLD_BASE Log file archive ($VAR_BASE/log-old/). /var/opt/tomcat/5.0/log-old/
PROC_BASE Processing information ($VAR_BASE/proc/). /var/opt/tomcat/5.0/proc/
HA_BASE High Availability base directory (/var/$BASEDIR/ha/).

/var/opt/tomcat/ha/

HA_COUNT HA counter directory ($HA_BASE/counter/). /var/opt/tomcat/ha/counter/
HA_MAINT HA maintenance directory ($HA_BASE/maint/). /var/opt/tomcat/ha/maint/

As you can see some variables are based on the application name, installation directory and version. Usually envsetup can find the applications installation directory automatically. However it might be that this detection fails if it’s installed in a special directory like /usr/local/something. In this cases it’s helpful to export BASEDIR to the applications installation directory (e.g. BASEDIR=”/usr/local/something”). This can be done by modifying .profile.default (refer to .profile.default).
The version number is also determined automatically. By default envsetup looks for a ‘current’ link pointing to the current version:

# ls –l /opt/tomcat/
drwxr-xr-x 8 catalina catalina 512 Sep 27 14:51 5.0
lrwxrwxrwx 1 root other 3 Nov 15 11:28 current -> 5.0

If this ‘current’ link does not exist envsetup uses the environment variable PRG_REL which has to refer to the current version number (e.g. PRG_REL=”5.0”). PRG_REL can also be exported by the default .profile.default (refer to .profile.default).

Application user profile

Object

.profile.$USER

Location

$HOME

Access Do not modify!
Severity Optional
Purpose Setup of variables only valid for this specific application/user

Apart of the other profile and environment setup files this file is specific to a certain application. It contains additional entries needed by the application. In general this file will not be needed as the default environment is enough for all applications.
However for historic reasons some applications still need additional settings which can be put into this file.

ctl

Ctl is the central controlling tool for all applications. It can be used to start, stop, restart and query the status of an application as well as to perform some maintenance operations. To get help just start ctl without any parameters:

ctl revision: 1.2
Usage: ctl <action> <handler-list>
Where:
  <action>   The action to apply to the listed handlers.
             Supported actions:
             start, stop, restart, status,
             maint, nomaint, critical, notcritical, list

  <handler>  A space-separated list of handlers to apply the action on.
             $HANDLER_LIST, all, haprocs
             While 'haprocs' referst to daemons only and
            'all' is a synonym for listing all handlers.
Examples:
$PRGNAME start all
$PRGNAME stop all
$PRGNAME maint handler1
$PRGNAME nomaint handler1

appctl, Copyright (C) 2005 Rainer Meier <SkyBeam>
appctl comes with ABSOLUTELY NO WARRANTY; for details refer to the GPL
This is free software, and you are welcome to redistribute it
under certain conditions; for details refer to the GPL
<http://sourceforge.net/projects/appctl/>

The general syntax is ‘ctl <action> <handler>’ where handler can also be all to perform the desired command for all handlers or haprocs to perform the command on all configured DAEMON programs.

Configuring ctl

Ctl is configured by ctlenv which is stored at $RUN/ directory. Ctlenv contains two variable definitions, the DAEMONS and NONDAEMONS lists. This variables contain a space separated list of handlers.
The difference between DAEMONS and NONDAEMONS is that for DAEMONS ctl checks if the process keeps running like a standard unix daemon. NONDAEMONS are simply started and ctl doesn’t care if they exit immediately after they were started.
DAEMONS are usually controlled by the HA while NONDAEMONS are not.
Additionally ctlenv contains a bunch of configuration parameters to influence the behaviour or display output of ctl. By default all configuration options are commented. If left untouched ctl will use its internal default values which should fit for most environments.

Here’s a short summary of the configuration values and a short description:

Parameter Description
MAINT_REASON Reason for maintenance mode – entered in the maintenance file.
ENV_EXTENSION The file extension e.g. env: prg1env, prg2env...
START_EXTENSION The file extension for startup-scripts e.g. start: prgstart, prg2start
START_FUNCTION Name of the function to be executed to start a module
STOP_EXTENSION The file extension for stop-scripts e.g. start: prgstop, prg2stop
STOP_FUNCTION Name of the function to be executed to stop a module
STATUS_EXTENSION

the file extension for status-scripts e.g. status: prgstatus, prg2status
this script has to check the COMPLETE handler status and to return
0 in case of properly running handler
1 in case of not properly running handler

STATUS_FUNCTION

Name of the status function which checks the application state this script has to check the COMPLETE handler status and to return

0 in case of properly running handler
1 in case of not properly running handler

ENABLE_EXT_SCRIPTS

Set this to a non-zero value to enable execution of start/stop/status extension scripts (pre/post start/stop/status scripts).

Disabling this will reduce the number of shell forks and env file source actions resulting in slightly less system load during execution.

Disabled by default since such scripts are used very rarely. Only enable it if you're using pre/post scripts.

PRESTART_EXTENSION

The file extension for pre-start scripts. This script (if it exists) is just executed before the handler is started.

e.g. prestart: prgprestart, prg2prestart.

PRESTART_FUNCTION Name of the pre-start function to execute if defined in env file.
POSTSTART_EXTENSION

The file extension for post-start scripts. This script (if it exists) is just executed after the handler has been started.

e.g. poststart: prgpoststart, prg2poststart.

POSTSTART_FUNCTION Name of post-start function to execute if defined in env file.
PRESTOP_EXTENSION

The file extension for pre-stop scripts. This script (if it exists) is just executed before the handler is stopped.

e.g. prestop: prgprestop, prg2prestop

PRESTOP_FUNCTION Name of the pre-stop function to execute if defined in env file.
POSTSTOP_EXTENSION

The file extension for post-stop scripts. This script (if it exists) is just executed after the handleris has been stopped.

e.g. poststop: prgpoststop, prg2poststop

POSTSTOP_FUNCTION Name of the post-stop function to execute if defined in env file.
PRESTATUS_EXTENSION

The file extension for pre-status scripts. This script (if it exists) is just executed before the handler status is printed. This allows PID file checking for example.

e.g. prestatus: prgprestatus, prg2prestatus

PRESTATUS_FUNCTION Name of the pre-status function to execute if defined in env file.
POSTSTATUS_EXTENSION

The file extension for post-status scripts. This script (if it exists) is just executed after the handleris status has been printed.

e.g. poststatus: prgpoststatus, prg2poststatus

This setting replaces the STATUSINFO_EXTENSION from earlier versions it is intended to use a statusinfo script to print additional information about the current handler status like running-modes, setings etc.

POSTSTATUS_FUNCTION Name of the post-status function to execute if defined in env file.
TIMEOUT Timeout to wait if a conflict occures:
e.g. if handler is in maint modus and is started manually the user can press CTRL-C within [TIMEOUT] seconds before it continues.
NOTE: This can also be overwritten on a handler-base in the handler env file.
START_TIMEOUT_MIN MINIMAL timeout to wait for handler startup
This can be used to wait some seconds on handler startup to check if it dies in the initialization phase. It can be considered as the minimal uptime required to prove a handler to be up and running.
NOTE: The script will not check if the handler is running before this period expires. Therefore you should keep this value as low as possible to prevent timeouts from external scripts like cluster agents. See START_TIMEOUT_MAX to add a grace timeout.
NOTE: This can also be overwritten on a handler-base in the handler env file.
START_TIMEOUT_MAX Additional handler startup timeout
After START_TIMEOUT_MIN has been passed the script will continuously monitor the handler to write a PID file (only in non PID-less mode) after this timeout has passed and still no valid PID exists then a startup failure message will be displayed. If a valid PID exists before the timeout expires a success message will be printed immediately.
In case of handlers which have a long initialization phase and which can die in this phase it's recommended to use START_TIMEOUT_MIN to define a minimal uptime required to consider a handler as running.
NOTE: This can also be overwritten on a handler-base in the handler env file.
KILL_TIMEOUT
KILL_TIMEOUT_CHILD
Timeout to wait for handler shutdown efore shutdown is enforced (‘kill –s KILL’).
NOTE: If you like to change the kill timeout for a specific handler set KILL_TIMEOUT
and/or KILL_TIMEOUT_CHILD inside the handler env file
NOTE: This can also be overwritten on a handler-base in the handler env file
NOTE: If KILL_TIMEOUT
<= SHUTDOWN_REP_WAIT then no repeated signals are sent and the scripts will still initiate forced shutdown at KILL_TIMEOUT
in case this is requested (see ASSURE_SHUTDOWN).
SHUTDOWN_SIGNALS_ONCE Space separated list of Signals to be sent to the process at the beginning of the shutdown procedure.
Please note that this signals are sent only ONCE.
expample:
Use the following for java processes to print the stack traces:
SHUTDOWN_SIGNALS_ONCE="QUIT"
SHUTDOWN_REP_WAIT Number of seconds to wait after sending the signals defined in SHUTDOWN_SIGNALS_ONCE before the signals defined in SHUTDOWN_SIGNALS_REP are sent continuously.
By default the scripts starts to send the repeating signals after one second.
NOTE: If SHUTDOWN_REP_WAIT >= KILL_TIMEOUT
the repeated signals are never sent and the script waits only till KILL_TIMEOUT expires and then forces shutdown (if enabled, see ASSURE_SHUTDOWN).
NOTE: This can also be overwritten on a handler-base in the handler env file.
SHUTDOWN_SIGNALS_REP Shutdown signals Space separated list of signals which will be sent to the process on shutdown Enter the signals to be passed to 'kill -s <signal>'
NOTE: This signals will be sent once per second until the process terminates
NOTE: This can also be overwritten on a handler-base in the handler env file
example:
KILL_SIGNALS="TERM"
PRIORITY_COMMAND Command name for scheduling priority alteration. On most systems this will be the 'nice' command (see manpage of 'nice') for more details.
PRIORITY

Specifies the process scheduling priority. This value is directly passed as a parameter to the PRIORITY_COMMAND ('nice' by default). For more details on the range of available priorities refer to the man page of 'nice' ('man nice') on your system.

For example if a value of 10 is specifiead this results in 'nice -10 <command>' to be invoked at startup. An empty string or undefined variable results in default priority.

ASSURE_SHUTDOWN Set this to a non-zero value (default) to force shutdown using 'kill -s KILL' after KILL_TIMEOUT has expired.
NOTE: It's not recommended to do this since the application might not be stopped reliable.
NOTE: This can also be overwritten on a handler-base in the handler env file.
INSTANCE_COLUMN
HANDLER_COLUMN
TIME_COLUMN
CPU_COLUMN
PID_COLUMN
MODE_COLUMN
COMMAND_COLUMN
PRINT_HEADER
Output format options
PID_WRITE

Specifies if a PID file is written after starting the process. If disabled ctl will not write any PID file and expects the process to write it.
The script will still remove invalid PIDs from the PID file in this case.
NOTE: In PIDLESS_MODE this option does not have any effect.

PIDLESS_MODE PID-less operation
ctl does not use any PID files (neither read nor write) in PID-less mode all processes are parsed from the process tree in this case
PID-less operation does not work for handlers with custom start/stop scripts or functions. For these handlers the PID file is always read.
DEBUG Enable debug mode if set to a non-zero value.
PRE_EXEC_FUNCTION Defines the name of the function which is run right before ctl starts to process actions. Do not mix it up with the PRESTART_FUNCTION which is run prior to handler startup.
POST_EXEC_FUNCTION Defines the name of the function which is run right after ctl finished to process actions. Do not mix it up with the POSTSTART_FUNCTION or POSTSTOP_FUNCTION which is after handler startup/shutdown.

In addition there are a couple of functions which can be defined within ctlenv. The following table gives a summary:

Function Description
prerun() {} Defines the function which is run prior to command execution. See PRE_EXEC_FUNCTION.
postrun() {} Defines the function which is run prior to command execution. See POST_EXEC_FUNCTION.

Ctl allows a set of global functions to be defined which are run before/after the execution of an action (start, stop, status, maint, nomaint, ...). The name of the function to be called is constructed as follows:

<pre|post><action>()

e.g.
prestart()
poststart()
prestatus()
poststatus()
...

The following variables are made available for convenience:

Variable Description
CTL_HANDLERS Name of handlers on which the action will be performed.
e.g. "handler1 handler2 handler3"
CTL_HANDLERS_ORIGINAL Name of handlers as passed on the command-line.
Note that this might be different from CTL_HANDLERS. For example if "all" is passed, then CTL_HANDLERS will contain a list of all handlers while CTL_HANDLERS_ORIGINAL contains the "all" string.
CTL_ACTION The action(s) which will be executed on the handlers.
e.g. "start", "stop", or "start stop"
CTL_ACTION_ORIGINAL Action as passed on the command-line. Note that this might be different from CTL_ACTION. For example if "restart" is passed, then CTL_ACTION will contain two actions ("start stop") while CTL_ACTION_ORIGINAL contains the "restart" string.
CTL_ACTION_EXIT_CODE Exit code returned by internal action processing. This might be helpful in post* functions to detect if the action performed was successful.

Some function examples:

prestart() {
    logger -p "daemon.notice" -t "$0[$$] invoked by `whoami`" "Starting handlers: $CTL_HANDLERS"
}
poststart() {
    logger -p "daemon.notice" -t "$0[$$] invoked by `whoami`" "Started handlers: $CTL_HANDLERS"
}
prestop() {
    logger -p "daemon.notice" -t "$0[$$] invoked by `whoami`" "Shutting down handlers: $CTL_HANDLERS"
}
poststop() {
    logger -p "daemon.notice" -t "$0[$$] invoked by `whoami`" "Stopped handlers: $CTL_HANDLERS"
}
prestatus() {
    logger -p "daemon.notice" -t "$0[$$] invoked by `whoami`" "Query status of handlers: $CTL_HANDLERS"
}
poststatus() {
    logger -p "daemon.notice" -t "$0[$$] invoked by `whoami`" "Querying of status finished on handlers: $CTL_HANDLERS"
}

Supported commands

Command Description
start Execute the desired handler (run it).
stop Shutdown the desired handler.
restart Shutdown the deried handler and directly restart it afterwards.
status Print current runtime status of desired handler. Returns 0 exit status if handler is running properly. Any other value indicates that the handler is not running.
statuscheck Just checks the status of a given handler. Returns the same exit values as ‘status’ but does not print anything to the screen.
maint Set maintenance status for desired handler. Handlers in maintenance mode are not monitored by HA. ‘ctl status’ on a handler in maintenance mode will always return 0 exit status.
nomaint Unset maintenance status for desired handler.
critical Set critical status for desired handler. If a handler is in critical mode HA should failover if it is unable to start the handler.
notcritical Unset critical status for desired handler. If a handler is in not-critical mode HA should not failover even if it is not able to start the handler.
pidlist Like 'status' but just prints a list of PIDs instead of full status lines. Returns the same exit values as ‘status’.
list Simply prints a list of the supplied handlers. HA can use this functionality to do a ‘ctl list haprocs’ to get a list of handlers to monitor.

Notes about handler start

The startup command is used to start a new handler instance. Following the steps at handler startup are described. These steps are executed in the sequence they are listed here.

Pre-start script

If a script called [handler name]$PRESTART_EXTENSION or a shell function with the same name as defined in $PRESTART_FUNCTION exists it will be executed before the handler is started.

NOTE: This will only be enabled if $ENABLE_EXT_SCRIPTS is set to a non-zero value.

Startup script

If there is a start script called [handler name]$START_EXTENSION (def. start) the script will simply execute it. This script is then responsible to start the application.

Startup function

f no startup script exists the script will look for a shell-function called as defined by the environment variable $START_FUNCTION and executes it if it exists. The easiest way to provide such a startup function is to declare it in the env file ([handler name]$ENV_EXTENSION).

No startup script, no startup function

If neither a startup-script nor a startup-function is defined it will run $COMMAND using nohup. $COMMAND refers by default to $RUN/[handler name] and can be overwritten in the env-file as well. In addition you can define additional startup-parameters by the $ARGUMENTS variable best defined in the env-file as well. If the startup-command is a java-command the script will add a default parameter "-DMODULE=[handler name]" which allows the script to find the corresponding process in the process tree.

Post-start script

f a script called [handler name]$POSTSTART_EXTENSION or a shell function with the same name as defined in $POSTSTART_FUNCTION exists it will be executed after the handler is started.

NOTE: This will only be enabled if $ENABLE_EXT_SCRIPTS is set to a non-zero value.

Notes about handler stop

The stop command is used to stop a running handler instance. Following the steps at handler shutdown are described. These steps are executed in the sequence they are listed here.

Pre-stop script

If a script called [handler name]$PRESTOP_EXTENSION or a shell function with the same name as defined in $PRESTOP_FUNCTION exists it will be executed before the handler is shut down.

NOTE: This will only be enabled if $ENABLE_EXT_SCRIPTS is set to a non-zero value.

Stop script

If there is a stop script called [handler name]$STOP_EXTENSION (def. stop) the script will simply execute it. This script is then responsible to shut down the application.

Stop function

If no stop script exists the script will look for a shell-function called as defined by the environment variable $STOP_FUNCTION and executes it if it exists. The easiest way to provide such a shutdown function is to declare it in the env file ([handler name]$ENV_EXTENSION).

No stop script, no shutdown function

If neither a stop-script nor a shutdown-function is defined it will try to kill the PIDs in PID file or kill PIDs found in the process tree. To find the correct PIDs in the process tree again the $COMMAND variable (overwriteable by [handler name]$ENV_EXTENSION) is used. For java commands it will additionally look for the "-DMODULE=[module name]" argument.
Additional note: You can change the timeout (in seconds) the scripts wait for a handler to shut down gracefully by setting the $KILL_TIMEOUT variable to the desired value. In addition you can set the $KILL_TIMEOUT_CHILD variable to define the number of seconds the scripts wait for child-processes to shut down before they are forced to. This values of course only takes place if you use the ctl-internal shutdown function without overwriting it by a stop script or shutdown function.

Post-stop script

If a script called [handler name]$POSTSTOP_EXTENSION or a shell function with the same name as defined in $POSTSTOP_FUNCTION exists it will be executed after the handler is shut down.

NOTE: This will only be enabled if $ENABLE_EXT_SCRIPTS is set to a non-zero value.

Notes about handler status

The script will always print the status of all the PIDs listed in the pid- file. If a PID is invalid it will be removed from the PID file. If the PID-file does not contain any valid PIDs it will search the process tree for running instances and write them to the PID-file (if not in PIDLESS_MODE, see PID-less operation).
In case the process is handled by ctl and no external script is used ctl will check the PID’s inside the PID file to point to the correct process. If the command line argument indicates that the PID is pointing to a wrong process ctl will remove this PID from the PID file as well.
If there is a running instance this script will exit with status code 0 and it will return a non-zero value for stopped handlers or if an error occured.
Additionally the following procedures are executed (if present).

Pre-status script

Pre-status script If a script called [handler name]$PRESTATUS_EXTENSION or a shell function with the same name as defined in $PRESTATUS_FUNCTION exists it will be executed before the status is printed by the script.

NOTE: This will only be enabled if $ENABLE_EXT_SCRIPTS is set to a non-zero value.

Status script

If there is a status script called [handler name]$STATUS_EXTENSION (def. status) the script will execute the status script every time the handler-status is requested. This script is executed right after the status of the valid PIDs are printed. Output from this script will be printed directly to the standard output.
For handlers which cannot be identified correctly in the process tree by the script it is recommended to verify or re-build all the PIDs in the PID-file by this status script so this script will print the correct results.
Ctl will take over the exit-status of the executed status script so make sure your script is correctly handling exit status codes.

Status function

If no status-script is executed the script will look for a shell-function called as defined by the environment variable $STATUS_FUNCTION and executes it if it exitst. The easiest way to provide such a status function is to declare it in the env file ([handler name]$ENV_EXTENSION).

For handlers which cannot be identified correctly in the process tree by the script it is recommended to verify or re-build all the PIDs in the PID-file by this status script so this script will print the correct results.

The script will take over the exit-status of the executed status function so make sure your script is correctly handling exit status codes.

Post-status script

If a script called [handler name]$POSTSTATUS_EXTENSION or a shell function with the same name as defined in $POSTSTATUS_FUNCTION exists it will be executed right after the status is printed by the script.

NOTE: This will only be enabled if $ENABLE_EXT_SCRIPTS is set to a non-zero value.

Notes about advanced ctl functionality

Ctl has some advanced interfaces to allow starting/stopping and monitoring of non-standard applications which need customized startup/stop/monitoring scripts.
If there is an executable <handler>start, <handler>stop or <handler>status script in $RUN then ctl will simply run this scripts if the corresponding command is executed. Ctl will then return the exit status of the corresponding script instead of returning its own exit status. Therefore you have to assure that your startup/stop/status script is returning correct exit values (0 for successful operation).

Example:
ls -l /opt/tomcat/5.0/bin
[…]
lrwxrwxrwx   1 root     other          3 Jul  9 17:09 tomcatstart -> tomcatctl
lrwxrwxrwx   1 root     other          3 Jul  9 17:09 tomcatstop -> tomcatctl
lrwxrwxrwx   1 root     other          3 Jul  9 17:09 tomcatstatus -> tomcatctl
[…]

As you can see it’s possible to link the start/stop/status scripts to a centralized script which is doing the desired action according to its call-name.
Typically the startup script is starting any process to simulate a daemon (for example starting java processes with nohup).
If such a script does not exist ctl will look for a start/shutdown/status function defined in the env file and execute this one.

PID-less operation

By exporting the environment variable PIDLESS_MODE=1 (preferably in ctlenv) ctl can be put into a special mode. In this mode ctl does not make any use of PID files when handling processes by its own (no startup/stop scripts/functions).
On handler start there is no PID file written by ctl. The status action looks for the processes in the process tree and does not use a PID file even if present. The stop action searches for running processes as well in the process tree without using PID files.
Of course this does not work if startup scripts are used because ctl cannot know which process(es) are run by the startup script/function. For handlers providing a startup script/function ctl automatically falls back to PID-file mode even if PIDLESS_MODE is activated. As documented ctl relies on the correct entries within the PID file in this case (they have to be handled by the external scripts).

Configuration matrix

This chapter contains a full list of all environment variables and gives an overview where they can be used.

Environment variables:

Variable Configurable in global ctlenv (allows global configuration for all modules). Configurable in handler env (allows per-module configuration). Will overwrite global value if defined.
ARGUMENTS no yes
ASSURE_SHUTDOWN yes yes
COMMAND no yes
DEBUG yes no
ENABLE_EXT_SCRIPTS yes no
ENV_EXTENSION yes no
KILL_TIMEOUT
KILL_TIMEOUT_CHILD
yes yes
MAINT_REASON yes no
PID_WRITE yes yes
PIDFILE no yes
PIDLESS_MODE yes no
POST_EXEC_FUNCTION yes no
POSTSTART_EXTENSION yes yes
POSTSTART_FUNCTION yes yes
POSTSTATUS_EXTENSION yes yes
POSTSTATUS_FUNCTION yes yes
POSTSTOP_EXTENSION yes yes
POSTSTOP_FUNCTION yes yes
PRE_EXEC_FUNCTION yes no
PRESTART_EXTENSION yes yes
PRESTART_FUNCTION yes yes
PRESTATUS_EXTENSION yes yes
PRESTATUS_FUNCTION yes yes
PRESTOP_EXTENSION yes yes
PRESTOP_FUNCTION yes yes
PRIORITY_COMMAND yes yes
PRIORITY yes yes
SHUTDOWN_REP_WAIT yes yes
SHUTDOWN_SIGNALS_ONCE yes yes
SHUTDOWN_SIGNALS_REP yes yes
START_EXTENSION yes yes
START_FUNCTION yes yes
START_TIMEOUT_MIN yes yes
START_TIMEOUT_MAX yes yes
STATUS_EXTENSION yes yes
STATUS_FUNCTION yes yes
STDOUT no yes
STOP_EXTENSION yes yes
STOP_FUNCTION yes yes
TIMEOUT yes no
INSTANCE_COLUMN
HANDLER_COLUMN
TIME_COLUMN
CPU_COLUMN
PID_COLUMN
MODE_COLUMN
COMMAND_COLUMN
PRINT_HEADER
yes no

Example environment files

This chapter contains some sample script to show the configuration of handlers for ctl.
Apart of defining environment-variables for a handler to run an env-file can contain the following constructs to modify ctl behaviour:

Name Type Description
COMMAND Variable The startup-command to be run by ctl. This defaults to “$RUN/<handler>” if not set in the environment-file.
ARGUMENTS Variable Arguments to pass to the startup-command when the handler is startet.
STDOUT Variable If this variable is defined any output to STDERR and STDOUT from $COMMAND will be redirected to this file. This defaults to “/dev/null” if not set In the environment-file.
KILL_TIMEOUT Variable See KILL_TIMEOUT
KILL_TIMEOUT_CHILD Variable See KILL_TIMEOUT_CHILD
START_TIMEOUT_MAX Variable See START_TIMEOUT_MAX
START_TIMEOUT_MIN Variable See START_TIMEOUT_MIN
SHUTDOWN_SIGNALS_ONCE Variable See SHUTDOWN_SIGNALS_ONCE
SHUTDOWN_SIGNALS_REP Variable See SHUTDOWN_SIGNALS_REP
SHUTDOWN_REP_WAIT Variable See SHUTDOWN_REP_WAIT
ASSURE_SHUTDOWN Variable See ASSURE_SHUTDOWN
PID_WRITE Variable See PID_WRITE
PIDFILE Variable Allows definition of absolute path to the PID file used for this handler.
start() {} Function

If such a function is defined ctl will execute it instead of starting the handler by its own. Ctl will exit with the return-code supplied by this function so make sure it returns 0 for successful startup and a non-zero value in case of error.

See START_FUNCTION.

This is equal to placing a script at "$RUN/[module]start".

See START_EXTENSION.

shutdown() {} Function

If such a function is defined ctl will execute it instead of stopping the handler by its own. Ctl will exit with the return-code supplied by this function so make sure it returns 0 for successful shutdown and a non-zero value in case of error.

See STOP_FUNCTION.

This is equal to placing a script at "$RUN/[module]stop".

See STOP_EXTENSION.

status() {} Function

On execution of “ctl status <handler>” ctl will call this function after printing the process information. Therefore this script can contain additional status output or (strongly recommended) verify-procedures for PIDs in PID files. Ctl will exit with the return-code supplied by this function so make sure it returns 0 for a running (and working) handler and a non-zero value for a stopped or improperly working handler.

See STATUS_FUNCTION.

This is equal to placing a script at "$RUN/[module]status".

See STATUS_EXTENSION.

prestart() {} Function

Function executed prior to module start.

See PRESTART_FUNCTION.

This is equal to placing a script at "$RUN/[module]prestart".

See PRESTART_EXTENSION.

poststart() {} Function

Function executed right after module start.

See POSTSTART_FUNCTION.

This is equal to placing a script at "$RUN/[module]poststart".

See POSTSTART_EXTENSION.

prestop() {} Function

Function executed prior to module stop.

See PRESTOP_FUNCTION.

This is equal to placing a script at "$RUN/[module]prestop".

See PRESTOP_EXTENSION.

poststop() {} Function

Function executed right after module stop.

See POSTSTOP_FUNCTION.

This is equal to placing a script at "$RUN/[module]poststop".

See POSTSTOP_EXTENSION.

prestatus() {} Function

Function executed before the status is printed.

See PRESTATUS_FUNCTION.

This is equal to placing a script at "$RUN/[module]prestatus".

See PRESTATUS_EXTENSION.

poststatus() {} Function

Function executed right after the status has been printed.

See POSTSTATUS_FUNCTION.

This is equal to placing a script at "$RUN/[module]poststatus".

See POSTSTATUS_EXTENSION.

Sample env file to set handler environment variables

# Environment setup for demo handler
# Project XY: Environment for [demo] handler
#
# $Name:  $
# $Log:  $

#
#
# set +u
#

If [ "$LOG_LEVEL" = "" ]; then
LOG_LEVEL=9
export LOG_LEVEL
fi

MSQ_LEVEL=7
export MSQ_LEVEL
RPHS_LEVEL=7
export RPHS_LEVEL
MSG_LEVEL=7
export MSG_LEVEL
PRM_LEVEL=7
export PRM_LEVEL

Env file to set custom startup command and parameters

# Environment setup for demo handler
# Project XY: Environment for [demo] handler
#
# $Name:  $
# $Log:  $

#

# set +u
#

# COMMAND=$RUN/handler1
COMMAND=java
export COMMAND

ARGUMENTS="-cp $LIB -jar -DCONF=$CONF $LIB/demo.jar"
export ARGUMENTS

STDOUT=$LOG_BASE/demo.out
Export STDOUT

If [ "$LOG_LEVEL" = "" ]; then
LOG_LEVEL=9
export LOG_LEVEL
fi

MSQ_LEVEL=7
export MSQ_LEVEL

Env file with custom start/shutdown/status functionality

This sample shows an example of an env-file with start/shutdown and status functions defined. It is not required to define all of them. For example if start() is not defined ctl will fall back to its internal startup routine.

# Environment setup for demo handler
# Project PPB: Environment for [demo] handler
#
# $Name:  $
# $Log:  $
#
#
# set +u
#

start() {
	cd $RUN
	nohup java -cp $LIB -jar -DCONF=$CONF $LIB/demo.jar >> $LOG_BASE/demo.out 2>&1 echo $! > $PID_BASE/demo.pid
}

shutdown() {
	RETURNCODE=0
for i in `cat $PID_BASE/demo.pid 2>/dev/null`
		kill -9 $i
		sleep 1
		ps -p $i
		# check if shutdown was successful
		if [ $? -eq 0 ]; then
			RETURNCODE=1
		fi
	done
	return $RETURNCODE
}

status() {
	# validate PIDs
	PID=ps -fu $USER | grep -v $$ | grep "\<java\>" | awk '{print $1}'
	echo $PID > $PID_BASE/demo.pid
	if [ "$PID" != "" ]; then
		return 0
	else
		return 1
	fi
}

Sample env file to handle Java processes

# DESCRIPTION
#
# Sets up environment for JBoss
# Sets configuration variables for ctl as well
#
# #############################################################################
#
# U S A G E
#
#
# #############################################################################
# $Name:  $
#
# Revision history
#
# $Log:  $
#
#
# #############################################################################

# server to start
SERVER_DIR=default

# name of cluster
# leave this empty in order not to run in a cluster environment
CLUSTER_NAME=""

# source jboss.conf to include default configuration
if [ -r $RUN/jboss.conf ]; then
    . $RUN/jboss.conf
fi

# set variables as set in run.sh
JBOSS_ENDORSED_DIRS="$LIB/endorsed"

# Check for SUN(tm) JVM w/ HotSpot support
if [ "x$HAS_HOTSPOT" = "x" ]; then
    HAS_HOTSPOT=`$JAVA -version 2&> grep -i HotSpot`
fi

# REM Sun JVM memory allocation pool parameters. Modify as appropriate
JAVA_OPTS="$JAVA_OPTS -Xms128m -Xmx512m"

# Enable -server if we have Hotspot, unless we can't
if [ "x$HAS_HOTSPOT" != "x" ]; then
    # check if server is already defined
    echo $JAVA_OPTS | grep '\-server' >/dev/null 2>&1
    if [ $? -gt 0 ]; then
        JAVA_OPTS="$JAVA_OPTS -server"
    fi
fi

# classpath
# Setup the classpath
runjar="$RUN/run.jar"
if [ ! -f "$runjar" ]; then
    die "Missing required file: $runjar"
fi
# Include the JDK javac compiler for JSP pages. The default is for a Sun JDK
# compatible distribution which JAVA_HOME points to
if [ "x$JAVAC_JAR" = "x" ]; then
    JAVAC_JAR="$JAVA_HOME/lib/tools.jar"
fi
JBOSS_BOOT_CLASSPATH="$runjar"
if [ "x$JBOSS_CLASSPATH" = "x" ]; then
    JBOSS_CLASSPATH="$JBOSS_BOOT_CLASSPATH:$JAVAC_JAR"
else
    JBOSS_CLASSPATH="$JBOSS_CLASSPATH:$JBOSS_BOOT_CLASSPATH:$JAVAC_JAR"
fi

# cluster options
CLUSTER_OPTS=""
if [ "$CLUSTER_NAME" != "" ]; then
    CLUSTER_OPTS="$CLUSTER_OPTS -Djboss.partition.name=$CLUSTER_NAME"
fi


# set path to file where to write stdout-output (used by ctl)
STDOUT=$LOG_BASE/jboss-stdout.log
export STDOUT

# set the command to run (used by ctl)
COMMAND=java
export COMMAND

# set arguments to append to command (used by ctl)
ARGUMENTS="$JAVA_OPTS -Djava.endorsed.dirs=$JBOSS_ENDORSED_DIRS \
-classpath $JBOSS_CLASSPATH org.jboss.Main \
$CLUSTER_OPTS -c $SERVER_DIR"
export ARGUMENTS