~derek-name/openvista-gtm-integration/bug818588-ovbackup_nice

« back to all changes in this revision

Viewing changes to scripts/etc/init.d/openvista-databases

  • Committer: Derek Veit
  • Date: 2011-08-22 19:04:10 UTC
  • mfrom: (131.2.576 replication)
  • Revision ID: derek.veit@medsphere.com-20110822190410-w4sepab2fxrs3u0p
Merge replication branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
### END INIT INFO
38
38
 
39
39
 
40
 
# Copyright (C) 2009 Medsphere Systems Corporation
 
40
# Copyright (C) 2009-2010 Medsphere Systems Corporation
41
41
#
42
42
# This program is free software; you can redistribute it and/or modify it solely
43
43
# under the terms of the GNU Affero General Public License version 3 as published
44
44
# by the Free Software Foundation.
45
 
 
45
#
46
46
# This program is distributed in the hope that it will be useful, but WITHOUT
47
47
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
48
48
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License
49
49
# for more details.
50
 
 
50
#
51
51
# You should have received a copy of the GNU Affero General Public License
52
52
# along with this program.  If not, see <http://www.gnu.org/licenses>.
53
 
54
 
# You can contact Medsphere Systems Corporation headquarters at 1917 Palomar 
 
53
#
 
54
# You can contact Medsphere Systems Corporation headquarters at 1917 Palomar
55
55
# Oaks Way, Suite 200, Carlsbad, CA 92008 or at legal@medsphere.com.
56
56
 
57
57
 
62
62
#
63
63
# Note that exiting 0 here is against LSB, but Debian policy and LSB conflict
64
64
# here, so we have to pick one.
65
 
[ -f /usr/lib/openvista/functions ] || exit 0
 
65
[[ -f /usr/lib/openvista/functions ]] || exit 0
66
66
 
67
 
# Source function library.
68
 
[ -f /etc/rc.d/init.d/functions ] && . /etc/rc.d/init.d/functions
69
 
[ -f /lib/lsb/init-functions ] && . /lib/lsb/init-functions
 
67
# source function libraries
 
68
# CentOS/RHEL, provides action(), status()
 
69
[[ -f /etc/rc.d/init.d/functions ]] && . /etc/rc.d/init.d/functions
 
70
# Ubuntu/Debian, provides log_daemon_msg(), status_of_proc()
 
71
[[ -f /lib/lsb/init-functions ]] && . /lib/lsb/init-functions
 
72
# OpenVista
70
73
. /usr/lib/openvista/functions
71
74
 
 
75
log_command_usage "$@"
 
76
 
 
77
usage()
 
78
{
 
79
    # Display usage information.
 
80
    cat <<EOF
 
81
Usage: openvista-databases {start|stop|restart|force-reload} [INSTANCE_NAME]
 
82
EOF
 
83
}
 
84
 
