blob: 6cfdee5256cda2d3048df758ec9467cc2a7c9d5f [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 Subbanna6d3a2c52019-10-24 07:21:30 -05006osstate,power,poweroff,poweron,state,status,rebootoff,rebooton"
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
Anthony Wilsonacf54d02018-09-20 15:19:28 -050019## NOTE: The following global variables are used only in the run_timeout cmd.
20## By declaring these globally instead of passing them through the
21## intermediary functions, which may not be "best practice", the readability
22## and cleanliness of the code should at least be increased.
23
24# The command passed in to be executed (e.g. poweron/off, status, etc.)
25# This will be be used in some instances of error reporting
26G_ORIG_CMD=
27# The state an interface should be in after executing the requested command.
28G_REQUESTED_STATE=
29# The query to run during a poweron/off or chassison/off to check that
30# the requested state (G_REQUESTED_STATE) of the interface has been reached.
31G_QUERY=
32# Wait the set period of time for state transitions to be successful before
33# continuing on with the program or reporting an error if timeout reached.
34G_WAIT=
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093035# Print the journal to the console
36G_VERBOSE=
Anthony Wilsonacf54d02018-09-20 15:19:28 -050037
Anthony Wilsonf3f16fa2018-09-13 14:10:52 -050038print_help ()
39{
40 echo "$USAGE"
41 echo ""
42 echo "positional arguments:"
Anthony Wilson0f359832018-09-13 14:28:07 -050043 echo " {$OPTS}"
Anthony Wilsonf3f16fa2018-09-13 14:10:52 -050044 echo ""
Vishwanatha Subbanna6d3a2c52019-10-24 07:21:30 -050045 echo "Examples:"
46 echo ""
47 echo "obmcutil rebootoff Disable auto reboot from Quiesce state"
48 echo "obmcutil rebooton Enable auto reboot from Quiesce state"
49 echo ""
Anthony Wilsonf3f16fa2018-09-13 14:10:52 -050050 echo "optional arguments:"
51 echo " -h, --help show this help message and exit"
Anthony Wilsonacf54d02018-09-20 15:19:28 -050052 echo " -w, --wait block until state transition succeeds or fails"
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093053 echo " -v, --verbose print the journal to stdout if --wait is supplied"
Anthony Wilsonf3f16fa2018-09-13 14:10:52 -050054 exit 0
55}
56
Anthony Wilsonacf54d02018-09-20 15:19:28 -050057run_timeout ()
58{
59 local timeout="$1"; shift
60 local cmd="$@"
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093061 local verbose_child=
62
Andrew Jeffery2869a922019-10-18 14:42:34 +103063 if [ -n "$G_VERBOSE" ]; then
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093064 journalctl -f &
65 verbose_child=$!
66 fi
Anthony Wilsonacf54d02018-09-20 15:19:28 -050067
68 $cmd
69
70 # Run a background query for the transition to the expected state
71 # This will be killed if the transition doesn't succeed within
72 # a timeout period.
73 (
74 while ! grep -q $G_REQUESTED_STATE <<< $(handle_cmd $G_QUERY) ; do
75 sleep 1
76 done
77 ) &
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093078 wait_child=$!
Anthony Wilsonacf54d02018-09-20 15:19:28 -050079
80 # Could be bad if process is killed before 'timeout' occurs if
81 # transition doesn't succeed.
82 trap -- "" SIGTERM
83
84 # Workaround for lack of 'timeout' command.
85 (
86 sleep $timeout
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093087 kill $wait_child
Anthony Wilsonacf54d02018-09-20 15:19:28 -050088 ) > /dev/null 2>&1 &
89
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093090 if ! wait $wait_child; then
Anthony Wilsonacf54d02018-09-20 15:19:28 -050091 echo "Unable to confirm '$G_ORIG_CMD' success" \
92 "within timeout period (${timeout}s)"
93 fi
Andrew Jeffery60c3ac82019-10-02 09:29:29 +093094
95 if [ -n $verbose_child ]; then
96 kill $verbose_child
97 fi
Anthony Wilsonacf54d02018-09-20 15:19:28 -050098}
99
100run_cmd ()
101{
102 local cmd="$@";
103
104 if [ -n "$G_WAIT" ]; then
105 run_timeout $G_WAIT "$cmd"
106 else
107 $cmd
108 fi
109}
110
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500111set_property ()
112{
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500113 run_cmd busctl set-property "$@"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500114}
115
Anthony Wilson79f697e2018-09-13 13:48:52 -0500116get_property ()
117{
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500118 G_WAIT=""
119 run_cmd busctl get-property "$@"
Anthony Wilson79f697e2018-09-13 13:48:52 -0500120}
121
122state_query ()
123{
124 local state=$(get_property "$@" | cut -d '"' -f2)
125 printf "%-20s: %s\n" $4 $state
126}
127
Anthony Wilsonea87db42018-09-26 16:06:38 -0500128print_usage_err ()
129{
130 echo "ERROR: $1" >&2
131 echo "$USAGE"
132 exit 1
133}
134
Anthony Wilson79f697e2018-09-13 13:48:52 -0500135handle_cmd ()
136{
137 case "$1" in
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500138 chassisoff)
139 OBJECT=$STATE_OBJECT/chassis0
140 SERVICE=$(mapper get-service $OBJECT)
141 INTERFACE=$STATE_INTERFACE.Chassis
142 PROPERTY=RequestedPowerTransition
143 VALUE=$INTERFACE.Transition.Off
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500144 G_REQUESTED_STATE=$INTERFACE.PowerState.Off
145 G_QUERY="chassisstate"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500146 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE
147 ;;
148 chassison)
149 OBJECT=$STATE_OBJECT/chassis0
150 SERVICE=$(mapper get-service $OBJECT)
151 INTERFACE=$STATE_INTERFACE.Chassis
152 PROPERTY=RequestedPowerTransition
153 VALUE=$INTERFACE.Transition.On
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500154 G_REQUESTED_STATE=$INTERFACE.PowerState.On
155 G_QUERY="chassisstate"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500156 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE
157 ;;
158 poweroff)
159 OBJECT=$STATE_OBJECT/host0
160 SERVICE=$(mapper get-service $OBJECT)
161 INTERFACE=$STATE_INTERFACE.Host
162 PROPERTY=RequestedHostTransition
163 VALUE=$INTERFACE.Transition.Off
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500164 G_REQUESTED_STATE=$INTERFACE.HostState.Off
165 G_QUERY="hoststate"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500166 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE
167 ;;
168 poweron)
169 OBJECT=$STATE_OBJECT/host0
170 SERVICE=$(mapper get-service $OBJECT)
171 INTERFACE=$STATE_INTERFACE.Host
172 PROPERTY=RequestedHostTransition
173 VALUE=$INTERFACE.Transition.On
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500174 G_REQUESTED_STATE=$INTERFACE.HostState.Running
175 G_QUERY="hoststate"
Anthony Wilson3ae0a352018-09-13 14:47:56 -0500176 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE
177 ;;
Anthony Wilson79f697e2018-09-13 13:48:52 -0500178 bmcstate)
179 OBJECT=$STATE_OBJECT/bmc0
180 SERVICE=$(mapper get-service $OBJECT)
181 INTERFACE=$STATE_INTERFACE.BMC
182 PROPERTY=CurrentBMCState
183 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
184 ;;
185 chassisstate)
186 OBJECT=$STATE_OBJECT/chassis0
187 SERVICE=$(mapper get-service $OBJECT)
188 INTERFACE=$STATE_INTERFACE.Chassis
189 PROPERTY=CurrentPowerState
190 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
191 ;;
192 hoststate)
193 OBJECT=$STATE_OBJECT/host0
194 SERVICE=$(mapper get-service $OBJECT)
195 INTERFACE=$STATE_INTERFACE.Host
196 PROPERTY=CurrentHostState
197 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
198 ;;
Alexander Filippov86cffd92019-04-03 16:29:57 +0300199 osstate)
200 OBJECT=$STATE_OBJECT/host0
201 SERVICE=$(mapper get-service $OBJECT)
202 INTERFACE=$STATE_INTERFACE.OperatingSystem.Status
203 PROPERTY=OperatingSystemState
204 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
205 ;;
Anthony Wilson79f697e2018-09-13 13:48:52 -0500206 state|status)
Alexander Filippov86cffd92019-04-03 16:29:57 +0300207 for query in bmcstate chassisstate hoststate bootprogress osstate
Anthony Wilson79f697e2018-09-13 13:48:52 -0500208 do
209 handle_cmd $query
210 done
211 ;;
Anthony Wilson50c5f882018-09-13 14:19:37 -0500212 bootprogress)
213 OBJECT=$STATE_OBJECT/host0
214 SERVICE=$(mapper get-service $OBJECT)
215 INTERFACE=$STATE_INTERFACE.Boot.Progress
216 PROPERTY=BootProgress
217 state_query $SERVICE $OBJECT $INTERFACE $PROPERTY
218 ;;
Anthony Wilson0f359832018-09-13 14:28:07 -0500219 power)
220 OBJECT=/org/openbmc/control/power0
221 SERVICE=$(mapper get-service $OBJECT)
222 INTERFACE=org.openbmc.control.Power
223 for property in pgood state pgood_timeout
224 do
225 # get_property can potentially return several
226 # different formats of values, so we do the parsing outside
227 # of get_property depending on the query. These queries
228 # return 'i VALUE' formatted strings.
229 STATE=$(get_property $SERVICE $OBJECT $INTERFACE $property \
230 | sed 's/i[ ^I]*//')
231 printf "%s = %s\n" $property $STATE
232 done
233 ;;
Anthony Wilson189cf242018-10-23 01:18:21 -0500234 chassiskill)
235 /usr/libexec/chassiskill
236 ;;
Vishwanatha Subbanna6d3a2c52019-10-24 07:21:30 -0500237 rebootoff)
238 OBJECT=$CONTROL_OBJECT/host0/auto_reboot
239 SERVICE=$(mapper get-service $OBJECT)
240 INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy
241 PROPERTY=AutoReboot
242 VALUE=false
243 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE
244 ;;
245 rebooton)
246 OBJECT=$CONTROL_OBJECT/host0/auto_reboot
247 SERVICE=$(mapper get-service $OBJECT)
248 INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy
249 PROPERTY=AutoReboot
250 VALUE=true
251 set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE
252 ;;
Anthony Wilson79f697e2018-09-13 13:48:52 -0500253 *)
Anthony Wilsonea87db42018-09-26 16:06:38 -0500254 print_usage_err "Invalid command '$1'"
Anthony Wilson79f697e2018-09-13 13:48:52 -0500255 ;;
256 esac
257}
258
Anthony Wilsonea87db42018-09-26 16:06:38 -0500259for arg in "$@"; do
260 case $arg in
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500261 -w|--wait)
262 G_WAIT=30
263 continue
264 ;;
Anthony Wilsonea87db42018-09-26 16:06:38 -0500265 -h|--help)
266 print_help
267 ;;
Andrew Jeffery60c3ac82019-10-02 09:29:29 +0930268 -v|--verbose)
269 G_VERBOSE=y
270 ;;
Anthony Wilsonea87db42018-09-26 16:06:38 -0500271 -*)
272 print_usage_err "Unknown option: $arg"
273 ;;
274 *)
Anthony Wilsonacf54d02018-09-20 15:19:28 -0500275 G_ORIG_CMD=$arg
Anthony Wilsonea87db42018-09-26 16:06:38 -0500276 handle_cmd $arg
277 break
278 ;;
279 esac
280done