summaryrefslogtreecommitdiffstats
path: root/extensions/openpower-pels
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2019-11-06 15:01:25 -0600
committerMatt Spinler <spinler@us.ibm.com>2019-12-03 15:07:54 -0600
commita7d9d9615308d6a43d69b0fedea67218f00322ae (patch)
treeff4b7899dfe2d91d4712cc3aae719926f8183212 /extensions/openpower-pels
parent19e89ce419499cb9a8e0f67a66896bc69f360b5c (diff)
downloadphosphor-logging-a7d9d9615308d6a43d69b0fedea67218f00322ae.tar.gz
phosphor-logging-a7d9d9615308d6a43d69b0fedea67218f00322ae.zip
PEL: Keep track of if host is running
Use the DataInterface class to keep track of if the host is up and running by keeping track of the OperatingSystemState property on the xyz.openbmc_project.State.OperatingSystem.Status interface on the /xyz/openbmc_project/state/host0 object path. Added a isHostUp() function as well as a subscribeToHostStateChange() function to allow a user to pass in a function to be run when the host changes state. Property values of 'BootComplete' or 'Standby' mean that the host is running, anything else is considered not running. Signed-off-by: Matt Spinler <spinler@us.ibm.com> Change-Id: I096b2bc4014dff9be85a4bbd74ef27193fd338fb
Diffstat (limited to 'extensions/openpower-pels')
-rw-r--r--extensions/openpower-pels/data_interface.cpp83
-rw-r--r--extensions/openpower-pels/data_interface.hpp115
2 files changed, 198 insertions, 0 deletions
diff --git a/extensions/openpower-pels/data_interface.cpp b/extensions/openpower-pels/data_interface.cpp
index 913faf5..66442c5 100644
--- a/extensions/openpower-pels/data_interface.cpp
+++ b/extensions/openpower-pels/data_interface.cpp
@@ -15,6 +15,8 @@
*/
#include "data_interface.hpp"
+#include <xyz/openbmc_project/State/OperatingSystem/Status/server.hpp>
+
namespace openpower
{
namespace pels
@@ -29,6 +31,7 @@ namespace object_path
{
constexpr auto objectMapper = "/xyz/openbmc_project/object_mapper";
constexpr auto systemInv = "/xyz/openbmc_project/inventory/system";
+constexpr auto hostState = "/xyz/openbmc_project/state/host0";
} // namespace object_path
namespace interface
@@ -36,11 +39,15 @@ namespace interface
constexpr auto dbusProperty = "org.freedesktop.DBus.Properties";
constexpr auto objectMapper = "xyz.openbmc_project.ObjectMapper";
constexpr auto invAsset = "xyz.openbmc_project.Inventory.Decorator.Asset";
+constexpr auto osStatus = "xyz.openbmc_project.State.OperatingSystem.Status";
} // namespace interface
+using namespace sdbusplus::xyz::openbmc_project::State::OperatingSystem::server;
+
DataInterface::DataInterface(sdbusplus::bus::bus& bus) : _bus(bus)
{
readMTMS();
+ readHostState();
}
void DataInterface::readMTMS()
@@ -113,6 +120,20 @@ DBusPropertyMap DataInterface::getAllProperties(const std::string& service,
return properties;
}
+void DataInterface::getProperty(const std::string& service,
+ const std::string& objectPath,
+ const std::string& interface,
+ const std::string& property, DBusValue& value)
+{
+
+ auto method = _bus.new_method_call(service.c_str(), objectPath.c_str(),
+ interface::dbusProperty, "Get");
+ method.append(interface, property);
+ auto reply = _bus.call(method);
+
+ reply.read(value);
+}
+
DBusService DataInterface::getService(const std::string& objectPath,
const std::string& interface)
{
@@ -134,5 +155,67 @@ DBusService DataInterface::getService(const std::string& objectPath,
return std::string{};
}
+
+void DataInterface::readHostState()
+{
+ _hostUp = false;
+
+ try
+ {
+ auto service = getService(object_path::hostState, interface::osStatus);
+ if (!service.empty())
+ {
+ DBusValue value;
+ getProperty(service, object_path::hostState, interface::osStatus,
+ "OperatingSystemState", value);
+
+ auto status =
+ Status::convertOSStatusFromString(std::get<std::string>(value));
+
+ if ((status == Status::OSStatus::BootComplete) ||
+ (status == Status::OSStatus::Standby))
+ {
+ _hostUp = true;
+ }
+ }
+ }
+ catch (std::exception& e)
+ {
+ // Not available yet.
+ }
+
+ // Keep up to date by watching for the propertiesChanged signal.
+ _osStateMatch = std::make_unique<sdbusplus::bus::match_t>(
+ _bus,
+ sdbusplus::bus::match::rules::propertiesChanged(object_path::hostState,
+ interface::osStatus),
+ std::bind(std::mem_fn(&DataInterface::osStatePropChanged), this,
+ std::placeholders::_1));
+}
+
+void DataInterface::osStatePropChanged(sdbusplus::message::message& msg)
+{
+ DBusInterface interface;
+ DBusPropertyMap properties;
+
+ msg.read(interface, properties);
+
+ auto state = properties.find("OperatingSystemState");
+ if (state != properties.end())
+ {
+ auto status = Status::convertOSStatusFromString(
+ std::get<std::string>(state->second));
+
+ bool newHostState = false;
+ if ((status == Status::OSStatus::BootComplete) ||
+ (status == Status::OSStatus::Standby))
+ {
+ newHostState = true;
+ }
+
+ setHostState(newHostState);
+ }
+}
+
} // namespace pels
} // namespace openpower
diff --git a/extensions/openpower-pels/data_interface.hpp b/extensions/openpower-pels/data_interface.hpp
index 14acd70..a3c118e 100644
--- a/extensions/openpower-pels/data_interface.hpp
+++ b/extensions/openpower-pels/data_interface.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
@@ -52,8 +53,72 @@ class DataInterfaceBase
return _machineSerialNumber;
}
+ /**
+ * @brief Says if the host is up and running
+ *
+ * @return bool - If the host is running
+ */
+ virtual bool isHostUp() const
+ {
+ return _hostUp;
+ }
+
+ using HostStateChangeFunc = std::function<void(bool)>;
+
+ /**
+ * @brief Register a callback function that will get
+ * called on all host on/off transitions.
+ *
+ * The void(bool) function will get passed the new
+ * value of the host state.
+ *
+ * @param[in] name - The subscription name
+ * @param[in] func - The function to run
+ */
+ void subscribeToHostStateChange(const std::string& name,
+ HostStateChangeFunc func)
+ {
+ _hostChangeCallbacks[name] = func;
+ }
+
+ /**
+ * @brief Unsubscribe from host state changes.
+ *
+ * @param[in] name - The subscription name
+ */
+ void unsubscribeFromHostStateChange(const std::string& name)
+ {
+ _hostChangeCallbacks.erase(name);
+ }
+
protected:
/**
+ * @brief Sets the host on/off state and runs any
+ * callback functions (if there was a change).
+ */
+ void setHostState(bool newState)
+ {
+ if (_hostUp != newState)
+ {
+ _hostUp = newState;
+
+ for (auto& [name, func] : _hostChangeCallbacks)
+ {
+ try
+ {
+ func(_hostUp);
+ }
+ catch (std::exception& e)
+ {
+ using namespace phosphor::logging;
+ log<level::ERR>("A host state change callback threw "
+ "an exception");
+ }
+ }
+ }
+ }
+
+ /**
* @brief The machine type-model. Always kept up to date
*/
std::string _machineTypeModel;
@@ -62,6 +127,17 @@ class DataInterfaceBase
* @brief The machine serial number. Always kept up to date
*/
std::string _machineSerialNumber;
+
+ /**
+ * @brief The host up status. Always kept up to date.
+ */
+ bool _hostUp = false;
+
+ /**
+ * @brief The map of host state change subscriber
+ * names to callback functions.
+ */
+ std::map<std::string, HostStateChangeFunc> _hostChangeCallbacks;
};
/**
@@ -98,6 +174,19 @@ class DataInterface : public DataInterfaceBase
void readMTMS();
/**
+ * @brief Reads the host state from D-Bus.
+ *
+ * For host on, looks for the values of 'BootComplete' or 'Standby'
+ * in the OperatingSystemState property on the
+ * 'xyz.openbmc_project.State.OperatingSystem.Status' interface
+ * on the '/xyz/openbmc_project/state/host0' path.
+ *
+ * Also adds a properties changed watch on it so the code can be
+ * kept up to date on changes.
+ */
+ void readHostState();
+
+ /**
* @brief Finds the D-Bus service name that hosts the
* passed in path and interface.
*
@@ -120,6 +209,19 @@ class DataInterface : public DataInterfaceBase
const std::string& interface);
/**
+ * @brief Wrapper for the 'Get' properties method call
+ *
+ * @param[in] service - The D-Bus service to call it on
+ * @param[in] objectPath - The D-Bus object path
+ * @param[in] interface - The interface to get the property on
+ * @param[in] property - The property name
+ * @param[out] value - Filled in with the property value.
+ */
+ void getProperty(const std::string& service, const std::string& objectPath,
+ const std::string& interface, const std::string& property,
+ DBusValue& value);
+
+ /**
* @brief The properties changed callback for the Asset iface
* on the system inventory object.
*
@@ -128,11 +230,24 @@ class DataInterface : public DataInterfaceBase
void sysAssetPropChanged(sdbusplus::message::message& msg);
/**
+ * @brief The properties changed callback for the OperatingSystemStatus
+ * interface on the host state object.
+ *
+ * @param[in] msg - The sdbusplus message of the signal
+ */
+ void osStatePropChanged(sdbusplus::message::message& msg);
+
+ /**
* @brief The match object for the system path's properties
*/
std::unique_ptr<sdbusplus::bus::match_t> _sysInventoryPropMatch;
/**
+ * @brief The match object for the operating system status.
+ */
+ std::unique_ptr<sdbusplus::bus::match_t> _osStateMatch;
+
+ /**
* @brief The sdbusplus bus object for making D-Bus calls.
*/
sdbusplus::bus::bus& _bus;
OpenPOWER on IntegriCloud