Hi again,
fix in validate all. See attachment...
Achim Stumpf wrote:
Hi Dejan,
After a long long time... You find the new script in the attachment.
Dejan Muhamedagic wrote:
Hi Achim,
On Thu, Nov 20, 2008 at 01:32:06PM +0100, Achim Stumpf wrote:
Hi,
I am still waiting for further advice to finish the commit
process to your repository. ;o)
I'd have a few suggestions as well:
1. You could drop both connect_timeout and max_time parameters.
It is advisable to have the upper layer decide when an operation
should timeout (by setting the operation's "timeout" attribute).
done
2. kill -0 "$1"
returns success with zombie processes too.
I have checked the other scripts, some of them check /proc/pid. But with
a zombie it's the same as with kill -0. What do you suggest?
3. Poftpd: a typo in a message.
done
4. In proftpd_start()
# check that the proftpd binary exists
if [ ! -x "$OCF_RESKEY_binary" ]; then
ocf_log err "Proftpd binary $OCF_RESKEY_binary does not exist"
exit $OCF_ERR_CONFIGURED
This belongs to validate. Should also be OCF_ERR_INSTALLED.
moved to validate
5. In proftpd_stop()
...
TRIES=0
while isRunning "$PID" && [ $TRIES -lt 5 ]
do
sleep 1
kill $PID > /dev/null 2>&1
ocf_log info "Killing Proftpd PID $PID"
TRIES=`expr $TRIES + 1`
done
Move the kill command in front of the loop: it's enough to send a
signal once. The same for the latter 'kill -9'. You can also try
other signals, such as HUP (see, perhaps, the proftpd docs).
Also, could it be that 5 seconds is a bit too short to let the
ftpd exit?
As in 1. above, it's better to leave the timeout handling to
lrmd. You can just do an infinite look here:
while isRunning "$PID"; do
sleep 1
...
done
Before it wasn't only 5 seconds. It was five seconds for kill, and then
you got another loop with kill -9. for kill it is 30 second's
now. And an infinite loop with kill -9. The kill and kill -9 is in front
of the loop and only sleep and logging is left inside the loop.
6. In proftpd_monitor()
ocf_log err "Proftpd monitor on PID $PID failed"
It may or may not be an error if proftpd is not running. Better
to keep silent.
changed to debug
ocf_log err "$OCF_RESKEY_curl_binary does not exist"
return $OCF_ERR_CONFIGURED
This belongs to the validate action. The error should be
OCF_ERR_INSTALLED.
See the validate action in other OCF agents. Note that a failure
to validate the environment and parameters shouldn't influence
the meta-data operation.
I have checked other scripts. Most of them return just ocf_success. What
I have to check in validate all?
I have made just a test with a wrong path to the curl binary. heartbeat
does not do a validate all or? In the logs I see only that monitoring
fails. For whom is that validate all???
And... very sorry for taking this long.
Never mind...
Cheers
Achim
Cheers,
Dejan
Achim
Achim Stumpf wrote:
Hi,
What's about the proftpd script? Maybe we could finish that one... ;o)
Thanks,
Achim
Achim Stumpf wrote:
Hi,
Lars Marowsky-Bree wrote:
"start_delay" should not be necessary, unless your start operation is
broken.
I have removed the start_delay.
You also need to do a check_binary on the proftpd binary somewhere
prior
to calling this command.
All config files and binaries get checked now.
proftpd_stop()
{
if proftpd_status ; then
PID=`head -n 1 $OCF_RESKEY_pidfile`
if [ ! -z $PID ] ; then
kill $PID
if [ $? -ne 0 ]; then
ocf_log err "Proftpd couldn't be stopped"
return $OCF_ERR_GENERIC
fi
fi
fi
You need to check afterwards that the process is really gone. kill is
not sufficient; it might send the signal, but if the process is
stuck on
IO, it might not stop. I'd also recommend kill -9.
I have adapted some code of the apache ocf script:
proftpd_stop()
{
if proftpd_status ; then
PID=`head -n 1 $OCF_RESKEY_pidfile`
if [ ! -z "$PID" ]; then
kill $PID > /dev/null 2>&1 if [ $? -eq 0 ]; then
TRIES=0
while isRunning "$PID" && [ $TRIES -lt 5
] do
sleep 1
kill $PID > /dev/null 2>&1
ocf_log info "Killing Proftpd PID $PID"
TRIES=`expr $TRIES + 1`
done
TRIES=0
while isRunning "$PID" && [ $TRIES -lt 3
] do
sleep 1
kill -9 $PID > /dev/null 2>&1
ocf_log info "Killing Proftpd PID $PID with
SIGKILL"
TRIES=`expr $TRIES + 1`
done
if isRunning "$PID" ; then
ocf_log err "Killing Proftpd PID $PID FAILED"
exit $OCF_ERR_GENERIC
fi
else
ocf_log err "Killing Proftpd PID $PID FAILED"
exit $OCF_ERR_GENERIC
fi
fi
fi exit $OCF_SUCCESS
}
1. kill -15 2. if it is still running try max. 5 times to kill
again with kill -15
3. after that if it is still running try 3 times with kill -9
Hope that it meets your needs ;o)
And actually I got the idea to send in the while loop with kill -9
a kill -9 signal to all the child processes as returned by:
ps --no-headers -o pid --ppid $PID
If you like the above code and the idea with kill -9 to the child
processes, I will implement that too.
proftpd_monitor()
{
if [ $OCF_CHECK_LEVEL -eq 0 ]; then if
proftpd_status ; then
ocf_log debug "Proftpd monitor succeded"
return $OCF_SUCCESS
fi
else
${OCF_RESKEY_curl_binary} -sS --connect-timeout
${OCF_RESKEY_connect_timeout} --max-time ${OCF_RESKEY_max_time}
-u "${OCF_RESKEY_test_user}:${OCF_RESKEY_test_pass}"
ftp://localhost/ > /dev/null 2>&1
The curl_binary also needs to be "check_binary"ed somewhere.
done
And you might be managing several proftpd instances, none of which
might
bind to "localhost"; I think the URL needs to be configurable.
done
Thanks for your advice. Let's see what is wrong now... ;o)
Achim
_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/
_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/
#!/bin/sh
#
# Resource script for Proftpd
#
# Description: Manages Proftpd as an OCF resource in
# an Active-Passive High Availability setup.
#
# Author: Rajat Upadhyaya <[email protected]> : Pure-FTPd script
# Author: Achim Stumpf <[email protected]> : Rewrite as Proftpd
# License: GNU General Public License (GPL)
#
#
# usage: $0 {start|stop|status|monitor|validate-all|meta-data}
#
# The "start" arg starts Proftpd.
#
# The "stop" arg stops it.
#
# OCF parameters:
# OCF_RESKEY_binary
# OCF_RESKEY_conffile
# OCF_RESKEY_pidfile
# OCF_RESKEY_curl_binary
# OCF_RESKEY_curl_url
# OCF_RESKEY_test_user
# OCF_RESKEY_test_pass
#
##########################################################################
# Initialization:
. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs
: ${OCF_RESKEY_binary="/usr/sbin/proftpd"}
: ${OCF_RESKEY_conffile="/etc/proftpd.conf"}
: ${OCF_RESKEY_pidfile="/var/run/proftpd.pid"}
: ${OCF_RESKEY_curl_binary="/usr/bin/curl"}
: ${OCF_RESKEY_curl_url="ftp://localhost/"}
: ${OCF_RESKEY_test_user="test"}
: ${OCF_RESKEY_test_pass=""}
USAGE="Usage: $0 {start|stop|status|monitor|validate-all|meta-data}";
##########################################################################
usage() {
echo $USAGE >&2
}
meta_data() {
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="proftpd">
<version>1.0</version>
<longdesc lang="en">
This script manages Proftpd in an Active-Passive setup
</longdesc>
<shortdesc lang="en">OCF Resource Agent compliant FTP script.</shortdesc>
<parameters>
<parameter name="binary" unique="0" required="0">
<longdesc lang="en">The Proftpd binary</longdesc>
<shortdesc lang="en">The Proftpd binary</shortdesc>
<content type="string" default="/usr/sbin/proftpd" />
</parameter>
<parameter name="conffile" unique="0" required="0">
<longdesc lang="en">
The Proftpd configuration file name with full path.
For example, "/etc/proftpd.conf"
</longdesc>
<shortdesc lang="en">Configuration file name with full path</shortdesc>
<content type="string" default="/etc/proftpd.conf" />
</parameter>
<parameter name="pidfile" unique="0" required="0">
<longdesc lang="en">The Proftpd PID file. The location of the PID file is
configured in the Proftpd configuration file.</longdesc>
<shortdesc lang="en">PID file</shortdesc>
<content type="string" default="/var/run/proftpd.pid" />
</parameter>
<parameter name="curl_binary" unique="0" required="0">
<longdesc lang="en">The absolut path to the curl binary for monitoring with
OCF_CHECK_LEVEL greater zero.</longdesc>
<shortdesc lang="en">The absolut path to the curl binary</shortdesc>
<content type="string" default="/usr/bin/curl" />
</parameter>
<parameter name="curl_url" unique="0" required="0">
<longdesc lang="en">The URL which is checked by curl with OCF_CHECK_LEVEL
greater zero.</longdesc>
<shortdesc lang="en">The URL which is checked by curl</shortdesc>
<content type="string" default="ftp://localhost/" />
</parameter>
<parameter name="test_user" unique="0" required="0">
<longdesc lang="en">The name of the ftp user for monitoring with
OCF_CHECK_LEVEL greater zero.</longdesc>
<shortdesc lang="en">The name of the ftp user</shortdesc>
<content type="string" default="test" />
</parameter>
<parameter name="test_pass" unique="0" required="0">
<longdesc lang="en">The password of the ftp user for monitoring with
OCF_CHECK_LEVEL greater zero.</longdesc>
<shortdesc lang="en">The password of the ftp user</shortdesc>
<content type="string" default="" />
</parameter>
</parameters>
<actions>
<action name="start" timeout="90" />
<action name="stop" timeout="100" />
<action name="monitor" depth="10" timeout="20s" interval="60s" />
<action name="validate-all" timeout="30s" />
<action name="meta-data" timeout="5s" />
</actions>
</resource-agent>
END
exit $OCF_SUCCESS
}
isRunning()
{
kill -0 "$1" > /dev/null 2>&1
}
proftpd_status()
{
if [ -f "$OCF_RESKEY_pidfile" ]
then
# Proftpd is probably running
PID=`head -n 1 $OCF_RESKEY_pidfile`
if [ ! -z "$PID" ] ; then
isRunning "$PID" && `ps -p $PID | grep proftpd >
/dev/null 2>&1`
return $?
fi
fi
# Proftpd is not running
return $OCF_NOT_RUNNING;
}
proftpd_start()
{
# make a few checks and start Proftpd
if ocf_is_root ; then : ; else
ocf_log err "You must be root"
exit $OCF_ERR_PERM
fi
# if Proftpd is running return success
if proftpd_status ; then
ocf_log info "Proftpd is running already"
exit $OCF_SUCCESS
fi
# check that the Proftpd config file exist
if [ ! -f "$OCF_RESKEY_conffile" ]; then
ocf_log err "Proftpd config file $OCF_RESKEY_conffile does not
exist"
exit $OCF_ERR_CONFIGURED
fi
# starting Proftpd
${OCF_RESKEY_binary} --config ${OCF_RESKEY_conffile} 2>/dev/null
if [ "$?" -ne 0 ]; then
ocf_log err "Proftpd returned error" $?
exit $OCF_ERR_GENERIC
fi
exit $OCF_SUCCESS
}
proftpd_stop()
{
if proftpd_status ; then
PID=`head -n 1 $OCF_RESKEY_pidfile`
if [ ! -z "$PID" ]; then
ocf_log info "Killing Proftpd PID $PID"
kill $PID > /dev/null 2>&1
if [ "$?" -eq 0 ]; then
TRIES=0
while isRunning "$PID" && [ "$TRIES" -lt 30 ]
do
sleep 1
ocf_log info "Proftpd PID $PID is still
running"
TRIES=`expr $TRIES + 1`
done
isRunning "$PID"
RET=$?
if [ "$RET" -eq 0 ]; then
ocf_log info "Killing Proftpd PID $PID
with SIGKILL"
kill -9 $PID > /dev/null 2>&1
while isRunning "$PID"
do
sleep 1
ocf_log info "Proftpd PID $PID
is still running"
done
fi
else
ocf_log err "Killing Proftpd PID $PID FAILED"
exit $OCF_ERR_GENERIC
fi
fi
fi
exit $OCF_SUCCESS
}
proftpd_monitor()
{
proftpd_status
RET=$?
if [ "$RET" -ne 0 -o "$OCF_CHECK_LEVEL" -eq 0 ]; then
if [ "$RET" -eq 0 ]; then
PID=`head -n 1 $OCF_RESKEY_pidfile`
ocf_log debug "Proftpd monitor on PID $PID succeeded"
return $OCF_SUCCESS
else
ocf_log debug "Proftpd monitor on PID $PID failed"
return $OCF_NOT_RUNNING
fi
else
${OCF_RESKEY_curl_binary} -sS -u
"${OCF_RESKEY_test_user}:${OCF_RESKEY_test_pass}" ${OCF_RESKEY_curl_url} >
/dev/null 2>&1
if [ "$?" -eq 0 ]; then
ocf_log debug "Proftpd monitor with curl on URL
$OCF_RESKEY_curl_url succeeded"
return $OCF_SUCCESS
else
ocf_log err "Proftpd monitor with curl on URL
$OCF_RESKEY_curl_url failed"
return $OCF_NOT_RUNNING
fi
fi
}
proftpd_validate_all()
{
# check that the proftpd binary exists
if [ ! -x "$OCF_RESKEY_binary" ]; then
ocf_log err "Proftpd binary $OCF_RESKEY_binary does not exist"
return $OCF_ERR_INSTALLED
fi
# check that the curl binary exists
if [ ! -x "$OCF_RESKEY_curl_binary" ]; then
ocf_log err "$OCF_RESKEY_curl_binary does not exist"
return $OCF_ERR_INSTALLED
fi
return $OCF_SUCCESS
}
#
# Main
#
if [ $# -ne 1 ]
then
usage
exit $OCF_ERR_ARGS
fi
case $1 in
start) proftpd_start
;;
stop) proftpd_stop
;;
status) if proftpd_status
then
ocf_log info "Proftpd is running"
exit $OCF_SUCCESS
else
ocf_log info "Proftpd is stopped"
exit $OCF_NOT_RUNNING
fi
;;
monitor) proftpd_monitor
exit $?
;;
validate-all) proftpd_validate_all
exit $?
;;
meta-data) meta_data
;;
usage) usage
exit $OCF_SUCCESS
;;
*) usage
exit $OCF_ERR_UNIMPLEMENTED
;;
esac
_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/