179f697e0SAnthony Wilson#!/bin/sh -e 279f697e0SAnthony Wilson 379f697e0SAnthony Wilsonset -euo pipefail 479f697e0SAnthony Wilson 5189cf248SAnthony WilsonOPTS="bmcstate,bootprogress,chassiskill,chassisoff,chassison,chassisstate,hoststate,\ 67a787dd7SVishwanatha 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 197a787dd7SVishwanatha SubbannaHOST_TIMEOUT_TARGET=obmc-host-timeout@0.target 20*84b3b29eSVishwanatha SubbannaHOST_CRASH_TARGET=obmc-host-crash@0.target 217a787dd7SVishwanatha Subbanna 22acf54d08SAnthony Wilson## NOTE: The following global variables are used only in the run_timeout cmd. 23acf54d08SAnthony Wilson## By declaring these globally instead of passing them through the 24acf54d08SAnthony Wilson## intermediary functions, which may not be "best practice", the readability 25acf54d08SAnthony Wilson## and cleanliness of the code should at least be increased. 26acf54d08SAnthony Wilson 27acf54d08SAnthony Wilson# The command passed in to be executed (e.g. poweron/off, status, etc.) 28acf54d08SAnthony Wilson# This will be be used in some instances of error reporting 29acf54d08SAnthony WilsonG_ORIG_CMD= 30acf54d08SAnthony Wilson# The state an interface should be in after executing the requested command. 31acf54d08SAnthony WilsonG_REQUESTED_STATE= 32acf54d08SAnthony Wilson# The query to run during a poweron/off or chassison/off to check that 33acf54d08SAnthony Wilson# the requested state (G_REQUESTED_STATE) of the interface has been reached. 34acf54d08SAnthony WilsonG_QUERY= 35acf54d08SAnthony Wilson# Wait the set period of time for state transitions to be successful before 36acf54d08SAnthony Wilson# continuing on with the program or reporting an error if timeout reached. 37acf54d08SAnthony WilsonG_WAIT= 3860c3ac8cSAndrew Jeffery# Print the journal to the console 3960c3ac8cSAndrew JefferyG_VERBOSE= 40acf54d08SAnthony Wilson 41f3f16fa9SAnthony Wilsonprint_help () 42f3f16fa9SAnthony Wilson{ 43f3f16fa9SAnthony Wilson echo "$USAGE" 44f3f16fa9SAnthony Wilson echo "" 45f3f16fa9SAnthony Wilson echo "positional arguments:" 460f35983dSAnthony Wilson echo " {$OPTS}" 47f3f16fa9SAnthony Wilson echo "" 486d3a2c54SVishwanatha Subbanna echo "Examples:" 496d3a2c54SVishwanatha Subbanna echo "" 506d3a2c54SVishwanatha Subbanna echo "obmcutil rebootoff Disable auto reboot from Quiesce state" 516d3a2c54SVishwanatha Subbanna echo "obmcutil rebooton Enable auto reboot from Quiesce state" 526d3a2c54SVishwanatha Subbanna echo "" 53*84b3b29eSVishwanatha Subbanna echo "obmcutil recoveryoff Disable handling boot watchdog timeout and host crash" 54*84b3b29eSVishwanatha Subbanna echo " Also, disable auto reboot from Quiesce state" 55*84b3b29eSVishwanatha Subbanna echo "obmcutil recoveryon Enable handling boot watchdog timeout and host crash" 56*84b3b29eSVishwanatha Subbanna echo " Also, enable auto reboot from Quiesce state" 577a787dd7SVishwanatha Subbanna echo "" 58f3f16fa9SAnthony Wilson echo "optional arguments:" 59f3f16fa9SAnthony Wilson echo " -h, --help show this help message and exit" 60acf54d08SAnthony Wilson echo " -w, --wait block until state transition succeeds or fails" 6160c3ac8cSAndrew Jeffery echo " -v, --verbose print the journal to stdout if --wait is supplied" 62f3f16fa9SAnthony Wilson exit 0 63f3f16fa9SAnthony Wilson} 64f3f16fa9SAnthony Wilson 65acf54d08SAnthony Wilsonrun_timeout () 66acf54d08SAnthony Wilson{ 67acf54d08SAnthony Wilson local timeout="$1"; shift 68acf54d08SAnthony Wilson local cmd="$@" 6960c3ac8cSAndrew Jeffery local verbose_child= 7060c3ac8cSAndrew Jeffery 712869a926SAndrew Jeffery if [ -n "$G_VERBOSE" ]; then 7260c3ac8cSAndrew Jeffery journalctl -f & 7360c3ac8cSAndrew Jeffery verbose_child=$! 7460c3ac8cSAndrew Jeffery fi 75acf54d08SAnthony Wilson 76acf54d08SAnthony Wilson $cmd 77acf54d08SAnthony Wilson 78acf54d08SAnthony Wilson # Run a background query for the transition to the expected state 79acf54d08SAnthony Wilson # This will be killed if the transition doesn't succeed within 80acf54d08SAnthony Wilson # a timeout period. 81acf54d08SAnthony Wilson ( 82acf54d08SAnthony Wilson while ! grep -q $G_REQUESTED_STATE <<< $(handle_cmd $G_QUERY) ; do 83acf54d08SAnthony Wilson sleep 1 84acf54d08SAnthony Wilson done 85acf54d08SAnthony Wilson ) & 8660c3ac8cSAndrew Jeffery wait_child=$! 87acf54d08SAnthony Wilson 88acf54d08SAnthony Wilson # Could be bad if process is killed before 'timeout' occurs if 89acf54d08SAnthony Wilson # transition doesn't succeed. 90acf54d08SAnthony Wilson trap -- "" SIGTERM 91acf54d08SAnthony Wilson 92acf54d08SAnthony Wilson # Workaround for lack of 'timeout' command. 93acf54d08SAnthony Wilson ( 94acf54d08SAnthony Wilson sleep $timeout 9560c3ac8cSAndrew Jeffery kill $wait_child 96acf54d08SAnthony Wilson ) > /dev/null 2>&1 & 97acf54d08SAnthony Wilson 9860c3ac8cSAndrew Jeffery if ! wait $wait_child; then 99acf54d08SAnthony Wilson echo "Unable to confirm '$G_ORIG_CMD' success" \ 100acf54d08SAnthony Wilson "within timeout period (${timeout}s)" 101acf54d08SAnthony Wilson fi 10260c3ac8cSAndrew Jeffery 10360c3ac8cSAndrew Jeffery if [ -n $verbose_child ]; then 10460c3ac8cSAndrew Jeffery kill $verbose_child 10560c3ac8cSAndrew Jeffery fi 106acf54d08SAnthony Wilson} 107acf54d08SAnthony Wilson 108acf54d08SAnthony Wilsonrun_cmd () 109acf54d08SAnthony Wilson{ 110acf54d08SAnthony Wilson local cmd="$@"; 111acf54d08SAnthony Wilson 112acf54d08SAnthony Wilson if [ -n "$G_WAIT" ]; then 113acf54d08SAnthony Wilson run_timeout $G_WAIT "$cmd" 114acf54d08SAnthony Wilson else 115acf54d08SAnthony Wilson $cmd 116acf54d08SAnthony Wilson fi 117acf54d08SAnthony Wilson} 118acf54d08SAnthony Wilson 1193ae0a354SAnthony Wilsonset_property () 1203ae0a354SAnthony Wilson{ 121acf54d08SAnthony Wilson run_cmd busctl set-property "$@" 1223ae0a354SAnthony Wilson} 1233ae0a354SAnthony Wilson 12479f697e0SAnthony Wilsonget_property () 12579f697e0SAnthony Wilson{ 126acf54d08SAnthony Wilson G_WAIT="" 127acf54d08SAnthony Wilson run_cmd busctl get-property "$@" 12879f697e0SAnthony Wilson} 12979f697e0SAnthony Wilson 13079f697e0SAnthony Wilsonstate_query () 13179f697e0SAnthony Wilson{ 13279f697e0SAnthony Wilson local state=$(get_property "$@" | cut -d '"' -f2) 13379f697e0SAnthony Wilson printf "%-20s: %s\n" $4 $state 13479f697e0SAnthony Wilson} 13579f697e0SAnthony Wilson 136ea87db40SAnthony Wilsonprint_usage_err () 137ea87db40SAnthony Wilson{ 138ea87db40SAnthony Wilson echo "ERROR: $1" >&2 139ea87db40SAnthony Wilson echo "$USAGE" 140ea87db40SAnthony Wilson exit 1 141ea87db40SAnthony Wilson} 142ea87db40SAnthony Wilson 1437a787dd7SVishwanatha Subbannamask_systemd_target () 1447a787dd7SVishwanatha Subbanna{ 1457a787dd7SVishwanatha Subbanna target="$@" 1467a787dd7SVishwanatha Subbanna systemctl mask $target 1477a787dd7SVishwanatha Subbanna} 1487a787dd7SVishwanatha Subbanna 1497a787dd7SVishwanatha Subbannaunmask_systemd_target () 1507a787dd7SVishwanatha Subbanna{ 1517a787dd7SVishwanatha Subbanna target="$@" 1527a787dd7SVishwanatha Subbanna systemctl unmask $target 1537a787dd7SVishwanatha Subbanna} 1547a787dd7SVishwanatha Subbanna 15579f697e0SAnthony Wilsonhandle_cmd () 15679f697e0SAnthony Wilson{ 15779f697e0SAnthony Wilson case "$1" in 1583ae0a354SAnthony Wilson chassisoff) 1593ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 1603ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1613ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 1623ae0a354SAnthony Wilson PROPERTY=RequestedPowerTransition 1633ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.Off 164acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.PowerState.Off 165acf54d08SAnthony Wilson G_QUERY="chassisstate" 1663ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1673ae0a354SAnthony Wilson ;; 1683ae0a354SAnthony Wilson chassison) 1693ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 1703ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1713ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 1723ae0a354SAnthony Wilson PROPERTY=RequestedPowerTransition 1733ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.On 174acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.PowerState.On 175acf54d08SAnthony Wilson G_QUERY="chassisstate" 1763ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1773ae0a354SAnthony Wilson ;; 1783ae0a354SAnthony Wilson poweroff) 1793ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/host0 1803ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1813ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 1823ae0a354SAnthony Wilson PROPERTY=RequestedHostTransition 1833ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.Off 184acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.HostState.Off 185acf54d08SAnthony Wilson G_QUERY="hoststate" 1863ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1873ae0a354SAnthony Wilson ;; 1883ae0a354SAnthony Wilson poweron) 1893ae0a354SAnthony Wilson OBJECT=$STATE_OBJECT/host0 1903ae0a354SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 1913ae0a354SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 1923ae0a354SAnthony Wilson PROPERTY=RequestedHostTransition 1933ae0a354SAnthony Wilson VALUE=$INTERFACE.Transition.On 194acf54d08SAnthony Wilson G_REQUESTED_STATE=$INTERFACE.HostState.Running 195acf54d08SAnthony Wilson G_QUERY="hoststate" 1963ae0a354SAnthony Wilson set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "s" $VALUE 1973ae0a354SAnthony Wilson ;; 19879f697e0SAnthony Wilson bmcstate) 19979f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/bmc0 20079f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 20179f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.BMC 20279f697e0SAnthony Wilson PROPERTY=CurrentBMCState 20379f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 20479f697e0SAnthony Wilson ;; 20579f697e0SAnthony Wilson chassisstate) 20679f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/chassis0 20779f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 20879f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.Chassis 20979f697e0SAnthony Wilson PROPERTY=CurrentPowerState 21079f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 21179f697e0SAnthony Wilson ;; 21279f697e0SAnthony Wilson hoststate) 21379f697e0SAnthony Wilson OBJECT=$STATE_OBJECT/host0 21479f697e0SAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 21579f697e0SAnthony Wilson INTERFACE=$STATE_INTERFACE.Host 21679f697e0SAnthony Wilson PROPERTY=CurrentHostState 21779f697e0SAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 21879f697e0SAnthony Wilson ;; 21986cffd9cSAlexander Filippov osstate) 22086cffd9cSAlexander Filippov OBJECT=$STATE_OBJECT/host0 22186cffd9cSAlexander Filippov SERVICE=$(mapper get-service $OBJECT) 22286cffd9cSAlexander Filippov INTERFACE=$STATE_INTERFACE.OperatingSystem.Status 22386cffd9cSAlexander Filippov PROPERTY=OperatingSystemState 22486cffd9cSAlexander Filippov state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 22586cffd9cSAlexander Filippov ;; 22679f697e0SAnthony Wilson state|status) 22786cffd9cSAlexander Filippov for query in bmcstate chassisstate hoststate bootprogress osstate 22879f697e0SAnthony Wilson do 22979f697e0SAnthony Wilson handle_cmd $query 23079f697e0SAnthony Wilson done 23179f697e0SAnthony Wilson ;; 23250c5f88dSAnthony Wilson bootprogress) 23350c5f88dSAnthony Wilson OBJECT=$STATE_OBJECT/host0 23450c5f88dSAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 23550c5f88dSAnthony Wilson INTERFACE=$STATE_INTERFACE.Boot.Progress 23650c5f88dSAnthony Wilson PROPERTY=BootProgress 23750c5f88dSAnthony Wilson state_query $SERVICE $OBJECT $INTERFACE $PROPERTY 23850c5f88dSAnthony Wilson ;; 2390f35983dSAnthony Wilson power) 2400f35983dSAnthony Wilson OBJECT=/org/openbmc/control/power0 2410f35983dSAnthony Wilson SERVICE=$(mapper get-service $OBJECT) 2420f35983dSAnthony Wilson INTERFACE=org.openbmc.control.Power 2430f35983dSAnthony Wilson for property in pgood state pgood_timeout 2440f35983dSAnthony Wilson do 2450f35983dSAnthony Wilson # get_property can potentially return several 2460f35983dSAnthony Wilson # different formats of values, so we do the parsing outside 2470f35983dSAnthony Wilson # of get_property depending on the query. These queries 2480f35983dSAnthony Wilson # return 'i VALUE' formatted strings. 2490f35983dSAnthony Wilson STATE=$(get_property $SERVICE $OBJECT $INTERFACE $property \ 2500f35983dSAnthony Wilson | sed 's/i[ ^I]*//') 2510f35983dSAnthony Wilson printf "%s = %s\n" $property $STATE 2520f35983dSAnthony Wilson done 2530f35983dSAnthony Wilson ;; 254189cf248SAnthony Wilson chassiskill) 255189cf248SAnthony Wilson /usr/libexec/chassiskill 256189cf248SAnthony Wilson ;; 2576d3a2c54SVishwanatha Subbanna rebootoff) 2586d3a2c54SVishwanatha Subbanna OBJECT=$CONTROL_OBJECT/host0/auto_reboot 2596d3a2c54SVishwanatha Subbanna SERVICE=$(mapper get-service $OBJECT) 2606d3a2c54SVishwanatha Subbanna INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy 2616d3a2c54SVishwanatha Subbanna PROPERTY=AutoReboot 2626d3a2c54SVishwanatha Subbanna VALUE=false 2636d3a2c54SVishwanatha Subbanna set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE 2646d3a2c54SVishwanatha Subbanna ;; 2656d3a2c54SVishwanatha Subbanna rebooton) 2666d3a2c54SVishwanatha Subbanna OBJECT=$CONTROL_OBJECT/host0/auto_reboot 2676d3a2c54SVishwanatha Subbanna SERVICE=$(mapper get-service $OBJECT) 2686d3a2c54SVishwanatha Subbanna INTERFACE=$CONTROL_INTERFACE.Boot.RebootPolicy 2696d3a2c54SVishwanatha Subbanna PROPERTY=AutoReboot 2706d3a2c54SVishwanatha Subbanna VALUE=true 2716d3a2c54SVishwanatha Subbanna set_property $SERVICE $OBJECT $INTERFACE $PROPERTY "b" $VALUE 2726d3a2c54SVishwanatha Subbanna ;; 2737a787dd7SVishwanatha Subbanna recoveryoff) 2747a787dd7SVishwanatha Subbanna handle_cmd rebootoff 2757a787dd7SVishwanatha Subbanna mask_systemd_target $HOST_TIMEOUT_TARGET 276*84b3b29eSVishwanatha Subbanna mask_systemd_target $HOST_CRASH_TARGET 2777a787dd7SVishwanatha Subbanna ;; 2787a787dd7SVishwanatha Subbanna recoveryon) 2797a787dd7SVishwanatha Subbanna handle_cmd rebooton 2807a787dd7SVishwanatha Subbanna unmask_systemd_target $HOST_TIMEOUT_TARGET 281*84b3b29eSVishwanatha Subbanna unmask_systemd_target $HOST_CRASH_TARGET 2827a787dd7SVishwanatha Subbanna ;; 28379f697e0SAnthony Wilson *) 284ea87db40SAnthony Wilson print_usage_err "Invalid command '$1'" 28579f697e0SAnthony Wilson ;; 28679f697e0SAnthony Wilson esac 28779f697e0SAnthony Wilson} 28879f697e0SAnthony Wilson 289ea87db40SAnthony Wilsonfor arg in "$@"; do 290ea87db40SAnthony Wilson case $arg in 291acf54d08SAnthony Wilson -w|--wait) 292acf54d08SAnthony Wilson G_WAIT=30 293acf54d08SAnthony Wilson continue 294acf54d08SAnthony Wilson ;; 295ea87db40SAnthony Wilson -h|--help) 296ea87db40SAnthony Wilson print_help 297ea87db40SAnthony Wilson ;; 29860c3ac8cSAndrew Jeffery -v|--verbose) 29960c3ac8cSAndrew Jeffery G_VERBOSE=y 30060c3ac8cSAndrew Jeffery ;; 301ea87db40SAnthony Wilson -*) 302ea87db40SAnthony Wilson print_usage_err "Unknown option: $arg" 303ea87db40SAnthony Wilson ;; 304ea87db40SAnthony Wilson *) 305acf54d08SAnthony Wilson G_ORIG_CMD=$arg 306ea87db40SAnthony Wilson handle_cmd $arg 307ea87db40SAnthony Wilson break 308ea87db40SAnthony Wilson ;; 309ea87db40SAnthony Wilson esac 310ea87db40SAnthony Wilsondone 311