72
85
recover_backward()
73
86
{
74
 
    set_gtm_env "$1" || return 1
 
87
    instance=$1
 
88
    set_gtm_env -v "$instance" || return $?
75
89
 
76
90
    umask 007
77
91
 
78
 
    logger -p user.info -t "openvista-databases[$$]" -- Performing recovery on $instance database
79
 
 
80
 
    mupip journal -recover -backward '*' 2>&1 \
81
 
      | grep -v '^$' \
82
 
      | logger -p user.info -t "openvista-databases[$$]"
83
 
    retval=${PIPESTATUS[0]}
84
 
    [ $retval -eq 0 ] || return 1
 
92
    # A recovery is performed only following a non-clean shutdown.
 
93
    #
 
94
    # When terminate_processes() stops mumps processes, it checks that they
 
95
    # have, in fact, exited.  If they have, it writes a 'clean' flag to
 
96
    # /etc/openvista/clean_shutdown_[instance].
 
97
    #
 
98
    # Here, that flag is checked and removed.  The recovery is only performed if
 
99
    # the shutdown was not clean.  Otherwise, rolling back the journal on a
 
100
    # primary replicating server could prevent the secondary from getting the
 
101
    # transactions that were backlogged at the time of the primary's shutdown,
 
102
    # and so the secondary instance(s) would need to be resynced with a complete
 
103
    # backup and restore (using `ovinstancerepl resync [instance]`) in order to
 
104
    # restart replication.
 
105
    #
 
106
    # The clean flag should normally be removed here, but the openvista init
 
107
    # script will also make sure that the flag is removed just before it runs
 
108
    # the ZSTART routine on an instance.
 
109
    if clean_flag get "$instance"; then
 
110
        log -l "Found the clean shutdown flag for $instance database"
 
111
        clean_flag set "$instance" false
 
112
    else
 
113
        log -l "Did not find the clean shutdown flag for $instance database"
 
114
        log -l "Performing recovery on $instance database"
 
115
        mupip journal -recover -backward '*' 2>&1 \
 
116
          | grep -v '^$' \
 
117
          | log -lp
 
118
        (( "${PIPESTATUS[0]}" == 0 )) || return 1
 
119
    fi
85
120
 
86
121
    # According to Bhaskar, database files should not need to be run down after
87
122
    # a successful recovery.  However, we've observed GT.M complaining about
88
123
    # databases requring rundown after a system crash, even after successful
89
 
    # journal recovery, on both our own OpenVista appliance and the WorldVistA 
90
 
    # VOE "four-slice toaster" appliance.  An easy (and somewhat reliable) way to
91
 
    # trigger the not-rundown effect is to connect with CIS, then halt the machine 
92
 
    # by killing qemu.  Upon the next boot, the journal recovery will run, but 
93
 
    # attempts to access the database will result in not-rundown errors.  Adding 
94
 
    # a call to mupip rundown here seems to fix the issue.
 
124
    # journal recovery, on both our own OpenVista appliance and the WorldVistA
 
125
    # VOE "four-slice toaster" appliance.  An easy (and somewhat reliable) way
 
126
    # to trigger the not-rundown effect is to connect with CIS, then halt the
 
127
    # machine by killing qemu.  Upon the next boot, the journal recovery will
 
128
    # run, but attempts to access the database will result in not-rundown
 
129
    # errors.  Adding a call to mupip rundown here seems to fix the issue.
95
130
    mupip rundown -region DEFAULT 2>&1 \
96
131
      | grep -v '^$' \
97
 
      | logger -p user.info -t "openvista-databases[$$]"
98
 
    retval=${PIPESTATUS[0]}
99
 
    [ $retval -eq 0 ] || return 1
100
 
 
101
 
    # Re-enable journaling
102
 
    mupip set -journal="ENABLE,ON,BEFORE_IMAGES" -region DEFAULT 2>&1 \
103
 
      | grep -v '^$' \
104
 
      | logger -p user.info -t "openvista-databases[$$]"
105
 
    retval=${PIPESTATUS[0]}
106
 
    [ $retval -eq 0 ] || return 1
 
132
      | log -lp
 
133
    (( "${PIPESTATUS[0]}" == 0 )) || return 1
 
134
 
 
135
    # Re-enable journaling and, if configured, replication
 
136
    case $replication_mode in
 
137
        primary|secondary)
 
138
            log -lc "Re-enabling journaling and replication on $instance" \
 
139
                    "database"
 
140
 
 
141
            # Turning on replication automatically enables journaling.
 
142
            mupip set -replication=ON \
 
143
                      -region DEFAULT 2>&1 \
 
144
              | grep -v '^$' \
 
145
              | log -lp
 
146
            (( "${PIPESTATUS[0]}" == 0 )) || return 1
 
147
            ;;
 
148
        *)
 
149
            log -l "Re-enabling journaling on $instance database"
 
150
 
 
151
            mupip set -journal="ENABLE,ON,BEFORE_IMAGES" \
 
152
                      -replication=OFF \
 
153
                      -region DEFAULT 2>&1 \
 
154
              | grep -v '^$' \
 
155
              | log -lp
 
156
            (( "${PIPESTATUS[0]}" == 0 )) || return 1
 
157
            ;;
 
158
    esac
 
159
 
 
160
    log -l "Creating new physical segment for SCRATCH on $instance database"
107
161
 
108
162
    # Back up scratch.dat - we're going to create a new one.  The previous
109
163
    # backup will be overwritten.
110
 
    mv -f "$root/$instance/globals/scratch.dat" "$root/$instance/globals/scratch.dat~"
111
 
    retval=$?
112
 
    [ $retval -eq 0 ] || return 1
 
