summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extensions/openpower-pels/host_notifier.cpp13
-rw-r--r--extensions/openpower-pels/host_notifier.hpp12
-rw-r--r--test/openpower-pels/host_notifier_test.cpp67
3 files changed, 92 insertions, 0 deletions
diff --git a/extensions/openpower-pels/host_notifier.cpp b/extensions/openpower-pels/host_notifier.cpp
index ca30340..2e132b9 100644
--- a/extensions/openpower-pels/host_notifier.cpp
+++ b/extensions/openpower-pels/host_notifier.cpp
@@ -419,4 +419,17 @@ void HostNotifier::setHostFull(uint32_t id)
}
}
+void HostNotifier::setBadPEL(uint32_t id)
+{
+ log<level::ERR>("PEL rejected by the host", entry("PEL_ID=0x%X", id));
+
+ auto sent = std::find(_sentPELs.begin(), _sentPELs.end(), id);
+ if (sent != _sentPELs.end())
+ {
+ _sentPELs.erase(sent);
+ }
+
+ _repo.setPELHostTransState(id, TransmissionState::badPEL);
+}
+
} // namespace openpower::pels
diff --git a/extensions/openpower-pels/host_notifier.hpp b/extensions/openpower-pels/host_notifier.hpp
index 21bd072..01eac48 100644
--- a/extensions/openpower-pels/host_notifier.hpp
+++ b/extensions/openpower-pels/host_notifier.hpp
@@ -117,6 +117,18 @@ class HostNotifier
*/
void setHostFull(uint32_t id);
+ /**
+ * @brief Called when the host receives a malformed PEL.
+ *
+ * Ideally this will never happen, as the Repository
+ * class already purges malformed PELs.
+ *
+ * The PEL should never be sent up again.
+ *
+ * @param[in] id - The PEL ID
+ */
+ void setBadPEL(uint32_t id);
+
private:
/**
* @brief This function gets called by the Repository class
diff --git a/test/openpower-pels/host_notifier_test.cpp b/test/openpower-pels/host_notifier_test.cpp
index cd30e8d..9bab030 100644
--- a/test/openpower-pels/host_notifier_test.cpp
+++ b/test/openpower-pels/host_notifier_test.cpp
@@ -746,3 +746,70 @@ TEST_F(HostNotifierTest, TestHostFull)
EXPECT_EQ(mockHostIface.numCmdsProcessed(), 5);
EXPECT_EQ(notifier.queueSize(), 0);
}
+
+// Test when the host says it was send a malformed PEL
+TEST_F(HostNotifierTest, TestBadPEL)
+{
+ MockDataInterface dataIface;
+ sdeventplus::Event sdEvent{event};
+
+ {
+ Repository repo{repoPath};
+
+ std::unique_ptr<HostInterface> hostIface =
+ std::make_unique<MockHostInterface>(event, dataIface);
+
+ MockHostInterface& mockHostIface =
+ reinterpret_cast<MockHostInterface&>(*hostIface);
+
+ HostNotifier notifier{repo, dataIface, std::move(hostIface)};
+
+ auto send = [&mockHostIface](uint32_t id, uint32_t size) {
+ return mockHostIface.send(0);
+ };
+
+ EXPECT_CALL(mockHostIface, sendNewLogCmd(_, _))
+ .WillRepeatedly(Invoke(send));
+
+ dataIface.changeHostState(true);
+
+ // Add a PEL and dispatch and send it
+ auto pel = makePEL();
+ auto id = pel->id();
+ repo.add(pel);
+
+ runEvents(sdEvent, 2);
+ EXPECT_EQ(mockHostIface.numCmdsProcessed(), 1);
+ EXPECT_EQ(notifier.queueSize(), 0);
+
+ // The host rejected it.
+ notifier.setBadPEL(id);
+
+ // Doesn't go back on the queue
+ EXPECT_EQ(notifier.queueSize(), 0);
+
+ // Check the state was saved in the PEL itself
+ Repository::LogID i{Repository::LogID::Pel{id}};
+ auto data = repo.getPELData(i);
+ PEL pelFromRepo{*data};
+ EXPECT_EQ(pelFromRepo.hostTransmissionState(),
+ TransmissionState::badPEL);
+
+ dataIface.changeHostState(false);
+
+ // Ensure it doesn't go back on the queue on a power cycle
+ EXPECT_EQ(notifier.queueSize(), 0);
+ }
+
+ // Now restore the repo, and make sure it doesn't come back
+ {
+ Repository repo{repoPath};
+
+ std::unique_ptr<HostInterface> hostIface =
+ std::make_unique<MockHostInterface>(event, dataIface);
+
+ HostNotifier notifier{repo, dataIface, std::move(hostIface)};
+
+ EXPECT_EQ(notifier.queueSize(), 0);
+ }
+}
OpenPOWER on IntegriCloud