summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2019-12-12 13:30:14 -0600
committerMatt Spinler <spinler@us.ibm.com>2020-01-27 08:06:26 -0600
commita19b6234410703c3b45d30636978e35f07f18394 (patch)
treeb11825e61e576142293f2a01778ec8a485936818
parent41293cb851e00807996950f34cb1ec4e410d6931 (diff)
downloadphosphor-logging-a19b6234410703c3b45d30636978e35f07f18394.tar.gz
phosphor-logging-a19b6234410703c3b45d30636978e35f07f18394.zip
PEL: Receive a 'bad PEL' indication from host
If the code somehow sent the host a malformed PEL, it will respond with the 'Ack PEL' PLDM command with a special value that indicates this, and the PLDM daemon will relay it to this daemon. In this case, change the host transmission state to 'bad' so it doesn't get sent again. This should never happen as the Repository class already validates PELs and removes bad ones, though maybe the host and Repository have different ideas about what constitutes a malformed PEL. In the future, if event logging support is added to the PEL code running inside the logging daemon, it may be a good idea to create a new PEL for this case. Signed-off-by: Matt Spinler <spinler@us.ibm.com> Change-Id: Id6f9fd37764bf5b5d09b4277a1e36b1f26b3e9a5
-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