164
    mv -f "$root/$instance/globals/scratch.dat" \
 
165
          "$root/$instance/globals/scratch.dat~" \
 
166
      || return 1
113
167
 
114
168
    mupip create -region=SCRATCH 2>&1 \
115
169
      | grep -v '^$' \
116
 
      | logger -p user.info -t "openvista-databases[$$]"
117
 
    retval=${PIPESTATUS[0]}
118
 
    [ $retval -eq 0 ] || return 1
 
170
      | log -lp
 
171
    (( "${PIPESTATUS[0]}" == 0 )) || return 1
119
172
 
120
 
    logger -p user.info -t "openvista-databases[$$]" -- Database recovery complete, $instance database is ready for use
 
173
    log -l "Database $instance is ready for use"
121
174
 
122
175
    return 0
123
176
}
124
177
 
125
178
terminate_processes()
126
179
{
127
 
    set_gtm_env "$1" || return 1
128
 
 
129
 
    logger -p user.info -t "openvista-databases[$$]" -- Terminating mumps processes in $instance
130
 
 
131
 
    # find all processes using this database and kill them
132
 
    for pid in `ls /proc`; do
133
 
        [ -L "/proc/$pid/cwd" ] || continue
134
 
        cwd=`readlink "/proc/$pid/cwd"`
135
 
        [ "$root/$instance/tmp" = "$cwd" ] || continue
136
 
 
137
 
        [ -L "/proc/$pid/exe" ] || continue
138
 
        exe=`readlink "/proc/$pid/exe"`
139
 
        exe_base=`basename "$exe"`
140
 
        [ "mumps" = "$exe_base" ] || continue
141
 
 
142
 
        mupip stop "$pid" 2>&1 \
143
 
          | grep -v '^$' \
144
 
          | logger -p user.info -t "openvista-databases[$$]"
 
180
    # Make sure all mumps processes using the database are stopped.
 
181
    #   Early in the shutdown sequence the /etc/init.d/openvista script calls
 
182
    #   the ZSTOP routine on the instance to stop OpenVista mumps processes.
 
183
    #   This function first allows some time for the processes to stop
 
184
    #   themselves in response to that routine, and then it calls `mupip stop`
 
185
    #   to more forcefully stop them.  It then waits again for the processes to
 
186
    #   be stopped.  Both wait loops check each second to see if the processes
 
187
    #   are stopped, so the function will not wait any longer than the time it
 
188
    #   actually takes for the processes to stop.  There are at least three
 
189
    #   reasons to wait:
 
190
    #       1)  To allow applications to complete whatever task they are in the
 
191
    #           middle of and stop at a point that makes sense in the context of
 
192
    #           the application.
 
193
    #       2)  To keep the system from shutting down while a process is writing
 
194
    #           data, which might corrupt the database.
 
195
    #       3)  To allow openvista-databases to write a 'clean' flag
 
196
    #           (representing that the problem of #2 was avoided) so that on
 
197
    #           system startup, openvista-databases will know that a database
 
198
    #           recovery won't be necessary.
 
199
 
 
200
    instance=$1
 
201
    set_gtm_env -v "$instance" || return $?
 
202
 
 
203
    log -l "Terminating OpenVista processes in $instance"
 
204
 
 
205
    local mumps_pids
 
206
 
 
207
    # allow time for ZSTOP, called by openvista, to succeed in stopping tasks
 
208
    #   The %ZISTCPS routine listens on the RPC broker port for 30 seconds at a
 
209
    #   time and will only respond to ZSTOP after its current listen period is
 
210
    #   up.  So we will wait up to 35 seconds.
 
211
    local max_wait=35
 
212
    for (( i=0; i!=$max_wait; i++ )); do
 
213
        mumps_pids=( $(get_mumps_pids "$instance") )
 
214
        (( "${#mumps_pids[@]}" == 0 )) && break
 
215
        sleep 1
145
216
    done
146
 
 
147
 
    # wait for processes to die
148
 
    sleep 1
 
217
    log -l "Waited $i seconds for all processes to die from ZSTOP"
 
218
 
 
219
    # kill any processes that are still using this database
 
220
    #   Generally, they should have already been stopped by ZSTOP.
 
221
    mumps_pids=( $(get_mumps_pids "$instance") )
 
222
    mumps_process_count=${#mumps_pids[@]}
 
223
    if (( "$mumps_process_count" != 0 )); then
 
224
        log -l "$mumps_process_count mumps processes remain after ZSTOP"
 
225
        local num
 
226
        for pid in "${mumps_pids[@]}"; do
 
227
            num=$(( $(array_index "$pid" "${mumps_pids[@]}") + 1 ))
 
228
            log -lc "Calling MUPIP STOP on process $pid" \
 
229
                    "($num of $mumps_process_count)"
 
230
            mupip stop "$pid" 2>&1 \
 
231
              | grep -v '^$' \
 
232
              | log -lp
 
233
        done
 
234
    fi
 
235
 
 
236
    # wait for any mumps processes to stop, and set the clean flag
 
237
    #   The clean flag is used by recover_backward() to determine whether to run
 
238
    #   backward recovery on the database.  If all mumps processes for the
 
239
    #   database were successfully stopped before shutdown, then the database
 
240
    #   should not require recovery, but if mumps processes were still running
 
241
    #   when the server was shut down, either because they failed to stop or
 
242
    #   because the shutdown was irregular, e.g. in the case of power failure,
 
243
    #   then the database potentially requires recovery.
 
244
    if wait_for_mumps_to_stop "$instance"; then
 
245
        clean_flag set "$instance" true
 
246
        # This would be a good place to perform RUNDOWN on the database, except
 
247
        # that the replication source server is still using the database file.
 
248
        # So openvista-replication takes care of the database rundown.
 
249
    else
 
250
        clean_flag set "$instance" false
 
251
    fi
149
252
 
150
253
    return 0
151
254
}
152
255
 
 
256
wait_for_mumps_to_stop()
 
257
{
 
258
    # Allow time for all mumps processes to stop.
 
259
    local instance=$1
 
260
 
 
261
    # how many times to give more time if mumps process count is reduced
 
262
    local allowed_tries=6
 
263
    # seconds to wait for mumps process count to be zero
 
264
    local allowed_delay=20
 
265
 
 
266
    local try
 
267
    local time_left
 
268
    local mumps_pids
 
269
    local initial_mumps_process_count
 
270
    local mumps_process_count
 
271
    for (( try=0; try!=$allowed_tries; try++ )); do
 
272
        mumps_pids=( $(get_mumps_pids "$instance") )
 
273
        initial_mumps_process_count=${#mumps_pids[@]}
 
274
        [[ "$initial_mumps_process_count" == 0 ]] || log -srlc \
 
275
          "$initial_mumps_process_count mumps processes still running," \
 
276
          "will wait up to $allowed_delay seconds for them to stop"
 
277
        for (( time_left=$allowed_delay; time_left!=0; time_left-- )); do
 
278
            mumps_pids=( $(get_mumps_pids "$instance") )
 
279
            mumps_process_count=${#mumps_pids[@]}
 
280
            [[ "$mumps_process_count" == "0" ]] && break
 
281
            sleep 1
 
282
        done
 
283
        if [[ "$mumps_process_count" == "0" ]]; then
 
284
            log -l "There are no mumps processes running"
 
285
            break
 
286
        elif (( "$mumps_process_count" >= \
 
287
                "$initial_mumps_process_count" )); then
 
288
            log -srlc \
 
289
              "$mumps_process_count mumps processes are still running," \
 
290
              "but the allowed time of $allowed_delay seconds is exceeded"
 
291
            log -srlc \
 
292
              "Remaining mumps processes:" ${mumps_pids[@]}
 
293
            break
 
294
        else
 
295
            log -srlc \
 
296
              "The number of mumps processes was reduced in the past" \
 
297
              "$allowed_delay seconds, so another $allowed_delay seconds" \
 
298
              "will be allowed for remaining mumps processes to exit"
 
299
            log -srlc \
 
300
              "Remaining mumps processes:" ${mumps_pids[@]}
 
301
        fi
 
302
    done
 
303
 
 
304
    (( "$mumps_process_count" == 0 ))
 
305
}
 
306
 
 
307
clean_flag()
 
308
{
 
309
    # Set the clean flag for openvista-databases to find on startup.
 
310
    local action=$1
 
311
    local instance=$2
 
312
    local is_clean=$3
 
313
 
 
314
    root=$(get_ov_root)
 
315
    clean_flag_file="$root/$instance/etc/clean_shutdown"
 
316
 
 
317
    case $action in
 
318
        "get")
 
319
            [[ -e "$clean_flag_file" ]]
 
320
            return $?
 
321
            ;;
 
322
        "set")
 
323
            if $is_clean; then
 
324
                # write the clean flag
 
325
                echo "openvista-databases completed a clean shutdown of" \
 
326
                     "$instance database at $(date --rfc-3339=ns)" \
 
327
                     >"$clean_flag_file"
 
328
                if [[ -e "$clean_flag_file" ]]; then
 
329
                    log -lc \
 
330
                      "Wrote the clean shutdown flag for $instance database"
 
331
                else
 
332
                    log -lc \
 
333
                      "Shutdown was clean for $instance database, but failed" \
 
334
                      "to write the clean shutdown flag"
 
335
                fi
 
336
            else
 
337
                # erase the clean flag
 
338
                if [[ -e "$clean_flag_file" ]]; then
 
339
                    if rm -f "$clean_flag_file"; then
 
340
                        log -lc \
 
341
                          "Removed the clean shutdown flag for $instance" \
 
342
                          "database"
 
343
                    else
 
344
                        log -lc \
 
345
                          "Failed to remove the clean shutdown flag for" \
 
346
                          "$instance database"
 
347
 
 
348
                    fi
 
349
                fi
 
350
            fi
 
351
            ;;
 
352
        *)
 
353
            exit_command 1 "Error: clean_flag() received invalid argument(s)"
 
354
            ;;
 
355
    esac
 
356
}
 
