~ubuntu-branches/ubuntu/maverick/cluster-agents/maverick-proposed

« back to all changes in this revision

Viewing changes to heartbeat/Xinetd

  • Committer: Bazaar Package Importer
  • Author(s): Ante Karamatic
  • Date: 2010-02-17 21:46:00 UTC
  • Revision ID: james.westby@ubuntu.com-20100217214600-g44grvtkw7jbpciz
Tags: upstream-1.0.2
ImportĀ upstreamĀ versionĀ 1.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/bin/sh
 
2
#
 
3
# Startup/shutdown script for services managed by xinetd.
 
4
#
 
5
#       Copyright (C) 2003 Charlie Brooks
 
6
#
 
7
# WARNING:      Tested ONLY on Red Hat 7.3 and Fedora Core 2/4 at this time.
 
8
#
 
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)
 
15
#
 
16
#         OCF parameters are as below:
 
17
#               OCF_RESKEY_service
 
18
 
 
19
#######################################################################
 
20
# Initialization:
 
21
 
 
22
: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/resource.d/heartbeat}
 
23
. ${OCF_FUNCTIONS_DIR}/.ocf-shellfuncs
 
24
 
 
25
#######################################################################
 
26
 
 
27
meta_data() {
 
28
        cat <<END
 
29
<?xml version="1.0"?>
 
30
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
 
31
<resource-agent name="Xinetd">
 
32
<version>1.0</version>
 
33
 
 
34
<longdesc lang="en">
 
35
Resource script for Xinetd. It starts/stops services managed
 
36
by xinetd.
 
37
 
 
38
Note that the xinetd daemon itself must be running: we are not
 
39
going to start it or stop it ourselves.
 
40
 
 
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.
 
45
</longdesc>
 
46
<shortdesc lang="en">Manages an Xinetd service</shortdesc>
 
47
 
 
48
<parameters>
 
49
<parameter name="service" unique="0" required="1">
 
50
<longdesc lang="en">
 
51
The service name managed by xinetd. 
 
52
</longdesc>
 
53
<shortdesc lang="en">service name</shortdesc>
 
54
<content type="string" default="" />
 
55
</parameter>
 
56
</parameters>
 
57
 
 
58
<actions>
 
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" />
 
66
</actions>
 
67
</resource-agent>
 
68
END
 
69
}
 
70
 
 
71
# don't rely on the pid file, but lookup xinetd in the list of
 
72
# processes
 
73
 
 
74
hup_inetd () {
 
75
    pid=`ps -e -o pid,command | grep '/[x]inetd' | awk '{print $1}'`
 
76
    if [ "$pid" ]; then
 
77
      if kill -HUP $pid; then
 
78
          :
 
79
      else
 
80
          ocf_log err "Could not SigHUP xinetd superdaemon!"
 
81
          ocf_log err "perhaps we are booting after a system crash"
 
82
          exit $OCF_ERR_GENERIC
 
83
      fi
 
84
    else
 
85
       ocf_log err "xinetd superdaemon process not found!"
 
86
       ocf_log err "perhaps we are currently booting the system."
 
87
       exit $OCF_ERR_GENERIC
 
88
    fi
 
89
}
 
90
 
 
91
xup_start () {
 
92
  if [ "running" = "`xup_status`" ]; then
 
93
    ocf_log info "Service $service already started"
 
94
    exit $OCF_SUCCESS
 
95
  fi
 
96
 
 
97
  ocf_log "info" "$0: enabling in $RCFILE"
 
98
  if $AWK '!/disable/' $RCFILE > $RCFILE.xup
 
99
    then
 
100
      if mv $RCFILE.xup $RCFILE
 
101
        then
 
102
          ocf_log "info" "$0: Starting"
 
103
          hup_inetd
 
104
          touch $PIDFILE
 
105
        else
 
106
          ocf_log "err" "Could not replace $RCFILE"
 
107
      fi
 
108
    else
 
109
      ocf_log "err" "Could not rewrite $RCFILE!"
 
110
  fi
 
111
}
 
