diff options
-rw-r--r-- | README.md | 11 | ||||
-rw-r--r-- | manager.cpp | 93 | ||||
-rw-r--r-- | manager.hpp | 26 | ||||
-rw-r--r-- | settings.cpp | 6 | ||||
-rw-r--r-- | settings.hpp | 4 | ||||
-rw-r--r-- | test/TestManager.cpp | 20 |
6 files changed, 83 insertions, 77 deletions
@@ -60,13 +60,12 @@ MANUAL | HOST | Not allowed | OK MANUAL | SPLIT | OK | OK MANUAL | BOTH | OK | OK -### Pgood -When host is on (pgood == 1), the changes of the above time mode/owner are not -applied but deferred. The changes of the mode/owner are saved to persistent -storage. +### Special note on host on +When host is on, the changes of the above time mode/owner are not applied but +deferred. The changes of the mode/owner are saved to persistent storage. -When host is off (pgood == 0), the saved mode/owner are read from -persistent storage and are applied. +When host is off, the saved mode/owner are read from persistent storage and are +applied. Note: user can set the time mode and owner in settings daemon at any time, but time manager applying them is governed by the above condition. diff --git a/manager.cpp b/manager.cpp index 15f1cec..1c971a3 100644 --- a/manager.cpp +++ b/manager.cpp @@ -5,20 +5,13 @@ #include <phosphor-logging/elog-errors.hpp> #include <phosphor-logging/log.hpp> #include <xyz/openbmc_project/Common/error.hpp> +#include <xyz/openbmc_project/State/Host/server.hpp> namespace rules = sdbusplus::bus::match::rules; namespace // anonymous { -const auto MATCH_PGOOD_CHANGE = - rules::type::signal() + - rules::member("PropertiesChanged") + - rules::path("/org/openbmc/control/power0") + - rules::interface("org.freedesktop.DBus.Properties"); - -constexpr auto POWER_PATH = "/org/openbmc/control/power0"; -constexpr auto POWER_INTERFACE = "org.openbmc.control.Power"; -constexpr auto PGOOD_STR = "pgood"; +constexpr auto HOST_CURRENT_STATE = "CurrentHostState"; constexpr auto SYSTEMD_TIME_SERVICE = "org.freedesktop.timedate1"; constexpr auto SYSTEMD_TIME_PATH = "/org/freedesktop/timedate1"; @@ -37,10 +30,15 @@ const std::set<std::string> Manager::managedProperties = {PROPERTY_TIME_MODE, PROPERTY_TIME_OWNER}; Manager::Manager(sdbusplus::bus::bus& bus) - : bus(bus), - pgoodChangeMatch(bus, MATCH_PGOOD_CHANGE, onPgoodChanged, this) + : bus(bus) { using namespace sdbusplus::bus::match::rules; + hostStateChangeMatch = + std::make_unique<decltype(hostStateChangeMatch)::element_type>( + bus, + propertiesChanged(settings.hostState, settings::hostStateIntf), + std::bind(std::mem_fn(&Manager::onHostStateChanged), + this, std::placeholders::_1)); settingsMatches.emplace_back( bus, propertiesChanged(settings.timeOwner, settings::timeOwnerIntf), @@ -94,16 +92,17 @@ void Manager::restoreSettings() void Manager::checkHostOn() { - std::string powerService = utils::getService(bus, - POWER_PATH, - POWER_INTERFACE); - - int pgood = utils::getProperty<int>(bus, - powerService.c_str(), - POWER_PATH, - POWER_INTERFACE, - PGOOD_STR); - hostOn = static_cast<bool>(pgood); + using Host = sdbusplus::xyz::openbmc_project::State::server::Host; + auto hostService = utils::getService(bus, + settings.hostState.c_str(), + settings::hostStateIntf); + auto stateStr = utils::getProperty<std::string>(bus, + hostService.c_str(), + settings.hostState.c_str(), + settings::hostStateIntf, + HOST_CURRENT_STATE); + auto state = Host::convertHostStateFromString(stateStr); + hostOn = (state == Host::HostState::Running); } void Manager::onPropertyChanged(const std::string& key, @@ -206,13 +205,39 @@ void Manager::updateNtpSetting(const std::string& value) } } -void Manager::onPgoodChanged(bool pgood) +void Manager::onHostStateChanged(sdbusplus::message::message& msg) { - hostOn = pgood; + using Interface = std::string; + using Property = std::string; + using Value = std::string; + using Properties = std::map<Property, sdbusplus::message::variant<Value>>; + using Host = sdbusplus::xyz::openbmc_project::State::server::Host; + + Interface interface; + Properties properties; + + msg.read(interface, properties); + + for(const auto& p : properties) + { + if (p.first == HOST_CURRENT_STATE) + { + auto state = Host::convertHostStateFromString(p.second.get<std::string>()); + onHostState(state == Host::HostState::Running); + break; + } + } +} + +void Manager::onHostState(bool on) +{ + hostOn = on; if (hostOn) { + log<level::INFO>("Changing time settings is *deferred* now"); return; } + log<level::INFO>("Changing time settings allowed now"); if (!requestedMode.empty()) { if (setCurrentTimeMode(requestedMode)) @@ -231,28 +256,6 @@ void Manager::onPgoodChanged(bool pgood) } } -int Manager::onPgoodChanged(sd_bus_message* msg, - void* userData, - sd_bus_error* retError) -{ - using properties = std::map < std::string, - sdbusplus::message::variant<int> >; - auto m = sdbusplus::message::message(msg); - // message type: sa{sv}as - std::string ignore; - properties props; - m.read(ignore, props); - for (const auto& item : props) - { - if (item.first == PGOOD_STR) - { - static_cast<Manager*>(userData) - ->onPgoodChanged(static_cast<bool>(item.second.get<int>())); - } - } - return 0; -} - bool Manager::setCurrentTimeMode(const std::string& mode) { auto newMode = utils::strToMode(mode); diff --git a/manager.hpp b/manager.hpp index f9ee511..e84652c 100644 --- a/manager.hpp +++ b/manager.hpp @@ -45,8 +45,8 @@ class Manager /** @brief The match of settings property change */ std::vector<sdbusplus::bus::match::match> settingsMatches; - /** @brief The match of pgood change */ - sdbusplus::bus::match::match pgoodChangeMatch; + /** @brief The match of host state change */ + std::unique_ptr<sdbusplus::bus::match::match> hostStateChangeMatch; /** @brief The container to hold all the listeners */ std::set<PropertyChangeListner*> listeners; @@ -135,11 +135,17 @@ class Manager void onPropertyChanged(const std::string& key, const std::string& value); - /** @brief Notified on pgood has changed + /** @brief Notified on host state has changed * - * @param[in] pgood - The changed pgood value + * @param[in] msg - sdbusplus dbusmessage */ - void onPgoodChanged(bool pgood); + void onHostStateChanged(sdbusplus::message::message& msg); + + /** @brief Notified on host state has changed + * + * @param[in] on - Indicate if the host is on or off + */ + void onHostState(bool on); /** @brief Set the property as requested time mode/owner * @@ -179,16 +185,6 @@ class Manager void* userData, sd_bus_error* retError); - /** @brief Notified on pgood has changed - * - * @param[in] msg - Data associated with subscribed signal - * @param[in] userData - Pointer to this object instance - * @param[out] retError - Not used but required with signal API - */ - static int onPgoodChanged(sd_bus_message* msg, - void* userData, - sd_bus_error* retError); - /** @brief The string of time mode property */ static constexpr auto PROPERTY_TIME_MODE = "TimeSyncMethod"; diff --git a/settings.cpp b/settings.cpp index 650d03d..a3eada9 100644 --- a/settings.cpp +++ b/settings.cpp @@ -17,7 +17,7 @@ Objects::Objects() { auto bus = sdbusplus::bus::new_default(); std::vector<std::string> settingsIntfs = - {timeOwnerIntf, timeSyncIntf}; + {timeOwnerIntf, timeSyncIntf, hostStateIntf}; auto depth = 0; auto mapperCall = bus.new_method_call(mapperService, @@ -57,6 +57,10 @@ Objects::Objects() { timeSyncMethod = path; } + else if (hostStateIntf == interface) + { + hostState = path; + } } } diff --git a/settings.hpp b/settings.hpp index db1e5e4..95d20dc 100644 --- a/settings.hpp +++ b/settings.hpp @@ -13,6 +13,7 @@ using Interface = std::string; constexpr auto root = "/"; constexpr auto timeOwnerIntf = "xyz.openbmc_project.Time.Owner"; constexpr auto timeSyncIntf = "xyz.openbmc_project.Time.Synchronization"; +constexpr auto hostStateIntf = "xyz.openbmc_project.State.Host"; /** @class Objects * @brief Fetch paths of settings D-bus objects of interest upon construction @@ -47,6 +48,9 @@ struct Objects /** @brief time sync method settings object */ Path timeSyncMethod; + + /** @brief host state object */ + Path hostState; }; } // namespace settings diff --git a/test/TestManager.cpp b/test/TestManager.cpp index d8c51ca..decc21d 100644 --- a/test/TestManager.cpp +++ b/test/TestManager.cpp @@ -56,9 +56,9 @@ class TestManager : public testing::Test { manager.onPropertyChanged(key, value); } - void notifyPgoodChanged(bool pgood) + void notifyOnHostState(bool hostOn) { - manager.onPgoodChanged(pgood); + manager.onHostState(hostOn); } }; @@ -74,11 +74,11 @@ TEST_F(TestManager, DISABLED_empty) } -TEST_F(TestManager, DISABLED_pgoodChange) +TEST_F(TestManager, DISABLED_hostStateChange) { - notifyPgoodChanged(true); + notifyOnHostState(true); EXPECT_TRUE(hostOn()); - notifyPgoodChanged(false); + notifyOnHostState(false); EXPECT_FALSE(hostOn()); } @@ -104,7 +104,7 @@ TEST_F(TestManager, DISABLED_propertyChanged) EXPECT_EQ("", getRequestedOwner()); // When host is on, property changes are saved as requested ones - notifyPgoodChanged(true); + notifyOnHostState(true); // Check mocked listeners shall not receive notifications EXPECT_CALL(listener1, onModeChanged(Mode::Manual)).Times(0); @@ -132,14 +132,14 @@ TEST_F(TestManager, DISABLED_propertyChanged) EXPECT_CALL(listener2, onModeChanged(Mode::NTP)).Times(1); EXPECT_CALL(listener2, onOwnerChanged(Owner::Split)).Times(1); - notifyPgoodChanged(false); + notifyOnHostState(false); EXPECT_EQ("", getRequestedMode()); EXPECT_EQ("", getRequestedOwner()); // When host is on, and invalid property is changed, // verify the code asserts because it shall never occur - notifyPgoodChanged(true); + notifyOnHostState(true); ASSERT_DEATH(notifyPropertyChanged("invalid property", "whatever"), ""); } @@ -154,7 +154,7 @@ TEST_F(TestManager, DISABLED_propertyChangedAndChangedbackWhenHostOn) "xyz.openbmc_project.Time.Owner.Owners.Host"); // Set host on - notifyPgoodChanged(true); + notifyOnHostState(true); // Check mocked listeners shall not receive notifications EXPECT_CALL(listener1, onModeChanged(_)).Times(0); @@ -197,7 +197,7 @@ TEST_F(TestManager, DISABLED_propertyChangedAndChangedbackWhenHostOn) EXPECT_CALL(listener2, onModeChanged(_)).Times(0); EXPECT_CALL(listener2, onOwnerChanged(_)).Times(0); - notifyPgoodChanged(false); + notifyOnHostState(false); EXPECT_EQ("", getRequestedMode()); EXPECT_EQ("", getRequestedOwner()); |