Hello All,

I made an OCF RA for syslog-ng and attached it to this message.

I confirmed that it can work with no problem in the following cases.

* Creating a resource instance
  - This RA can invoke a new syslog-ng process as an OCF resource
    with starting Heartbeat. This works independently of the system
    syslog-ng process.
   "system process" means that it's managed by RC script.

* Terminating a resource instance
  - This RA can revoke a working syslog-ng process as an OCF resource
    with stopping Heartbeat. This works independently of the system
    syslog-ng process.

* Failing over a resource instance at its start failure
  - When the syslog-ng command returns a error status due to a wrong
    syslog-ng configuration file, this RA can exit with an error status.
    Then a resource instance restarts on the SBY node.

* Failing over a resource instance at its monitor failure
  - When a syslog-ng of a working resource instance disappears,
    this RA returns an error status as a result of its monitor action.
    Then a resource instance restarts on the SBY node.

* Relocation
  - If the crm_resource command is performed to relocate a working
    syslog-ng resource, this RA can respond the request.

These tests were carried out under the following enviroment.

2 node cluster(ACT/SBY) with
  Redhat 5.2(i386)
  heartbeat 2.1.4
  syslog-ng 2.1.3

I appreciate any comments.

Best reagard.
-- 
Takenaka Kazuhiro <takenaka.kazuh...@oss.ntt.co.jp>


#!/bin/bash
#
# Description:  Manages a syslog-ng instance, provided by NTT OSSC as an 
#               OCF High-Availability resource under Heartbeat/LinuxHA control
#
# Copyright (c) 2009 NIPPON TELEGRAPH AND TELEPHONE CORPORATION
#
##############################################################################
# OCF parameters:
#   OCF_RESKEY_syslog_ng_exe    : Executable file
#   OCF_RESKEY_syslog_ng_conf   : Configuration file
#   OCF_RESKEY_syslog_ng_pidfile: Process id file
#   OCF_RESKEY_syslog_ng_opts   : Extra options
#   OCF_RESKEY_syslog_ng_stop_timeout:
#                                 Number of seconds to await to confirm a 
#                                 normal stop method
#   OCF_RESKEY_syslog_ng_suspend_trialcount:
#                                 Number of times to try forcible 
#                                 stop methods
#   OCF_RESKEY_debug_mode       : Debug mode
#   OCF_RESKEY_debug_log        : Debug log file
#
#   Only OCF_RESKEY_syslog_ng_conf must be specified. Each of the rests 
#   has its default value or refers OCF_RESKEY_syslog_ng_conf to make
#   its value when no explicit value is given.
#
# Further infomation for setup:
#   There are sample configurations at the end of this file.
#
###############################################################################

. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs

usage() 
{
        cat <<-!
usage: $0 action

action:
        start       : start a new syslog-ng instance

        stop        : stop the running syslog-ng instance

        status      : return the status of syslog-ng, run or down

        monitor     : return TRUE if the syslog-ng appears to be working.

        meta-data   : show meta data message

        validate-all: validate the instance parameters
!
        return $OCF_ERR_ARGS
}