112
 
 
113
xup_stop () {
 
114
  if [ "stopped" = "`xup_status`" ]; then
 
115
    ocf_log info "Service $service already stopped"
 
116
    exit $OCF_SUCCESS
 
117
  fi
 
118
 
 
119
  ocf_log "info" "$0: disabling in $RCFILE"
 
120
  if $AWK '!/disable/;/{/{printf "\tdisable\t\t\t= yes\n"}' $RCFILE >$RCFILE.xup
 
121
    then
 
122
      if mv $RCFILE.xup $RCFILE
 
123
        then
 
124
          ocf_log "info" "$0: Shutting down"
 
125
          hup_inetd 
 
126
          rm -f $PIDFILE
 
127
        else
 
128
          ocf_log "err" "Could not replace $RCFILE"
 
129
      fi
 
130
    else
 
131
      ocf_log "err" "Could not rewrite $RCFILE!"
 
132
  fi
 
133
}
 
134
 
 
135
xup_usage () {
 
136
        echo "Usage: $0 {start|stop|restart|status|monitor|validate-all|meta-data}"
 
137
        return 0
 
138
}
 
139
 
 
140
xup_status () {
 
141
        if [ -f $PIDFILE ]; then
 
142
                echo running
 
143
                return $OCF_SUCCESS
 
144
        else
 
145
                echo stopped
 
146
                return $OCF_NOT_RUNNING
 
147
        fi
 
148
}
 
149
 
 
150
#
 
151
#       Check if the arg is a valid integer
 
152
#
 
153
CheckInteger() {
 
154
#       Examples of valid integer: "1080", "1", "0080", "0", "0000"
 
155
#       Examples of invalid integer: "1080bad", ""
 
156
  case "$1" in
 
157
    "") #empty string 
 
158
        false;;
 
159
    *[!0-9]*) #got invalid char
 
160
        false;;
 
161
    *) #no invalid char, and has at least one digit, so is a good integer
 
162
        true;;
 
163
  esac
 
164
}
 
165
 
 
166
#
 
167
#       Check if the arg is a valid umask
 
168
#
 
169
CheckUmask() {
 
170
#       Examples of valid umask: "100", "1", "000", "0"
 
171
#       Examples of invalid umask: "108", "bad", "1111" ""
 
172
  case "$1" in
 
173
    [0-7])
 
174
        true;;
 
175
    [0-7][0-7])
 
176
        true;;
 
177
    [0-7][0-7][0-7])
 
178
        true;;
 
179
    *)
 
180
        false;;
 
181
  esac
 
182
}
 
183
 
 
184
# Check (part of) the attributes based on xinetd.conf(5) and xinetd source code
 
185
#       confparse.c
 
186
#       parsers.c
 
187
#       attr.h
 
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 
 
192
  VAR=""
 
193
  for SECTION in $*; do
 
194
    case $SECTION in
 
195
      *=*) # Check to see if we need to export the previous name=value
 
196
           # pair.
 
197
           if [ -n "$VAR" ]; then
 
198
             export "$VAR"
 
199
           fi
 
200
           # Save the "new" name=value pair in VAR
 
201
           VAR=$SECTION
 
202
           ;;
 
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.
 
206
           VAR="$VAR $SECTION"
 
207
           ;;
 
208
    esac
 
209
    # A final cleanup step.
 
210
    # Do we need to export VAR ?
 
211
    if [ -n "$VAR" ]; then
 
212
      export "$VAR"
 
213
    fi  
 
214
  done
 
215
  if [ $? -ne 0 ]; then
 
216
        return $OCF_ERR_GENERIC
 
217
  fi
 
218
 
 
219
  case $disable in
 
220
        "")     disable=no # Default to no.
 
221
                ;;
 
222
        yes|no) ;;
 
223
        *)      ocf_log err "Invalid value for disable [$disable] in $RCFILE, yes|no please"
 
224
                exit $OCF_ERR_CONFIGURED
 
225
                ;;
 
226
  esac
 
227
 
 
228
  case $socket_type in
 
229
        "")     socket_type=dgram
 
230
                # Default value for socket_type is dgram.
 
231
                ;;
 
232
        stream|dgram|raw|seqpacket)
 
233
                ;;
 
234
        *)      ocf_log err "Invalid socket type $socket_type in $RCFILE"
 
235
                exit $OCF_ERR_CONFIGURED
 
236
                ;;
 
237
  esac
 
238
 
 
239
  case $wait in # Wait has no default value.
 
240
        yes|no) ;;
 
