summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishwanatha Subbanna <vishwa@linux.vnet.ibm.com>2017-08-22 16:06:11 +0530
committerVishwanatha Subbanna <vishwa@linux.vnet.ibm.com>2017-08-23 18:56:41 +0530
commit3ace7576176afed9196fb308c766de6b1252d3ea (patch)
tree67682cab04671d496086c9043e1c69e98ba4c3b8
parent1ec291fbaddf4f2b44cdfff3891d8782f28fb2c9 (diff)
downloadopenpower-occ-control-3ace7576176afed9196fb308c766de6b1252d3ea.zip
openpower-occ-control-3ace7576176afed9196fb308c766de6b1252d3ea.tar.gz
Only consider CPUs that are Present and Functional
OCC control application looks at CPU inventory and creates D-Bus objects. In some of the cases, hostboot marks the CPU as Not Present but also marks Functional and this results in creating an OCC object for the CPU which is not present. Need to filter CPUs based on Present and Functional properties to address the issue and this commit adds that support. Fixes openbmc/openbmc#2024 Change-Id: I58a06bfd09131bc3deba8f132547095c53bde5e1 Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
-rw-r--r--configure.ac4
-rw-r--r--occ_finder.cpp86
-rw-r--r--occ_finder.hpp42
3 files changed, 123 insertions, 9 deletions
diff --git a/configure.ac b/configure.ac
index 24191c8..254cc77 100644
--- a/configure.ac
+++ b/configure.ac
@@ -65,10 +65,6 @@ AC_ARG_VAR(OCC_CONTROL_ROOT, [The Dbus root])
AS_IF([test "x$OCC_CONTROL_ROOT" == "x"], [OCC_CONTROL_ROOT="/org/open_power/control"])
AC_DEFINE_UNQUOTED([OCC_CONTROL_ROOT], ["$OCC_CONTROL_ROOT"], [The Dbus root])
-AC_ARG_VAR(INVENTORY_ITEM_INTERFACE, [The Inventory.Item interface])
-AS_IF([test "x$INVENTORY_ITEM_INTERFACE" == "x"], [INVENTORY_ITEM_INTERFACE="xyz.openbmc_project.Inventory.Item"])
-AC_DEFINE_UNQUOTED([INVENTORY_ITEM_INTERFACE], ["$INVENTORY_ITEM_INTERFACE"], [The Inventory.Item root])
-
AC_ARG_VAR(CPU_PATH, [CPU inventory path])
AS_IF([test "x$CPU_PATH" == "x"], [CPU_PATH="/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu"])
AC_DEFINE_UNQUOTED([CPU_PATH], ["$CPU_PATH"], [CPU inventory path])
diff --git a/occ_finder.cpp b/occ_finder.cpp
index b47cc8f..b931452 100644
--- a/occ_finder.cpp
+++ b/occ_finder.cpp
@@ -7,7 +7,6 @@
#include <xyz/openbmc_project/Common/error.hpp>
#include "occ_finder.hpp"
#include "config.h"
-
namespace open_power
{
namespace occ
@@ -23,6 +22,40 @@ constexpr auto toChar(size_t c)
return map[c];
}
+template <typename T>
+T getDbusProperty(sdbusplus::bus::bus& bus,
+ const std::string& service,
+ const std::string& objPath,
+ const std::string& interface,
+ const std::string& property)
+{
+ using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
+ constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties";
+
+ auto method = bus.new_method_call(
+ service.c_str(),
+ objPath.c_str(),
+ PROPERTY_INTF,
+ "Get");
+ method.append(interface, property);
+
+ auto reply = bus.call(method);
+ if (reply.is_method_error())
+ {
+ log<level::ERR>("Failed to get property",
+ entry("PROPERTY=%s", property.c_str()),
+ entry("PATH=%s", objPath.c_str()),
+ entry("INTERFACE=%s", interface.c_str()));
+ elog<InternalFailure>();
+ }
+
+ sdbusplus::message::variant<T> value;
+ reply.read(value);
+
+ return sdbusplus::message::variant_ns::get<T>(value);
+}
+
std::vector<std::string> get(sdbusplus::bus::bus& bus)
{
namespace fs = std::experimental::filesystem;
@@ -40,7 +73,12 @@ std::vector<std::string> get(sdbusplus::bus::bus& bus)
auto depth = 0;
Path path = CPU_SUBPATH;
- Interfaces interfaces{INVENTORY_ITEM_INTERFACE};
+ Interfaces interfaces
+ {
+ "xyz.openbmc_project.Inventory.Item",
+ "xyz.openbmc_project.State.Decorator.OperationalStatus"
+ };
+
mapper.append(path);
mapper.append(depth);
mapper.append(interfaces);
@@ -66,16 +104,54 @@ std::vector<std::string> get(sdbusplus::bus::bus& bus)
{
fs::path p(path);
p /= std::string(CPU_NAME) + toChar(count);
- if (response.end() != response.find(p.string()))
+
+ auto entry = response.find(p.string());
+ if (response.end() != entry)
{
- occs.emplace_back(std::string(OCC_NAME) +
- toChar(count));
+ Criteria match{};
+ match.emplace_back(std::make_tuple(
+ "xyz.openbmc_project.Inventory.Item",
+ "Present",
+ true));
+
+ match.emplace_back(std::make_tuple(
+ "xyz.openbmc_project.State.Decorator.OperationalStatus",
+ "Functional",
+ true));
+
+ // Select only if the CPU is marked 'Present' and 'Functional'
+ // Local variable to make it readable
+ auto path = entry->first;
+ auto service = entry->second.begin()->first;
+ if (matchCriteria(bus, path, service, match))
+ {
+ occs.emplace_back(std::string(OCC_NAME) +
+ toChar(count));
+ }
}
}
return occs;
}
+bool matchCriteria(sdbusplus::bus::bus& bus,
+ const std::string& path,
+ const std::string& service,
+ const Criteria& match)
+{
+ for (const auto& iter: match)
+ {
+ auto result = getDbusProperty<bool>(bus, service, path,
+ std::get<0>(iter),
+ std::get<1>(iter));
+ if (result != std::get<2>(iter))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
} // namespace finder
} // namespace occ
} // namespace open_power
diff --git a/occ_finder.hpp b/occ_finder.hpp
index c096c4b..557d468 100644
--- a/occ_finder.hpp
+++ b/occ_finder.hpp
@@ -11,6 +11,15 @@ namespace occ
namespace finder
{
+// Map of property and interface
+// This is used to filter the OCCs based on the property value
+using Interface = std::string;
+using Property = std::string;
+
+using Value = bool;
+using Match = std::tuple<Interface, Property, Value>;
+using Criteria = std::vector<Match>;
+
/** @brief Get OCC objects on the system by mapping them to CPU inventory
* @returns vector of occ objects, such as occ0, occ1, and so on.
*
@@ -18,6 +27,39 @@ namespace finder
*/
std::vector<std::string> get(sdbusplus::bus::bus& bus);
+/** @brief Returns true if the inventory item matches the criteria
+ *
+ * @param[in] bus - sdbusplus handler
+ * @param[in] path - D-Bus path
+ * @param[in] service - D-Bus service name
+ * @param[in] match - Criteria match vector
+ *
+ * @return true on match, false otherwise
+ */
+bool matchCriteria(sdbusplus::bus::bus& bus,
+ const std::string& path,
+ const std::string& service,
+ const Criteria& match);
+
+/** @brief Gets the value associated with the given object
+ * and the interface.
+ *
+ * @param[in] bus - sdbusplus handler
+ * @param[in] service - D-Bus service name.
+ * @param[in] objPath - D-Bus object path.
+ * @param[in] interface - D-Bus interface.
+ * @param[in] property - Name of the property.
+ *
+ * @return Value of the property
+ */
+
+template <typename T>
+T getDbusProperty(sdbusplus::bus::bus& bus,
+ const std::string& service,
+ const std::string& objPath,
+ const std::string& interface,
+ const std::string& property);
+
} // namespace finder
} // namespace occ
} // namespace open_power
OpenPOWER on IntegriCloud