3
# Startup/shutdown script for services managed by xinetd.
5
# Copyright (C) 2003 Charlie Brooks
7
# WARNING: Tested ONLY on Red Hat 7.3 and Fedora Core 2/4 at this time.
9
# Author: Charlie Brooks <ha@HBCS.Org>
10
# Description: given parameters of a service name and start|stop|status,
11
# will enable, disable or report on a specified xinetd service
12
# Config: all services must have a descriptor file in /etc/xinetd.d
13
# Support: linux-ha@lists.linux-ha.org
14
# License: GNU General Public License (GPL)
16
# OCF parameters are as below:
19
#######################################################################
22
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
23
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs
25
#######################################################################
30
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
31
<resource-agent name="Xinetd">
32
<version>1.0</version>
35
Resource script for Xinetd. It starts/stops services managed
38
Note that the xinetd daemon itself must be running: we are not
39
going to start it or stop it ourselves.
41
Important: in case the services managed by the cluster are the
42
only ones enabled, you should specify the -stayalive option for
43
xinetd or it will exit on Heartbeat stop. Alternatively, you may
44
enable some internal service such as echo.
46
<shortdesc lang="en">Manages an Xinetd service</shortdesc>
49
<parameter name="service" unique="0" required="1">
51
The service name managed by xinetd.
53
<shortdesc lang="en">service name</shortdesc>
54
<content type="string" default="" />
59
<action name="start" timeout="20" />
60
<action name="stop" timeout="20" />
61
<action name="restart" timeout="40" />
62
<action name="status" depth="0" timeout="10" interval="10" />
63
<action name="monitor" depth="0" timeout="10" interval="10" />
64
<action name="validate-all" timeout="5" />
65
<action name="meta-data" timeout="5" />
71
# don't rely on the pid file, but lookup xinetd in the list of
75
pid=`ps -e -o pid,command | grep '/[x]inetd' | awk '{print $1}'`
77
if kill -HUP $pid; then
80
ocf_log err "Could not SigHUP xinetd superdaemon!"
81
ocf_log err "perhaps we are booting after a system crash"
85
ocf_log err "xinetd superdaemon process not found!"
86
ocf_log err "perhaps we are currently booting the system."
92
if [ "running" = "`xup_status`" ]; then
93
ocf_log info "Service $service already started"
97
ocf_log "info" "$0: enabling in $RCFILE"
98
if $AWK '!/disable/' $RCFILE > $RCFILE.xup
100
if mv $RCFILE.xup $RCFILE
102
ocf_log "info" "$0: Starting"
106
ocf_log "err" "Could not replace $RCFILE"
109
ocf_log "err" "Could not rewrite $RCFILE!"
114
if [ "stopped" = "`xup_status`" ]; then
115
ocf_log info "Service $service already stopped"
119
ocf_log "info" "$0: disabling in $RCFILE"
120
if $AWK '!/disable/;/{/{printf "\tdisable\t\t\t= yes\n"}' $RCFILE >$RCFILE.xup
122
if mv $RCFILE.xup $RCFILE
124
ocf_log "info" "$0: Shutting down"
128
ocf_log "err" "Could not replace $RCFILE"
131
ocf_log "err" "Could not rewrite $RCFILE!"
136
echo "Usage: $0 {start|stop|restart|status|monitor|validate-all|meta-data}"
141
if [ -f $PIDFILE ]; then
146
return $OCF_NOT_RUNNING
151
# Check if the arg is a valid integer
154
# Examples of valid integer: "1080", "1", "0080", "0", "0000"
155
# Examples of invalid integer: "1080bad", ""
159
*[!0-9]*) #got invalid char
161
*) #no invalid char, and has at least one digit, so is a good integer
167
# Check if the arg is a valid umask
170
# Examples of valid umask: "100", "1", "000", "0"
171
# Examples of invalid umask: "108", "bad", "1111" ""
184
# Check (part of) the attributes based on xinetd.conf(5) and xinetd source code
188
check_attributes () {
189
# Empty these attributes before validating them
190
unset socket_type wait server user protocol port group instances \
191
type flags disable nice umask
193
for SECTION in $*; do
195
*=*) # Check to see if we need to export the previous name=value
197
if [ -n "$VAR" ]; then
200
# Save the "new" name=value pair in VAR
203
*) # This section does not have an equal sign, therefore it is part of
204
# the *previous* name=value pair, thus we will append it to the
205
# previous name=value assignment.
209
# A final cleanup step.
210
# Do we need to export VAR ?
211
if [ -n "$VAR" ]; then
215
if [ $? -ne 0 ]; then
216
return $OCF_ERR_GENERIC
220
"") disable=no # Default to no.
223
*) ocf_log err "Invalid value for disable [$disable] in $RCFILE, yes|no please"
224
exit $OCF_ERR_CONFIGURED
229
"") socket_type=dgram
230
# Default value for socket_type is dgram.
232
stream|dgram|raw|seqpacket)
234
*) ocf_log err "Invalid socket type $socket_type in $RCFILE"
235
exit $OCF_ERR_CONFIGURED
239
case $wait in # Wait has no default value.
241
*) ocf_log err "Invalid waid [$wait] in $RCFILE, yes|no please"
242
exit $OCF_ERR_CONFIGURED
247
# Default value for type is RPC or INTERNAL, determined at compile time.
248
# It may be a list in $RCFILE, however we only capture the first one.
249
""|RPC|INTERNAL|UNLISTED|SPECIAL|TCPMUX|TCPMUXPLUS)
251
*) ocf_log err "Invalid service type [$type] in $RCFILE"
252
exit $OCF_ERR_CONFIGURED
256
if [ ! -z "$type" -a "INTERNAL" != "$type" ]; then
257
# Type is explicitly set to EXTERNAL, hence server and user are necessary.
259
"") ocf_log err "Please specify server in $RCFILE"
260
exit $OCF_ERR_CONFIGURED
262
/*) if [ -x $server ]; then
265
ocf_log err "Server $server is not executable"
266
exit $OCF_ERR_CONFIGURED
269
*) ocf_log err "Server $server is not of obsolute path"
270
exit $OCF_ERR_CONFIGURED
275
"") ocf_log err "Please specify user in $RCFILE"
276
exit $OCF_ERR_CONFIGURED
278
*) getent passwd $user >/dev/null 2>&1
279
if [ $? -ne 0 ]; then
280
ocf_log err "User $user does not exist!"
281
exit $OCF_ERR_CONFIGURED
286
# Protocol is necessary when type is MUX
287
if [ $type = "TCPMUX" -o $type ="TCPMUXPLUS" ]; then
289
"") ocf_log err "Please specify protocol in $RCFILE"
290
exit $OCF_ERR_CONFIGURED
292
*) get protocols $protocol >/dev/null 2>&1
293
if [ $? -ne 0 ]; then
294
ocf_log err "Invalid protocol [$protocol] in $RCFILE"
295
exit $OCF_ERR_CONFIGURED
303
"") ;; # OK to be empty, the group for $user is used
304
*) getent group $group >/dev/null 2>&1
305
if [ $? -ne 0 ]; then
306
ocf_log err "Group $group does not exist!"
307
exit $OCF_ERR_CONFIGURED
313
# Default value for flags is REUSE.
314
# It may be a list in $RCFILE, however we only capture the first one.
317
REUSE|INTERCEPT|NORETRY|IDONLY|NAMEINARGS|NODELAY|KEEPALIVE|NOLIBWRAP|SENSOR|IPv4|IPv6) ;;
318
*) ocf_log err "Invalid flags [$flags] in $RCFILE"
319
exit $OCF_ERR_CONFIGURED
324
""|[Uu][Nn][Ll][Ii][Mm][Ii][Ti][Ee][Dd]) ;;
325
*) if CheckInteger $instances; then
328
ocf_log err "Invalid instances [$instances] in $RCFILE, non-negative integer expected"
329
exit $OCF_ERR_CONFIGURED
336
*) local foo=`echo $nice | sed s/^-//`
337
if CheckInteger $foo; then
340
ocf_log err "Invalid nice [$nice] in $RCFILE, integer expected"
341
exit $OCF_ERR_CONFIGURED
346
if [ ! -z $umask ]; then
347
if CheckUmask $umask; then
350
ocf_log err "Invalid umask [$umask] in $RCFILE"
351
exit $OCF_ERR_CONFIGURED
356
xup_validate_all () {
359
# Parse the $RCFILE for necessary attributes, assume $RCFILE does not
360
# contain "include" or "includedir" directives.
362
leading_space="^$space"
363
trailing_space="$space$"
366
# Strip comments, delete blank lines.
367
stripped=`sed -e "/^$comment/d" -e "/=$trailing_space/d" -e "/$leading_space$/d" $RCFILE`
369
stripped=`echo $stripped`
370
# At this stage, stripped="service <service-name> { attribute-list }".
373
ocf_log err "Descriptor file $RCFILE contains extra \"#\", which is forbidden"
374
exit $OCF_ERR_CONFIGURED
380
ocf_log err "Attribute needs a space before operator ="
381
exit $OCF_ERR_CONFIGURED
384
ocf_log err "Attribute needs a space before operator [+-]="
385
exit $OCF_ERR_CONFIGURED
390
# Strip leading "service" keyword, remove spaces surrounding "=".
391
stripped=`echo $stripped | sed -e "s/^service//" -e "s/-=/ /g" \
392
-e "s/+=/=/g" -e "s/$space=$space/=/g"`
393
# At this stage, stripped=" <service-name> { attribute-list }",
394
# note that the leading space before <service-name> is significant.
397
stripped=`echo $stripped | sed -e "s/$leading_space[^ \t]\+$space//"`
398
# At this stage, stripped="{ attribute-list }"
401
stripped=`echo $stripped | sed -e "s/^{//" -e "s/}$//"`
402
# At this stage, stripped=<attribute-list>
404
check_attributes "$stripped"
408
ocf_log err "Attrbute list should be contained in {}"
409
exit $OCF_ERR_CONFIGURED
415
ocf_log err "Service name should follow the service key word"
416
exit $OCF_ERR_CONFIGURED
422
ocf_log err "Service key word is necessary in $RCFILE"
423
exit $OCF_ERR_CONFIGURED
434
# These operations do not require OCF instance parameters to be set
448
[ -z "$OCF_RESKEY_service" ]
450
ocf_log err "Please set OCF_RESKEY_service to the service managed by Xinetd"
451
if [ "$1" = "start" ]; then
454
exit $OCF_NOT_RUNNING
458
service=$OCF_RESKEY_service
459
RCFILE=/etc/xinetd.d/$service
460
PIDFILE=$HA_VARRUN/xup$service
462
# Make sure the OCF_RESKEY_service is a valid xinetd service name
463
if [ ! -f $RCFILE ]; then
464
ocf_log err "Service descriptor $RCFILE not found!"
465
if [ "$1" = "start" ]; then
468
exit $OCF_NOT_RUNNING
472
# See how we were called.
488
xup_status > /dev/null
495
exit $OCF_ERR_UNIMPLEMENTED