metadata_syslog_ng()
{
    cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="syslog_ng">
<version>1.0</version>

<longdesc lang="en">
This script manages a syslog-ng instance as an HA resource.
</longdesc>
<shortdesc lang="en">Syslog-ng resource agent</shortdesc>

<parameters>

<parameter name="syslog_ng_exe" unique="0">
<longdesc lang="en">
This is a required parameter. This parameter specifies syslog-ng's
executable file.
</longdesc>
<shortdesc>Executable file</shortdesc>
<content type="string" default=""/>
</parameter>

<parameter name="syslog_ng_conf" unique="0">
<longdesc lang="en">
This is a required parameter. This parameter specifies a configuration file 
for a syslog-ng instance managed by this RA.
</longdesc>
<shortdesc>Configuration file</shortdesc>
<content type="string" default=""/>
</parameter>

<parameter name="syslog_ng_pidfile" unique="0">
<longdesc lang="en">
This is an omittable parameter. This parameter specifies a process id file 
for a syslog-ng instance managed by this RA. When no value is given, 
it's made by the following rules: "/var/run" as a directory part, 
the basename of the configuration file given by "syslog_ng_conf" 
as a basename part, ".pid" as a suffix.
</longdesc>
<shortdesc>Pidfile</shortdesc>
<content type="string" default=""/>
</parameter>

<parameter name="syslog_ng_opts" unique="0">
<longdesc lang="en">
This is an optional parameter. This parameter specifies extra options for a 
syslog-ng instance managed by this RA. When no value is given, no extra 
options is used. Don't use option '-F'. It causes a stuck of a start action.
</longdesc>
<shortdesc>Configuration file</shortdesc>
<content type="string" default=""/>
</parameter>

<parameter name="syslog_ng_stop_timeout" unique="0">
<longdesc lang="en">
This is an omittable parameter. 
On a stop action, a normal stop method is firstly used.
And then the confirmation of its completion is waited for
the specified seconds by this parameter.
The default value is 10.
</longdesc>
<shortdesc>Number of seconds to await to confirm a normal stop 
method</shortdesc>
<content type="integer" default="10"/>
</parameter>

<parameter name="syslog_ng_suspend_trialcount" unique="0">
<longdesc lang="en">
This is an omittable parameter.
On a stop action, if a normal stop method ends up with a failure,
more forcible methods are taken. These methods are repeated the 
specified numbers by this parameter.
The default value is 10.
If every normal or forcible stop methods run into a failure,
the KILL signal is used as a final method to stop.
</longdesc>
<shortdesc>Number of times to try forcible stop methods</shortdesc>
<content type="integer" default="10"/>
</parameter>

<parameter name="debug_mode" unique="0">
<longdesc lang="en">
This is an optional parameter.
This RA runs in debug mode when this parameter includes 'x' or 'v'.
If 'x' is included, both of STDOUT and STDERR redirect to the logfile 
specified by "debug_log", and then the builtin shell option 'x' is turned on.
It is similar about 'v'.
</longdesc>
<shortdesc>Debug mode</shortdesc>
<content type="string" default=""/>
</parameter>

<parameter name="debug_log" unique="0">
<longdesc lang="en">
This is an optional and omittable parameter.
This parameter specifies a destination file for debug logs
and works only if this RA run in debug mode.  Refer to the term of 
"debug_mode" about debug mode. If no value is given but it's requied, 
it's made by the following rules: "/var/log/" as a directory part, 
the basename of the configuration file given by "syslog_ng_conf" as a 
basename part, ".log" as a suffix.
</longdesc>
<shortdesc>A destination of the debug log</shortdesc>
<content type="string" default="" />
</parameter>

</parameters>

<actions>
<action name="start" timeout="60s" />
<action name="stop" timeout="120s" />
<action name="status" timeout="60" />
<action name="monitor" depth="0" timeout="30s" interval="10s" start-delay="10s" 
/>
<action name="meta-data" timeout="5s" />
<action name="validate-all"  timeout="5"/>
</actions>
</resource-agent>
END
        return $OCF_SUCCESS
}

monitor_syslog_ng()
{
        set -- $(pgrep -f "$PROCESS_PATTERN" 2>/dev/null)
        case $# in
                0) ocf_log debug "No syslog-ng process for $SYSLOG_NG_CONF"
                   return $OCF_NOT_RUNNING;;
                1) return $OCF_SUCCESS;;
        esac
        ocf_log err "mutiple syslog-ng process for $SYSLOG_NG_CONF"
        return $OCF_ERR_GENERIC
}

start_syslog_ng()
{
        monitor_syslog_ng
        if [[ $? = "$OCF_SUCCESS" ]]; then
                return $OCF_SUCCESS
        fi

        rm -f "$SYSLOG_NG_PIDFILE"
        set -- $SYSLOG_NG_OPTS
        ocf_run "$SYSLOG_NG_EXE" -f "$SYSLOG_NG_CONF" -p "$SYSLOG_NG_PIDFILE" 
"$@"
        ocf_status=$?
        if [[ "$ocf_status" != "$OCF_SUCCESS" ]]; then
                return $ocf_status
        fi

        while true; do
                monitor_syslog_ng
                if [[ $? = "$OCF_SUCCESS" ]]; then
                        return $OCF_SUCCESS
                fi
                sleep 1
        done
}