357
 
153
358
# While it would be possible to run the journal recovery and database
154
359
# rundown as a normal user, root access is required to delete/re-create
155
360
# scratch.dat.  Root access is also required to run mupip stop.
156
 
if [ `id -u` -ne 0 ]; then
157
 
    echo "openvista-databases: Must be run as root" >&2
 
361
if [[ $(id -u) != 0 ]]; then
 
362
    log -sr "openvista-databases: Must be run as root"
158
363
    exit 4 # LSB: user had insufficient privilege
159
364
fi
160
365
 
161
 
# check for for valid arguments (requires correct permissions to do; must happen after permission checks)
162
 
if [ -n "$2" ]; then
163
 
    set_gtm_env "$2" || {
164
 
        echo "openvista-databases: $instance: Not an OpenVista instance" >&2
165
 
        exit 2 # LSB: invalid or excess argument(s)
166
 
    }
 
366
# check for for valid arguments
 
367
instance=$2
 
368
if [[ "$instance" ]]; then
 
369
    is_openvista_instance "$instance" || exit_command 2 "$ov_error"
167
370
fi
168
371
 
 
372
 
169
373
case $1 in
 
374
    # For 'start' and 'stop', the ov_init_action calls provide the exit value
 
375
    # for the script.  The CentOS/RHEL subsys lock is set and cleared
 
