179f697e0SAnthony Wilson#!/bin/sh -e 279f697e0SAnthony Wilson 379f697e0SAnthony Wilsonset -euo pipefail 479f697e0SAnthony Wilson 5189cf248SAnthony WilsonOPTS="bmcstate,bootprogress,chassiskill,chassisoff,chassison,chassisstate,hoststate,\ 686cffd9cSAlexander Filippovosstate,power,poweroff,poweron,state,status" 70f35983dSAnthony Wilson 8*60c3ac8cSAndrew JefferyUSAGE="Usage: obmcutil [-h] [--wait] [--verbose] 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= 33*60c3ac8cSAndrew Jeffery# Print the journal to the console 34*60c3ac8cSAndrew JefferyG_VERBOSE= 35acf54d08SAnthony Wilson 36f3f16fa9SAnthony Wilsonprint_help () 37f3f16fa9SAnthony Wilson{ 38f3f16fa9SAnthony Wilson echo "$USAGE" 39f3f16fa9SAnthony Wilson echo "" 40f3f16fa9SAnthony Wilson echo "positional arguments:" 410f35983dSAnthony Wilson echo " {$OPTS}" 42f3f16fa9SAnthony Wilson echo "" 43f3f16fa9SAnthony Wilson echo "optional arguments:" 44f3f16fa9SAnthony Wilson echo " -h, --help show this help message and exit" 45acf54d08SAnthony Wilson echo " -w, --wait block until state transition succeeds or fails" 46*60c3ac8cSAndrew Jeffery echo " -v, --verbose print the journal to stdout if --wait is supplied" 47f3f16fa9SAnthony Wilson exit 0 48f3f16fa9SAnthony Wilson} 49f3f16fa9SAnthony Wilson 50acf54d08SAnthony Wilsonrun_timeout () 51acf54d08SAnthony Wilson{ 52acf54d08SAnthony Wilson local timeout="$1"; shift 53acf54d08SAnthony Wilson local cmd="$@" 54*60c3ac8cSAndrew Jeffery local verbose_child= 55*60c3ac8cSAndrew Jeffery 56*60c3ac8cSAndrew Jeffery if [ -n $G_VERBOSE ]; then 57*60c3ac8cSAndrew Jeffery journalctl -f & 58*60c3ac8cSAndrew Jeffery verbose_child=$! 59*60c3ac8cSAndrew Jeffery fi 60acf54d08SAnthony Wilson 61acf54d08SAnthony Wilson $cmd 62acf54d08SAnthony Wilson 63acf54d08SAnthony Wilson # Run a background query for the transition to the expected state 64acf54d08SAnthony Wilson # This will be killed if the transition doesn't succeed within 65acf54d08SAnthony Wilson # a timeout period. 66acf54d08SAnthony Wilson ( 67acf54d08SAnthony Wilson while ! grep -q $G_REQUESTED_STATE <<< $(handle_cmd $G_QUERY) ; do 68acf54d08SAnthony Wilson sleep 1 69acf54d08SAnthony Wilson done 70acf54d08SAnthony Wilson ) & 71*60c3ac8cSAndrew Jeffery wait_child=$! 72acf54d08SAnthony Wilson 73acf54d08SAnthony Wilson # Could be bad if process is killed before 'timeout' occurs if 74acf54d08SAnthony Wilson # transition doesn't succeed. 75acf54d08SAnthony Wilson trap -- "" SIGTERM 76acf54d08SAnthony Wilson 77acf54d08SAnthony Wilson # Workaround for lack of 'timeout' command. 78acf54d08SAnthony Wilson ( 79acf54d08SAnthony Wilson sleep $timeout 80*60c3ac8cSAndrew Jeffery kill $wait_child 81acf54d08SAnthony Wilson ) > /dev/null 2>&1 & 82acf54d08SAnthony Wilson 83*60c3ac8cSAndrew Jeffery if ! wait $wait_child; then 84acf54d08SAnthony Wilson echo "Unable to confirm '$G_ORIG_CMD' success" \ 85acf54d08SAnthony Wilson "within timeout period (${timeout}s)" 86acf54d08SAnthony Wilson fi 87*60c3ac8cSAndrew Jeffery 88*60c3ac8cSAndrew Jeffery if [ -n $verbose_child ]; then 89*60c3ac8cSAndrew Jeffery kill $verbose_child 90*60c3ac8cSAndrew Jeffery fi 91acf54d08SAnthony Wilson} 92acf54d08SAnthony Wilson 93acf54d08SAnthony Wilsonrun_cmd () 94acf54d08SAnthony Wilson{ 95acf54d08SAnthony Wilson local cmd="$@"; 96acf54d08SAnthony Wilson 97acf54d08SAnthony Wilson if [ -n "$G_WAIT" ]; then 98acf54d08SAnthony Wilson run_timeout $G_WAIT "$cmd" 99acf54d08SAnthony Wilson else 100acf54d08SAnthony Wilson $cmd 101acf54d08SAnthony Wilson fi 102acf54d08SAnthony Wilson} 103acf54d08SAnthony Wilson 1043ae0a354SAnthony Wilsonset_property () 1053ae0a354SAnthony Wilson{ 106acf54d08SAnthony Wilson run_cmd busctl set-property "$@" 1073ae0a354SAnthony Wilson} 1083ae0a354SAnthony Wilson 10979f697e0SAnthony Wilsonget_property () 11079f697e0SAnthony Wilson{ 111acf54d08SAnthony Wilson G_WAIT="" 112acf54d08SAnthony Wilson run_cmd busctl get-property "$@" 11379f697e0SAnthony Wilson} 11479f697e0SAnthony Wilson 11579f697e0SAnthony Wilsonstate_query () 11679f697e0SAnthony Wilson{ 11779f697e0SAnthony Wilson local state=$(get_property "$@" | cut -d '"' -f2) 11879f697e0SAnthony Wilson printf "%-20s: %s\n" $4 $state 11979f697e0SAnthony Wilson} 12079f697e0SAnthony Wilson 121ea87db40SAnthony Wilsonprint_usage_err () 122ea87db40SAnthony Wilson{ 123ea87db40SAnthony Wilson echo "ERROR: $1" >&2 124ea87db40SAnthony Wilson echo "$USAGE" 125ea87db40SAnthony Wilson exit 1 126ea87db40SAnthony Wilson} 127ea87db40SAnthony Wilson 12879f697e0SAnthony Wilsonhandle_cmd () 12979f697e0SAnthony Wilson{ 13079f697e0SAnthony Wilson case "$1" in 1313ae0a354SAnthony Wilson chassisoff) 1323ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 1333ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1343ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 1353ae0a354SAnthony Wilson PROPERTY=RequestedPowerTransition 1363ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.Off 137acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.PowerState.Off 138acf54d08SAnthony Wilson G_QUERY="chassisstate" 1393ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1403ae0a354SAnthony Wilson ;; 1413ae0a354SAnthony Wilson chassison) 1423ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 1433ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1443ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 1453ae0a354SAnthony Wilson PROPERTY=RequestedPowerTransition 1463ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.On 147acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.PowerState.On 148acf54d08SAnthony Wilson G_QUERY="chassisstate" 1493ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1503ae0a354SAnthony Wilson ;; 1513ae0a354SAnthony Wilson poweroff) 1523ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/host0 1533ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1543ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 1553ae0a354SAnthony Wilson PROPERTY=RequestedHostTransition 1563ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.Off 157acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.HostState.Off 158acf54d08SAnthony Wilson G_QUERY="hoststate" 1593ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1603ae0a354SAnthony Wilson ;; 1613ae0a354SAnthony Wilson poweron) 1623ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/host0 1633ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1643ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 1653ae0a354SAnthony Wilson PROPERTY=RequestedHostTransition 1663ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.On 167acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.HostState.Running 168acf54d08SAnthony Wilson G_QUERY="hoststate" 1693ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1703ae0a354SAnthony Wilson ;; 17179f697e0SAnthony Wilson bmcstate) 17279f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/bmc0 17379f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 17479f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.BMC 17579f697e0SAnthony Wilson PROPERTY=CurrentBMCState 17679f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 17779f697e0SAnthony Wilson ;; 17879f697e0SAnthony Wilson chassisstate) 17979f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 18079f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 18179f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 18279f697e0SAnthony Wilson PROPERTY=CurrentPowerState 18379f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 18479f697e0SAnthony Wilson ;; 18579f697e0SAnthony Wilson hoststate) 18679f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/host0 18779f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 18879f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 18979f697e0SAnthony Wilson PROPERTY=CurrentHostState 19079f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 19179f697e0SAnthony Wilson ;; 19286cffd9cSAlexander Filippov osstate) 19386cffd9cSAlexander Filippov OBJECT=$STATE_OBJECT/host0 19486cffd9cSAlexander Filippov SERVICE=$(mapper get-service $OBJECT) 19586cffd9cSAlexander Filippov INTERFACE=$STATE_INTERFACE.OperatingSystem.Status 19686cffd9cSAlexander Filippov PROPERTY=OperatingSystemState 19786cffd9cSAlexander Filippov state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 19886cffd9cSAlexander Filippov ;; 19979f697e0SAnthony Wilson state|status) 20086cffd9cSAlexander Filippov for query in bmcstate chassisstate hoststate bootprogress osstate 20179f697e0SAnthony Wilson do 20279f697e0SAnthony Wilson handle_cmd $query 20379f697e0SAnthony Wilson done 20479f697e0SAnthony Wilson ;; 20550c5f88dSAnthony Wilson bootprogress) 20650c5f88dSAnthony Wilson OBJECT=$STATE_OBJECT/host0 20750c5f88dSAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 20850c5f88dSAnthony Wilson INTERFACE=$STATE_INTERFACE.Boot.Progress 20950c5f88dSAnthony Wilson PROPERTY=BootProgress 21050c5f88dSAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 21150c5f88dSAnthony Wilson ;; 2120f35983dSAnthony Wilson power) 2130f35983dSAnthony Wilson OBJECT=/org/openbmc/control/power0 2140f35983dSAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 2150f35983dSAnthony Wilson INTERFACE=org.openbmc.control.Power 2160f35983dSAnthony Wilson for property in pgood state pgood_timeout 2170f35983dSAnthony Wilson do 2180f35983dSAnthony Wilson # get_property can potentially return several 2190f35983dSAnthony Wilson # different formats of values, so we do the parsing outside 2200f35983dSAnthony Wilson # of get_property depending on the query. These queries 2210f35983dSAnthony Wilson # return 'i VALUE' formatted strings. 2220f35983dSAnthony Wilson STATE=$(get_property $SERVICE $OBJECT $INTERFACE $property \ 2230f35983dSAnthony Wilson | sed 's/i[ ^I]*//') 2240f35983dSAnthony Wilson printf "%s = %s\n" $property $STATE 2250f35983dSAnthony Wilson done 2260f35983dSAnthony Wilson ;; 227189cf248SAnthony Wilson chassiskill) 228189cf248SAnthony Wilson /usr/libexec/chassiskill 229189cf248SAnthony Wilson ;; 23079f697e0SAnthony Wilson *) 231ea87db40SAnthony Wilson print_usage_err "Invalid command '$1'" 23279f697e0SAnthony Wilson ;; 23379f697e0SAnthony Wilson esac 23479f697e0SAnthony Wilson} 23579f697e0SAnthony Wilson 236ea87db40SAnthony Wilsonfor arg in "$@"; do 237ea87db40SAnthony Wilson case $arg in 238acf54d08SAnthony Wilson -w|--wait) 239acf54d08SAnthony Wilson G_WAIT=30 240acf54d08SAnthony Wilson continue 241acf54d08SAnthony Wilson ;; 242ea87db40SAnthony Wilson -h|--help) 243ea87db40SAnthony Wilson print_help 244ea87db40SAnthony Wilson ;; 245*60c3ac8cSAndrew Jeffery -v|--verbose) 246*60c3ac8cSAndrew Jeffery G_VERBOSE=y 247*60c3ac8cSAndrew Jeffery ;; 248ea87db40SAnthony Wilson -*) 249ea87db40SAnthony Wilson print_usage_err "Unknown option: $arg" 250ea87db40SAnthony Wilson ;; 251ea87db40SAnthony Wilson *) 252acf54d08SAnthony Wilson G_ORIG_CMD=$arg 253ea87db40SAnthony Wilson handle_cmd $arg 254ea87db40SAnthony Wilson break 255ea87db40SAnthony Wilson ;; 256ea87db40SAnthony Wilson esac 257ea87db40SAnthony Wilsondone 258