stop_syslog_ng()
{
        pkill -TERM -f "$PROCESS_PATTERN"

        typeset lapse_sec=0
        while pgrep -f "$PROCESS_PATTERN" > /dev/null; do
                sleep 1
                lapse_sec=$(( lapse_sec + 1 ))
                ocf_log debug "stop_syslog_ng[$SYSLOG_NG_NAME]:" \
                        "stop NORM $lapse_sec/$SYSLOG_NG_STOP_TIMEOUT"
                if (( lapse_sec >= SYSLOG_NG_STOP_TIMEOUT )); then
                        break
                fi
        done

        if pgrep -f "$PROCESS_PATTERN" > /dev/null; then
                lapse_sec=0
                while true; do
                        lapse_sec=$(( lapse_sec + 1 ))
                        pkill -QUIT -f "$PROCESS_PATTERN"
                        sleep 1
                        if pgrep -f "$PROCESS_PATTERN" > /dev/null; then
                                ocf_log err "stop_syslog_ng[$SYSLOG_NG_NAME]:" \
                                        "suspend syslog_ng by SIGQUIT " \
                                        
"($lapse_sec/$SYSLOG_NG_SUSPEND_TRIALCOUNT)"
                        else
                                break
                        fi
                done
        fi

        lapse_sec=0
        while pgrep -f "$PROCESS_PATTERN" > /dev/null; do
                pkill -KILL -f "$PROCESS_PATTERN"
                sleep 1
                lapse_sec=$(( lapse_sec + 1 ))
                ocf_log debug "stop_syslog_ng[$SYSLOG_NG_NAME]: " \
                        "suspend syslog_ng by SIGKILL ($lapse_sec/@@@)"
        done

        rm -f "$SYSLOG_NG_PIDFILE"
        return $OCF_SUCCESS
}

status_syslog_ng()
{
        return $OCF_SUCCESS
}

validate_all_syslog_ng()
{
        ocf_log info "validate_all_syslog_ng[$SYSLOG_NG_NAME]"
        return $OCF_SUCCESS
}

: === Debug ${0##*/} $1 ===

if [[ "$1" = "meta-data" ]]; then
        metadata_syslog_ng
        exit $?
fi

SYSLOG_NG_CONF="${OCF_RESKEY_syslog_ng_conf}"
if [[ -z "$SYSLOG_NG_CONF" ]]; then
        ocf_log err "undefined parameter:syslog_ng_conf"
        exit $OCF_ERR_CONFIGURED
fi
SYSLOG_NG_NAME=${SYSLOG_NG_CONF##*/}
SYSLOG_NG_NAME=${SYSLOG_NG_NAME%.*}

DEBUG_LOG="${OCF_RESKEY_debug_log}"
if [[ -z "$DEBUG_LOG" ]]; then
        DEBUG_LOG="/var/log/$SYSLOG_NG_NAME.log"
fi

DEBUG_MODE=""
case $OCF_RESKEY_debug_mode in
        *x*) DEBUG_MODE="${DEBUG_MODE}x";;
esac
case $OCF_RESKEY_debug_mode in
        *v*) DEBUG_MODE="${DEBUG_MODE}v";;
esac

if [ -n "$DEBUG_MODE" ]; then
        PS4='\d \t \h '"${1-unknown} "; export PS4
        exec 1>>$DEBUG_LOG 2>&1
        set -$DEBUG_MODE
fi

: === Debug ${0##*/} $1 ===

SYSLOG_NG_EXE="${OCF_RESKEY_syslog_ng_exe}"
if [[ -z "$SYSLOG_NG_EXE" ]]; then
        ocf_log err "Undefined parameter:syslog_ng_exe"
        exit $OCF_ERR_CONFIGURED
fi
if [[ ! -x "$SYSLOG_NG_EXE" ]]; then
        ocf_log err "Invalid value:syslog_ng_exe:$SYSLOG_NG_EXE"
        exit $OCF_ERR_CONFIGURED
fi

SYSLOG_NG_PIDFILE="${OCF_RESKEY_syslog_ng_pidfile}"
if [[ -z "$SYSLOG_NG_PIDFILE" ]]; then
        SYSLOG_NG_PIDFILE="/var/run/$SYSLOG_NG_NAME.pid"
fi

SYSLOG_NG_STOP_TIMEOUT="${OCF_RESKEY_syslog_ng_stop_timeout-10}"
if ! ocf_is_decimal "$SYSLOG_NG_STOP_TIMEOUT"; then
        ocf_log err "Invalid 
value:syslog_ng_stop_timeout:$SYSLOG_NG_STOP_TIMEOUT"
        exit $OCF_ERR_CONFIGURED
fi

SYSLOG_NG_SUSPEND_TRIALCOUNT="${OCF_RESKEY_syslog_ng_suspend_trialcount-10}"
if ! ocf_is_decimal "$SYSLOG_NG_SUSPEND_TRIALCOUNT"; then
        ocf_log err "Invalid 
value:syslog_ng_suspend_trialcount:$SYSLOG_NG_SUSPEND_TRIALCOUNT"
        exit $OCF_ERR_CONFIGURED
fi

SYSLOG_NG_OPTS=${OCF_RESKEY_syslog_ng_opts}
PROCESS_PATTERN="$SYSLOG_NG_EXE -f $SYSLOG_NG_CONF -p $SYSLOG_NG_PID"

SCRIPT_NAME=${0##*/}
COMMAND=$1

case "$COMMAND" in
        start)
                ocf_log debug  "[$SYSLOG_NG_NAME] Enter syslog_ng start"
                start_syslog_ng
                func_status=$?
                ocf_log debug  "[$SYSLOG_NG_NAME] Leave syslog_ng start 
$func_status"
                exit $func_status
                ;;
        stop)
                ocf_log debug  "[$SYSLOG_NG_NAME] Enter syslog_ng stop"
                stop_syslog_ng
                func_status=$?
                ocf_log debug  "[$SYSLOG_NG_NAME] Leave syslog_ng stop 
