blob: 24bce75e444b4a5a6458cd30053f6577912f38c3 [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 Subbanna7a787dd2019-10-31 06:02:31 -05006osstate,power,poweroff,poweron,state,status,rebootoff,rebooton,recoveryoff,recoveryon"
Anthony Wilson0f359832018-09-13 14:28:07 -05007
Andrew Jeffery60c3ac82019-10-02 09:29:29 +09308USAGE="Usage: obmcutil [-h] [--wait] [--verbose]
Anthony Wilson0f359832018-09-13 14:28:07 -05009 {$OPTS}"
Anthony Wilson79f697e2018-09-13 13:48:52 -050010
11INTERFACE_ROOT=xyz.openbmc_project
12STATE_INTERFACE=$INTERFACE_ROOT.State
Vishwanatha Subbanna6d3a2c52019-10-24 07:21:30 -050013CONTROL_INTERFACE=$INTERFACE_ROOT.Control
Anthony Wilson79f697e2018-09-13 13:48:52 -050014
15OBJECT_ROOT=/xyz/openbmc_project
16STATE_OBJECT=$OBJECT_ROOT/state
Vishwanatha Subbanna6d3a2c52019-10-24 07:21:30 -050017CONTROL_OBJECT=$OBJECT_ROOT/control
Anthony Wilson79f697e2018-09-13 13:48:52 -050018
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -050019HOST_TIMEOUT_TARGET=obmc-host-timeout@0.target
Vishwanatha Subbanna84b3b292019-11-04 05:43:19 -060020HOST_CRASH_TARGET=obmc-host-crash@0.target
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -050021
Anthony Wilsonacf54d02018-09-20 15:19:28 -050022## NOTE: The following global variables are used only in the run_timeout cmd.
23## By declaring these globally instead of passing them through the
24## intermediary functions, which may not be "best practice", the readability
25## and cleanliness of the code should at least be increased.
26
27# The command passed in to be executed (e.g. poweron/off, status, etc.)
28# This will be be used in some instances of error reporting
29G_ORIG_CMD=
30# The state an interface should be in after executing the requested command.
31G_REQUESTED_STATE=
32# The query to run during a poweron/off or chassison/off to check that
33# the requested state (G_REQUESTED_STATE) of the interface has been reached.
34G_QUERY=
35# Wait the set period of time for state transitions to be successful before
36# continuing on with the program or reporting an error if timeout reached.
37G_WAIT=
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093038# Print the journal to the console
39G_VERBOSE=
Anthony Wilsonacf54d02018-09-20 15:19:28 -050040
Anthony Wilsonf3f16fa2018-09-13 14:10:52 -050041print_help ()
42{
43 echo "$USAGE"
44 echo ""
45 echo "positional arguments:"
Anthony Wilson0f359832018-09-13 14:28:07 -050046 echo " {$OPTS}"
Anthony Wilsonf3f16fa2018-09-13 14:10:52 -050047 echo ""
Vishwanatha Subbanna6d3a2c52019-10-24 07:21:30 -050048 echo "Examples:"
49 echo ""
50 echo "obmcutil rebootoff Disable auto reboot from Quiesce state"
51 echo "obmcutil rebooton Enable auto reboot from Quiesce state"
52 echo ""
Vishwanatha Subbanna84b3b292019-11-04 05:43:19 -060053 echo "obmcutil recoveryoff Disable handling boot watchdog timeout and host crash"
54 echo " Also, disable auto reboot from Quiesce state"
55 echo "obmcutil recoveryon Enable handling boot watchdog timeout and host crash"
56 echo " Also, enable auto reboot from Quiesce state"
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -050057 echo ""
Anthony Wilsonf3f16fa2018-09-13 14:10:52 -050058 echo "optional arguments:"
59 echo " -h, --help show this help message and exit"
Anthony Wilsonacf54d02018-09-20 15:19:28 -050060 echo " -w, --wait block until state transition succeeds or fails"
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093061 echo " -v, --verbose print the journal to stdout if --wait is supplied"
Anthony Wilsonf3f16fa2018-09-13 14:10:52 -050062 exit 0
63}
64
Anthony Wilsonacf54d02018-09-20 15:19:28 -050065run_timeout ()
66{
67 local timeout="$1"; shift
68 local cmd="$@"
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093069 local verbose_child=
70
Andrew Jeffery2869a922019-10-18 14:42:34 +103071 if [ -n "$G_VERBOSE" ]; then
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093072 journalctl -f &
73 verbose_child=$!
74 fi
Anthony Wilsonacf54d02018-09-20 15:19:28 -050075
76 $cmd
77
78 # Run a background query for the transition to the expected state
79 # This will be killed if the transition doesn't succeed within
80 # a timeout period.
81 (
82 while ! grep -q $G_REQUESTED_STATE <<< $(handle_cmd $G_QUERY) ; do
83 sleep 1
84 done
85 ) &
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093086 wait_child=$!
Anthony Wilsonacf54d02018-09-20 15:19:28 -050087
88 # Could be bad if process is killed before 'timeout' occurs if
89 # transition doesn't succeed.
90 trap -- "" SIGTERM
91
92 # Workaround for lack of 'timeout' command.
93 (
94 sleep $timeout
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093095 kill $wait_child
Anthony Wilsonacf54d02018-09-20 15:19:28 -050096 ) > /dev/null 2>&1 &
97
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093098 if ! wait $wait_child; then
Anthony Wilsonacf54d02018-09-20 15:19:28 -050099 echo "Unable to confirm '$G_ORIG_CMD' success" \
100 "within timeout period (${timeout}s)"
101 fi
Andrew Jeffery60c3ac82019-10-02 09:29:29 +0930102
Andrew Jeffery8be70292019-11-01 08:56:49 +1030103 if [ -n "$verbose_child" ]; then
Andrew Jeffery60c3ac82019-10-02 09:29:29 +0930104 kill $verbose_child
105 fi
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500106}
107
108run_cmd ()
109{
110 local cmd="$@";
111
112 if [ -n "$G_WAIT" ]; then
113 run_timeout $G_WAIT "$cmd"
114 else
115 $cmd
116 fi
117}
118
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500119set_property ()
120{
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500121 run_cmd busctl set-property "$@"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500122}
123
Anthony Wilson79f697e2018-09-13 13:48:52 -0500124get_property ()
125{
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500126 G_WAIT=""
127 run_cmd busctl get-property "$@"
Anthony Wilson79f697e2018-09-13 13:48:52 -0500128}
129
130state_query ()
131{
132 local state=$(get_property "$@" | cut -d '"' -f2)
133 printf "%-20s: %s\n" $4 $state
134}
135
Anthony Wilsonea87db42018-09-26 16:06:38 -0500136print_usage_err ()
137{
138 echo "ERROR: $1" >&2
139 echo "$USAGE"
140 exit 1
141}
142
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -0500143mask_systemd_target ()
144{
145 target="$@"
146 systemctl mask $target
147}
148
149unmask_systemd_target ()
150{
151 target="$@"
152 systemctl unmask $target
153}
154
Anthony Wilson79f697e2018-09-13 13:48:52 -0500155handle_cmd ()
156{
157 case "$1" in
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500158 chassisoff)
159 OBJECT=$STATE_OBJECT/chassis0
160 SERVICE=$(mapper get-service $OBJECT)
161 INTERFACE=$STATE_INTERFACE.Chassis
162 PROPERTY=RequestedPowerTransition
163 VALUE=$INTERFACE.Transition.Off
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500164 G_REQUESTED_STATE=$INTERFACE.PowerState.Off
165 G_QUERY="chassisstate"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500166 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE
167 ;;
168 chassison)
169 OBJECT=$STATE_OBJECT/chassis0
170 SERVICE=$(mapper get-service $OBJECT)
171 INTERFACE=$STATE_INTERFACE.Chassis
172 PROPERTY=RequestedPowerTransition
173 VALUE=$INTERFACE.Transition.On
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500174 G_REQUESTED_STATE=$INTERFACE.PowerState.On
175 G_QUERY="chassisstate"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500176 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE
177 ;;
178 poweroff)
179 OBJECT=$STATE_OBJECT/host0
180 SERVICE=$(mapper get-service $OBJECT)
181 INTERFACE=$STATE_INTERFACE.Host
182 PROPERTY=RequestedHostTransition
183 VALUE=$INTERFACE.Transition.Off
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500184 G_REQUESTED_STATE=$INTERFACE.HostState.Off
185 G_QUERY="hoststate"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500186 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE
187 ;;
188 poweron)
189 OBJECT=$STATE_OBJECT/host0
190 SERVICE=$(mapper get-service $OBJECT)
191 INTERFACE=$STATE_INTERFACE.Host
192 PROPERTY=RequestedHostTransition
193 VALUE=$INTERFACE.Transition.On
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500194 G_REQUESTED_STATE=$INTERFACE.HostState.Running
195 G_QUERY="hoststate"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500196 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE
197 ;;
Anthony Wilson79f697e2018-09-13 13:48:52 -0500198 bmcstate)
199 OBJECT=$STATE_OBJECT/bmc0
200 SERVICE=$(mapper get-service $OBJECT)
201 INTERFACE=$STATE_INTERFACE.BMC
202 PROPERTY=CurrentBMCState
203 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
204 ;;
205 chassisstate)
206 OBJECT=$STATE_OBJECT/chassis0
207 SERVICE=$(mapper get-service $OBJECT)
208 INTERFACE=$STATE_INTERFACE.Chassis
209 PROPERTY=CurrentPowerState
210 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
211 ;;
212 hoststate)
213 OBJECT=$STATE_OBJECT/host0
214 SERVICE=$(mapper get-service $OBJECT)
215 INTERFACE=$STATE_INTERFACE.Host
216 PROPERTY=CurrentHostState
217 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
218 ;;
Alexander Filippov86cffd92019-04-03 16:29:57 +0300219 osstate)
220 OBJECT=$STATE_OBJECT/host0
221 SERVICE=$(mapper get-service $OBJECT)
222 INTERFACE=$STATE_INTERFACE.OperatingSystem.Status
223 PROPERTY=OperatingSystemState
224 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
225 ;;
Anthony Wilson79f697e2018-09-13 13:48:52 -0500226 state|status)
Alexander Filippov86cffd92019-04-03 16:29:57 +0300227 for query in bmcstate chassisstate hoststate bootprogress osstate
Anthony Wilson79f697e2018-09-13 13:48:52 -0500228 do
229 handle_cmd $query
230 done
231 ;;
Anthony Wilson50c5f882018-09-13 14:19:37 -0500232 bootprogress)
233 OBJECT=$STATE_OBJECT/host0
234 SERVICE=$(mapper get-service $OBJECT)
235 INTERFACE=$STATE_INTERFACE.Boot.Progress
236 PROPERTY=BootProgress
237 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
238 ;;
Anthony Wilson0f359832018-09-13 14:28:07 -0500239 power)
240 OBJECT=/org/openbmc/control/power0
241 SERVICE=$(mapper get-service $OBJECT)
242 INTERFACE=org.openbmc.control.Power
243 for property in pgood state pgood_timeout
244 do
245 # get_property can potentially return several
246 # different formats of values, so we do the parsing outside
247 # of get_property depending on the query. These queries
248 # return 'i VALUE' formatted strings.
249 STATE=$(get_property $SERVICE $OBJECT $INTERFACE $property \
250 | sed 's/i[ ^I]*//')
251 printf "%s = %s\n" $property $STATE
252 done
253 ;;
Anthony Wilson189cf242018-10-23 01:18:21 -0500254 chassiskill)
255 /usr/libexec/chassiskill
256 ;;
Vishwanatha Subbanna6d3a2c52019-10-24 07:21:30 -0500257 rebootoff)
258 OBJECT=$CONTROL_OBJECT/host0/auto_reboot
259 SERVICE=$(mapper get-service $OBJECT)
260 INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy
261 PROPERTY=AutoReboot
262 VALUE=false
263 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE
264 ;;
265 rebooton)
266 OBJECT=$CONTROL_OBJECT/host0/auto_reboot
267 SERVICE=$(mapper get-service $OBJECT)
268 INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy
269 PROPERTY=AutoReboot
270 VALUE=true
271 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE
272 ;;
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -0500273 recoveryoff)
274 handle_cmd rebootoff
275 mask_systemd_target $HOST_TIMEOUT_TARGET
Vishwanatha Subbanna84b3b292019-11-04 05:43:19 -0600276 mask_systemd_target $HOST_CRASH_TARGET
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -0500277 ;;
278 recoveryon)
279 handle_cmd rebooton
280 unmask_systemd_target $HOST_TIMEOUT_TARGET
Vishwanatha Subbanna84b3b292019-11-04 05:43:19 -0600281 unmask_systemd_target $HOST_CRASH_TARGET
Vishwanatha Subbanna7a787dd2019-10-31 06:02:31 -0500282 ;;
Anthony Wilson79f697e2018-09-13 13:48:52 -0500283 *)
Anthony Wilsonea87db42018-09-26 16:06:38 -0500284 print_usage_err "Invalid command '$1'"
Anthony Wilson79f697e2018-09-13 13:48:52 -0500285 ;;
286 esac
287}
288
Anthony Wilsonea87db42018-09-26 16:06:38 -0500289for arg in "$@"; do
290 case $arg in
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500291 -w|--wait)
292 G_WAIT=30
293 continue
294 ;;
Anthony Wilsonea87db42018-09-26 16:06:38 -0500295 -h|--help)
296 print_help
297 ;;
Andrew Jeffery60c3ac82019-10-02 09:29:29 +0930298 -v|--verbose)
299 G_VERBOSE=y
300 ;;
Anthony Wilsonea87db42018-09-26 16:06:38 -0500301 -*)
302 print_usage_err "Unknown option: $arg"
303 ;;
304 *)
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500305 G_ORIG_CMD=$arg
Anthony Wilsonea87db42018-09-26 16:06:38 -0500306 handle_cmd $arg
307 break
308 ;;
309 esac
310done