376
    # independently of the return code, because a partial failure of one action
 
377
    # should not cause the other to be skipped.  The lock is only set or cleared
 
378
    # when being called without an instance name argument.  Any error from
 
379
    # touching or removing the lock file is hidden from the console so that the
 
380
    # script can be run without an instance name by a non-root admin without
 
381
    # printing confusing error messages.
170
382
    start)
171
 
        if [ -z "$2" ]; then
172
 
            if function_exists "action"; then
173
 
                echo "Performing backward journal recovery on OpenVista databases..."
174
 
            elif function_exists "log_daemon_msg"; then
175
 
                log_daemon_msg "Performing backward journal recovery on OpenVista databases"
176
 
            fi
177
 
 
178
 
            for instance in `list_openvista_instances`; do
179
 
                if function_exists "action"; then
180
 
                    action $"  Performing recovery on $instance database: " recover_backward "$instance"
181
 
                elif function_exists "log_daemon_msg"; then
182
 
                    log_progress_msg "$instance"
183
 
                    recover_backward "$instance" || end_msg=1
184
 
                else
185
 
                    recover_backward "$instance"
186
 
                fi
187
 
            done
188
 
 
189
 
            if function_exists "log_daemon_msg"; then
190
 
                log_end_msg ${end_msg:-0}
191
 
            fi
 
