179f697e0SAnthony Wilson#!/bin/sh -e 279f697e0SAnthony Wilson 379f697e0SAnthony Wilsonset -euo pipefail 479f697e0SAnthony Wilson 5189cf248SAnthony WilsonOPTS="bmcstate,bootprogress,chassiskill,chassisoff,chassison,chassisstate,hoststate,\ 6*86cffd9cSAlexander Filippovosstate,power,poweroff,poweron,state,status" 70f35983dSAnthony Wilson 8acf54d08SAnthony WilsonUSAGE="Usage: obmcutil [-h] [--wait] 90f35983dSAnthony Wilson {$OPTS}" 1079f697e0SAnthony Wilson 1179f697e0SAnthony WilsonINTERFACE_ROOT=xyz.openbmc_project 1279f697e0SAnthony WilsonSTATE_INTERFACE=$INTERFACE_ROOT.State 1379f697e0SAnthony Wilson 1479f697e0SAnthony WilsonOBJECT_ROOT=/xyz/openbmc_project 1579f697e0SAnthony WilsonSTATE_OBJECT=$OBJECT_ROOT/state 1679f697e0SAnthony Wilson 17acf54d08SAnthony Wilson## NOTE: The following global variables are used only in the run_timeout cmd. 18acf54d08SAnthony Wilson## By declaring these globally instead of passing them through the 19acf54d08SAnthony Wilson## intermediary functions, which may not be "best practice", the readability 20acf54d08SAnthony Wilson## and cleanliness of the code should at least be increased. 21acf54d08SAnthony Wilson 22acf54d08SAnthony Wilson# The command passed in to be executed (e.g. poweron/off, status, etc.) 23acf54d08SAnthony Wilson# This will be be used in some instances of error reporting 24acf54d08SAnthony WilsonG_ORIG_CMD= 25acf54d08SAnthony Wilson# The state an interface should be in after executing the requested command. 26acf54d08SAnthony WilsonG_REQUESTED_STATE= 27acf54d08SAnthony Wilson# The query to run during a poweron/off or chassison/off to check that 28acf54d08SAnthony Wilson# the requested state (G_REQUESTED_STATE) of the interface has been reached. 29acf54d08SAnthony WilsonG_QUERY= 30acf54d08SAnthony Wilson# Wait the set period of time for state transitions to be successful before 31acf54d08SAnthony Wilson# continuing on with the program or reporting an error if timeout reached. 32acf54d08SAnthony WilsonG_WAIT= 33acf54d08SAnthony Wilson 34f3f16fa9SAnthony Wilsonprint_help () 35f3f16fa9SAnthony Wilson{ 36f3f16fa9SAnthony Wilson echo "$USAGE" 37f3f16fa9SAnthony Wilson echo "" 38f3f16fa9SAnthony Wilson echo "positional arguments:" 390f35983dSAnthony Wilson echo " {$OPTS}" 40f3f16fa9SAnthony Wilson echo "" 41f3f16fa9SAnthony Wilson echo "optional arguments:" 42f3f16fa9SAnthony Wilson echo " -h, --help show this help message and exit" 43acf54d08SAnthony Wilson echo " -w, --wait block until state transition succeeds or fails" 44f3f16fa9SAnthony Wilson exit 0 45f3f16fa9SAnthony Wilson} 46f3f16fa9SAnthony Wilson 47acf54d08SAnthony Wilsonrun_timeout () 48acf54d08SAnthony Wilson{ 49acf54d08SAnthony Wilson local timeout="$1"; shift 50acf54d08SAnthony Wilson local cmd="$@" 51acf54d08SAnthony Wilson 52acf54d08SAnthony Wilson $cmd 53acf54d08SAnthony Wilson 54acf54d08SAnthony Wilson # Run a background query for the transition to the expected state 55acf54d08SAnthony Wilson # This will be killed if the transition doesn't succeed within 56acf54d08SAnthony Wilson # a timeout period. 57acf54d08SAnthony Wilson ( 58acf54d08SAnthony Wilson while ! grep -q $G_REQUESTED_STATE <<< $(handle_cmd $G_QUERY) ; do 59acf54d08SAnthony Wilson sleep 1 60acf54d08SAnthony Wilson done 61acf54d08SAnthony Wilson ) & 62acf54d08SAnthony Wilson child=$! 63acf54d08SAnthony Wilson 64acf54d08SAnthony Wilson # Could be bad if process is killed before 'timeout' occurs if 65acf54d08SAnthony Wilson # transition doesn't succeed. 66acf54d08SAnthony Wilson trap -- "" SIGTERM 67acf54d08SAnthony Wilson 68acf54d08SAnthony Wilson # Workaround for lack of 'timeout' command. 69acf54d08SAnthony Wilson ( 70acf54d08SAnthony Wilson sleep $timeout 71acf54d08SAnthony Wilson kill $child 72acf54d08SAnthony Wilson ) > /dev/null 2>&1 & 73acf54d08SAnthony Wilson 74acf54d08SAnthony Wilson if ! wait $child; then 75acf54d08SAnthony Wilson echo "Unable to confirm '$G_ORIG_CMD' success" \ 76acf54d08SAnthony Wilson "within timeout period (${timeout}s)" 77acf54d08SAnthony Wilson fi 78acf54d08SAnthony Wilson} 79acf54d08SAnthony Wilson 80acf54d08SAnthony Wilsonrun_cmd () 81acf54d08SAnthony Wilson{ 82acf54d08SAnthony Wilson local cmd="$@"; 83acf54d08SAnthony Wilson 84acf54d08SAnthony Wilson if [ -n "$G_WAIT" ]; then 85acf54d08SAnthony Wilson run_timeout $G_WAIT "$cmd" 86acf54d08SAnthony Wilson else 87acf54d08SAnthony Wilson $cmd 88acf54d08SAnthony Wilson fi 89acf54d08SAnthony Wilson} 90acf54d08SAnthony Wilson 913ae0a354SAnthony Wilsonset_property () 923ae0a354SAnthony Wilson{ 93acf54d08SAnthony Wilson run_cmd busctl set-property "$@" 943ae0a354SAnthony Wilson} 953ae0a354SAnthony Wilson 9679f697e0SAnthony Wilsonget_property () 9779f697e0SAnthony Wilson{ 98acf54d08SAnthony Wilson G_WAIT="" 99acf54d08SAnthony Wilson run_cmd busctl get-property "$@" 10079f697e0SAnthony Wilson} 10179f697e0SAnthony Wilson 10279f697e0SAnthony Wilsonstate_query () 10379f697e0SAnthony Wilson{ 10479f697e0SAnthony Wilson local state=$(get_property "$@" | cut -d '"' -f2) 10579f697e0SAnthony Wilson printf "%-20s: %s\n" $4 $state 10679f697e0SAnthony Wilson} 10779f697e0SAnthony Wilson 108ea87db40SAnthony Wilsonprint_usage_err () 109ea87db40SAnthony Wilson{ 110ea87db40SAnthony Wilson echo "ERROR: $1" >&2 111ea87db40SAnthony Wilson echo "$USAGE" 112ea87db40SAnthony Wilson exit 1 113ea87db40SAnthony Wilson} 114ea87db40SAnthony Wilson 11579f697e0SAnthony Wilsonhandle_cmd () 11679f697e0SAnthony Wilson{ 11779f697e0SAnthony Wilson case "$1" in 1183ae0a354SAnthony Wilson chassisoff) 1193ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 1203ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1213ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 1223ae0a354SAnthony Wilson PROPERTY=RequestedPowerTransition 1233ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.Off 124acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.PowerState.Off 125acf54d08SAnthony Wilson G_QUERY="chassisstate" 1263ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1273ae0a354SAnthony Wilson ;; 1283ae0a354SAnthony Wilson chassison) 1293ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 1303ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1313ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 1323ae0a354SAnthony Wilson PROPERTY=RequestedPowerTransition 1333ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.On 134acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.PowerState.On 135acf54d08SAnthony Wilson G_QUERY="chassisstate" 1363ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1373ae0a354SAnthony Wilson ;; 1383ae0a354SAnthony Wilson poweroff) 1393ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/host0 1403ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1413ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 1423ae0a354SAnthony Wilson PROPERTY=RequestedHostTransition 1433ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.Off 144acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.HostState.Off 145acf54d08SAnthony Wilson G_QUERY="hoststate" 1463ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1473ae0a354SAnthony Wilson ;; 1483ae0a354SAnthony Wilson poweron) 1493ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/host0 1503ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1513ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 1523ae0a354SAnthony Wilson PROPERTY=RequestedHostTransition 1533ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.On 154acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.HostState.Running 155acf54d08SAnthony Wilson G_QUERY="hoststate" 1563ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1573ae0a354SAnthony Wilson ;; 15879f697e0SAnthony Wilson bmcstate) 15979f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/bmc0 16079f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 16179f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.BMC 16279f697e0SAnthony Wilson PROPERTY=CurrentBMCState 16379f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 16479f697e0SAnthony Wilson ;; 16579f697e0SAnthony Wilson chassisstate) 16679f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 16779f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 16879f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 16979f697e0SAnthony Wilson PROPERTY=CurrentPowerState 17079f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 17179f697e0SAnthony Wilson ;; 17279f697e0SAnthony Wilson hoststate) 17379f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/host0 17479f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 17579f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 17679f697e0SAnthony Wilson PROPERTY=CurrentHostState 17779f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 17879f697e0SAnthony Wilson ;; 179*86cffd9cSAlexander Filippov osstate) 180*86cffd9cSAlexander Filippov OBJECT=$STATE_OBJECT/host0 181*86cffd9cSAlexander Filippov SERVICE=$(mapper get-service $OBJECT) 182*86cffd9cSAlexander Filippov INTERFACE=$STATE_INTERFACE.OperatingSystem.Status 183*86cffd9cSAlexander Filippov PROPERTY=OperatingSystemState 184*86cffd9cSAlexander Filippov state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 185*86cffd9cSAlexander Filippov ;; 18679f697e0SAnthony Wilson state|status) 187*86cffd9cSAlexander Filippov for query in bmcstate chassisstate hoststate bootprogress osstate 18879f697e0SAnthony Wilson do 18979f697e0SAnthony Wilson handle_cmd $query 19079f697e0SAnthony Wilson done 19179f697e0SAnthony Wilson ;; 19250c5f88dSAnthony Wilson bootprogress) 19350c5f88dSAnthony Wilson OBJECT=$STATE_OBJECT/host0 19450c5f88dSAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 19550c5f88dSAnthony Wilson INTERFACE=$STATE_INTERFACE.Boot.Progress 19650c5f88dSAnthony Wilson PROPERTY=BootProgress 19750c5f88dSAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 19850c5f88dSAnthony Wilson ;; 1990f35983dSAnthony Wilson power) 2000f35983dSAnthony Wilson OBJECT=/org/openbmc/control/power0 2010f35983dSAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 2020f35983dSAnthony Wilson INTERFACE=org.openbmc.control.Power 2030f35983dSAnthony Wilson for property in pgood state pgood_timeout 2040f35983dSAnthony Wilson do 2050f35983dSAnthony Wilson # get_property can potentially return several 2060f35983dSAnthony Wilson # different formats of values, so we do the parsing outside 2070f35983dSAnthony Wilson # of get_property depending on the query. These queries 2080f35983dSAnthony Wilson # return 'i VALUE' formatted strings. 2090f35983dSAnthony Wilson STATE=$(get_property $SERVICE $OBJECT $INTERFACE $property \ 2100f35983dSAnthony Wilson | sed 's/i[ ^I]*//') 2110f35983dSAnthony Wilson printf "%s = %s\n" $property $STATE 2120f35983dSAnthony Wilson done 2130f35983dSAnthony Wilson ;; 214189cf248SAnthony Wilson chassiskill) 215189cf248SAnthony Wilson /usr/libexec/chassiskill 216189cf248SAnthony Wilson ;; 21779f697e0SAnthony Wilson *) 218ea87db40SAnthony Wilson print_usage_err "Invalid command '$1'" 21979f697e0SAnthony Wilson ;; 22079f697e0SAnthony Wilson esac 22179f697e0SAnthony Wilson} 22279f697e0SAnthony Wilson 223ea87db40SAnthony Wilsonfor arg in "$@"; do 224ea87db40SAnthony Wilson case $arg in 225acf54d08SAnthony Wilson -w|--wait) 226acf54d08SAnthony Wilson G_WAIT=30 227acf54d08SAnthony Wilson continue 228acf54d08SAnthony Wilson ;; 229ea87db40SAnthony Wilson -h|--help) 230ea87db40SAnthony Wilson print_help 231ea87db40SAnthony Wilson ;; 232ea87db40SAnthony Wilson -*) 233ea87db40SAnthony Wilson print_usage_err "Unknown option: $arg" 234ea87db40SAnthony Wilson ;; 235ea87db40SAnthony Wilson *) 236acf54d08SAnthony Wilson G_ORIG_CMD=$arg 237ea87db40SAnthony Wilson handle_cmd $arg 238ea87db40SAnthony Wilson break 239ea87db40SAnthony Wilson ;; 240ea87db40SAnthony Wilson esac 241ea87db40SAnthony Wilsondone 242