xref: /openbmc/phosphor-state-manager/obmcutil (revision 7a787dd7cfa4c52f1842e40a6757cccc8ca356d6)
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