179f697e0SAnthony Wilson#!/bin/sh -e 279f697e0SAnthony Wilson 379f697e0SAnthony Wilsonset -euo pipefail 479f697e0SAnthony Wilson 5189cf248SAnthony WilsonOPTS="bmcstate,bootprogress,chassiskill,chassisoff,chassison,chassisstate,hoststate,\ 6*7a787dd7SVishwanatha Subbannaosstate,power,poweroff,poweron,state,status,rebootoff,rebooton,recoveryoff,recoveryon" 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 136d3a2c54SVishwanatha SubbannaCONTROL_INTERFACE=$INTERFACE_ROOT.Control 1479f697e0SAnthony Wilson 1579f697e0SAnthony WilsonOBJECT_ROOT=/xyz/openbmc_project 1679f697e0SAnthony WilsonSTATE_OBJECT=$OBJECT_ROOT/state 176d3a2c54SVishwanatha SubbannaCONTROL_OBJECT=$OBJECT_ROOT/control 1879f697e0SAnthony Wilson 19*7a787dd7SVishwanatha SubbannaHOST_TIMEOUT_TARGET=obmc-host-timeout@0.target 20*7a787dd7SVishwanatha Subbanna 21acf54d08SAnthony Wilson## NOTE: The following global variables are used only in the run_timeout cmd. 22acf54d08SAnthony Wilson## By declaring these globally instead of passing them through the 23acf54d08SAnthony Wilson## intermediary functions, which may not be "best practice", the readability 24acf54d08SAnthony Wilson## and cleanliness of the code should at least be increased. 25acf54d08SAnthony Wilson 26acf54d08SAnthony Wilson# The command passed in to be executed (e.g. poweron/off, status, etc.) 27acf54d08SAnthony Wilson# This will be be used in some instances of error reporting 28acf54d08SAnthony WilsonG_ORIG_CMD= 29acf54d08SAnthony Wilson# The state an interface should be in after executing the requested command. 30acf54d08SAnthony WilsonG_REQUESTED_STATE= 31acf54d08SAnthony Wilson# The query to run during a poweron/off or chassison/off to check that 32acf54d08SAnthony Wilson# the requested state (G_REQUESTED_STATE) of the interface has been reached. 33acf54d08SAnthony WilsonG_QUERY= 34acf54d08SAnthony Wilson# Wait the set period of time for state transitions to be successful before 35acf54d08SAnthony Wilson# continuing on with the program or reporting an error if timeout reached. 36acf54d08SAnthony WilsonG_WAIT= 3760c3ac8cSAndrew Jeffery# Print the journal to the console 3860c3ac8cSAndrew JefferyG_VERBOSE= 39acf54d08SAnthony Wilson 40f3f16fa9SAnthony Wilsonprint_help () 41f3f16fa9SAnthony Wilson{ 42f3f16fa9SAnthony Wilson echo "$USAGE" 43f3f16fa9SAnthony Wilson echo "" 44f3f16fa9SAnthony Wilson echo "positional arguments:" 450f35983dSAnthony Wilson echo " {$OPTS}" 46f3f16fa9SAnthony Wilson echo "" 476d3a2c54SVishwanatha Subbanna echo "Examples:" 486d3a2c54SVishwanatha Subbanna echo "" 496d3a2c54SVishwanatha Subbanna echo "obmcutil rebootoff Disable auto reboot from Quiesce state" 506d3a2c54SVishwanatha Subbanna echo "obmcutil rebooton Enable auto reboot from Quiesce state" 516d3a2c54SVishwanatha Subbanna echo "" 52*7a787dd7SVishwanatha Subbanna echo "obmcutil recoveryoff Disable boot watchdog timeout handling and" 53*7a787dd7SVishwanatha Subbanna echo " disable auto reboot from Quiesce state" 54*7a787dd7SVishwanatha Subbanna echo "obmcutil recoveryon Enable boot watchdog timeout handling and" 55*7a787dd7SVishwanatha Subbanna echo " enable auto reboot from Quiesce state" 56*7a787dd7SVishwanatha Subbanna echo "" 57f3f16fa9SAnthony Wilson echo "optional arguments:" 58f3f16fa9SAnthony Wilson echo " -h, --help show this help message and exit" 59acf54d08SAnthony Wilson echo " -w, --wait block until state transition succeeds or fails" 6060c3ac8cSAndrew Jeffery echo " -v, --verbose print the journal to stdout if --wait is supplied" 61f3f16fa9SAnthony Wilson exit 0 62f3f16fa9SAnthony Wilson} 63f3f16fa9SAnthony Wilson 64acf54d08SAnthony Wilsonrun_timeout () 65acf54d08SAnthony Wilson{ 66acf54d08SAnthony Wilson local timeout="$1"; shift 67acf54d08SAnthony Wilson local cmd="$@" 6860c3ac8cSAndrew Jeffery local verbose_child= 6960c3ac8cSAndrew Jeffery 702869a926SAndrew Jeffery if [ -n "$G_VERBOSE" ]; then 7160c3ac8cSAndrew Jeffery journalctl -f & 7260c3ac8cSAndrew Jeffery verbose_child=$! 7360c3ac8cSAndrew Jeffery fi 74acf54d08SAnthony Wilson 75acf54d08SAnthony Wilson $cmd 76acf54d08SAnthony Wilson 77acf54d08SAnthony Wilson # Run a background query for the transition to the expected state 78acf54d08SAnthony Wilson # This will be killed if the transition doesn't succeed within 79acf54d08SAnthony Wilson # a timeout period. 80acf54d08SAnthony Wilson ( 81acf54d08SAnthony Wilson while ! grep -q $G_REQUESTED_STATE <<< $(handle_cmd $G_QUERY) ; do 82acf54d08SAnthony Wilson sleep 1 83acf54d08SAnthony Wilson done 84acf54d08SAnthony Wilson ) & 8560c3ac8cSAndrew Jeffery wait_child=$! 86acf54d08SAnthony Wilson 87acf54d08SAnthony Wilson # Could be bad if process is killed before 'timeout' occurs if 88acf54d08SAnthony Wilson # transition doesn't succeed. 89acf54d08SAnthony Wilson trap -- "" SIGTERM 90acf54d08SAnthony Wilson 91acf54d08SAnthony Wilson # Workaround for lack of 'timeout' command. 92acf54d08SAnthony Wilson ( 93acf54d08SAnthony Wilson sleep $timeout 9460c3ac8cSAndrew Jeffery kill $wait_child 95acf54d08SAnthony Wilson ) > /dev/null 2>&1 & 96acf54d08SAnthony Wilson 9760c3ac8cSAndrew Jeffery if ! wait $wait_child; then 98acf54d08SAnthony Wilson echo "Unable to confirm '$G_ORIG_CMD' success" \ 99acf54d08SAnthony Wilson "within timeout period (${timeout}s)" 100acf54d08SAnthony Wilson fi 10160c3ac8cSAndrew Jeffery 10260c3ac8cSAndrew Jeffery if [ -n $verbose_child ]; then 10360c3ac8cSAndrew Jeffery kill $verbose_child 10460c3ac8cSAndrew Jeffery fi 105acf54d08SAnthony Wilson} 106acf54d08SAnthony Wilson 107acf54d08SAnthony Wilsonrun_cmd () 108acf54d08SAnthony Wilson{ 109acf54d08SAnthony Wilson local cmd="$@"; 110acf54d08SAnthony Wilson 111acf54d08SAnthony Wilson if [ -n "$G_WAIT" ]; then 112acf54d08SAnthony Wilson run_timeout $G_WAIT "$cmd" 113acf54d08SAnthony Wilson else 114acf54d08SAnthony Wilson $cmd 115acf54d08SAnthony Wilson fi 116acf54d08SAnthony Wilson} 117acf54d08SAnthony Wilson 1183ae0a354SAnthony Wilsonset_property () 1193ae0a354SAnthony Wilson{ 120acf54d08SAnthony Wilson run_cmd busctl set-property "$@" 1213ae0a354SAnthony Wilson} 1223ae0a354SAnthony Wilson 12379f697e0SAnthony Wilsonget_property () 12479f697e0SAnthony Wilson{ 125acf54d08SAnthony Wilson G_WAIT="" 126acf54d08SAnthony Wilson run_cmd busctl get-property "$@" 12779f697e0SAnthony Wilson} 12879f697e0SAnthony Wilson 12979f697e0SAnthony Wilsonstate_query () 13079f697e0SAnthony Wilson{ 13179f697e0SAnthony Wilson local state=$(get_property "$@" | cut -d '"' -f2) 13279f697e0SAnthony Wilson printf "%-20s: %s\n" $4 $state 13379f697e0SAnthony Wilson} 13479f697e0SAnthony Wilson 135ea87db40SAnthony Wilsonprint_usage_err () 136ea87db40SAnthony Wilson{ 137ea87db40SAnthony Wilson echo "ERROR: $1" >&2 138ea87db40SAnthony Wilson echo "$USAGE" 139ea87db40SAnthony Wilson exit 1 140ea87db40SAnthony Wilson} 141ea87db40SAnthony Wilson 142*7a787dd7SVishwanatha Subbannamask_systemd_target () 143*7a787dd7SVishwanatha Subbanna{ 144*7a787dd7SVishwanatha Subbanna target="$@" 145*7a787dd7SVishwanatha Subbanna systemctl mask $target 146*7a787dd7SVishwanatha Subbanna} 147*7a787dd7SVishwanatha Subbanna 148*7a787dd7SVishwanatha Subbannaunmask_systemd_target () 149*7a787dd7SVishwanatha Subbanna{ 150*7a787dd7SVishwanatha Subbanna target="$@" 151*7a787dd7SVishwanatha Subbanna systemctl unmask $target 152*7a787dd7SVishwanatha Subbanna} 153*7a787dd7SVishwanatha Subbanna 15479f697e0SAnthony Wilsonhandle_cmd () 15579f697e0SAnthony Wilson{ 15679f697e0SAnthony Wilson case "$1" in 1573ae0a354SAnthony Wilson chassisoff) 1583ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 1593ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1603ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 1613ae0a354SAnthony Wilson PROPERTY=RequestedPowerTransition 1623ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.Off 163acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.PowerState.Off 164acf54d08SAnthony Wilson G_QUERY="chassisstate" 1653ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1663ae0a354SAnthony Wilson ;; 1673ae0a354SAnthony Wilson chassison) 1683ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 1693ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1703ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 1713ae0a354SAnthony Wilson PROPERTY=RequestedPowerTransition 1723ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.On 173acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.PowerState.On 174acf54d08SAnthony Wilson G_QUERY="chassisstate" 1753ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1763ae0a354SAnthony Wilson ;; 1773ae0a354SAnthony Wilson poweroff) 1783ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/host0 1793ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1803ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 1813ae0a354SAnthony Wilson PROPERTY=RequestedHostTransition 1823ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.Off 183acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.HostState.Off 184acf54d08SAnthony Wilson G_QUERY="hoststate" 1853ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1863ae0a354SAnthony Wilson ;; 1873ae0a354SAnthony Wilson poweron) 1883ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/host0 1893ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1903ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 1913ae0a354SAnthony Wilson PROPERTY=RequestedHostTransition 1923ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.On 193acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.HostState.Running 194acf54d08SAnthony Wilson G_QUERY="hoststate" 1953ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1963ae0a354SAnthony Wilson ;; 19779f697e0SAnthony Wilson bmcstate) 19879f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/bmc0 19979f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 20079f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.BMC 20179f697e0SAnthony Wilson PROPERTY=CurrentBMCState 20279f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 20379f697e0SAnthony Wilson ;; 20479f697e0SAnthony Wilson chassisstate) 20579f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 20679f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 20779f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 20879f697e0SAnthony Wilson PROPERTY=CurrentPowerState 20979f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 21079f697e0SAnthony Wilson ;; 21179f697e0SAnthony Wilson hoststate) 21279f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/host0 21379f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 21479f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 21579f697e0SAnthony Wilson PROPERTY=CurrentHostState 21679f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 21779f697e0SAnthony Wilson ;; 21886cffd9cSAlexander Filippov osstate) 21986cffd9cSAlexander Filippov OBJECT=$STATE_OBJECT/host0 22086cffd9cSAlexander Filippov SERVICE=$(mapper get-service $OBJECT) 22186cffd9cSAlexander Filippov INTERFACE=$STATE_INTERFACE.OperatingSystem.Status 22286cffd9cSAlexander Filippov PROPERTY=OperatingSystemState 22386cffd9cSAlexander Filippov state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 22486cffd9cSAlexander Filippov ;; 22579f697e0SAnthony Wilson state|status) 22686cffd9cSAlexander Filippov for query in bmcstate chassisstate hoststate bootprogress osstate 22779f697e0SAnthony Wilson do 22879f697e0SAnthony Wilson handle_cmd $query 22979f697e0SAnthony Wilson done 23079f697e0SAnthony Wilson ;; 23150c5f88dSAnthony Wilson bootprogress) 23250c5f88dSAnthony Wilson OBJECT=$STATE_OBJECT/host0 23350c5f88dSAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 23450c5f88dSAnthony Wilson INTERFACE=$STATE_INTERFACE.Boot.Progress 23550c5f88dSAnthony Wilson PROPERTY=BootProgress 23650c5f88dSAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 23750c5f88dSAnthony Wilson ;; 2380f35983dSAnthony Wilson power) 2390f35983dSAnthony Wilson OBJECT=/org/openbmc/control/power0 2400f35983dSAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 2410f35983dSAnthony Wilson INTERFACE=org.openbmc.control.Power 2420f35983dSAnthony Wilson for property in pgood state pgood_timeout 2430f35983dSAnthony Wilson do 2440f35983dSAnthony Wilson # get_property can potentially return several 2450f35983dSAnthony Wilson # different formats of values, so we do the parsing outside 2460f35983dSAnthony Wilson # of get_property depending on the query. These queries 2470f35983dSAnthony Wilson # return 'i VALUE' formatted strings. 2480f35983dSAnthony Wilson STATE=$(get_property $SERVICE $OBJECT $INTERFACE $property \ 2490f35983dSAnthony Wilson | sed 's/i[ ^I]*//') 2500f35983dSAnthony Wilson printf "%s = %s\n" $property $STATE 2510f35983dSAnthony Wilson done 2520f35983dSAnthony Wilson ;; 253189cf248SAnthony Wilson chassiskill) 254189cf248SAnthony Wilson /usr/libexec/chassiskill 255189cf248SAnthony Wilson ;; 2566d3a2c54SVishwanatha Subbanna rebootoff) 2576d3a2c54SVishwanatha Subbanna OBJECT=$CONTROL_OBJECT/host0/auto_reboot 2586d3a2c54SVishwanatha Subbanna SERVICE=$(mapper get-service $OBJECT) 2596d3a2c54SVishwanatha Subbanna INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy 2606d3a2c54SVishwanatha Subbanna PROPERTY=AutoReboot 2616d3a2c54SVishwanatha Subbanna VALUE=false 2626d3a2c54SVishwanatha Subbanna set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE 2636d3a2c54SVishwanatha Subbanna ;; 2646d3a2c54SVishwanatha Subbanna rebooton) 2656d3a2c54SVishwanatha Subbanna OBJECT=$CONTROL_OBJECT/host0/auto_reboot 2666d3a2c54SVishwanatha Subbanna SERVICE=$(mapper get-service $OBJECT) 2676d3a2c54SVishwanatha Subbanna INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy 2686d3a2c54SVishwanatha Subbanna PROPERTY=AutoReboot 2696d3a2c54SVishwanatha Subbanna VALUE=true 2706d3a2c54SVishwanatha Subbanna set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE 2716d3a2c54SVishwanatha Subbanna ;; 272*7a787dd7SVishwanatha Subbanna recoveryoff) 273*7a787dd7SVishwanatha Subbanna handle_cmd rebootoff 274*7a787dd7SVishwanatha Subbanna mask_systemd_target $HOST_TIMEOUT_TARGET 275*7a787dd7SVishwanatha Subbanna ;; 276*7a787dd7SVishwanatha Subbanna recoveryon) 277*7a787dd7SVishwanatha Subbanna handle_cmd rebooton 278*7a787dd7SVishwanatha Subbanna unmask_systemd_target $HOST_TIMEOUT_TARGET 279*7a787dd7SVishwanatha Subbanna ;; 28079f697e0SAnthony Wilson *) 281ea87db40SAnthony Wilson print_usage_err "Invalid command '$1'" 28279f697e0SAnthony Wilson ;; 28379f697e0SAnthony Wilson esac 28479f697e0SAnthony Wilson} 28579f697e0SAnthony Wilson 286ea87db40SAnthony Wilsonfor arg in "$@"; do 287ea87db40SAnthony Wilson case $arg in 288acf54d08SAnthony Wilson -w|--wait) 289acf54d08SAnthony Wilson G_WAIT=30 290acf54d08SAnthony Wilson continue 291acf54d08SAnthony Wilson ;; 292ea87db40SAnthony Wilson -h|--help) 293ea87db40SAnthony Wilson print_help 294ea87db40SAnthony Wilson ;; 29560c3ac8cSAndrew Jeffery -v|--verbose) 29660c3ac8cSAndrew Jeffery G_VERBOSE=y 29760c3ac8cSAndrew Jeffery ;; 298ea87db40SAnthony Wilson -*) 299ea87db40SAnthony Wilson print_usage_err "Unknown option: $arg" 300ea87db40SAnthony Wilson ;; 301ea87db40SAnthony Wilson *) 302acf54d08SAnthony Wilson G_ORIG_CMD=$arg 303ea87db40SAnthony Wilson handle_cmd $arg 304ea87db40SAnthony Wilson break 305ea87db40SAnthony Wilson ;; 306ea87db40SAnthony Wilson esac 307ea87db40SAnthony Wilsondone 308