179f697e0SAnthony Wilson#!/bin/sh -e 279f697e0SAnthony Wilson 379f697e0SAnthony Wilsonset -euo pipefail 479f697e0SAnthony Wilson 5189cf248SAnthony WilsonOPTS="bmcstate,bootprogress,chassiskill,chassisoff,chassison,chassisstate,hoststate,\ 6*6d3a2c54SVishwanatha Subbannaosstate,power,poweroff,poweron,state,status,rebootoff,rebooton" 70f35983dSAnthony Wilson 860c3ac8cSAndrew JefferyUSAGE="Usage: obmcutil [-h] [--wait] [--verbose] 90f35983dSAnthony Wilson {$OPTS}" 1079f697e0SAnthony Wilson 1179f697e0SAnthony WilsonINTERFACE_ROOT=xyz.openbmc_project 1279f697e0SAnthony WilsonSTATE_INTERFACE=$INTERFACE_ROOT.State 13*6d3a2c54SVishwanatha SubbannaCONTROL_INTERFACE=$INTERFACE_ROOT.Control 1479f697e0SAnthony Wilson 1579f697e0SAnthony WilsonOBJECT_ROOT=/xyz/openbmc_project 1679f697e0SAnthony WilsonSTATE_OBJECT=$OBJECT_ROOT/state 17*6d3a2c54SVishwanatha SubbannaCONTROL_OBJECT=$OBJECT_ROOT/control 1879f697e0SAnthony Wilson 19acf54d08SAnthony Wilson## NOTE: The following global variables are used only in the run_timeout cmd. 20acf54d08SAnthony Wilson## By declaring these globally instead of passing them through the 21acf54d08SAnthony Wilson## intermediary functions, which may not be "best practice", the readability 22acf54d08SAnthony Wilson## and cleanliness of the code should at least be increased. 23acf54d08SAnthony Wilson 24acf54d08SAnthony Wilson# The command passed in to be executed (e.g. poweron/off, status, etc.) 25acf54d08SAnthony Wilson# This will be be used in some instances of error reporting 26acf54d08SAnthony WilsonG_ORIG_CMD= 27acf54d08SAnthony Wilson# The state an interface should be in after executing the requested command. 28acf54d08SAnthony WilsonG_REQUESTED_STATE= 29acf54d08SAnthony Wilson# The query to run during a poweron/off or chassison/off to check that 30acf54d08SAnthony Wilson# the requested state (G_REQUESTED_STATE) of the interface has been reached. 31acf54d08SAnthony WilsonG_QUERY= 32acf54d08SAnthony Wilson# Wait the set period of time for state transitions to be successful before 33acf54d08SAnthony Wilson# continuing on with the program or reporting an error if timeout reached. 34acf54d08SAnthony WilsonG_WAIT= 3560c3ac8cSAndrew Jeffery# Print the journal to the console 3660c3ac8cSAndrew JefferyG_VERBOSE= 37acf54d08SAnthony Wilson 38f3f16fa9SAnthony Wilsonprint_help () 39f3f16fa9SAnthony Wilson{ 40f3f16fa9SAnthony Wilson echo "$USAGE" 41f3f16fa9SAnthony Wilson echo "" 42f3f16fa9SAnthony Wilson echo "positional arguments:" 430f35983dSAnthony Wilson echo " {$OPTS}" 44f3f16fa9SAnthony Wilson echo "" 45*6d3a2c54SVishwanatha Subbanna echo "Examples:" 46*6d3a2c54SVishwanatha Subbanna echo "" 47*6d3a2c54SVishwanatha Subbanna echo "obmcutil rebootoff Disable auto reboot from Quiesce state" 48*6d3a2c54SVishwanatha Subbanna echo "obmcutil rebooton Enable auto reboot from Quiesce state" 49*6d3a2c54SVishwanatha Subbanna echo "" 50f3f16fa9SAnthony Wilson echo "optional arguments:" 51f3f16fa9SAnthony Wilson echo " -h, --help show this help message and exit" 52acf54d08SAnthony Wilson echo " -w, --wait block until state transition succeeds or fails" 5360c3ac8cSAndrew Jeffery echo " -v, --verbose print the journal to stdout if --wait is supplied" 54f3f16fa9SAnthony Wilson exit 0 55f3f16fa9SAnthony Wilson} 56f3f16fa9SAnthony Wilson 57acf54d08SAnthony Wilsonrun_timeout () 58acf54d08SAnthony Wilson{ 59acf54d08SAnthony Wilson local timeout="$1"; shift 60acf54d08SAnthony Wilson local cmd="$@" 6160c3ac8cSAndrew Jeffery local verbose_child= 6260c3ac8cSAndrew Jeffery 632869a926SAndrew Jeffery if [ -n "$G_VERBOSE" ]; then 6460c3ac8cSAndrew Jeffery journalctl -f & 6560c3ac8cSAndrew Jeffery verbose_child=$! 6660c3ac8cSAndrew Jeffery fi 67acf54d08SAnthony Wilson 68acf54d08SAnthony Wilson $cmd 69acf54d08SAnthony Wilson 70acf54d08SAnthony Wilson # Run a background query for the transition to the expected state 71acf54d08SAnthony Wilson # This will be killed if the transition doesn't succeed within 72acf54d08SAnthony Wilson # a timeout period. 73acf54d08SAnthony Wilson ( 74acf54d08SAnthony Wilson while ! grep -q $G_REQUESTED_STATE <<< $(handle_cmd $G_QUERY) ; do 75acf54d08SAnthony Wilson sleep 1 76acf54d08SAnthony Wilson done 77acf54d08SAnthony Wilson ) & 7860c3ac8cSAndrew Jeffery wait_child=$! 79acf54d08SAnthony Wilson 80acf54d08SAnthony Wilson # Could be bad if process is killed before 'timeout' occurs if 81acf54d08SAnthony Wilson # transition doesn't succeed. 82acf54d08SAnthony Wilson trap -- "" SIGTERM 83acf54d08SAnthony Wilson 84acf54d08SAnthony Wilson # Workaround for lack of 'timeout' command. 85acf54d08SAnthony Wilson ( 86acf54d08SAnthony Wilson sleep $timeout 8760c3ac8cSAndrew Jeffery kill $wait_child 88acf54d08SAnthony Wilson ) > /dev/null 2>&1 & 89acf54d08SAnthony Wilson 9060c3ac8cSAndrew Jeffery if ! wait $wait_child; then 91acf54d08SAnthony Wilson echo "Unable to confirm '$G_ORIG_CMD' success" \ 92acf54d08SAnthony Wilson "within timeout period (${timeout}s)" 93acf54d08SAnthony Wilson fi 9460c3ac8cSAndrew Jeffery 9560c3ac8cSAndrew Jeffery if [ -n $verbose_child ]; then 9660c3ac8cSAndrew Jeffery kill $verbose_child 9760c3ac8cSAndrew Jeffery fi 98acf54d08SAnthony Wilson} 99acf54d08SAnthony Wilson 100acf54d08SAnthony Wilsonrun_cmd () 101acf54d08SAnthony Wilson{ 102acf54d08SAnthony Wilson local cmd="$@"; 103acf54d08SAnthony Wilson 104acf54d08SAnthony Wilson if [ -n "$G_WAIT" ]; then 105acf54d08SAnthony Wilson run_timeout $G_WAIT "$cmd" 106acf54d08SAnthony Wilson else 107acf54d08SAnthony Wilson $cmd 108acf54d08SAnthony Wilson fi 109acf54d08SAnthony Wilson} 110acf54d08SAnthony Wilson 1113ae0a354SAnthony Wilsonset_property () 1123ae0a354SAnthony Wilson{ 113acf54d08SAnthony Wilson run_cmd busctl set-property "$@" 1143ae0a354SAnthony Wilson} 1153ae0a354SAnthony Wilson 11679f697e0SAnthony Wilsonget_property () 11779f697e0SAnthony Wilson{ 118acf54d08SAnthony Wilson G_WAIT="" 119acf54d08SAnthony Wilson run_cmd busctl get-property "$@" 12079f697e0SAnthony Wilson} 12179f697e0SAnthony Wilson 12279f697e0SAnthony Wilsonstate_query () 12379f697e0SAnthony Wilson{ 12479f697e0SAnthony Wilson local state=$(get_property "$@" | cut -d '"' -f2) 12579f697e0SAnthony Wilson printf "%-20s: %s\n" $4 $state 12679f697e0SAnthony Wilson} 12779f697e0SAnthony Wilson 128ea87db40SAnthony Wilsonprint_usage_err () 129ea87db40SAnthony Wilson{ 130ea87db40SAnthony Wilson echo "ERROR: $1" >&2 131ea87db40SAnthony Wilson echo "$USAGE" 132ea87db40SAnthony Wilson exit 1 133ea87db40SAnthony Wilson} 134ea87db40SAnthony Wilson 13579f697e0SAnthony Wilsonhandle_cmd () 13679f697e0SAnthony Wilson{ 13779f697e0SAnthony Wilson case "$1" in 1383ae0a354SAnthony Wilson chassisoff) 1393ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 1403ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1413ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 1423ae0a354SAnthony Wilson PROPERTY=RequestedPowerTransition 1433ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.Off 144acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.PowerState.Off 145acf54d08SAnthony Wilson G_QUERY="chassisstate" 1463ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1473ae0a354SAnthony Wilson ;; 1483ae0a354SAnthony Wilson chassison) 1493ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 1503ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1513ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 1523ae0a354SAnthony Wilson PROPERTY=RequestedPowerTransition 1533ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.On 154acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.PowerState.On 155acf54d08SAnthony Wilson G_QUERY="chassisstate" 1563ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1573ae0a354SAnthony Wilson ;; 1583ae0a354SAnthony Wilson poweroff) 1593ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/host0 1603ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1613ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 1623ae0a354SAnthony Wilson PROPERTY=RequestedHostTransition 1633ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.Off 164acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.HostState.Off 165acf54d08SAnthony Wilson G_QUERY="hoststate" 1663ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1673ae0a354SAnthony Wilson ;; 1683ae0a354SAnthony Wilson poweron) 1693ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/host0 1703ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1713ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 1723ae0a354SAnthony Wilson PROPERTY=RequestedHostTransition 1733ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.On 174acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.HostState.Running 175acf54d08SAnthony Wilson G_QUERY="hoststate" 1763ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1773ae0a354SAnthony Wilson ;; 17879f697e0SAnthony Wilson bmcstate) 17979f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/bmc0 18079f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 18179f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.BMC 18279f697e0SAnthony Wilson PROPERTY=CurrentBMCState 18379f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 18479f697e0SAnthony Wilson ;; 18579f697e0SAnthony Wilson chassisstate) 18679f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 18779f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 18879f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 18979f697e0SAnthony Wilson PROPERTY=CurrentPowerState 19079f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 19179f697e0SAnthony Wilson ;; 19279f697e0SAnthony Wilson hoststate) 19379f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/host0 19479f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 19579f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 19679f697e0SAnthony Wilson PROPERTY=CurrentHostState 19779f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 19879f697e0SAnthony Wilson ;; 19986cffd9cSAlexander Filippov osstate) 20086cffd9cSAlexander Filippov OBJECT=$STATE_OBJECT/host0 20186cffd9cSAlexander Filippov SERVICE=$(mapper get-service $OBJECT) 20286cffd9cSAlexander Filippov INTERFACE=$STATE_INTERFACE.OperatingSystem.Status 20386cffd9cSAlexander Filippov PROPERTY=OperatingSystemState 20486cffd9cSAlexander Filippov state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 20586cffd9cSAlexander Filippov ;; 20679f697e0SAnthony Wilson state|status) 20786cffd9cSAlexander Filippov for query in bmcstate chassisstate hoststate bootprogress osstate 20879f697e0SAnthony Wilson do 20979f697e0SAnthony Wilson handle_cmd $query 21079f697e0SAnthony Wilson done 21179f697e0SAnthony Wilson ;; 21250c5f88dSAnthony Wilson bootprogress) 21350c5f88dSAnthony Wilson OBJECT=$STATE_OBJECT/host0 21450c5f88dSAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 21550c5f88dSAnthony Wilson INTERFACE=$STATE_INTERFACE.Boot.Progress 21650c5f88dSAnthony Wilson PROPERTY=BootProgress 21750c5f88dSAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 21850c5f88dSAnthony Wilson ;; 2190f35983dSAnthony Wilson power) 2200f35983dSAnthony Wilson OBJECT=/org/openbmc/control/power0 2210f35983dSAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 2220f35983dSAnthony Wilson INTERFACE=org.openbmc.control.Power 2230f35983dSAnthony Wilson for property in pgood state pgood_timeout 2240f35983dSAnthony Wilson do 2250f35983dSAnthony Wilson # get_property can potentially return several 2260f35983dSAnthony Wilson # different formats of values, so we do the parsing outside 2270f35983dSAnthony Wilson # of get_property depending on the query. These queries 2280f35983dSAnthony Wilson # return 'i VALUE' formatted strings. 2290f35983dSAnthony Wilson STATE=$(get_property $SERVICE $OBJECT $INTERFACE $property \ 2300f35983dSAnthony Wilson | sed 's/i[ ^I]*//') 2310f35983dSAnthony Wilson printf "%s = %s\n" $property $STATE 2320f35983dSAnthony Wilson done 2330f35983dSAnthony Wilson ;; 234189cf248SAnthony Wilson chassiskill) 235189cf248SAnthony Wilson /usr/libexec/chassiskill 236189cf248SAnthony Wilson ;; 237*6d3a2c54SVishwanatha Subbanna rebootoff) 238*6d3a2c54SVishwanatha Subbanna OBJECT=$CONTROL_OBJECT/host0/auto_reboot 239*6d3a2c54SVishwanatha Subbanna SERVICE=$(mapper get-service $OBJECT) 240*6d3a2c54SVishwanatha Subbanna INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy 241*6d3a2c54SVishwanatha Subbanna PROPERTY=AutoReboot 242*6d3a2c54SVishwanatha Subbanna VALUE=false 243*6d3a2c54SVishwanatha Subbanna set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE 244*6d3a2c54SVishwanatha Subbanna ;; 245*6d3a2c54SVishwanatha Subbanna rebooton) 246*6d3a2c54SVishwanatha Subbanna OBJECT=$CONTROL_OBJECT/host0/auto_reboot 247*6d3a2c54SVishwanatha Subbanna SERVICE=$(mapper get-service $OBJECT) 248*6d3a2c54SVishwanatha Subbanna INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy 249*6d3a2c54SVishwanatha Subbanna PROPERTY=AutoReboot 250*6d3a2c54SVishwanatha Subbanna VALUE=true 251*6d3a2c54SVishwanatha Subbanna set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE 252*6d3a2c54SVishwanatha Subbanna ;; 25379f697e0SAnthony Wilson *) 254ea87db40SAnthony Wilson print_usage_err "Invalid command '$1'" 25579f697e0SAnthony Wilson ;; 25679f697e0SAnthony Wilson esac 25779f697e0SAnthony Wilson} 25879f697e0SAnthony Wilson 259ea87db40SAnthony Wilsonfor arg in "$@"; do 260ea87db40SAnthony Wilson case $arg in 261acf54d08SAnthony Wilson -w|--wait) 262acf54d08SAnthony Wilson G_WAIT=30 263acf54d08SAnthony Wilson continue 264acf54d08SAnthony Wilson ;; 265ea87db40SAnthony Wilson -h|--help) 266ea87db40SAnthony Wilson print_help 267ea87db40SAnthony Wilson ;; 26860c3ac8cSAndrew Jeffery -v|--verbose) 26960c3ac8cSAndrew Jeffery G_VERBOSE=y 27060c3ac8cSAndrew Jeffery ;; 271ea87db40SAnthony Wilson -*) 272ea87db40SAnthony Wilson print_usage_err "Unknown option: $arg" 273ea87db40SAnthony Wilson ;; 274ea87db40SAnthony Wilson *) 275acf54d08SAnthony Wilson G_ORIG_CMD=$arg 276ea87db40SAnthony Wilson handle_cmd $arg 277ea87db40SAnthony Wilson break 278ea87db40SAnthony Wilson ;; 279ea87db40SAnthony Wilson esac 280ea87db40SAnthony Wilsondone 281