383
        instance_function=recover_backward
 
384
        if function_exists "action"; then
 
385
            # CentOS/RHEL
 
386
            touch /var/lock/subsys/openvista-databases \
 
387
              2>&1 | log -lp
 
388
            ov_init_action_rhel "$instance_function" \
 
389
              "Performing recovery if needed on OpenVista databases" \
 
390
              "Performing recovery if needed on {instance} database" \
 
391
              "$instance"
 
392
        elif function_exists "log_daemon_msg"; then
 
393
            # Ubuntu/Debian
 
394
            ov_init_action_debian "$instance_function" \
 
395
              "Performing recovery if needed on OpenVista databases" \
 
396
              "Performing recovery if needed on OpenVista database" \
 
397
              "$instance"
192
398
        else
193
 
            if function_exists "action"; then
194
 
                action $"Performing recovery on $instance database: " recover_backward "$instance"
195
 
            elif function_exists "log_daemon_msg"; then
196
 
                log_daemon_msg "Performing backward journal recovery on OpenVista databases" "$instance"
197
 
                recover_backward "$instance"
198
 
                log_end_msg $?
199
 
            else
200
 
                recover_backward "$instance"
201
 
            fi
 
399
            # other
 
400
            ov_init_action_other "$instance_function" "$instance"
202
401
        fi
203
402
        ;;
204
403
    stop)
205
 
        if [ -z "$2" ]; then
206
 
            if function_exists "action"; then
207
 
                echo "Terminating remaining mumps processes..."
208
 
            elif function_exists "log_daemon_msg"; then
209
 
                log_daemon_msg "Terminating remaining mumps processes"
210
 
            fi
211
 
 
212
 
            for instance in `list_openvista_instances`; do
213
 
                if function_exists "action"; then
214
 
                    action $"  Terminating mumps processes in $instance: " terminate_processes "$instance"
215
 
                elif function_exists "log_daemon_msg"; then
216
 
                    log_progress_msg "$instance"
217
 
                    terminate_processes "$instance" || end_msg=1
218
 
                else
219
 
                    terminate_processes "$instance"
220
 
                fi
221
 
            done
222
 
 
223
 
            if function_exists "log_daemon_msg"; then
224
 
                log_end_msg ${end_msg:-0}
225
 
            fi
 
404
        instance_function=terminate_processes
 
405
        if function_exists "action"; then
 
406
            # CentOS/RHEL
 
407
            [[ "$instance" ]] || rm -f /var/lock/subsys/openvista-databases \
 
408
              2>&1 | log -lp
 
409
            ov_init_action_rhel "$instance_function" \
 
410
              "Terminating remaining OpenVista processes" \
 
411
              "Terminating OpenVista processes in {instance}" \
 
412
              "$instance"
 
413
        elif function_exists "log_daemon_msg"; then
 
414
            # Ubuntu/Debian
 
415
            ov_init_action_debian "$instance_function" \
 
416
              "Terminating remaining OpenVista processes" \
 
417
              "Terminating remaining OpenVista processes" \
 
418
              "$instance"
226
419
        else
227
 
            if function_exists "action"; then
228
 
                action $"Terminating mumps processes in $instance: " terminate_processes "$instance"
229
 
            elif function_exists "log_daemon_msg"; then
230
 
                log_daemon_msg "Terminating remaining mumps processes" "$instance"
231
 
                terminate_processes "$instance"
232
 
                log_end_msg $?
233
 
            else
234
 
                terminate_processes "$instance"
235
 
            fi
 
420
            # other
 
421
            ov_init_action_other "$instance_function" "$instance"
236
422
        fi
237
423
        ;;
238
424
    restart|force-reload)
241
427
        ;;
242
428
    status)
243
429
        # print usage info for humans, but fake success for RHCS
244
 
        echo "Usage: openvista-databases {start|stop|restart|force-reload} [INSTANCE_NAME]"
 
430
        usage
245
431
        exit 0 # LSB: program is running or service is OK
246
432
        ;;
247
433
    *)
248
 
        echo "Usage: openvista-databases {start|stop|restart|force-reload} [INSTANCE_NAME]" >&2
 
434
        usage >&2
249
435
        exit 2 # LSB: invalid or excess argument(s)
250
436
        ;;
251
437
esac
252