$func_status"
                exit $func_status
                ;;
        status)
                status_syslog_ng
                exit $?
                ;;
        monitor)
                #ocf_log debug  "[$SYSLOG_NG_NAME] Enter syslog_ng monitor"
                monitor_syslog_ng
                func_status=$?
                #ocf_log debug  "[$SYSLOG_NG_NAME] Leave syslog_ng monitor 
$func_status"
                exit $func_status
                ;;
        validate-all)
                validate_all_syslog_ng
                exit $?
                ;;
        *)
                usage
                ;;
esac

# vim: set sw=4 ts=4 :

### A sample snippet of cib.xml for a syslog-ng resource
##
#         <primitive id="prmApSyslog-ng" class="ocf" type="syslog-ng" 
provider="heartbeat">
#           <instance_attributes id="prmDummyB_instance_attrs">
#             <attributes>
#              <nvpair id="atr:Syslog-ng:syslog-ng:syslog_ng_exe"  
name="syslog_ng_exe"  value="/sbin/syslog-ng"/>
#              <nvpair id="atr:Syslog-ng:syslog-ng:syslog_ng_conf" 
name="syslog_ng_conf" value="/etc/syslog-ng/syslog-ng-ext.conf"/>
#             </attributes>
#           </instance_attributes>
#           <operations>
#             <op id="op:prmSyslog-ng:start"   name="start" timeout="60s" 
on_fail="restart"/>
#             <op id="op:prmSyslog-ng:monitor" name="monitor" interval="10s" 
timeout="60s" on_fail="restart"/>
#             <op id="op:prmSyslog-ng:stop"    name="stop" timeout="60s" 
on_fail="block"/>
#           </operations>
#         </primitive>

### A sample syslog-ng configuration file for a log collecting host
### 
### This sample is for a log collecting host by syslog-ng.
### A syslog-ng process configurated by this sample accepts all messages
### from a certain network. Any message from the network is preserved into
### a file for security infomation. Restricting messages to "authpriv" from
### the network is done on log sending hosts. (See the sample below)
### Any internal message of the syslog-ng process is preserved into its 
### dedicated file. And any "authpriv" internal message of the syslog-ng 
### process is also preserved into the security infomation file.
###
### Change "f_incoming" to suit your enviroment.
### If you use it as a configuration file for the sample cib.xml above,
### save it into "/etc/syslog-ng/syslog-ng-ext.conf".
##
#options {
#    sync (0);
#    time_reopen (10);
#    log_fifo_size (1000);
#    long_hostnames (off);
#    use_dns (yes);
#    use_fqdn (no);
#    create_dirs (no);
#    keep_hostname (yes); };
#
#source s_internal { internal(); };
#source s_incoming { udp(port(514)); };
#filter f_internal { facility(authpriv); };
#filter f_incoming { netmask("172.20.0.0/255.255.192.0"); };
#
#destination d_internal { file("/var/log/syslog-ng-ext.log" perm(0640));};
#destination d_incoming {
#    file("/var/log/secure-ext.log" create_dirs(yes) perm(0640)); };
#
#log { source(s_internal); destination(d_internal); };
#log { source(s_internal); filter(f_internal); destination(d_incoming); };
#log { source(s_incoming); filter(f_incoming); destination(d_incoming); };

### A sample snippet of syslog-ng configuration file for a log sending host
###
### This sample is for a log sending host that uses syslog-ng.
###
### Replace "syslog-ng-ext" to the IP address or the hostname of your
### log collecting host and append it to "syslog-ng.conf" of each log sending
### host. See the install default syslog-ng.conf to know what "s_sys" and 
### "f_auth" are.
##
#destination d_outgoing  { udp("syslog-ng-ext" port(514)); };
#log { source(s_sys); filter(f_auth); destination(d_outgoing); };

### A sample snippet of syslog configuration file for a log sending host
###
### This sample is for a log sending host that uses syslog.
###
### Replace "syslog-ng-ext" to the IP address or the hostname of your
### log collecting host and append it to "syslog.conf" of each log sending
### host.
##
# authpriv.*                                              @syslog-ng-ext
_______________________________________________________
Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/

Reply via email to