blob: 6fef0e0a8da8b473d377a4afb8e1b58ea9c4dc40 [file] [log] [blame]
Anthony Wilson79f697e2018-09-13 13:48:52 -05001#!/bin/sh -e
2
3set -euo pipefail
4
Anthony Wilson189cf242018-10-23 01:18:21 -05005OPTS="bmcstate,bootprogress,chassiskill,chassisoff,chassison,chassisstate,hoststate,\
Vishwanatha Subbannaa65d30d2019-11-13 01:26:12 -06006osstate,power,poweroff,poweron,state,status,hostrebootoff,hostrebooton,recoveryoff,recoveryon,\
Andrew Geissler42f28982020-05-14 15:12:42 -05007bmcrebootoff, bmcrebooton, listbootblock listlogs showlog deletelogs"
Anthony Wilson0f359832018-09-13 14:28:07 -05008
Andrew Jeffery60c3ac82019-10-02 09:29:29 +09309USAGE="Usage: obmcutil [-h] [--wait] [--verbose]
Anthony Wilson0f359832018-09-13 14:28:07 -050010 {$OPTS}"
Anthony Wilson79f697e2018-09-13 13:48:52 -050011
12INTERFACE_ROOT=xyz.openbmc_project
13STATE_INTERFACE=$INTERFACE_ROOT.State
Vishwanatha Subbanna6d3a2c52019-10-24 07:21:30 -050014CONTROL_INTERFACE=$INTERFACE_ROOT.Control
Anthony Wilson79f697e2018-09-13 13:48:52 -050015
16OBJECT_ROOT=/xyz/openbmc_project
17STATE_OBJECT=$OBJECT_ROOT/state
Vishwanatha Subbanna6d3a2c52019-10-24 07:21:30 -050018CONTROL_OBJECT=$OBJECT_ROOT/control
Anthony Wilson79f697e2018-09-13 13:48:52 -050019
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -050020HOST_TIMEOUT_TARGET=obmc-host-timeout@0.target
Vishwanatha Subbanna84b3b292019-11-04 05:43:19 -060021HOST_CRASH_TARGET=obmc-host-crash@0.target
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -050022
Anthony Wilsonacf54d02018-09-20 15:19:28 -050023## NOTE: The following global variables are used only in the run_timeout cmd.
24## By declaring these globally instead of passing them through the
25## intermediary functions, which may not be "best practice", the readability
26## and cleanliness of the code should at least be increased.
27
28# The command passed in to be executed (e.g. poweron/off, status, etc.)
29# This will be be used in some instances of error reporting
30G_ORIG_CMD=
31# The state an interface should be in after executing the requested command.
32G_REQUESTED_STATE=
33# The query to run during a poweron/off or chassison/off to check that
34# the requested state (G_REQUESTED_STATE) of the interface has been reached.
35G_QUERY=
36# Wait the set period of time for state transitions to be successful before
37# continuing on with the program or reporting an error if timeout reached.
38G_WAIT=
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093039# Print the journal to the console
40G_VERBOSE=
Anthony Wilsonacf54d02018-09-20 15:19:28 -050041
Anthony Wilsonf3f16fa2018-09-13 14:10:52 -050042print_help ()
43{
44 echo "$USAGE"
45 echo ""
46 echo "positional arguments:"
Anthony Wilson0f359832018-09-13 14:28:07 -050047 echo " {$OPTS}"
Anthony Wilsonf3f16fa2018-09-13 14:10:52 -050048 echo ""
Vishwanatha Subbanna6d3a2c52019-10-24 07:21:30 -050049 echo "Examples:"
50 echo ""
Vishwanatha Subbannaa65d30d2019-11-13 01:26:12 -060051 echo "obmcutil hostrebootoff Disable auto reboot of Host from Quiesce state"
Andrew Geissler3191be82020-10-23 10:45:55 -050052 echo "obmcutil hostrebootoffonetime Disable auto reboot of Host from"
53 echo " Quiesce state for a single boot"
Vishwanatha Subbannaa65d30d2019-11-13 01:26:12 -060054 echo "obmcutil hostrebooton Enable auto reboot of Host from Quiesce state"
Vishwanatha Subbanna6d3a2c52019-10-24 07:21:30 -050055 echo ""
Vishwanatha Subbannaa65d30d2019-11-13 01:26:12 -060056 echo "obmcutil bmcrebootoff Disable reboot of BMC"
57 echo "obmcutil bmcrebooton Enable reboot of BMC"
58 echo ""
59 echo "obmcutil recoveryoff Disable handling boot watchdog timeout and host crash"
60 echo " Also, disable BMC and Host auto reboots"
61 echo ""
62 echo "obmcutil recoveryon Enable handling boot watchdog timeout and host crash"
63 echo " Also, enable BMC and Host auto reboots"
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -050064 echo ""
Andrew Geissler3b7b5612020-05-14 10:45:29 -050065 echo "obmcutil listbootblock Check for and list any errors blocking the boot"
66 echo " of the system"
67 echo ""
Andrew Geissler295ee4f2020-05-14 14:14:05 -050068 echo "obmcutil listlogs List all phosphor-logging entries on the"
69 echo " system"
70 echo ""
Andrew Geisslerd8c63202020-05-14 15:06:31 -050071 echo "obmcutil showlog <log> Display details of input log. Format of <log>"
72 echo " should match listlogs output"
73 echo ""
Andrew Geissler42f28982020-05-14 15:12:42 -050074 echo "obmcutil deletelogs Delete all phosphor-logging entries from"
75 echo " system"
76 echo ""
Andrew Geisslerd8779cd2020-06-11 10:48:40 -050077 echo "optional arguments (must precede the positional options above):"
Anthony Wilsonf3f16fa2018-09-13 14:10:52 -050078 echo " -h, --help show this help message and exit"
Anthony Wilsonacf54d02018-09-20 15:19:28 -050079 echo " -w, --wait block until state transition succeeds or fails"
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093080 echo " -v, --verbose print the journal to stdout if --wait is supplied"
Anthony Wilsonf3f16fa2018-09-13 14:10:52 -050081 exit 0
82}
83
Anthony Wilsonacf54d02018-09-20 15:19:28 -050084run_timeout ()
85{
86 local timeout="$1"; shift
87 local cmd="$@"
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093088 local verbose_child=
89
Andrew Jeffery2869a922019-10-18 14:42:34 +103090 if [ -n "$G_VERBOSE" ]; then
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093091 journalctl -f &
92 verbose_child=$!
93 fi
Anthony Wilsonacf54d02018-09-20 15:19:28 -050094
95 $cmd
96
97 # Run a background query for the transition to the expected state
98 # This will be killed if the transition doesn't succeed within
99 # a timeout period.
100 (
101 while ! grep -q $G_REQUESTED_STATE <<< $(handle_cmd $G_QUERY) ; do
102 sleep 1
103 done
104 ) &
Andrew Jeffery60c3ac82019-10-02 09:29:29 +0930105 wait_child=$!
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500106
107 # Could be bad if process is killed before 'timeout' occurs if
108 # transition doesn't succeed.
109 trap -- "" SIGTERM
110
111 # Workaround for lack of 'timeout' command.
112 (
113 sleep $timeout
Andrew Jeffery60c3ac82019-10-02 09:29:29 +0930114 kill $wait_child
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500115 ) > /dev/null 2>&1 &
116
Andrew Jeffery60c3ac82019-10-02 09:29:29 +0930117 if ! wait $wait_child; then
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500118 echo "Unable to confirm '$G_ORIG_CMD' success" \
119 "within timeout period (${timeout}s)"
120 fi
Andrew Jeffery60c3ac82019-10-02 09:29:29 +0930121
Andrew Jeffery8be70292019-11-01 08:56:49 +1030122 if [ -n "$verbose_child" ]; then
Andrew Jeffery60c3ac82019-10-02 09:29:29 +0930123 kill $verbose_child
124 fi
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500125}
126
127run_cmd ()
128{
129 local cmd="$@";
130
131 if [ -n "$G_WAIT" ]; then
132 run_timeout $G_WAIT "$cmd"
133 else
134 $cmd
135 fi
136}
137
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500138set_property ()
139{
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500140 run_cmd busctl set-property "$@"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500141}
142
Anthony Wilson79f697e2018-09-13 13:48:52 -0500143get_property ()
144{
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500145 G_WAIT=""
146 run_cmd busctl get-property "$@"
Anthony Wilson79f697e2018-09-13 13:48:52 -0500147}
148
149state_query ()
150{
151 local state=$(get_property "$@" | cut -d '"' -f2)
152 printf "%-20s: %s\n" $4 $state
153}
154
Anthony Wilsonea87db42018-09-26 16:06:38 -0500155print_usage_err ()
156{
157 echo "ERROR: $1" >&2
158 echo "$USAGE"
159 exit 1
160}
161
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -0500162mask_systemd_target ()
163{
164 target="$@"
165 systemctl mask $target
166}
167
168unmask_systemd_target ()
169{
170 target="$@"
171 systemctl unmask $target
172}
173
Vishwanatha Subbannaa65d30d2019-11-13 01:26:12 -0600174disable_bmc_reboot ()
175{
176 dir="/run/systemd/system/"
177 file="reboot-guard.conf"
178 units=("reboot" "poweroff" "halt")
179
180 for unit in "${units[@]}"; do
181 mkdir -p ${dir}${unit}.target.d
182 echo -e "[Unit]\nRefuseManualStart=yes" >> ${dir}${unit}.target.d/${file}
183 done
184}
185
186enable_bmc_reboot ()
187{
188 dir="/run/systemd/system/"
189 file="reboot-guard.conf"
190 units=("reboot" "poweroff" "halt")
191
192 for unit in "${units[@]}"; do
193 rm -rf ${dir}${unit}.target.d/${file}
194 rm -rf ${dir}${unit}.target.d
195 done
196}
197
Andrew Geissler3b7b5612020-05-14 10:45:29 -0500198# will write blocking errors to stdout
199check_boot_block_errors ()
200{
201 # array of boot block objects
202 blockArray=()
203
204 # Look for any objects under logging that implement the
205 # xyz.openbmc_project.Logging.ErrorBlocksTransition
206 subtree="$(busctl call xyz.openbmc_project.ObjectMapper \
207 /xyz/openbmc_project/object_mapper \
208 xyz.openbmc_project.ObjectMapper \
209 GetSubTree sias "/xyz/openbmc_project/logging/" 0 1 \
210 xyz.openbmc_project.Logging.ErrorBlocksTransition)"
211
212 # remove quotation marks
213 subtree="$(echo $subtree | sed 's/\"//g')"
214
215 for entry in $subtree; do
216 if [[ ${entry} =~ "xyz/openbmc_project/logging/block"* ]]; then
217 blockArray+=( $entry )
218 fi
219 done
220
221 # now find associated error log for each boot block error
222 for berror in "${blockArray[@]}"; do
223 assocs="$(busctl call xyz.openbmc_project.Logging $berror \
224 org.freedesktop.DBus.Properties Get \
225 ss xyz.openbmc_project.Association.Definitions Associations)"
226
227 # remove quotation marks
228 assocs="$(echo $assocs | sed 's/\"//g')"
229
230 for entry in $assocs; do
231 if [[ ${entry} =~ "xyz/openbmc_project/logging/entry"* ]]; then
232 echo "Blocking Error: $entry"
233 fi
234 done
235 done
236}
237
Andrew Geisslerdeb6bb42020-05-14 13:44:57 -0500238# helper function to check for boot block errors and notify user
239check_and_warn_boot_block()
240{
241 blockingErrors=$(check_boot_block_errors)
242 if ! [ -z "$blockingErrors" ]; then
243 echo !!!!!!!!!!
244 echo "WARNING! System has blocking errors that will prevent boot"
245 echo "$blockingErrors"
246 echo !!!!!!!!!!
247 fi
248}
249
Andrew Geissler295ee4f2020-05-14 14:14:05 -0500250# list all phosphor-logging entries
251list_logs()
252{
253 # Look for any objects under logging that implement the
254 # xyz.openbmc_project.Logging.Entry
255 busctl -j call xyz.openbmc_project.ObjectMapper \
256 /xyz/openbmc_project/object_mapper \
257 xyz.openbmc_project.ObjectMapper \
258 GetSubTreePaths sias "/xyz/openbmc_project/logging/" 0 1 \
259 xyz.openbmc_project.Logging.Entry
260}
261
Andrew Geisslerd8c63202020-05-14 15:06:31 -0500262# display input log details
263show_log()
264{
265 busctl -j call xyz.openbmc_project.Logging \
266 $1 \
267 org.freedesktop.DBus.Properties \
268 GetAll s xyz.openbmc_project.Logging.Entry
269}
270
Andrew Geissler42f28982020-05-14 15:12:42 -0500271# delete all phosphor-logging entries
272delete_logs()
273{
274 busctl call xyz.openbmc_project.Logging \
275 /xyz/openbmc_project/logging \
276 xyz.openbmc_project.Collection.DeleteAll DeleteAll
277}
278
Anthony Wilson79f697e2018-09-13 13:48:52 -0500279handle_cmd ()
280{
281 case "$1" in
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500282 chassisoff)
283 OBJECT=$STATE_OBJECT/chassis0
284 SERVICE=$(mapper get-service $OBJECT)
285 INTERFACE=$STATE_INTERFACE.Chassis
286 PROPERTY=RequestedPowerTransition
287 VALUE=$INTERFACE.Transition.Off
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500288 G_REQUESTED_STATE=$INTERFACE.PowerState.Off
289 G_QUERY="chassisstate"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500290 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE
291 ;;
292 chassison)
Andrew Geisslerdeb6bb42020-05-14 13:44:57 -0500293 check_and_warn_boot_block
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500294 OBJECT=$STATE_OBJECT/chassis0
295 SERVICE=$(mapper get-service $OBJECT)
296 INTERFACE=$STATE_INTERFACE.Chassis
297 PROPERTY=RequestedPowerTransition
298 VALUE=$INTERFACE.Transition.On
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500299 G_REQUESTED_STATE=$INTERFACE.PowerState.On
300 G_QUERY="chassisstate"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500301 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE
302 ;;
303 poweroff)
304 OBJECT=$STATE_OBJECT/host0
305 SERVICE=$(mapper get-service $OBJECT)
306 INTERFACE=$STATE_INTERFACE.Host
307 PROPERTY=RequestedHostTransition
308 VALUE=$INTERFACE.Transition.Off
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500309 G_REQUESTED_STATE=$INTERFACE.HostState.Off
310 G_QUERY="hoststate"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500311 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE
312 ;;
313 poweron)
Andrew Geisslerdeb6bb42020-05-14 13:44:57 -0500314 check_and_warn_boot_block
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500315 OBJECT=$STATE_OBJECT/host0
316 SERVICE=$(mapper get-service $OBJECT)
317 INTERFACE=$STATE_INTERFACE.Host
318 PROPERTY=RequestedHostTransition
319 VALUE=$INTERFACE.Transition.On
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500320 G_REQUESTED_STATE=$INTERFACE.HostState.Running
321 G_QUERY="hoststate"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500322 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE
323 ;;
Anthony Wilson79f697e2018-09-13 13:48:52 -0500324 bmcstate)
325 OBJECT=$STATE_OBJECT/bmc0
326 SERVICE=$(mapper get-service $OBJECT)
327 INTERFACE=$STATE_INTERFACE.BMC
328 PROPERTY=CurrentBMCState
329 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
330 ;;
331 chassisstate)
332 OBJECT=$STATE_OBJECT/chassis0
333 SERVICE=$(mapper get-service $OBJECT)
334 INTERFACE=$STATE_INTERFACE.Chassis
335 PROPERTY=CurrentPowerState
336 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
337 ;;
338 hoststate)
339 OBJECT=$STATE_OBJECT/host0
340 SERVICE=$(mapper get-service $OBJECT)
341 INTERFACE=$STATE_INTERFACE.Host
342 PROPERTY=CurrentHostState
343 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
344 ;;
Alexander Filippov86cffd92019-04-03 16:29:57 +0300345 osstate)
346 OBJECT=$STATE_OBJECT/host0
347 SERVICE=$(mapper get-service $OBJECT)
348 INTERFACE=$STATE_INTERFACE.OperatingSystem.Status
349 PROPERTY=OperatingSystemState
350 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
351 ;;
Anthony Wilson79f697e2018-09-13 13:48:52 -0500352 state|status)
Alexander Filippov86cffd92019-04-03 16:29:57 +0300353 for query in bmcstate chassisstate hoststate bootprogress osstate
Anthony Wilson79f697e2018-09-13 13:48:52 -0500354 do
355 handle_cmd $query
356 done
Andrew Geisslerdeb6bb42020-05-14 13:44:57 -0500357 check_and_warn_boot_block
Anthony Wilson79f697e2018-09-13 13:48:52 -0500358 ;;
Anthony Wilson50c5f882018-09-13 14:19:37 -0500359 bootprogress)
360 OBJECT=$STATE_OBJECT/host0
361 SERVICE=$(mapper get-service $OBJECT)
362 INTERFACE=$STATE_INTERFACE.Boot.Progress
363 PROPERTY=BootProgress
364 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
365 ;;
Anthony Wilson0f359832018-09-13 14:28:07 -0500366 power)
367 OBJECT=/org/openbmc/control/power0
368 SERVICE=$(mapper get-service $OBJECT)
369 INTERFACE=org.openbmc.control.Power
370 for property in pgood state pgood_timeout
371 do
372 # get_property can potentially return several
373 # different formats of values, so we do the parsing outside
374 # of get_property depending on the query. These queries
375 # return 'i VALUE' formatted strings.
376 STATE=$(get_property $SERVICE $OBJECT $INTERFACE $property \
377 | sed 's/i[ ^I]*//')
378 printf "%s = %s\n" $property $STATE
379 done
380 ;;
Anthony Wilson189cf242018-10-23 01:18:21 -0500381 chassiskill)
382 /usr/libexec/chassiskill
383 ;;
Vishwanatha Subbannaa65d30d2019-11-13 01:26:12 -0600384 hostrebootoff)
Vishwanatha Subbanna6d3a2c52019-10-24 07:21:30 -0500385 OBJECT=$CONTROL_OBJECT/host0/auto_reboot
386 SERVICE=$(mapper get-service $OBJECT)
387 INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy
388 PROPERTY=AutoReboot
389 VALUE=false
390 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE
391 ;;
Andrew Geissler3191be82020-10-23 10:45:55 -0500392 hostrebootoffonetime)
393 OBJECT=$CONTROL_OBJECT/host0/auto_reboot/one_time
394 SERVICE=$(mapper get-service $OBJECT)
395 INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy
396 PROPERTY=AutoReboot
397 VALUE=false
398 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE
399 ;;
Vishwanatha Subbannaa65d30d2019-11-13 01:26:12 -0600400 hostrebooton)
Vishwanatha Subbanna6d3a2c52019-10-24 07:21:30 -0500401 OBJECT=$CONTROL_OBJECT/host0/auto_reboot
402 SERVICE=$(mapper get-service $OBJECT)
403 INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy
404 PROPERTY=AutoReboot
405 VALUE=true
406 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE
407 ;;
Vishwanatha Subbannaa65d30d2019-11-13 01:26:12 -0600408 bmcrebootoff)
409 disable_bmc_reboot
410 ;;
411 bmcrebooton)
412 enable_bmc_reboot
413 ;;
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -0500414 recoveryoff)
Vishwanatha Subbannaa65d30d2019-11-13 01:26:12 -0600415 handle_cmd hostrebootoff
416 handle_cmd bmcrebootoff
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -0500417 mask_systemd_target $HOST_TIMEOUT_TARGET
Vishwanatha Subbanna84b3b292019-11-04 05:43:19 -0600418 mask_systemd_target $HOST_CRASH_TARGET
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -0500419 ;;
420 recoveryon)
Vishwanatha Subbannaa65d30d2019-11-13 01:26:12 -0600421 handle_cmd hostrebooton
422 handle_cmd bmcrebooton
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -0500423 unmask_systemd_target $HOST_TIMEOUT_TARGET
Vishwanatha Subbanna84b3b292019-11-04 05:43:19 -0600424 unmask_systemd_target $HOST_CRASH_TARGET
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -0500425 ;;
Andrew Geissler3b7b5612020-05-14 10:45:29 -0500426 listbootblock)
427 blockingErrors=$(check_boot_block_errors)
428 if [ -z "$blockingErrors" ]; then
429 echo "No blocking errors present"
430 else
431 echo "$blockingErrors"
432 fi
433 ;;
Andrew Geissler295ee4f2020-05-14 14:14:05 -0500434 listlogs)
435 list_logs
436 ;;
Andrew Geisslerd8c63202020-05-14 15:06:31 -0500437 showlog)
438 show_log $2
439 ;;
Andrew Geissler42f28982020-05-14 15:12:42 -0500440 deletelogs)
441 delete_logs
442 ;;
Anthony Wilson79f697e2018-09-13 13:48:52 -0500443 *)
Anthony Wilsonea87db42018-09-26 16:06:38 -0500444 print_usage_err "Invalid command '$1'"
Anthony Wilson79f697e2018-09-13 13:48:52 -0500445 ;;
446 esac
447}
448
Andrew Geisslerd8779cd2020-06-11 10:48:40 -0500449shiftcnt=0
Anthony Wilsonea87db42018-09-26 16:06:38 -0500450for arg in "$@"; do
451 case $arg in
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500452 -w|--wait)
453 G_WAIT=30
Andrew Geisslerd8779cd2020-06-11 10:48:40 -0500454 shiftcnt=$((shiftcnt+1))
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500455 continue
456 ;;
Anthony Wilsonea87db42018-09-26 16:06:38 -0500457 -h|--help)
458 print_help
459 ;;
Andrew Jeffery60c3ac82019-10-02 09:29:29 +0930460 -v|--verbose)
461 G_VERBOSE=y
Andrew Geisslerd8779cd2020-06-11 10:48:40 -0500462 shiftcnt=$((shiftcnt+1))
Andrew Jeffery60c3ac82019-10-02 09:29:29 +0930463 ;;
Anthony Wilsonea87db42018-09-26 16:06:38 -0500464 -*)
465 print_usage_err "Unknown option: $arg"
466 ;;
467 *)
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500468 G_ORIG_CMD=$arg
Andrew Geisslerd8779cd2020-06-11 10:48:40 -0500469 # shift out the optional parameters
470 shift $shiftcnt
Andrew Geisslerd8c63202020-05-14 15:06:31 -0500471 # pass all arguments to handle_cmd in case command takes additional
472 # parameters
473 handle_cmd "$@"
Anthony Wilsonea87db42018-09-26 16:06:38 -0500474 break
475 ;;
476 esac
477done