Skip to content

Commit

Permalink
PIM: changes for critical associtation removal
Browse files Browse the repository at this point in the history
When a faulty CEC FRU is repaired or replaced during runtime,
its corresponding chassis critical associations were left unremoved.
This leads in displaying Chassis Health Rollup as "Critical" in GUI even
after the fault FRU is repaired/replaced.

This commit has changes that removes the critical association on chassis,
when the FRU's "Functional" property (present under the d-bus interface
"xyz.openbmc_project.State.Decorator.OperationalStatus") is changed from
false to true, which indicates that the FRU is repaired and is functional.

This is needed to handle hotpluggable or concurrently maintainable FRUs
which are associated with the chassis.
  • Loading branch information
GiridhariKrishnan committed Dec 13, 2023
1 parent a81ea0f commit bb277bc
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 2 deletions.
14 changes: 12 additions & 2 deletions functor.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "remove_association.hpp"
#include "types.hpp"
#include "utils.hpp"

Expand Down Expand Up @@ -208,7 +209,7 @@ struct PropertyChangedCondition
* Extract the property from the PropertiesChanged
* message and run the condition test.
*/
bool operator()(sdbusplus::bus_t&, sdbusplus::message_t& msg,
bool operator()(sdbusplus::bus_t& bus, sdbusplus::message_t& msg,
Manager&) const
{
std::map<std::string, std::variant<T>> properties;
Expand All @@ -226,7 +227,16 @@ struct PropertyChangedCondition
{
return false;
}

if (!strcmp(_property, "Functional"))
{
const bool* value = std::get_if<bool>(&it->second);
if (*value)
{
std::string invObjectPath = msg.get_path();
const std::string service = getService(invObjectPath, iface);
removeCriticalAssociation(bus, invObjectPath, service);
}
}
return _condition(std::forward<T>(std::get<T>(it->second)));
}

Expand Down
51 changes: 51 additions & 0 deletions manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "manager.hpp"

#include "errors.hpp"
#include "remove_association.hpp"

#include <algorithm>
#include <chrono>
Expand All @@ -41,6 +42,23 @@ auto _signal(sd_bus_message* m, void* data, sd_bus_error* /* e */) noexcept
try
{
auto msg = sdbusplus::message_t(m);
std::string interfaceName{};
std::map<std::string, std::variant<bool>> properties;
msg.read(interfaceName, properties);
const auto it = properties.find("Functional");
std::string invObjectPath = msg.get_path();
if (it != properties.end())
{
static auto bus = sdbusplus::bus::new_default();
bus = msg.get_bus();
const std::string service =
getService(invObjectPath, interfaceName);
const bool* value = std::get_if<bool>(&it->second);
if (*value)
{
removeCriticalAssociation(bus, invObjectPath, service);
}
}
auto& args = *static_cast<Manager::SigArg*>(data);
sd_bus_message_ref(m);
auto& mgr = *std::get<0>(args);
Expand Down Expand Up @@ -82,6 +100,8 @@ Manager::Manager(sdbusplus::bus_t&& bus, const char* root) :
_sigargs.emplace_back(
std::make_unique<SigArg>(this, dbusEvent, &group));

// check if functional

// Register our callback and the context for
// each signal event.
_matches.emplace_back(_bus, dbusEvent->signature, _signal,
Expand Down Expand Up @@ -266,6 +286,22 @@ void Manager::updateObjects(
});
}
#endif
for (auto interface = (objit->second).begin();
interface != (objit->second).end(); interface++)
{
const auto it = interface->second.find("Functional");
if (it != (interface->second).end())
{
const std::string service =
getService(absPath, interface->first);
const bool* value = std::get_if<bool>(&it->second);
if (*value)
{
removeCriticalAssociation(_bus, absPath, service);
}
}
}

++objit;
}
}
Expand All @@ -287,6 +323,21 @@ void Manager::handleEvent(sdbusplus::message_t& msg, const Event& event,
return;
}
}
std::string interfaceName{};
std::map<std::string, std::variant<bool>> properties;
msg.read(interfaceName, properties);
const auto it = properties.find("Functional");
std::string invObjectPath = msg.get_path();
if (it != properties.end())
{
const std::string service = getService(invObjectPath, interfaceName);
const bool* value = std::get_if<bool>(&it->second);
if (*value)
{
removeCriticalAssociation(_bus, invObjectPath, service);
}
}

for (auto& action : actions)
{
action(_bus, *this);
Expand Down
3 changes: 3 additions & 0 deletions manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ class Manager final : public ServerObject<ManagerIface>
/** @brief Provided for testing only. */
void shutdown() noexcept;

/** @brief Get Service name */
// const std::string getService(const std::string& path, const std::string& interface);

/** @brief sd_bus Notify method implementation callback. */
void
notify(std::map<sdbusplus::message::object_path, Object> objs) override;
Expand Down
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ sources += [
gen_serialization_hpp,
'app.cpp',
'errors.cpp',
'remove_association.cpp',
'functor.cpp',
'manager.cpp',
]
Expand Down
24 changes: 24 additions & 0 deletions remove_association.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,30 @@ void getProperty(sdbusplus::bus::bus& bus, const std::string& service,
reply.read(value);
}

/** @brief get Dbus service
*
*/
const std::string getService(const std::string& path,
const std::string& interface)
{
constexpr auto mapper_busname = "xyz.openbmc_project.objectmapper";
constexpr auto mapper_obj_path = "/xyz/openbmc_project/object_mapper";
constexpr auto mapper_iface = "xyz.openbmc_project.objectmapper";
using interfacelist = std::vector<std::string>;
std::map<std::string, std::vector<std::string>> mapperresponse;

static auto bus = sdbusplus::bus::new_default();
auto mapper = bus.new_method_call(mapper_busname, mapper_obj_path,
mapper_iface, "getobject");
mapper.append(path, interfacelist({interface}));

auto mapperresponsemsg = bus.call(mapper);
mapperresponsemsg.read(mapperresponse);

// the value here will be the service name
return mapperresponse.cbegin()->first;
}

void removeCriticalAssociation(sdbusplus::bus::bus& bus,
const std::string& objectPath,
const std::string& service)
Expand Down
9 changes: 9 additions & 0 deletions remove_association.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,15 @@ void removeCriticalAssociation(sdbusplus::bus::bus& bus,
const std::string& objectPath,
const std::string& service);

/** @brief get Dbus service
*
* @param[in] path - The D-Bus object path
* @param[in] interface - The DBus interface.
*/
const std::string getService(const std::string& path,
const std::string& interface);


} // namespace manager
} // namespace inventory
} // namespace phosphor

0 comments on commit bb277bc

Please sign in to comment.