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