summaryrefslogtreecommitdiffstats
path: root/extensions/openpower-pels
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2019-12-11 13:47:50 -0600
committerMatt Spinler <spinler@us.ibm.com>2020-01-27 08:06:26 -0600
commitf60ac27e3ee4aa7166065db93a3fc0ae2d9481ac (patch)
tree5c293bb43577cac4458a3a7a4e39b3fb6084ceab /extensions/openpower-pels
parent99196688997f16d1611229e007a443d7e1a9f760 (diff)
downloadphosphor-logging-f60ac27e3ee4aa7166065db93a3fc0ae2d9481ac.tar.gz
phosphor-logging-f60ac27e3ee4aa7166065db93a3fc0ae2d9481ac.zip
PEL: Add HostNotifier class
This class will watch for new PELs being created, and handle sending them up to the host. This first commit for this class mostly just fills in the constructor to set up the various callbacks it will use. It is only instantiated in the Manager class if the Manager constructor used is the one that passes in the HostInterface object, to allow for configurations that don't need PELs passed up. Signed-off-by: Matt Spinler <spinler@us.ibm.com> Change-Id: I0ddcf94d047979eb78209d396c2351566c634dbe
Diffstat (limited to 'extensions/openpower-pels')
-rw-r--r--extensions/openpower-pels/host_notifier.cpp107
-rw-r--r--extensions/openpower-pels/host_notifier.hpp125
-rw-r--r--extensions/openpower-pels/manager.hpp28
-rw-r--r--extensions/openpower-pels/openpower-pels.mk1
4 files changed, 259 insertions, 2 deletions
diff --git a/extensions/openpower-pels/host_notifier.cpp b/extensions/openpower-pels/host_notifier.cpp
new file mode 100644
index 0000000..ec5db41
--- /dev/null
+++ b/extensions/openpower-pels/host_notifier.cpp
@@ -0,0 +1,107 @@
+/**
+ * Copyright © 2019 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "host_notifier.hpp"
+
+#include <phosphor-logging/log.hpp>
+
+namespace openpower::pels
+{
+
+const auto subscriptionName = "PELHostNotifier";
+
+using namespace phosphor::logging;
+
+HostNotifier::HostNotifier(Repository& repo, DataInterfaceBase& dataIface,
+ std::unique_ptr<HostInterface> hostIface) :
+ _repo(repo),
+ _dataIface(dataIface), _hostIface(std::move(hostIface))
+{
+ // Subscribe to be told about new PELs.
+ _repo.subscribeToAdds(subscriptionName,
+ std::bind(std::mem_fn(&HostNotifier::newLogCallback),
+ this, std::placeholders::_1));
+
+ // Add any existing PELs to the queue to send them if necessary.
+ _repo.for_each(std::bind(std::mem_fn(&HostNotifier::addPELToQueue), this,
+ std::placeholders::_1));
+
+ // Subscribe to be told about host state changes.
+ _dataIface.subscribeToHostStateChange(
+ subscriptionName,
+ std::bind(std::mem_fun(&HostNotifier::hostStateChange), this,
+ std::placeholders::_1));
+
+ // Set the function to call when the async reponse is received.
+ _hostIface->setResponseFunction(
+ std::bind(std::mem_fn(&HostNotifier::commandResponse), this,
+ std::placeholders::_1));
+
+ // Start sending logs if the host is running
+ if (!_pelQueue.empty() && _dataIface.isHostUp())
+ {
+ doNewLogNotify();
+ }
+}
+
+HostNotifier::~HostNotifier()
+{
+ _repo.unsubscribeFromAdds(subscriptionName);
+ _dataIface.unsubscribeFromHostStateChange(subscriptionName);
+}
+
+bool HostNotifier::addPELToQueue(const PEL& pel)
+{
+ if (enqueueRequired(pel.id()))
+ {
+ _pelQueue.push_back(pel.id());
+ }
+
+ // Return false so that Repo::for_each keeps going.
+ return false;
+}
+
+bool HostNotifier::enqueueRequired(uint32_t id) const
+{
+ bool required = true;
+
+ return required;
+}
+
+void HostNotifier::newLogCallback(const PEL& pel)
+{
+ if (!enqueueRequired(pel.id()))
+ {
+ return;
+ }
+
+ _pelQueue.push_back(pel.id());
+
+ // TODO: Check if a send is needed now
+}
+
+void HostNotifier::doNewLogNotify()
+{
+}
+
+void HostNotifier::hostStateChange(bool hostUp)
+{
+}
+
+void HostNotifier::commandResponse(ResponseStatus status)
+{
+}
+
+} // namespace openpower::pels
diff --git a/extensions/openpower-pels/host_notifier.hpp b/extensions/openpower-pels/host_notifier.hpp
new file mode 100644
index 0000000..ee1ba0c
--- /dev/null
+++ b/extensions/openpower-pels/host_notifier.hpp
@@ -0,0 +1,125 @@
+#pragma once
+
+#include "host_interface.hpp"
+#include "pel.hpp"
+#include "repository.hpp"
+
+#include <deque>
+
+namespace openpower::pels
+{
+
+/**
+ * @class HostNotifier
+ *
+ * This class handles notifying the host firmware of new PELs.
+ */
+class HostNotifier
+{
+ public:
+ HostNotifier() = delete;
+ HostNotifier(const HostNotifier&) = delete;
+ HostNotifier& operator=(const HostNotifier&) = delete;
+ HostNotifier(HostNotifier&&) = delete;
+ HostNotifier& operator=(HostNotifier&&) = delete;
+
+ /**
+ * @brief Constructor
+ *
+ * @param[in] repo - The PEL repository object
+ * @param[in] dataIface - The data interface object
+ * @param[in] hostIface - The host interface object
+ */
+ HostNotifier(Repository& repo, DataInterfaceBase& dataIface,
+ std::unique_ptr<HostInterface> hostIface);
+
+ /**
+ * @brief Destructor
+ */
+ ~HostNotifier();
+
+ /**
+ * @brief Returns the PEL queue size.
+ *
+ * For testing.
+ *
+ * @return size_t - The queue size
+ */
+ size_t queueSize() const
+ {
+ return _pelQueue.size();
+ }
+
+ /**
+ * @brief Specifies if the PEL needs to go onto the queue to be
+ * set to the host.
+ *
+ * @param[in] id - The PEL ID
+ *
+ * @return bool - If enqueue is required
+ */
+ bool enqueueRequired(uint32_t id) const;
+
+ private:
+ /**
+ * @brief This function gets called by the Repository class
+ * when a new PEL is added to it.
+ *
+ * @param[in] pel - The new PEL
+ */
+ void newLogCallback(const PEL& pel);
+
+ /**
+ * @brief This function runs on every existing PEL at startup
+ * and puts the PEL on the queue to send if necessary.
+ *
+ * @param[in] pel - The PEL
+ *
+ * @return bool - This is an indicator to the Repository::for_each
+ * function to traverse every PEL. Always false.
+ */
+ bool addPELToQueue(const PEL& pel);
+
+ /**
+ * @brief Takes the PEL off the front of the queue and issues
+ * the PLDM send.
+ */
+ void doNewLogNotify();
+
+ /**
+ * @brief Called when the host changes state.
+ *
+ * @param[in] hostUp - The new host state
+ */
+ void hostStateChange(bool hostUp);
+
+ /**
+ * @brief The callback function invoked after the asynchronous
+ * PLDM receive function is complete.
+ *
+ * @param[in] status - The response status
+ */
+ void commandResponse(ResponseStatus status);
+
+ /**
+ * @brief The PEL repository object
+ */
+ Repository& _repo;
+
+ /**
+ * @brief The data interface object
+ */
+ DataInterfaceBase& _dataIface;
+
+ /**
+ * @brief Base class pointer for the host command interface
+ */
+ std::unique_ptr<HostInterface> _hostIface;
+
+ /**
+ * @brief The list of PEL IDs that need to be sent.
+ */
+ std::deque<uint32_t> _pelQueue;
+};
+
+} // namespace openpower::pels
diff --git a/extensions/openpower-pels/manager.hpp b/extensions/openpower-pels/manager.hpp
index 5f092f4..731dd16 100644
--- a/extensions/openpower-pels/manager.hpp
+++ b/extensions/openpower-pels/manager.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "data_interface.hpp"
+#include "host_notifier.hpp"
#include "log_manager.hpp"
#include "paths.hpp"
#include "registry.hpp"
@@ -28,9 +29,10 @@ class Manager
* @brief constructor
*
* @param[in] logManager - internal::Manager object
+ * @param[in] dataIface - The data interface object
*/
- explicit Manager(phosphor::logging::internal::Manager& logManager,
- std::unique_ptr<DataInterfaceBase>&& dataIface) :
+ Manager(phosphor::logging::internal::Manager& logManager,
+ std::unique_ptr<DataInterfaceBase> dataIface) :
_logManager(logManager),
_repo(getPELRepoPath()),
_registry(getMessageRegistryPath() / message::registryFileName),
@@ -39,6 +41,22 @@ class Manager
}
/**
+ * @brief constructor that enables host notification
+ *
+ * @param[in] logManager - internal::Manager object
+ * @param[in] dataIface - The data interface object
+ * @param[in] hostIface - The hostInterface object
+ */
+ Manager(phosphor::logging::internal::Manager& logManager,
+ std::unique_ptr<DataInterfaceBase> dataIface,
+ std::unique_ptr<HostInterface> hostIface) :
+ Manager(logManager, std::move(dataIface))
+ {
+ _hostNotifier = std::make_unique<HostNotifier>(
+ _repo, *(_dataIface.get()), std::move(hostIface));
+ }
+
+ /**
* @brief Creates a PEL based on the OpenBMC event log contents. If
* a PEL was passed in via the RAWPEL specifier in the
* additionalData parameter, use that instead.
@@ -117,6 +135,12 @@ class Manager
* @brief The API the PEL sections use to gather data
*/
std::unique_ptr<DataInterfaceBase> _dataIface;
+
+ /**
+ * @brief The HostNotifier object used for telling the
+ * host about new PELs
+ */
+ std::unique_ptr<HostNotifier> _hostNotifier;
};
} // namespace pels
diff --git a/extensions/openpower-pels/openpower-pels.mk b/extensions/openpower-pels/openpower-pels.mk
index f028293..220668f 100644
--- a/extensions/openpower-pels/openpower-pels.mk
+++ b/extensions/openpower-pels/openpower-pels.mk
@@ -1,5 +1,6 @@
phosphor_log_manager_SOURCES += \
extensions/openpower-pels/entry_points.cpp \
+ extensions/openpower-pels/host_notifier.cpp \
extensions/openpower-pels/manager.cpp \
extensions/openpower-pels/repository.cpp \
extensions/openpower-pels/user_data.cpp
OpenPOWER on IntegriCloud