diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 49b5c58bc..c079f1a88 100644 --- a/doc/man/Makefile.am +++ b/doc/man/Makefile.am @@ -1,166 +1,167 @@ # # doc: Linux-HA resource agents # # Copyright (C) 2009 Florian Haas # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = $(doc_DATA) $(REFENTRY_STYLESHEET) \ mkappendix.sh ralist.sh CLEANFILES = $(man_MANS) $(xmlfiles) metadata-*.xml STYLESHEET_PREFIX ?= http://docbook.sourceforge.net/release/xsl/current MANPAGES_STYLESHEET ?= $(STYLESHEET_PREFIX)/manpages/docbook.xsl HTML_STYLESHEET ?= $(STYLESHEET_PREFIX)/xhtml/docbook.xsl FO_STYLESHEET ?= $(STYLESHEET_PREFIX)/fo/docbook.xsl REFENTRY_STYLESHEET ?= ra2refentry.xsl XSLTPROC_OPTIONS ?= --xinclude XSLTPROC_MANPAGES_OPTIONS ?= $(XSLTPROC_OPTIONS) XSLTPROC_HTML_OPTIONS ?= $(XSLTPROC_OPTIONS) XSLTPROC_FO_OPTIONS ?= $(XSLTPROC_OPTIONS) radir = $(top_srcdir)/heartbeat # OCF_ROOT=. is necessary due to a sanity check in ocf-shellfuncs # (which tests whether $OCF_ROOT points to a directory metadata-%.xml: $(radir)/% OCF_ROOT=. OCF_FUNCTIONS_DIR=$(radir) $< meta-data > $@ metadata-IPv6addr.xml: ../../heartbeat/IPv6addr OCF_ROOT=. OCF_FUNCTIONS_DIR=$(radir) $< meta-data > $@ # Please note: we can't name the man pages # ocf:heartbeat:. Believe me, I've tried. It looks like it # works, but then it doesn't. While make can deal correctly with # colons in target names (when properly escaped), it royally messes up # when it is deals with _dependencies_ that contain colons. See Bug # 12126 on savannah.gnu.org. But, maybe it gets fixed soon, it was # first reported in 1995 and added to Savannah in in 2005... if BUILD_DOC man_MANS = ocf_heartbeat_AoEtarget.7 \ ocf_heartbeat_AudibleAlarm.7 \ ocf_heartbeat_ClusterMon.7 \ ocf_heartbeat_CTDB.7 \ ocf_heartbeat_Delay.7 \ ocf_heartbeat_Dummy.7 \ ocf_heartbeat_EvmsSCC.7 \ ocf_heartbeat_Evmsd.7 \ ocf_heartbeat_Filesystem.7 \ ocf_heartbeat_ICP.7 \ ocf_heartbeat_IPaddr.7 \ ocf_heartbeat_IPaddr2.7 \ ocf_heartbeat_IPsrcaddr.7 \ ocf_heartbeat_LVM.7 \ ocf_heartbeat_LinuxSCSI.7 \ ocf_heartbeat_MailTo.7 \ ocf_heartbeat_ManageRAID.7 \ ocf_heartbeat_ManageVE.7 \ ocf_heartbeat_Pure-FTPd.7 \ ocf_heartbeat_Raid1.7 \ ocf_heartbeat_Route.7 \ ocf_heartbeat_SAPDatabase.7 \ ocf_heartbeat_SAPInstance.7 \ ocf_heartbeat_SendArp.7 \ ocf_heartbeat_ServeRAID.7 \ ocf_heartbeat_SphinxSearchDaemon.7 \ ocf_heartbeat_Squid.7 \ ocf_heartbeat_Stateful.7 \ ocf_heartbeat_SysInfo.7 \ ocf_heartbeat_VIPArip.7 \ ocf_heartbeat_VirtualDomain.7 \ ocf_heartbeat_WAS.7 \ ocf_heartbeat_WAS6.7 \ ocf_heartbeat_WinPopup.7 \ ocf_heartbeat_Xen.7 \ ocf_heartbeat_Xinetd.7 \ ocf_heartbeat_anything.7 \ ocf_heartbeat_apache.7 \ ocf_heartbeat_asterisk.7 \ ocf_heartbeat_clvm.7 \ ocf_heartbeat_conntrackd.7 \ ocf_heartbeat_db2.7 \ ocf_heartbeat_dhcpd.7 \ ocf_heartbeat_eDir88.7 \ ocf_heartbeat_ethmonitor.7 \ ocf_heartbeat_exportfs.7 \ ocf_heartbeat_fio.7 \ ocf_heartbeat_iSCSILogicalUnit.7 \ ocf_heartbeat_iSCSITarget.7 \ ocf_heartbeat_iface-bridge.7 \ ocf_heartbeat_iface-vlan.7 \ ocf_heartbeat_ids.7 \ ocf_heartbeat_iscsi.7 \ ocf_heartbeat_jboss.7 \ + ocf_heartbeat_kamailio.7 \ ocf_heartbeat_lxc.7 \ ocf_heartbeat_mysql.7 \ ocf_heartbeat_mysql-proxy.7 \ ocf_heartbeat_named.7 \ ocf_heartbeat_nfsserver.7 \ ocf_heartbeat_nginx.7 \ ocf_heartbeat_oracle.7 \ ocf_heartbeat_oralsnr.7 \ ocf_heartbeat_pgsql.7 \ ocf_heartbeat_pingd.7 \ ocf_heartbeat_portblock.7 \ ocf_heartbeat_postfix.7 \ ocf_heartbeat_pound.7 \ ocf_heartbeat_proftpd.7 \ ocf_heartbeat_rsyncd.7 \ ocf_heartbeat_rsyslog.7 \ ocf_heartbeat_scsi2reservation.7 \ ocf_heartbeat_sfex.7 \ ocf_heartbeat_slapd.7 \ ocf_heartbeat_symlink.7 \ ocf_heartbeat_syslog-ng.7 \ ocf_heartbeat_tomcat.7 \ ocf_heartbeat_varnish.7 \ ocf_heartbeat_vmware.7 \ ocf_heartbeat_zabbixserver.7 if USE_IPV6ADDR_AGENT man_MANS += ocf_heartbeat_IPv6addr.7 endif xmlfiles = $(man_MANS:.7=.xml) %.1 %.5 %.7 %.8: %.xml $(XSLTPROC) \ $(XSLTPROC_MANPAGES_OPTIONS) \ $(MANPAGES_STYLESHEET) $< ocf_heartbeat_%.xml: metadata-%.xml $(srcdir)/$(REFENTRY_STYLESHEET) $(XSLTPROC) --novalid \ --stringparam package $(PACKAGE_NAME) \ --stringparam version $(VERSION) \ --output $@ \ $(srcdir)/$(REFENTRY_STYLESHEET) $< ocf_resource_agents.xml: $(xmlfiles) mkappendix.sh ./mkappendix.sh $(xmlfiles) > $@ %.html: %.xml $(XSLTPROC) \ $(XSLTPROC_HTML_OPTIONS) \ --output $@ \ $(HTML_STYLESHEET) $< xml: ocf_resource_agents.xml endif diff --git a/heartbeat/Makefile.am b/heartbeat/Makefile.am index 2c3056da0..a82c926a2 100644 --- a/heartbeat/Makefile.am +++ b/heartbeat/Makefile.am @@ -1,148 +1,149 @@ # Makefile.am for OCF RAs # # Author: Sun Jing Dong # Copyright (C) 2004 IBM # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = $(ocf_SCRIPTS) $(ocfcommon_DATA) \ $(common_DATA) $(hb_DATA) $(dtd_DATA) \ README AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/linux-ha halibdir = $(libexecdir)/heartbeat ocfdir = $(OCF_RA_DIR_PREFIX)/heartbeat dtddir = $(datadir)/$(PACKAGE_NAME) dtd_DATA = ra-api-1.dtd if USE_IPV6ADDR_AGENT ocf_PROGRAMS = IPv6addr else ocf_PROGRAMS = endif if IPV6ADDR_COMPATIBLE halib_PROGRAMS = send_ua else halib_PROGRAMS = endif IPv6addr_SOURCES = IPv6addr.c IPv6addr_utils.c send_ua_SOURCES = send_ua.c IPv6addr_utils.c IPv6addr_LDADD = -lplumb $(LIBNETLIBS) send_ua_LDADD = $(LIBNETLIBS) ocf_SCRIPTS = ClusterMon \ CTDB \ Dummy \ IPaddr \ IPaddr2 \ anything \ AoEtarget \ apache \ asterisk \ nginx \ AudibleAlarm \ clvm \ conntrackd \ db2 \ dhcpd \ Delay \ eDir88 \ EvmsSCC \ Evmsd \ ethmonitor \ exportfs \ Filesystem \ fio \ ids \ iscsi \ ICP \ IPsrcaddr \ iSCSITarget \ iSCSILogicalUnit \ iface-bridge \ iface-vlan \ jboss \ + kamailio \ LinuxSCSI \ LVM \ lxc \ MailTo \ ManageRAID \ ManageVE \ mysql \ mysql-proxy \ named \ nfsserver \ oracle \ oralsnr \ pingd \ portblock \ postfix \ pound \ pgsql \ proftpd \ Pure-FTPd \ Raid1 \ Route \ rsyncd \ rsyslog \ SAPDatabase \ SAPInstance \ SendArp \ ServeRAID \ slapd \ SphinxSearchDaemon \ Squid \ Stateful \ SysInfo \ scsi2reservation \ sfex \ symlink \ syslog-ng \ tomcat \ VIPArip \ VirtualDomain \ varnish \ vmware \ WAS \ WAS6 \ WinPopup \ Xen \ Xinetd \ zabbixserver ocfcommondir = $(OCF_LIB_DIR_PREFIX)/heartbeat ocfcommon_DATA = ocf-shellfuncs \ ocf-binaries \ ocf-directories \ ocf-returncodes \ ocf-rarun \ apache-conf.sh \ http-mon.sh \ sapdb-nosha.sh \ sapdb.sh \ ora-common.sh \ findif.sh # Legacy locations hbdir = $(sysconfdir)/ha.d hb_DATA = shellfuncs diff --git a/heartbeat/kamailio b/heartbeat/kamailio new file mode 100755 index 000000000..e80e4a053 --- /dev/null +++ b/heartbeat/kamailio @@ -0,0 +1,642 @@ +#!/bin/bash +# +# OCF resource agent for Kamailio for pacemaker +# + +# Copyright (c) 2013 FREQUENTIS AG, +# Authors: Stefan Wenk +# Rainer Brestan +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +# + +# OCF input parameters: +# OCF_RESKEY_binary +# OCF_RESKEY_conffile +# OCF_RESKEY_pidfile +# OCF_RESKEY_monitoring_ip +# OCF_RESKEY_listen_address +# OCF_RESKEY_port +# OCF_RESKEY_proto +# OCF_RESKEY_sipsak +# OCF_RESKEY_kamctlrc + +# Initialization: + +: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat} +. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs + +####################################################################### +# Defaults + +RESKEY_binary_default="/usr/sbin/kamailio" +RESKEY_conffile_default="/etc/kamailio/kamailio.cfg" +RESKEY_pidfile_default="/var/run/kamailio.pid" +RESKEY_monitoring_ip_default=127.0.0.1 +RESKEY_port_default=5060 +RESKEY_proto_default="udptcp" +RESKEY_sipsak_default="/usr/bin/sipsak" +RESKEY_kamctlrc_default="/etc/kamailio/kamctlrc" + +####################################################################### +: ${OCF_RESKEY_binary=${RESKEY_binary_default}} +: ${OCF_RESKEY_conffile=${RESKEY_conffile_default}} +: ${OCF_RESKEY_pidfile=${RESKEY_pidfile_default}} +: ${OCF_RESKEY_monitoring_ip=${RESKEY_monitoring_ip_default}} +: ${OCF_RESKEY_port=${RESKEY_port_default}} +: ${OCF_RESKEY_proto=${RESKEY_proto_default}} +: ${OCF_RESKEY_sipsak=${RESKEY_sipsak_default}} +: ${OCF_RESKEY_kamctlrc=${RESKEY_kamctlrc_default}} + +####################################################################### +usage() { + cat < + + +1.0 + + + Resource agent for the Kamailio SIP proxy/registrar. + Multiple instances are possible when using following parameter combinations: + + Parameters for Kamailio instance 1: + listen_address=192.168.159.128 + monitoring_ip=192.168.159.128 + proto=udptcp + port=5060 + + Parameters for Kamailio instance 2: + listen_address=192.168.159.128 + monitoring_ip=192.168.159.128 + proto=udp + port=5070 + conffile=/etc/kamailio/kamailio2.cfg + kamctlrc="" + pidfile="/var/run/kamailio2.pid" + + Only one instance can be monitored via the command "kamctl monitor" + because the kamctl tool of kamailio 4.x is not designed for multiple + instances. Therefore, the provided kamctrlrc file path needs to be + empty for instance 2, 3 ... + +Parameters for a third Kamailio instance: + listen_address=192.168.159.128 + monitoring_ip=192.168.159.128 + proto=tcp + port=5080 + conffile=/etc/kamailio/kamailio3.cfg + kamctlrc="" + pidfile="/var/run/kamailio3.pid" +... + + + +Resource agent for Kamailio + + + + The kamailio binary + The kamailio binary + + + + + + The kamailio configuration file name with full path. + For example, "/etc/kamailio/kamailio.cfg" , which is the default value. + Make sure to use unique names in case of having multiple instances. + + Configuration file name with full path + + + + + + The kamailio PID file. Make sure to use unique PID file names in case of multiple instances. + + PID file + + + + + + SIP IP Address of the kamailio instance used for SIP OPTIONS polling monitoring. + Usually the same IP address value as for parameter listen_address should be + provided. + + In order to respond with a 200 OK response to the SIP OOPTION requests, + the kamailio.cfg file needs to contain following section: + Note: The following "kamailio.cfg" code sniplet is part of an XML section. + Therefore it contains two & characters, which need to be replaced + with two ampersand characters within "kamailio.cfg": + + if (is_method("OPTIONS") && ($ru=~"sip:monitor@.*")) { + ## + ## If the method is an OPTIONS we are simply going to respond + ## with a 200 OK. + # xlog("L_INFO", "Method is an OPTIONS, probably just monitoring\n"); + sl_send_reply("200", "Kamailio is alive"); + exit; + } + + + Monitoring IP address used for SIP OPTIONS polling. + + + + + + SIP IP address the kamailio will listen on. + + Listening SIP address + + + + + + SIP port for the kamailio instance. + + SIP Port + + + + + + The protocol used for SIP proto = udp|tcp|udptcp. + + protocol + + + + + + The installation path of the sipsak tool, which is used + for monitoring Kamailio via SIP OPTIONS polling. + + protocol + + + + + + The location of the "kamctlrc" file for the Kamailio instance. + The file "kamctlrc" is the Kamailio configuration file for its "kamctl" control tool. + + This parameter only needs to be provided in case of using multiple Kamailio server + instances on a single cluster node: + + In case that the parameter "kamctlrc" is not empty, this ressource agent monitors + the health state of the Kamailio server via the command "kamctl monitor 1". This + setting is recommended in case of using a single Kamailio server instance. + + In case that the parameter "kamctlrc" is empty, the ressource agent does not + monitor the health state of the Kamailio server instance via the "kamctl" command. + + Please note that the "kamctl" control command of Kamailio 4.x does not support + running multiple Kamailio instances on one host. Nevertheless this resource agent + does allow multiple Kamailio instances per host. The result of the "kamctl" + limitation in terms of number of Kamailio server instances is that the health + check via "kamctl monitor 1" can be configured for a single Kamailio instance + only. + + Please refer to the long description of this resoure agent for an example + of parameter combinations in case that multiple instances are to be + configured per cluster node. + + + protocol + + + + + + + + + + + + + + +END + + exit $OCF_SUCCESS +} + +####################################################################### +# Constants + +# Timeouts +KAMAILIO_START_TIMEOUT=3 # time for kamailio process to come up (s) +KAMAILIO_STOP_TIMEOUT=25 # time for kill SIGTERM (s) + +### +#Check if a process with given PID is running +# Parameter 1: PID +### +isRunning_PID() +{ + kill -s 0 "$1" > /dev/null 2>&1 +} + +### +#Check if an instance with given command line is running +# Parameter 1: command line. +### +isRunning_cmd() +{ + pkill -s 0 "$1" > /dev/null 2>&1 +} + +### +# Formats the result of a command. +# +# Parameter 1: Exit status. +# Parameter 2: Standard output (stdout). +# Parameter 3: Error output (stderr). +# Returns: Formatted result. +kamailio_format_result() { + local exitstatus="$1" + local value="$2" + local error="$3" + echo -n "exit status: ${exitstatus}" + if [ -n "$value" ]; then + echo -n ", value: ${value}" + fi + if [ -n "$error" ]; then + echo -n ", error: ${error}" + fi + echo +} + +### +# Put the command line, how the kamailio process is started according +# to the configured parameters, into the variable "kam_cmd". +### + +kamailio_cmd() +{ + case ${OCF_RESKEY_proto} in + udp) listen_param="-T -l udp:${OCF_RESKEY_listen_address}:${OCF_RESKEY_port} -l udp:127.0.0.1:${OCF_RESKEY_port}" + ;; + tcp) listen_param="-l tcp:${OCF_RESKEY_listen_address}:${OCF_RESKEY_port} -l tcp:127.0.0.1:${OCF_RESKEY_port}" + ;; + udptcp) listen_param1="-l udp:${OCF_RESKEY_listen_address}:${OCF_RESKEY_port} -l udp:127.0.0.1:${OCF_RESKEY_port}" + listen_param2="-l tcp:${OCF_RESKEY_listen_address}:${OCF_RESKEY_port} -l tcp:127.0.0.1:${OCF_RESKEY_port}" + listen_param="${listen_param1} ${listen_param2}" + ;; + *) listen_param="-T" + ;; + esac + + kam_cmd="${OCF_RESKEY_binary} -P ${OCF_RESKEY_pidfile} -f ${OCF_RESKEY_conffile} $listen_param" +} + +### +# Gets the PID for the running Kamailio instance. +# +# Returns: The variable $PID contains the found PID value or an empty string. +# Exit Status: Zero if the PID file was found and this process run under +# the command line parameters of our instance. +# 1) if the PID file is not present and no process running under +# our command line options is active. +# 2) in all other fatal cases, which we classify in the followig +# as OCF_ERR_genering. These are folloing cases: +# a) The PID file contains a PID value which does no match to +# to our instance +# b) The PID contains a empty string in its first line +# c) The PID file contains some text and some processeses +# from our instance are still active + +kamailio_get_pid() { + if [ -f ${OCF_RESKEY_pidfile} ]; then + PID=`head -n 1 $OCF_RESKEY_pidfile` + if [ ! -z "$PID" ]; then + #Cross check if the PID file really contains a process of our kamailio instance: + kamailio_cmd + CROSSPID=`pgrep -o -f "${kam_cmd}"` + if [ x"$PID" == x"$CROSSPID" ]; then + #ocf_log debug "Found kamailio process PID with value: $PID." + return 0 + else + #ocf_log debug "PID file does not contain a PID of a $OCF_RESKEY_binary process!" + return 2 + fi + else + #PID file does not contain a valid PID + rm -f ${OCF_RESKEY_pidfile} + return 2 + fi + else + # No PID file found! + #Check if still a process exists even though we don't have the PID any longer: + kamailio_cmd + pgrep -f "${kam_cmd}" + if [ $? -eq 0 ]; then + ocf_log info "PID file does not contain a valid PID, but kamailio process is still active" + return 2 + else + ocf_log info "No PID file found and our kamailio instance is not active" + return 1 + fi + fi +} + +kamailio_status() { + local not_running_log_level="warn" + if [ "$__OCF_ACTION" = "start" ]; then + not_running_log_level="debug" + fi + + kamailio_get_pid >/dev/null + RET=$? + if [ $RET -eq 0 ]; then + PID=`head -n 1 $OCF_RESKEY_pidfile` + isRunning_PID "$PID" + RET=$? + if [ "$RET" -ne 0 ]; then + ocf_log $not_running_log_level "PID from $PID from ${OCF_RESKEY_pidfile} not running" + rm -f ${OCF_RESKEY_pidfile} + return $OCF_NOT_RUNNING + fi + + rc=0 + # In case that OCF_RESKEY_kamctlrc we perfom a health check via "kamctl monitor 1" + if [ ! -z ${OCF_RESKEY_kamctlrc} ]; then + # PID is running now but it is not save to check via kamctl without care, because + # the implementation analysis in the case that we kill all running processes + # shows that in case that the fifo cannot be read, then kamctl blocks. This needs + # to be avoided. + # In order to be on the safe side, we run this check therefore under "timeout" control: + rc=1 + timeout 3 kamctl monitor 1 |grep "Up since" ; rc=$? + fi + + if [ $rc -ne 0 ]; + then + ocf_log $not_running_log_level "Kamailio is not up according to kamctl monitor!" + return $OCF_NOT_RUNNING + else + local errorfile error output + errorfile=`mktemp` + case ${OCF_RESKEY_proto} in + udp) output=`$OCF_RESKEY_sipsak -s sip:monitor@$OCF_RESKEY_monitoring_ip:${OCF_RESKEY_port} -H localhost --transport udp>/dev/null 2>>$errorfile` + result=$? + ;; + tcp) output=`$OCF_RESKEY_sipsak -s sip:monitor@$OCF_RESKEY_monitoring_ip:${OCF_RESKEY_port} -H localhost --transport tcp>/dev/null 2>>$errorfile` + result=$? + ;; + udptcp) output=`$OCF_RESKEY_sipsak -s sip:monitor@$OCF_RESKEY_monitoring_ip:${OCF_RESKEY_port} -H localhost --transport tcp>/dev/null 2>>$errorfile` + result=$? + if [ $result -eq 0 ]; then + output=`$OCF_RESKEY_sipsak -s sip:monitor@$OCF_RESKEY_monitoring_ip:${OCF_RESKEY_port} -H localhost --transport udp>/dev/null 2>>$errorfile` + result=$? + else + error=`cat $errorfile` + rm -f $errorfile + ocf_log $not_running_log_level "Kamailio is running, but not functional as sipsak TCP check failed with $(kamailio_format_result $result "$output" "$error")" + result=$? + fi + ;; + *) output=`$OCF_RESKEY_sipsak -s sip:monitor@$OCF_RESKEY_monitoring_ip:${OCF_RESKEY_port} -H localhost --transport udp>/dev/null 2>>$errorfile` + result=$? + ;; + esac + + error=`cat $errorfile` + rm -f $errorfile + + if [ $result -ne 0 ]; then + ocf_log $not_running_log_level "Kamailio is running, but not functional as sipsak ${OCF_RESKEY_proto} failed with $(kamailio_format_result $result "$output" "$error")" + return $OCF_ERR_GENERIC + else + return $OCF_SUCCESS + fi + fi + else + if [ $RET -eq 2 ]; then + ocf_log $not_running_log_level "PID file does not contain a PID of a ${OCF_RESKEY_binary} process!" + return $OCF_ERR_GENERIC + else + return $OCF_NOT_RUNNING + fi + fi +} + +kamailio_monitor() { + kamailio_status +} + +kamailio_start() { +if + kamailio_status +then + ocf_log info "kamailio already running." + return $OCF_SUCCESS +else + kamailio_cmd + #ocf_log debug ${kam_cmd} + + local errorfile error output + errorfile=`mktemp` + output=`${kam_cmd} 2>>$errorfile` + result=$? + error=`cat $errorfile` + rm -f $errorfile + + if [ $result -eq 0 ]; then + local -i wait_tries=$KAMAILIO_START_TIMEOUT + result=1 + while [ $wait_tries != 0 -a $result != 0 ]; do + sleep 1 + ((wait_tries--)) + kamailio_get_pid >/dev/null + result=$? + done + if [ $result -ne 0 ]; then + if [ $result -eq 2 ]; then + ocf_log err "kamailio instance could not be started: PID file does not contain a PID of a ${OCF_RESKEY_binary} process!" + result=$OCF_ERR_GENERIC + else + ocf_log error "Kamailio has not started (timeout)!" + result=$OCF_NOT_RUNNING + fi + else + ocf_log info "kamailio instance PID=$PID started." + result=$OCF_SUCCESS + fi + else + ocf_log err "kamailio instance could not be started, $(kamailio_format_result $result "$output" "$error")" + result=$OCF_NOT_RUNNING + fi + return $result +fi +} + +kamailio_stop() { + result=$OCF_SUCCESS + kamailio_cmd + + ocf_log info "Stopping kamailio by sending SIGTERM to ${kam_cmd}" + pkill -SIGTERM -x -f "${kam_cmd}" + if [ "$?" -eq 0 ]; then + TRIES=0 + while isRunning_cmd "${kam_cmd}" && [ "$TRIES" -lt "${KAMAILIO_STOP_TIMEOUT}" ] + do + sleep 1 + ocf_log info "kamailio ${kam_cmd} is still running after SIGTERM" + TRIES=`expr $TRIES + 1` + done + isRunning_cmd "${kam_cmd}" + RET=$? + if [ "$RET" -eq 0 ]; then + ocf_log info "Killing ${kam_cmd} with SIGKILL" + TRIES=0 + pkill -SIGKILL -x -f "${kam_cmd}" > /dev/null 2>&1 + while isRunning_cmd "${kam_cmd}" && [ "$TRIES" -lt 3 ] + do + sleep 1 + ocf_log info "kamailio ${kam_cmd} is still running after SIGKILL" + TRIES=`expr $TRIES + 1` + done + isRunning_cmd "${kam_cmd}" + RET=$? + if [ "$RET" -eq 0 ]; then + ocf_log fatal "kamailio is still running even after SIGKILL" + result=$OCF_ERR_GENERIC + fi + else + ocf_log info "${kam_cmd} has stopped." + fi + fi + + rm -f ${OCF_RESKEY_pidfile} + return $result + +} + +kamailio_validate_all() { + # Check if kamailio configuration is valid before starting the server + + if [ ! -f $OCF_RESKEY_binary ]; then + ocf_log err "File OCF_RESKEY_binary [${OCF_RESKEY_binary}] does not exist!" + return $OCF_NOT_INSTALLED + fi + + out=$($OCF_RESKEY_binary -c 2>&1 > /dev/null) + retcode=$? + if [ "$retcode" -ne '0' ]; then + ocf_log info "Not starting kamailio: $OCF_RESKEY_binary does not start!" + return $OCF_ERR_CONFIGURED + fi + + case $OCF_RESKEY_monitoring_ip in + "") ocf_log err "Required parameter OCF_RESKEY_monitoring_ip is missing!" + return $OCF_ERR_CONFIGURED + ;; + [0-9]*.[0-9]*.[0-9]*.[0-9]*) : OK + ;; + *) ocf_log err "Parameter OCF_RESKEY_monitoring_ip [$OCF_RESKEY_monitoring_ip] is not an IP address!" + return $OCF_ERR_CONFIGURED + ;; + esac + + case $OCF_RESKEY_listen_address in + "") ocf_log err "Required parameter $OCF_RESKEY_listen_address is missing!" + return $OCF_ERR_CONFIGURED + ;; + [0-9]*.[0-9]*.[0-9]*.[0-9]*) : OK + ;; + *) ocf_log err "Parameter OCF_RESKEY_listen_address [$OCF_RESKEY_listen_address] not an IP address!" + return $OCF_ERR_CONFIGURED + ;; + esac + + if [ ! -f ${OCF_RESKEY_sipsak} ]; then + ocf_log err "sipsak [${OCF_RESKEY_sipsak}] does not exist!" + return $OCF_NOT_INSTALLED + fi + + if [ ! -z ${OCF_RESKEY_kamctlrc} ]; then + if [ ! -f ${OCF_RESKEY_kamctlrc} ]; then + ocf_log err "kamctlrc file [${kamctlrc}] does not exist!" + return $OCF_NOT_INSTALLED + fi + else + ocf_log debug "No monitoring via kamctl monitor because the parameter [kamctlrc] is empty." + fi + + if [ ! -f ${OCF_RESKEY_conffile} ]; then + ocf_log err "Kamailio configuration file provided in the parameter conffile [${OCF_RESKEY_conffile}] does not exist!" + return $OCF_ERR_CONFIGURED + fi + + case $OCF_RESKEY_proto in + "") ocf_log err "Parameter $OCF_RESKEY_proto is empty!" + return $OCF_ERR_CONFIGURED + ;; + udp|tcp|udptcp) : OK + ;; + *) ocf_log err "Parameter value $OCF_RESKEY_proto for parameter [proto] not yet supported!" + return $OCF_ERR_CONFIGURED + ;; + esac + + return $OCF_SUCCESS +} + +if [ $# -ne 1 ]; then + usage + exit $OCF_ERR_ARGS +fi + +case $__OCF_ACTION in + meta-data) meta_data + exit $OCF_SUCCESS + ;; + start|stop|status|monitor) + kamailio_${__OCF_ACTION} + ;; + validate-all) kamailio_validate_all + ;; + notify) exit $OCF_SUCCESS + ;; + usage) usage + exit $OCF_SUCCESS + ;; +# reload) #Not supported by Kamailio, but not needed by pacemaker +# ;; +# recover #Not needed by pacemaker +# ;; + *) usage + exit $OCF_ERR_UNIMPLEMENTED + ;; +esac + +exit $?