241
        *)      ocf_log err "Invalid waid [$wait] in $RCFILE, yes|no please"
 
242
                exit $OCF_ERR_CONFIGURED
 
243
                ;;
 
244
  esac
 
245
 
 
246
  case $type in
 
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)
 
250
                ;;
 
251
        *)      ocf_log err "Invalid service type [$type] in $RCFILE"
 
252
                exit $OCF_ERR_CONFIGURED
 
253
                ;;
 
254
  esac
 
255
 
 
256
  if [ ! -z "$type" -a "INTERNAL" != "$type" ]; then
 
257
  # Type is explicitly set to EXTERNAL, hence server and user are necessary.
 
258
        case $server in
 
259
            "") ocf_log err "Please specify server in $RCFILE"
 
260
                exit $OCF_ERR_CONFIGURED
 
261
                ;;
 
262
            /*) if [ -x $server ]; then
 
263
                        : OK
 
264
                else
 
265
                        ocf_log err "Server $server is not executable"
 
266
                        exit $OCF_ERR_CONFIGURED
 
267
                fi
 
268
                ;;
 
269
            *)  ocf_log err "Server $server is not of obsolute path"
 
270
                exit $OCF_ERR_CONFIGURED
 
271
                ;;
 
272
        esac 
 
273
 
 
274
        case $user in
 
275
            "") ocf_log err "Please specify user in $RCFILE"
 
276
                exit $OCF_ERR_CONFIGURED
 
277
                ;;
 
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
 
282
                fi
 
283
                ;;
 
284
        esac
 
285
 
 
286
        # Protocol is necessary when type is MUX
 
287
        if [ $type = "TCPMUX" -o $type ="TCPMUXPLUS" ]; then
 
288
            case $protocol in
 
289
                "")     ocf_log err "Please specify protocol in $RCFILE"
 
290
                        exit $OCF_ERR_CONFIGURED
 
291
                        ;;
 
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
 
296
                        fi
 
297
                        ;;
 
298
            esac
 
299
        fi
 
300
  fi
 
301
 
 
302
  case $group in
 
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
 
308
        fi
 
309
        ;;
 
310
  esac
 
311
 
 
312
  case $flags in
 
313
  # Default value for flags is REUSE.
 
314
  # It may be a list in $RCFILE, however we only capture the first one.
 
315
        "")     flags=RESUME
 
316
                ;;
 
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
 
320
                ;;
 
321
  esac
 
322
 
 
323
  case $instances in
 
324
        ""|[Uu][Nn][Ll][Ii][Mm][Ii][Ti][Ee][Dd])        ;;
 
325
        *)      if CheckInteger $instances; then
 
326
                    : OK
 
327
                else
 
328
                    ocf_log err "Invalid instances [$instances] in $RCFILE, non-negative integer expected"
 
329
                    exit $OCF_ERR_CONFIGURED
 
330
                fi
 
331
                ;;
 
332
  esac
 
333
 
 
334
  case $nice in
 
335
        "")     ;;
 
336
        *)      local foo=`echo $nice | sed s/^-//`
 
337
                if CheckInteger $foo; then
 
338
                    : OK
 
339
                else
 
340
                    ocf_log err "Invalid nice [$nice] in $RCFILE, integer expected"
 
341
                    exit $OCF_ERR_CONFIGURED
 
342
                fi
 
343
                ;;
 
344
  esac
 
345
 
 
346
  if [ ! -z $umask ]; then
 
347
        if CheckUmask $umask; then
 
348
            : OK
 
349
        else
 
350
            ocf_log err "Invalid umask [$umask] in $RCFILE"
 
351
            exit $OCF_ERR_CONFIGURED
 
352
        fi
 
353
  fi
 
354
}
 
355
 
 
356
xup_validate_all () {
 
357
  check_binary $AWK
 
358
 
 
359
# Parse the $RCFILE for necessary attributes, assume $RCFILE does not
 
360
# contain "include" or "includedir" directives.
 
361
  space="[ \t]*"
 
362
  leading_space="^$space"
 
363
  trailing_space="$space$"
 
364
  comment="$space\#"
 
365
 
 
366
  # Strip comments, delete blank lines.
 
367
  stripped=`sed -e "/^$comment/d" -e "/=$trailing_space/d" -e "/$leading_space$/d" $RCFILE`
 
368
 
 
369
  stripped=`echo $stripped`
 
370
  # At this stage, stripped="service <service-name> { attribute-list }".
 
371
  case $stripped in
 
372
        *#*)
 
373
        ocf_log err "Descriptor file $RCFILE contains extra \"#\", which is forbidden"
 
374
        exit $OCF_ERR_CONFIGURED
 
375
        ;;
 
376
 
 
377
        service*)
 
378
        case $stripped in
 
379
            *[!\        \ +-]=*)
 
380
                ocf_log err "Attribute needs a space before operator ="
 
381
                exit $OCF_ERR_CONFIGURED
 
382
                ;;
 
383
            *[!\        \ ][+-]=*)
 
384
                ocf_log err "Attribute needs a space before operator [+-]="
 
385
                exit $OCF_ERR_CONFIGURED
 
386
                ;;
 
387
            *)  ;;
 
388
        esac
 
389
 
 
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.
 
395
        case $stripped in
 
396
            " "*)
 
397
            stripped=`echo $stripped | sed -e "s/$leading_space[^ \t]\+$space//"`
 
398
            # At this stage, stripped="{ attribute-list }"
 
399
            case $stripped in
 
400
                {*})
 
401
                stripped=`echo $stripped | sed -e "s/^{//" -e "s/}$//"`
 
402
                # At this stage, stripped=<attribute-list>
 
403
#                   echo $stripped
 
404
                check_attributes "$stripped"
 
405
                ;;
 
406
 
 
407
                *)
 
408
                ocf_log err "Attrbute list should be contained in {}"
 
409
                exit $OCF_ERR_CONFIGURED
 
410
                ;;
 
411
            esac
 
412
            ;;
 
413
 
 
414
            *)
 
415
            ocf_log err "Service name should follow the service key word"
 
416
            exit $OCF_ERR_CONFIGURED
 
417
            ;;
 
418
        esac
 
419
        ;;
 
420
 
 
421
        *)
 
422
        ocf_log err "Service key word is necessary in $RCFILE"
 
423
        exit $OCF_ERR_CONFIGURED
 
424
        ;;
 
425
  esac
 
426
}
 
427
if
 
428
  ( [ $# -ne 1 ] )
 
429
then
 
430
  xup_usage
 
431
  exit $OCF_ERR_ARGS
 
432
fi
 
433
 
 
434
# These operations do not require OCF instance parameters to be set
 
435
case "$1" in
 
436
  meta-data)
 
437
        meta_data
 
438
        exit $OCF_SUCCESS
 
439
        ;;
 
440
  usage)
 
441
        xup_usage
 
442
        exit $OCF_SUCCESS
 
443
        ;;
 
444
  *)    ;;
 
445
esac
 
446
 
 
447
if 
 
448
  [ -z "$OCF_RESKEY_service" ]
 
449
then
 
450
  ocf_log err "Please set OCF_RESKEY_service to the service managed by Xinetd"
 
451
  if [ "$1" = "start" ]; then 
 
452
      exit $OCF_ERR_ARGS
 
453
  else
 
454
      exit $OCF_NOT_RUNNING
 
455
  fi
 
456
fi
 
457
 
 
458
service=$OCF_RESKEY_service
 
459
RCFILE=/etc/xinetd.d/$service
 
460
PIDFILE=$HA_VARRUN/xup$service
 
461
 
 
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 
 
466
        exit $OCF_ERR_ARGS
 
467
    else
 
468
        exit $OCF_NOT_RUNNING
 
469
    fi
 
470
fi
 
471
 
 
472
# See how we were called.
 
473
case "$1" in
 
474
  start)
 
475
        xup_start
 
476
        ;;
 
477
  stop)
 
478
        xup_stop
 
479
        ;;
 
480
  restart)
 
481
        $0 stop
 
482
        $0 start
 
483
        ;;
 
484
  status)
 
485
        xup_status
 
486
        ;;
 
487
  monitor)
 
488
        xup_status > /dev/null
 
489
        ;;
 
490
  validate-all)
 
491
        xup_validate_all
 
492
        ;;
 
493
  *)
 
494
        xup_usage
 
495
        exit $OCF_ERR_UNIMPLEMENTED
 
496
esac
 
497
 
 
498
exit $?