PEL: Prevent deletion if it's associated with HWIsolation
- This ensures that PELs linked to HWIsolation records are protected
from accidental deletion.
- Shows error message of "Call failed: The service is temporarily
unavailable.", when attempting to delete such a PEL individually.
- If trying to Delete all, will skip such PELs without showing any
message.
Tested:
Sample output:
```bash
$ busctl call xyz.openbmc_project.Logging /xyz/openbmc_project/
logging xyz.openbmc_project.Collection.DeleteAll DeleteAll
$ busctl call xyz.openbmc_project.Logging /xyz/openbmc_project/
logging/entry/2 xyz.openbmc_project.Object.Delete Delete
Call failed: The service is temporarily unavailable.
```
Change-Id: I2d28de91bbb0fbc2a991e3d5e5631814d41fe044
Signed-off-by: Harsh Agarwal <Harsh.Agarwal@ibm.com>
diff --git a/extensions/openpower-pels/data_interface.cpp b/extensions/openpower-pels/data_interface.cpp
index 146b92f..1975e95 100644
--- a/extensions/openpower-pels/data_interface.cpp
+++ b/extensions/openpower-pels/data_interface.cpp
@@ -984,6 +984,42 @@
#endif
}
+DBusPathList DataInterface::getAssociatedPaths(
+ const DBusPath& associatedPath, const DBusPath& subtree, int32_t depth,
+ const DBusInterfaceList& interfaces) const
+{
+ DBusPathList paths;
+ try
+ {
+ auto method = _bus.new_method_call(
+ service_name::objectMapper, object_path::objectMapper,
+ interface::objectMapper, "GetAssociatedSubTreePaths");
+ method.append(sdbusplus::message::object_path(associatedPath),
+ sdbusplus::message::object_path(subtree), depth,
+ interfaces);
+
+ auto reply = _bus.call(method, dbusTimeout);
+ reply.read(paths);
+ }
+ catch (const std::exception& e)
+ {
+ std::string ifaces(
+ std::ranges::fold_left_first(
+ interfaces,
+ [](std::string ifaces, const std::string& iface) {
+ return ifaces + ", " + iface;
+ })
+ .value_or(""));
+
+ lg2::error("Failed getting associated paths: {ERROR}. "
+ "AssociatedPath: {ASSOIC_PATH} Subtree: {SUBTREE} "
+ "Interfaces: {IFACES}",
+ "ERROR", e, "ASSOIC_PATH", associatedPath, "SUBTREE",
+ subtree, "IFACES", ifaces);
+ }
+ return paths;
+}
+
void DataInterface::startFruPlugWatch()
{
// Add a watch on inventory InterfacesAdded and then find all
diff --git a/extensions/openpower-pels/data_interface.hpp b/extensions/openpower-pels/data_interface.hpp
index 713f4cd..c6cfe4e 100644
--- a/extensions/openpower-pels/data_interface.hpp
+++ b/extensions/openpower-pels/data_interface.hpp
@@ -537,6 +537,23 @@
*/
void addDIMMLocCode(const std::string& locCode, bool isFRUDIMM);
+ /**
+ * @brief Finds all D-Bus Associated paths that contain any of the
+ * interfaces passed in, by using GetAssociatedSubTreePaths.
+ *
+ * @param[in] associatedPath - The D-Bus object path
+ * @param[in] subtree - The subtree path for which the result should be
+ * fetched
+ * @param[in] depth - The maximum subtree depth for which results should be
+ * fetched
+ * @param[in] interfaces - The desired interfaces
+ *
+ * @return The D-Bus paths.
+ */
+ virtual DBusPathList getAssociatedPaths(
+ const DBusPath& associatedPath, const DBusPath& subtree, int32_t depth,
+ const DBusInterfaceList& interfaces) const = 0;
+
protected:
/**
* @brief Sets the host on/off state and runs any
@@ -907,6 +924,23 @@
std::optional<std::vector<uint8_t>>
getDIProperty(const std::string& locationCode) const override;
+ /**
+ * @brief Finds all D-Bus Associated paths that contain any of the
+ * interfaces passed in, by using GetAssociatedSubTreePaths.
+ *
+ * @param[in] associatedPath - The D-Bus object path
+ * @param[in] subtree - The subtree path for which the result should be
+ * fetched
+ * @param[in] depth - The maximum subtree depth for which results should be
+ * fetched
+ * @param[in] interfaces - The desired interfaces
+ *
+ * @return The D-Bus paths.
+ */
+ DBusPathList getAssociatedPaths(
+ const DBusPath& associatedPath, const DBusPath& subtree, int32_t depth,
+ const DBusInterfaceList& interfaces) const override;
+
private:
/**
* @brief Reads the BMC firmware version string and puts it into
diff --git a/extensions/openpower-pels/entry_points.cpp b/extensions/openpower-pels/entry_points.cpp
index dd00103..aba0457 100644
--- a/extensions/openpower-pels/entry_points.cpp
+++ b/extensions/openpower-pels/entry_points.cpp
@@ -87,5 +87,12 @@
REGISTER_EXTENSION_FUNCTION(pelDeleteProhibited)
+void getLogIDWithHwIsolation(std::vector<uint32_t>& logIDs)
+{
+ manager->getLogIDWithHwIsolation(logIDs);
+}
+
+REGISTER_EXTENSION_FUNCTION(getLogIDWithHwIsolation)
+
} // namespace pels
} // namespace openpower
diff --git a/extensions/openpower-pels/manager.cpp b/extensions/openpower-pels/manager.cpp
index a362e01..03254d2 100644
--- a/extensions/openpower-pels/manager.cpp
+++ b/extensions/openpower-pels/manager.cpp
@@ -301,8 +301,28 @@
_repo.remove(id);
}
-bool Manager::isDeleteProhibited(uint32_t /*obmcLogID*/)
+void Manager::getLogIDWithHwIsolation(std::vector<uint32_t>& idsWithHwIsoEntry)
{
+ idsWithHwIsoEntry = _dataIface->getLogIDWithHwIsolation();
+}
+
+bool Manager::isDeleteProhibited(uint32_t obmcLogID)
+{
+ auto entryPath{std::string(OBJ_ENTRY) + '/' + std::to_string(obmcLogID)};
+ auto entry = _pelEntries.find(entryPath);
+ if (entry != _pelEntries.end())
+ {
+ if (entry->second->guard())
+ {
+ auto hwIsolationAssocPaths = _dataIface->getAssociatedPaths(
+ entryPath += "/isolated_hw_entry", "/", 0,
+ {"xyz.openbmc_project.HardwareIsolation.Entry"});
+ if (!hwIsolationAssocPaths.empty())
+ {
+ return true;
+ }
+ }
+ }
return false;
}
diff --git a/extensions/openpower-pels/manager.hpp b/extensions/openpower-pels/manager.hpp
index 462949d..2429aec 100644
--- a/extensions/openpower-pels/manager.hpp
+++ b/extensions/openpower-pels/manager.hpp
@@ -125,6 +125,14 @@
*/
void erase(uint32_t obmcLogID);
+ /**
+ * @brief Get the list of event log ids that have an associated
+ * hardware isolation entry.
+ *
+ * @param[in] idsWithHwIsoEntry - List to store the list of log ids
+ */
+ void getLogIDWithHwIsolation(std::vector<uint32_t>& idsWithHwIsoEntry);
+
/** @brief Says if an OpenBMC event log may not be manually deleted at this
* time because its corresponding PEL cannot be.
*