From 744398dc49661363f32af3a34b71ca4b865c20e9 Mon Sep 17 00:00:00 2001 From: Nagaraju Goruganti Date: Tue, 20 Feb 2018 09:52:00 -0600 Subject: Remove use of legacy inventory interface Made below given changes: 1.With legacy code we used to read software version info from the system file: /etc/os-release, now with new updates we will read it from the s/w object which is implementing the interface "xyz.openbmc_project.Software.RedundancyPriority" interface. 2.Removed legacy code related to inventory(FRU) for sensors Tested: 1.Verified f/w version info using below given command >ipmitool mc info -I dbus 2.Verified get sensor type info using below given command >ipmitool raw 0x04 0x2f 0x02 -I dbus Resolves openbmc/openbmc#2870 Change-Id: I384bf4aaacd56f4a871833b533b2a8a68c489959 Signed-off-by: Nagaraju Goruganti --- apphandler.cpp | 146 +++++++++++++++++++++++++++++++++++++++++------------- sensorhandler.cpp | 70 -------------------------- 2 files changed, 111 insertions(+), 105 deletions(-) diff --git a/apphandler.cpp b/apphandler.cpp index e370f0c..6564181 100644 --- a/apphandler.cpp +++ b/apphandler.cpp @@ -24,6 +24,8 @@ #include #include #include "xyz/openbmc_project/Common/error.hpp" +#include "xyz/openbmc_project/Software/Version/server.hpp" +#include "xyz/openbmc_project/Software/Activation/server.hpp" extern sd_bus *bus; @@ -32,10 +34,21 @@ constexpr auto bmc_guid_interface = "xyz.openbmc_project.Common.UUID"; constexpr auto bmc_guid_property = "UUID"; constexpr auto bmc_guid_len = 16; +static constexpr auto redundancyIntf = + "xyz.openbmc_project.Software.RedundancyPriority"; +static constexpr auto versionIntf = + "xyz.openbmc_project.Software.Version"; +static constexpr auto activationIntf = + "xyz.openbmc_project.Software.Activation"; +static constexpr auto softwareRoot = "/xyz/openbmc_project/software"; + void register_netfn_app_functions() __attribute__((constructor)); using namespace phosphor::logging; using namespace sdbusplus::xyz::openbmc_project::Common::Error; +using Version = sdbusplus::xyz::openbmc_project::Software::server::Version; +using Activation = + sdbusplus::xyz::openbmc_project::Software::server::Activation; namespace fs = std::experimental::filesystem; // Offset in get device id command. @@ -51,6 +64,82 @@ typedef struct uint8_t aux[4]; }__attribute__((packed)) ipmi_device_id_t; +/** + * @brief Returns the Version info from primary s/w object + * + * Get the Version info from the active s/w object which is having high + * "Priority" value(a smaller number is a higher priority) and "Purpose" + * is "BMC" from the list of all s/w objects those are implementing + * RedundancyPriority interface from the given softwareRoot path. + * + * @return On success returns the Version info from primary s/w object. + * + */ +std::string getActiveSoftwareVersionInfo() +{ + sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; + + std::string revision{}; + auto objectTree = ipmi::getAllDbusObjects(bus, softwareRoot, redundancyIntf, + ""); + if (objectTree.empty()) + { + log("No Obj has implemented the s/w redundancy interface", + entry("INTERFACE=%s", redundancyIntf)); + elog(); + } + + auto objectFound = false; + for (auto& softObject : objectTree) + { + auto service = ipmi::getService(bus, redundancyIntf, softObject.first); + auto objValueTree = ipmi::getManagedObjects(bus, service, softwareRoot); + + auto minPriority = 0xFF; + for (const auto& objIter : objValueTree) + { + try + { + auto& intfMap = objIter.second; + auto& redundancyPriorityProps = intfMap.at(redundancyIntf); + auto& versionProps = intfMap.at(versionIntf); + auto& activationProps = intfMap.at(activationIntf); + auto priority = + redundancyPriorityProps.at("Priority").get(); + auto purpose = versionProps.at("Purpose").get(); + auto activation = + activationProps.at("Activation").get(); + auto version = versionProps.at("Version").get(); + if ((Version::convertVersionPurposeFromString(purpose) == + Version::VersionPurpose::BMC) && + (Activation::convertActivationsFromString(activation) == + Activation::Activations::Active)) + { + if (priority < minPriority) + { + minPriority = priority; + objectFound = true; + revision = std::move(version); + } + } + } + catch (const std::exception& e) + { + log(e.what()); + } + } + } + + if (!objectFound) + { + log("Could not found an BMC software Object"); + elog(); + } + + return revision; +} + + ipmi_ret_t ipmi_app_set_acpi_power_state(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request, ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context) @@ -162,12 +251,7 @@ ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_data_len_t data_len, ipmi_context_t context) { ipmi_ret_t rc = IPMI_CC_OK; - const char *objname = - "/org/openbmc/inventory/system/chassis/motherboard/bmc"; - const char *iface = "org.openbmc.InventoryItem"; - char *ver = NULL; - char *busname = NULL; - int r; + int r = -1; rev_t rev = {0}; static ipmi_device_id_t dev_id{}; static bool dev_id_initialized = false; @@ -178,33 +262,27 @@ ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd, if (!dev_id_initialized) { - // Firmware revision is already implemented, - // so get it from appropriate position. - r = mapper_get_service(bus, objname, &busname); - if (r < 0) { - fprintf(stderr, "Failed to get %s bus name: %s\n", - objname, strerror(-r)); - goto finish; + try + { + auto version = getActiveSoftwareVersionInfo(); + r = convert_version(version.c_str(), &rev); } - r = sd_bus_get_property_string(bus,busname,objname,iface,"version", - NULL, &ver); - if ( r < 0 ) { - fprintf(stderr, "Failed to obtain version property: %s\n", - strerror(-r)); - } else { - r = convert_version(ver, &rev); - if( r >= 0 ) { - // bit7 identifies if the device is available - // 0=normal operation - // 1=device firmware, SDR update, - // or self-initialization in progress. - // our SDR is normal working condition, so mask: - dev_id.fw[0] = 0x7F & rev.major; - - rev.minor = (rev.minor > 99 ? 99 : rev.minor); - dev_id.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16; - memcpy(&dev_id.aux, rev.d, 4); - } + catch (const std::exception& e) + { + log(e.what()); + } + + if( r >= 0 ) { + // bit7 identifies if the device is available + // 0=normal operation + // 1=device firmware, SDR update, + // or self-initialization in progress. + // our SDR is normal working condition, so mask: + dev_id.fw[0] = 0x7F & rev.major; + + rev.minor = (rev.minor > 99 ? 99 : rev.minor); + dev_id.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16; + memcpy(&dev_id.aux, rev.d, 4); } // IPMI Spec version 2.0 @@ -247,9 +325,7 @@ ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd, // Pack the actual response memcpy(response, &dev_id, *data_len); -finish: - free(busname); - free(ver); + return rc; } diff --git a/sensorhandler.cpp b/sensorhandler.cpp index 7d9d394..f6ccc13 100644 --- a/sensorhandler.cpp +++ b/sensorhandler.cpp @@ -71,57 +71,6 @@ struct sensorreadingresp_t { uint8_t indication[2]; } __attribute__ ((packed)) ; -// Use a lookup table to find the interface name of a specific sensor -// This will be used until an alternative is found. this is the first -// step for mapping IPMI -int find_interface_property_fru_type(dbus_interface_t *interface, const char *property_name, char *property_value) { - - char *str1; - sd_bus_error error = SD_BUS_ERROR_NULL; - sd_bus_message *reply = NULL, *m=NULL; - - - int r; - - r = sd_bus_message_new_method_call(bus,&m,interface->bus,interface->path,"org.freedesktop.DBus.Properties","Get"); - if (r < 0) { - fprintf(stderr, "Failed to create a method call: %s", strerror(-r)); - fprintf(stderr,"Bus: %s Path: %s Interface: %s \n", - interface->bus, interface->path, interface->interface); - goto final; - } - - r = sd_bus_message_append(m, "ss", "org.openbmc.InventoryItem", property_name); - if (r < 0) { - fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r)); - fprintf(stderr,"Bus: %s Path: %s Interface: %s \n", - interface->bus, interface->path, interface->interface); - goto final; - } - - r = sd_bus_call(bus, m, 0, &error, &reply); - if (r < 0) { - fprintf(stderr, "Failed to call the method: %s", strerror(-r)); - goto final; - } - - r = sd_bus_message_read(reply, "v", "s", &str1) ; - if (r < 0) { - fprintf(stderr, "Failed to get a response: %s", strerror(-r)); - goto final; - } - - strcpy(property_value, str1); - -final: - - sd_bus_error_free(&error); - m = sd_bus_message_unref(m); - reply = sd_bus_message_unref(reply); - - return r; -} - int get_bus_for_path(const char *path, char **busname) { return mapper_get_service(bus, path, busname); } @@ -332,19 +281,6 @@ uint8_t dbus_to_sensor_type(char *p) { } -uint8_t dbus_to_sensor_type_from_dbus(dbus_interface_t *a) { - char fru_type_name[64]; - int r= 0; - - r = find_interface_property_fru_type(a, "fru_type", fru_type_name); - if (r<0) { - fprintf(stderr, "Failed to get a fru type: %s", strerror(-r)); - return -1; - } else { - return dbus_to_sensor_type(fru_type_name); - } -} - uint8_t get_type_from_interface(dbus_interface_t dbus_if) { char *p; @@ -359,12 +295,6 @@ uint8_t get_type_from_interface(dbus_interface_t dbus_if) { if (dbus_if.sensortype != 0) { type = dbus_if.sensortype; - } - // Legacy codebase does not populate type during initial handling: - else if (strstr(dbus_if.interface, "InventoryItem")) { - // InventoryItems are real frus. So need to get the - // fru_type property - type = dbus_to_sensor_type_from_dbus(&dbus_if); } else { // Non InventoryItems p = strrchr (dbus_if.path, '/'); -- cgit v1.2.1