Move bmcweb over to sdbusplus
This patchset moves bmcweb from using boost-dbus over entirely to
sdbusplus. This has some nice improvements in performance (about 30%
of CPU cycles saved in dbus transactions), as well as makes this
project manuver closer to the upstream way of thinking.
Changes to bmcweb are largely ceremonial, and fall into a few
categories:
1. Moves async_method_call instances to the new format, and deletes any
use of the "endpoint" object in leiu of the sdbusplus style interface
2. sdbus object_path object doesn't allow access to the string
directly, so code that uses it moves to explicit casts.
3. The mapbox variant, while attempting to recreate boost::variant,
misses a T* get<T*>() method implementation, which allows using variant
without exceptions. Currently, there is an overload for
mapbox::get_ptr implementation which replecates the functionality.
Tested by: Booting the bmcweb on a target, iterating through redfish
basic phosphor-webui usage, and websockets usage
Change-Id: I2d95882908d6eb6dba00b9219a221dd96449ca7b
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index c7f7b95..7db9357 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -24,14 +24,16 @@
* DBus types primitives for several generic DBus interfaces
* TODO(Pawel) consider move this to separate file into boost::dbus
*/
-using ManagedObjectsType = std::vector<
- std::pair<dbus::object_path,
- std::vector<std::pair<
- std::string,
- std::vector<std::pair<std::string, dbus::dbus_variant>>>>>>;
+// Note, this is not a very useful variant, but because it isn't used to get
+// values, it should be as simple as possible
+// TODO(ed) invent a nullvariant type
+using VariantType = sdbusplus::message::variant<std::string>;
+using ManagedObjectsType = std::vector<std::pair<
+ sdbusplus::message::object_path,
+ std::vector<std::pair<std::string,
+ std::vector<std::pair<std::string, VariantType>>>>>>;
-using PropertiesType =
- boost::container::flat_map<std::string, dbus::dbus_variant>;
+using PropertiesType = boost::container::flat_map<std::string, VariantType>;
/**
* OnDemandChassisProvider
@@ -79,7 +81,8 @@
{"serial_number", "SerialNumber"}}}) {
PropertiesType::const_iterator it = properties.find(p.first);
if (it != properties.end()) {
- const std::string *s = boost::get<std::string>(&it->second);
+ const std::string *s =
+ mapbox::get_ptr<const std::string>(it->second);
if (s != nullptr) {
output[p.second] = *s;
}
@@ -88,9 +91,9 @@
// Callback with success, and hopefully data.
callback(true, output);
},
- {"xyz.openbmc_project.EntityManager",
- "/xyz/openbmc_project/Inventory/Item/Chassis/" + res_name,
- "org.freedesktop.DBus.Properties", "GetAll"},
+ "xyz.openbmc_project.EntityManager",
+ "/xyz/openbmc_project/Inventory/Item/Chassis/" + res_name,
+ "org.freedesktop.DBus.Properties", "GetAll",
"xyz.openbmc_project.Configuration.Chassis");
}
@@ -126,7 +129,7 @@
if (interface.first ==
"xyz.openbmc_project.Configuration.Chassis") {
// Cut out everything until last "/", ...
- const std::string &chassis_id = objpath.first.value;
+ const std::string &chassis_id = objpath.first.str;
std::size_t last_pos = chassis_id.rfind("/");
if (last_pos != std::string::npos) {
// and put it into output vector.
@@ -138,9 +141,9 @@
// Finally make a callback with useful data
callback(true, chassis_list);
},
- {"xyz.openbmc_project.EntityManager",
- "/xyz/openbmc_project/Inventory/Item/Chassis",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+ "xyz.openbmc_project.EntityManager",
+ "/xyz/openbmc_project/Inventory/Item/Chassis",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
};
};
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 88ce9f2..ea465fb 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -24,14 +24,19 @@
* DBus types primitives for several generic DBus interfaces
* TODO(Pawel) consider move this to separate file into boost::dbus
*/
-using PropertiesMapType =
- boost::container::flat_map<std::string, dbus::dbus_variant>;
+using PropertiesMapType = boost::container::flat_map<
+ std::string,
+ sdbusplus::message::variant<std::string, bool, uint8_t, int16_t, uint16_t,
+ int32_t, uint32_t, int64_t, uint64_t, double>>;
using GetManagedObjectsType = boost::container::flat_map<
- dbus::object_path,
- boost::container::flat_map<std::string, PropertiesMapType>>;
-
-using GetAllPropertiesType = PropertiesMapType;
+ sdbusplus::message::object_path,
+ boost::container::flat_map<
+ std::string,
+ boost::container::flat_map<
+ std::string, sdbusplus::message::variant<
+ std::string, bool, uint8_t, int16_t, uint16_t,
+ int32_t, uint32_t, int64_t, uint64_t, double>>>>;
/**
* Structure for keeping IPv4 data required by Redfish
@@ -76,8 +81,8 @@
// Helper function that allows to extract GetAllPropertiesType from
// GetManagedObjectsType, based on object path, and interface name
const PropertiesMapType *extractInterfaceProperties(
- const dbus::object_path &objpath, const std::string &interface,
- const GetManagedObjectsType &dbus_data) {
+ const sdbusplus::message::object_path &objpath,
+ const std::string &interface, const GetManagedObjectsType &dbus_data) {
const auto &dbus_obj = dbus_data.find(objpath);
if (dbus_obj != dbus_data.end()) {
const auto &iface = dbus_obj->second.find(interface);
@@ -89,22 +94,22 @@
}
// Helper Wrapper that does inline object_path conversion from string
- // into dbus::object_path type
+ // into sdbusplus::message::object_path type
inline const PropertiesMapType *extractInterfaceProperties(
const std::string &objpath, const std::string &interface,
const GetManagedObjectsType &dbus_data) {
- const auto &dbus_obj = dbus::object_path{objpath};
+ const auto &dbus_obj = sdbusplus::message::object_path{objpath};
return extractInterfaceProperties(dbus_obj, interface, dbus_data);
}
// Helper function that allows to get pointer to the property from
// GetAllPropertiesType native, or extracted by GetAllPropertiesType
template <typename T>
- inline const T *extractProperty(const PropertiesMapType &properties,
- const std::string &name) {
+ inline T const *const extractProperty(const PropertiesMapType &properties,
+ const std::string &name) {
const auto &property = properties.find(name);
if (property != properties.end()) {
- return boost::get<T>(&property->second);
+ return mapbox::get_ptr<const T>(property->second);
}
return nullptr;
}
@@ -177,7 +182,7 @@
for (auto &objpath : dbus_data) {
// Check if proper patter for object path appears
if (boost::starts_with(
- objpath.first.value,
+ static_cast<std::string>(objpath.first),
"/xyz/openbmc_project/network/" + ethiface_id + "/ipv4/")) {
// and get approrpiate interface
const auto &interface =
@@ -244,7 +249,7 @@
this, ethiface_id{std::move(ethiface_id)},
callback{std::move(callback)}
](const boost::system::error_code error_code,
- const GetManagedObjectsType &resp) {
+ GetManagedObjectsType &resp) {
EthernetInterfaceData eth_data{};
std::vector<IPv4AddressData> ipv4_data;
@@ -273,8 +278,8 @@
// Finally make a callback with useful data
callback(true, eth_data, ipv4_data);
},
- {"xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+ "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
};
/**
@@ -288,7 +293,7 @@
crow::connections::system_bus->async_method_call(
[ this, callback{std::move(callback)} ](
const boost::system::error_code error_code,
- const GetManagedObjectsType &resp) {
+ GetManagedObjectsType &resp) {
// Callback requires vector<string> to retrieve all available ethernet
// interfaces
std::vector<std::string> iface_list;
@@ -310,8 +315,9 @@
// this is what we're looking for.
if (interface.first ==
"xyz.openbmc_project.Network.EthernetInterface") {
- // Cut out everything until last "/", ...
- const std::string &iface_id = objpath.first.value;
+ // Cut out everyting until last "/", ...
+ const std::string iface_id =
+ static_cast<std::string>(objpath.first);
std::size_t last_pos = iface_id.rfind("/");
if (last_pos != std::string::npos) {
// and put it into output vector.
@@ -323,8 +329,8 @@
// Finally make a callback with useful data
callback(true, iface_list);
},
- {"xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"});
+ "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
};
};
diff --git a/redfish-core/lib/network_protocol.hpp b/redfish-core/lib/network_protocol.hpp
index 1410122..581eb03 100644
--- a/redfish-core/lib/network_protocol.hpp
+++ b/redfish-core/lib/network_protocol.hpp
@@ -95,10 +95,10 @@
}
}
- std::map<int, std::string> portToProtocolMap{
+ boost::container::flat_map<int, std::string> portToProtocolMap{
{22, "SSH"}, {80, "HTTP"}, {443, "HTTPS"}, {623, "IPMI"}, {1900, "SSDP"}};
- std::set<int> listeningPorts;
+ boost::container::flat_set<int> listeningPorts;
};
} // namespace redfish
diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp
index f427909..b0cbbe1 100644
--- a/redfish-core/lib/sensors.hpp
+++ b/redfish-core/lib/sensors.hpp
@@ -21,8 +21,6 @@
#include <boost/algorithm/string/split.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/range/algorithm/replace_copy_if.hpp>
-#include <boost/variant.hpp>
-#include <boost/variant/get.hpp>
namespace redfish {
@@ -32,11 +30,12 @@
std::pair<std::string,
std::vector<std::pair<std::string, std::vector<std::string>>>>>;
+using SensorVariant = sdbusplus::message::variant<int64_t, double>;
+
using ManagedObjectsVectorType = std::vector<std::pair<
- dbus::object_path,
+ sdbusplus::message::object_path,
boost::container::flat_map<
- std::string,
- boost::container::flat_map<dbus::string, dbus::dbus_variant>>>>;
+ std::string, boost::container::flat_map<std::string, SensorVariant>>>>;
/**
* AsyncResp
@@ -83,9 +82,6 @@
const std::string path = "/xyz/openbmc_project/Sensors";
const std::array<std::string, 1> interfaces = {
"xyz.openbmc_project.Sensor.Value"};
- const dbus::endpoint object_mapper(
- "xyz.openbmc_project.ObjectMapper", "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTree");
// Response handler for parsing objects subtree
auto resp_handler = [ callback{std::move(callback)}, asyncResp, sensorNames ](
@@ -136,8 +132,10 @@
};
// Make call to ObjectMapper to find all sensors objects
- crow::connections::system_bus->async_method_call(resp_handler, object_mapper,
- path, 2, interfaces);
+ crow::connections::system_bus->async_method_call(
+ resp_handler, "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper", "xyz.openbmc_project.ObjectMapper",
+ "GetSubTree", path, 2, interfaces);
}
/**
@@ -149,10 +147,6 @@
void getChassis(const std::shared_ptr<AsyncResp>& asyncResp,
Callback&& callback) {
CROW_LOG_DEBUG << "getChassis Done";
- const dbus::endpoint entityManager = {
- "xyz.openbmc_project.EntityManager",
- "/xyz/openbmc_project/Inventory/Item/Chassis",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"};
// Process response from EntityManager and extract chassis data
auto resp_handler = [ callback{std::move(callback)}, asyncResp ](
@@ -170,10 +164,11 @@
CROW_LOG_DEBUG << "Chassis Prefix " << chassis_prefix;
bool foundChassis = false;
for (const auto& objDictEntry : resp) {
- if (boost::starts_with(objDictEntry.first.value, chassis_prefix)) {
+ if (boost::starts_with(static_cast<std::string>(objDictEntry.first),
+ chassis_prefix)) {
foundChassis = true;
const std::string sensorName =
- objDictEntry.first.value.substr(chassis_prefix.size());
+ std::string(objDictEntry.first).substr(chassis_prefix.size());
// Make sure this isn't a subobject (like a threshold)
const std::size_t sensorPos = sensorName.find('/');
if (sensorPos == std::string::npos) {
@@ -194,7 +189,10 @@
};
// Make call to EntityManager to find all chassis objects
- crow::connections::system_bus->async_method_call(resp_handler, entityManager);
+ crow::connections::system_bus->async_method_call(
+ resp_handler, "xyz.openbmc_project.EntityManager",
+ "/xyz/openbmc_project/Inventory/Item/Chassis",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
}
/**
@@ -209,8 +207,7 @@
void objectInterfacesToJson(
const std::string& sensorName, const std::string& sensorType,
const boost::container::flat_map<
- std::string,
- boost::container::flat_map<dbus::string, dbus::dbus_variant>>&
+ std::string, boost::container::flat_map<std::string, SensorVariant>>&
interfacesDict,
nlohmann::json& sensor_json) {
// We need a value interface before we can do anything with it
@@ -226,7 +223,8 @@
auto scale_it = value_it->second.find("Scale");
// If a scale exists, pull value as int64, and use the scaling.
if (scale_it != value_it->second.end()) {
- const int64_t* int64Value = boost::get<int64_t>(&scale_it->second);
+ const int64_t* int64Value =
+ mapbox::get_ptr<const int64_t>(scale_it->second);
if (int64Value != nullptr) {
scaleMultiplier = *int64Value;
}
@@ -289,10 +287,12 @@
if (interfaceProperties != interfacesDict.end()) {
auto value_it = interfaceProperties->second.find(std::get<1>(p));
if (value_it != interfaceProperties->second.end()) {
- const dbus::dbus_variant& valueVariant = value_it->second;
+ const SensorVariant& valueVariant = value_it->second;
nlohmann::json& value_it = sensor_json[std::get<2>(p)];
+
// Attempt to pull the int64 directly
- const int64_t* int64Value = boost::get<int64_t>(&valueVariant);
+ const int64_t* int64Value =
+ mapbox::get_ptr<const int64_t>(valueVariant);
if (int64Value != nullptr) {
if (forceToInt || scaleMultiplier >= 0) {
@@ -303,7 +303,7 @@
}
}
// Attempt to pull the float directly
- const double* doubleValue = boost::get<double>(&valueVariant);
+ const double* doubleValue = mapbox::get_ptr<const double>(valueVariant);
if (doubleValue != nullptr) {
if (!forceToInt) {
@@ -342,7 +342,8 @@
// Go through all objects and update response with
// sensor data
for (const auto& objDictEntry : resp) {
- const std::string& objPath = objDictEntry.first.value;
+ const std::string& objPath =
+ static_cast<std::string>(objDictEntry.first);
CROW_LOG_DEBUG << "getManagedObjectsCb parsing object "
<< objPath;
if (!boost::starts_with(objPath, DBUS_SENSOR_PREFIX)) {
@@ -406,11 +407,9 @@
}
};
- dbus::endpoint ep(connection, "/xyz/openbmc_project/Sensors",
- "org.freedesktop.DBus.ObjectManager",
- "GetManagedObjects");
crow::connections::system_bus->async_method_call(
- getManagedObjectsCb, ep);
+ getManagedObjectsCb, connection, "/xyz/openbmc_project/Sensors",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
};
};
// Get connections and then pass it to get sensors