summaryrefslogtreecommitdiffstats
path: root/host_state_manager.hpp
blob: af748f5d7ea4bbb22f6683978cd56357e403a5eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#pragma once

#include <string>
#include <functional>
#include <sdbusplus/bus.hpp>
#include <phosphor-logging/log.hpp>
#include <xyz/openbmc_project/State/Boot/Progress/server.hpp>
#include <xyz/openbmc_project/Control/Boot/RebootAttempts/server.hpp>
#include <xyz/openbmc_project/State/OperatingSystem/Status/server.hpp>
#include "xyz/openbmc_project/State/Host/server.hpp"
#include "settings.hpp"
#include "config.h"

namespace phosphor
{
namespace state
{
namespace manager
{

using HostInherit = sdbusplus::server::object::object<
        sdbusplus::xyz::openbmc_project::State::server::Host,
        sdbusplus::xyz::openbmc_project::State::Boot::server::Progress,
        sdbusplus::xyz::openbmc_project::Control::Boot::server::RebootAttempts,
        sdbusplus::xyz::openbmc_project::State::OperatingSystem::server::Status>;

using namespace phosphor::logging;

namespace sdbusRule = sdbusplus::bus::match::rules;

/** @class Host
 *  @brief OpenBMC host state management implementation.
 *  @details A concrete implementation for xyz.openbmc_project.State.Host
 *  DBus API.
 */
class Host : public HostInherit
{
    public:
        /** @brief Constructs Host State Manager
         *
         * @note This constructor passes 'true' to the base class in order to
         *       defer dbus object registration until we can run
         *       determineInitialState() and set our properties
         *
         * @param[in] bus       - The Dbus bus object
         * @param[in] busName   - The Dbus name to own
         * @param[in] objPath   - The Dbus object path
         */
        Host(sdbusplus::bus::bus& bus,
             const char* busName,
             const char* objPath) :
                HostInherit(bus, objPath, true),
                bus(bus),
                systemdSignals(
                        bus,
                        sdbusRule::type::signal() +
                        sdbusRule::member("JobRemoved") +
                        sdbusRule::path("/org/freedesktop/systemd1") +
                        sdbusRule::interface(
                                "org.freedesktop.systemd1.Manager"),
                        std::bind(std::mem_fn(&Host::sysStateChange),
                                  this, std::placeholders::_1)),
                settings(bus)
        {
            // Enable systemd signals
            subscribeToSystemdSignals();

            // Will throw exception on fail
            determineInitialState();

            attemptsLeft(BOOT_COUNT_MAX_ALLOWED);

            // We deferred this until we could get our property correct
            this->emit_object_added();
        }

        /** @brief Set value of HostTransition */
        Transition requestedHostTransition(Transition value) override;

        /** @brief Set value of CurrentHostState */
        HostState currentHostState(HostState value) override;

        /**
         * @brief Set host reboot count to default
         *
         * OpenBMC software controls the number of allowed reboot attempts so
         * any external set request of this property will be overridden by
         * this function and set to the default.
         *
         * The only code responsible for decrementing the boot count resides
         * within this process and that will use the sub class interface
         * directly
         *
         * @param[in] value      - Reboot count value, will be ignored
         *
         * @return Default number of reboot attempts left
         */
        uint32_t attemptsLeft(uint32_t value) override
        {
            log<level::DEBUG>("External request to reset reboot count");
            return (sdbusplus::xyz::openbmc_project::Control::Boot::server::
                    RebootAttempts::attemptsLeft(BOOT_COUNT_MAX_ALLOWED));
        }

    private:
        /**
         * @brief subscribe to the systemd signals
         *
         * This object needs to capture when it's systemd targets complete
         * so it can keep it's state updated
         *
         **/
        void subscribeToSystemdSignals();

        /**
         * @brief Determine initial host state and set internally
         *
         * @return Will throw exceptions on failure
         **/
        void determineInitialState();

        /** @brief Execute the transition request
         *
         * This function assumes the state has been validated and the host
         * is in an appropriate state for the transition to be started.
         *
         * @param[in] tranReq    - Transition requested
         */
        void executeTransition(Transition tranReq);

        /**
         * @brief Determine if target is active
         *
         * This function determines if the target is active and
         * helps prevent misleading log recorded states.
         *
         * @param[in] target - Target string to check on
         *
         * @return boolean corresponding to state active
         **/
        bool stateActive(const std::string& target);

        /**
         * @brief Determine if auto reboot flag is set
         *
         * @return boolean corresponding to current auto_reboot setting
         **/
        bool isAutoReboot();

        /** @brief Check if systemd state change is relevant to this object
         *
         * Instance specific interface to handle the detected systemd state
         * change
         *
         * @param[in]  msg       - Data associated with subscribed signal
         *
         */
        void sysStateChange(sdbusplus::message::message& msg);

        /** @brief Determine whether restoring of host requested state is enabled
         *
         * @return boolean corresponding to restore setting
         */
        bool getStateRestoreSetting() const;

        /** @brief Decrement reboot count
         *
         * This is used internally to this application to decrement the boot
         * count on each boot attempt. The host will use the external
         * attemptsLeft() interface to reset the count when a boot is successful
         *
         * @return number of reboot count attempts left
         */
        uint32_t decrementRebootCount();

        /** @brief Persistent sdbusplus DBus bus connection. */
        sdbusplus::bus::bus& bus;

        /** @brief Used to subscribe to dbus systemd signals **/
        sdbusplus::bus::match_t systemdSignals;

        // Settings objects of interest
        settings::Objects settings;
};

} // namespace manager
} // namespace state
} // namespace phosphor
OpenPOWER on IntegriCloud