health: Add option to disable health-populate
The Health populate calls GetManagedObjects at `/` which can take a lot
of time. Add the option to disable to improve performance if it is not
needed.
Tested:
```
$ meson build -Dhealth-populate=disabled
...
User defined options
backend : ninja
health-populate : disabled
```
Build passed.
Health Status removed. Some resource still create HealthPopulate, but
does not populate. It will require further refactoring to clean it out.
Testing on `/redfish/v1/Chassis?$expand=.($levels=1)`
On 14 chassis, from about 2.5 seconds to 400 ms. :)
Before:
```
Getting times for chassis
Getting good line count with wget -q -O- localhost:80/redfish/v1/Chassis?$expand=.($levels=1)
Line count: 980
17:05:56: real 0m2.908s user 0m0.000s sys 0m0.030s
17:05:59: real 0m2.414s user 0m0.010s sys 0m0.010s
17:05:03: real 0m3.410s user 0m0.000s sys 0m0.020s
17:05:09: real 0m2.372s user 0m0.000s sys 0m0.010s
17:05:13: real 0m3.407s user 0m0.010s sys 0m0.000s
17:05:19: real 0m2.420s user 0m0.010s sys 0m0.000s
17:05:23: real 0m3.463s user 0m0.010s sys 0m0.000s
17:05:29: real 0m2.414s user 0m0.000s sys 0m0.010s
17:05:33: real 0m2.843s user 0m0.010s sys 0m0.010s
17:05:38: real 0m2.512s user 0m0.000s sys 0m0.020s
17:05:42: real 0m2.474s user 0m0.000s sys 0m0.010s
17:05:47: real 0m2.557s user 0m0.010s sys 0m0.010s
17:05:52: real 0m2.439s user 0m0.020s sys 0m0.000s
17:05:56: real 0m3.127s user 0m0.010s sys 0m0.000s
17:05:01: real 0m2.563s user 0m0.020s sys 0m0.000s
17:05:06: real 0m2.392s user 0m0.020s sys 0m0.020s
17:05:10: real 0m2.405s user 0m0.020s sys 0m0.000s
17:05:15: real 0m2.514s user 0m0.010s sys 0m0.010s
17:05:19: real 0m2.809s user 0m0.020s sys 0m0.010s
17:05:24: real 0m2.944s user 0m0.010s sys 0m0.010s
17:05:29: real 0m2.537s user 0m0.010s sys 0m0.000s
17:05:34: real 0m3.290s user 0m0.000s sys 0m0.000s
17:05:39: real 0m2.601s user 0m0.040s sys 0m0.000s
17:05:43: real 0m2.398s user 0m0.010s sys 0m0.040s
17:05:48: real 0m2.664s user 0m0.000s sys 0m0.020s
17:05:53: real 0m2.323s user 0m0.010s sys 0m0.000s
17:05:57: real 0m3.033s user 0m0.000s sys 0m0.010s
17:05:02: real 0m3.243s user 0m0.000s sys 0m0.010s
17:05:07: real 0m2.604s user 0m0.010s sys 0m0.010s
17:05:12: real 0m2.813s user 0m0.010s sys 0m0.010s
17:05:17: real 0m2.325s user 0m0.020s sys 0m0.000s
17:05:21: real 0m2.577s user 0m0.010s sys 0m0.000s
17:05:26: real 0m2.882s user 0m0.030s sys 0m0.000s
17:05:31: real 0m2.572s user 0m0.000s sys 0m0.020s
17:05:35: real 0m2.678s user 0m0.010s sys 0m0.010s
17:05:40: real 0m2.656s user 0m0.010s sys 0m0.010s
17:05:45: real 0m2.921s user 0m0.020s sys 0m0.000s
17:05:49: real 0m2.723s user 0m0.000s sys 0m0.020s
17:05:54: real 0m2.910s user 0m0.010s sys 0m0.010s
17:05:59: real 0m2.601s user 0m0.020s sys 0m0.000s
17:05:04: real 0m2.615s user 0m0.000s sys 0m0.000s
```
After:
```
Getting times for chassis
Getting good line count with wget -q -O- localhost:80/redfish/v1/Chassis?$expand=.($levels=1)
Line count: 980
16:04:43: real 0m0.188s user 0m0.020s sys 0m0.000s
16:04:43: real 0m0.195s user 0m0.010s sys 0m0.000s
16:04:45: real 0m0.219s user 0m0.010s sys 0m0.000s
16:04:48: real 0m0.226s user 0m0.020s sys 0m0.000s
16:04:50: real 0m0.208s user 0m0.020s sys 0m0.010s
16:04:52: real 0m0.226s user 0m0.010s sys 0m0.010s
16:04:54: real 0m0.419s user 0m0.000s sys 0m0.010s
16:04:57: real 0m0.222s user 0m0.010s sys 0m0.020s
16:04:59: real 0m0.194s user 0m0.000s sys 0m0.010s
16:04:01: real 0m0.191s user 0m0.010s sys 0m0.010s
16:04:04: real 0m0.276s user 0m0.010s sys 0m0.020s
16:04:06: real 0m0.183s user 0m0.020s sys 0m0.000s
16:04:08: real 0m0.193s user 0m0.040s sys 0m0.000s
16:04:10: real 0m0.406s user 0m0.020s sys 0m0.010s
16:04:13: real 0m0.317s user 0m0.000s sys 0m0.000s
16:04:15: real 0m0.442s user 0m0.005s sys 0m0.005s
16:04:18: real 0m0.226s user 0m0.010s sys 0m0.000s
16:04:20: real 0m0.217s user 0m0.020s sys 0m0.000s
16:04:22: real 0m0.200s user 0m0.010s sys 0m0.030s
16:04:24: real 0m0.423s user 0m0.010s sys 0m0.010s
16:04:27: real 0m0.203s user 0m0.020s sys 0m0.010s
16:04:29: real 0m0.433s user 0m0.000s sys 0m0.000s
16:04:31: real 0m0.318s user 0m0.020s sys 0m0.000s
16:04:34: real 0m1.206s user 0m0.000s sys 0m0.010s
16:04:37: real 0m0.403s user 0m0.000s sys 0m0.020s
16:04:39: real 0m0.353s user 0m0.010s sys 0m0.000s
16:04:42: real 0m0.291s user 0m0.000s sys 0m0.030s
16:04:44: real 0m0.742s user 0m0.020s sys 0m0.010s
16:04:47: real 0m0.369s user 0m0.010s sys 0m0.000s
16:04:49: real 0m0.215s user 0m0.020s sys 0m0.000s
16:04:52: real 0m0.204s user 0m0.000s sys 0m0.010s
16:04:54: real 0m0.418s user 0m0.000s sys 0m0.000s
16:04:56: real 0m0.215s user 0m0.000s sys 0m0.010s
16:04:58: real 0m0.202s user 0m0.010s sys 0m0.010s
16:04:01: real 0m0.202s user 0m0.010s sys 0m0.010s
16:04:03: real 0m0.212s user 0m0.010s sys 0m0.000s
16:04:05: real 0m0.694s user 0m0.010s sys 0m0.010s
16:04:08: real 0m0.201s user 0m0.010s sys 0m0.010s
16:04:10: real 0m0.230s user 0m0.000s sys 0m0.020s
16:04:12: real 0m0.206s user 0m0.010s sys 0m0.010s
16:04:15: real 0m0.446s user 0m0.010s sys 0m0.010s
```
Change-Id: I90b242e2cd24973420de871fedf9793dd1e310f3
Signed-off-by: Willy Tu <wltu@google.com>
diff --git a/config/bmcweb_config.h.in b/config/bmcweb_config.h.in
index ae98675..1290bd6 100644
--- a/config/bmcweb_config.h.in
+++ b/config/bmcweb_config.h.in
@@ -16,4 +16,7 @@
constexpr const bool bmcwebInsecureEnableHttpPushStyleEventing = @BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING@ == 1;
constexpr const char* bmcwebLoggingLevel = "@BMCWEB_LOGGING_LEVEL@";
+
+constexpr const bool bmcwebEnableHealthPopulate = @BMCWEB_ENABLE_HEALTH_POPULATE@ == 1;
+
// clang-format on
diff --git a/config/meson.build b/config/meson.build
index b13a023..bd8aada 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -12,6 +12,9 @@
conf_data.set10('BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING', insecure_push_style_notification.enabled())
conf_data.set('MESON_INSTALL_PREFIX', get_option('prefix'))
conf_data.set('HTTPS_PORT', get_option('https_port'))
+conf_data.set('HTTPS_PORT', get_option('https_port'))
+enable_health_populate = get_option('health-populate')
+conf_data.set10('BMCWEB_ENABLE_HEALTH_POPULATE', enable_health_populate.enabled())
# Logging level
loglvlopt = get_option('bmcweb-logging')
diff --git a/meson_options.txt b/meson_options.txt
index 3c2d3f7..3f37f9e 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -325,3 +325,11 @@
enable on production systems at this time. Other query
parameters such as only are not controlled by this option.'''
)
+
+option(
+ 'health-populate',
+ type: 'feature',
+ value: 'enabled',
+ description: '''Enables HealthPopulate and generate the Status property for
+ the resource'''
+)
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index a274421..32eb29b 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -15,6 +15,8 @@
*/
#pragma once
+#include "bmcweb_config.h"
+
#include "app.hpp"
#include "dbus_utility.hpp"
#include "health.hpp"
@@ -252,18 +254,21 @@
auto health = std::make_shared<HealthPopulate>(asyncResp);
- dbus::utility::getAssociationEndPoints(
- path + "/all_sensors",
- [health](const boost::system::error_code& ec2,
- const dbus::utility::MapperEndPoints& resp) {
- if (ec2)
- {
- return; // no sensors = no failures
- }
- health->inventory = resp;
- });
+ if constexpr (bmcwebEnableHealthPopulate)
+ {
+ dbus::utility::getAssociationEndPoints(
+ path + "/all_sensors",
+ [health](const boost::system::error_code& ec2,
+ const dbus::utility::MapperEndPoints& resp) {
+ if (ec2)
+ {
+ return; // no sensors = no failures
+ }
+ health->inventory = resp;
+ });
- health->populate();
+ health->populate();
+ }
if (connectionNames.empty())
{
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 330e68e..5330be1 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -15,6 +15,8 @@
*/
#pragma once
+#include "bmcweb_config.h"
+
#include "app.hpp"
#include "dbus_singleton.hpp"
#include "dbus_utility.hpp"
@@ -1559,30 +1561,31 @@
const std::vector<IPv4AddressData>& ipv4Data,
const std::vector<IPv6AddressData>& ipv6Data)
{
- constexpr std::array<std::string_view, 1> inventoryForEthernet = {
- "xyz.openbmc_project.Inventory.Item.Ethernet"};
-
nlohmann::json& jsonResponse = asyncResp->res.jsonValue;
jsonResponse["Id"] = ifaceId;
jsonResponse["@odata.id"] = boost::urls::format(
"/redfish/v1/Managers/bmc/EthernetInterfaces/{}", ifaceId);
jsonResponse["InterfaceEnabled"] = ethData.nicEnabled;
- auto health = std::make_shared<HealthPopulate>(asyncResp);
+ if constexpr (bmcwebEnableHealthPopulate)
+ {
+ constexpr std::array<std::string_view, 1> inventoryForEthernet = {
+ "xyz.openbmc_project.Inventory.Item.Ethernet"};
+ auto health = std::make_shared<HealthPopulate>(asyncResp);
+ dbus::utility::getSubTreePaths(
+ "/", 0, inventoryForEthernet,
+ [health](const boost::system::error_code& ec,
+ const dbus::utility::MapperGetSubTreePathsResponse& resp) {
+ if (ec)
+ {
+ return;
+ }
- dbus::utility::getSubTreePaths(
- "/", 0, inventoryForEthernet,
- [health](const boost::system::error_code& ec,
- const dbus::utility::MapperGetSubTreePathsResponse& resp) {
- if (ec)
- {
- return;
- }
+ health->inventory = resp;
+ });
- health->inventory = resp;
- });
-
- health->populate();
+ health->populate();
+ }
if (ethData.nicEnabled)
{
diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
index b08ee51..827cfdb 100644
--- a/redfish-core/lib/managers.hpp
+++ b/redfish-core/lib/managers.hpp
@@ -15,6 +15,8 @@
*/
#pragma once
+#include "bmcweb_config.h"
+
#include "app.hpp"
#include "dbus_utility.hpp"
#include "health.hpp"
@@ -2015,9 +2017,12 @@
asyncResp->res.jsonValue["Links"]["ManagerForServers"] =
std::move(managerForServers);
- auto health = std::make_shared<HealthPopulate>(asyncResp);
- health->isManagersHealth = true;
- health->populate();
+ if constexpr (bmcwebEnableHealthPopulate)
+ {
+ auto health = std::make_shared<HealthPopulate>(asyncResp);
+ health->isManagersHealth = true;
+ health->populate();
+ }
sw_util::populateSoftwareInformation(asyncResp, sw_util::bmcPurpose,
"FirmwareVersion", true);
diff --git a/redfish-core/lib/memory.hpp b/redfish-core/lib/memory.hpp
index 46b35d5..1f554cc 100644
--- a/redfish-core/lib/memory.hpp
+++ b/redfish-core/lib/memory.hpp
@@ -15,6 +15,8 @@
*/
#pragma once
+#include "bmcweb_config.h"
+
#include "app.hpp"
#include "dbus_utility.hpp"
#include "health.hpp"
@@ -601,9 +603,12 @@
const std::string& service,
const std::string& objPath)
{
- auto health = std::make_shared<HealthPopulate>(aResp);
- health->selfPath = objPath;
- health->populate();
+ if constexpr (bmcwebEnableHealthPopulate)
+ {
+ auto health = std::make_shared<HealthPopulate>(aResp);
+ health->selfPath = objPath;
+ health->populate();
+ }
BMCWEB_LOG_DEBUG << "Get available system components.";
sdbusplus::asio::getAllProperties(
diff --git a/redfish-core/lib/storage.hpp b/redfish-core/lib/storage.hpp
index a77bb91..5ec6b5c 100644
--- a/redfish-core/lib/storage.hpp
+++ b/redfish-core/lib/storage.hpp
@@ -15,6 +15,8 @@
*/
#pragma once
+#include "bmcweb_config.h"
+
#include "app.hpp"
#include "dbus_utility.hpp"
#include "generated/enums/drive.hpp"
@@ -92,8 +94,11 @@
auto& count = asyncResp->res.jsonValue["Drives@odata.count"];
count = 0;
- health->inventory.insert(health->inventory.end(), driveList.begin(),
- driveList.end());
+ if constexpr (bmcwebEnableHealthPopulate)
+ {
+ health->inventory.insert(health->inventory.end(), driveList.begin(),
+ driveList.end());
+ }
for (const std::string& drive : driveList)
{
@@ -240,21 +245,24 @@
});
}
- // this is done after we know the json array will no longer
- // be resized, as json::array uses vector underneath and we
- // need references to its members that won't change
- size_t count = 0;
- // Pointer based on |asyncResp->res.jsonValue|
- nlohmann::json::json_pointer rootPtr =
- "/StorageControllers"_json_pointer;
- for (const auto& [path, interfaceDict] : subtree)
+ if constexpr (bmcwebEnableHealthPopulate)
{
- auto subHealth = std::make_shared<HealthPopulate>(
- asyncResp, rootPtr / count / "Status");
- subHealth->inventory.emplace_back(path);
- health->inventory.emplace_back(path);
- health->children.emplace_back(subHealth);
- count++;
+ // this is done after we know the json array will no longer
+ // be resized, as json::array uses vector underneath and we
+ // need references to its members that won't change
+ size_t count = 0;
+ // Pointer based on |asyncResp->res.jsonValue|
+ nlohmann::json::json_pointer rootPtr =
+ "/StorageControllers"_json_pointer;
+ for (const auto& [path, interfaceDict] : subtree)
+ {
+ auto subHealth = std::make_shared<HealthPopulate>(
+ asyncResp, rootPtr / count / "Status");
+ subHealth->inventory.emplace_back(path);
+ health->inventory.emplace_back(path);
+ health->children.emplace_back(subHealth);
+ count++;
+ }
}
});
}
@@ -278,7 +286,10 @@
asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
auto health = std::make_shared<HealthPopulate>(asyncResp);
- health->populate();
+ if constexpr (bmcwebEnableHealthPopulate)
+ {
+ health->populate();
+ }
getDrives(asyncResp, health);
getStorageControllers(asyncResp, health);
@@ -703,9 +714,12 @@
// default it to Enabled
asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
- auto health = std::make_shared<HealthPopulate>(asyncResp);
- health->inventory.emplace_back(path);
- health->populate();
+ if constexpr (bmcwebEnableHealthPopulate)
+ {
+ auto health = std::make_shared<HealthPopulate>(asyncResp);
+ health->inventory.emplace_back(path);
+ health->populate();
+ }
addAllDriveInfo(asyncResp, connectionNames[0].first, path,
connectionNames[0].second);
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index 4a60748..8d978f1 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -15,6 +15,8 @@
*/
#pragma once
+#include "bmcweb_config.h"
+
#include "app.hpp"
#include "dbus_singleton.hpp"
#include "dbus_utility.hpp"
@@ -380,8 +382,11 @@
auto cpuHealth = std::make_shared<HealthPopulate>(
aResp, "/ProcessorSummary/Status"_json_pointer);
- systemHealth->children.emplace_back(memoryHealth);
- systemHealth->children.emplace_back(cpuHealth);
+ if constexpr (bmcwebEnableHealthPopulate)
+ {
+ systemHealth->children.emplace_back(memoryHealth);
+ systemHealth->children.emplace_back(cpuHealth);
+ }
// This is not system, so check if it's cpu, dimm, UUID or
// BiosVer
@@ -3107,27 +3112,30 @@
nlohmann::json::array_t({"KVMIP"});
#endif // BMCWEB_ENABLE_KVM
- constexpr std::array<std::string_view, 4> inventoryForSystems{
- "xyz.openbmc_project.Inventory.Item.Dimm",
- "xyz.openbmc_project.Inventory.Item.Cpu",
- "xyz.openbmc_project.Inventory.Item.Drive",
- "xyz.openbmc_project.Inventory.Item.StorageController"};
auto health = std::make_shared<HealthPopulate>(asyncResp);
- dbus::utility::getSubTreePaths(
- "/", 0, inventoryForSystems,
- [health](const boost::system::error_code& ec,
- const std::vector<std::string>& resp) {
- if (ec)
- {
- // no inventory
- return;
- }
+ if constexpr (bmcwebEnableHealthPopulate)
+ {
+ constexpr std::array<std::string_view, 4> inventoryForSystems{
+ "xyz.openbmc_project.Inventory.Item.Dimm",
+ "xyz.openbmc_project.Inventory.Item.Cpu",
+ "xyz.openbmc_project.Inventory.Item.Drive",
+ "xyz.openbmc_project.Inventory.Item.StorageController"};
- health->inventory = resp;
- });
+ dbus::utility::getSubTreePaths(
+ "/", 0, inventoryForSystems,
+ [health](const boost::system::error_code& ec,
+ const std::vector<std::string>& resp) {
+ if (ec)
+ {
+ // no inventory
+ return;
+ }
- health->populate();
+ health->inventory = resp;
+ });
+ health->populate();
+ }
getMainChassisId(asyncResp,
[](const std::string& chassisId,
diff --git a/redfish-core/lib/task.hpp b/redfish-core/lib/task.hpp
index 78817ff..050b75c 100644
--- a/redfish-core/lib/task.hpp
+++ b/redfish-core/lib/task.hpp
@@ -14,6 +14,7 @@
// limitations under the License.
*/
#pragma once
+#include "bmcweb_config.h"
#include "app.hpp"
#include "dbus_utility.hpp"
@@ -490,8 +491,11 @@
asyncResp->res.jsonValue["LifeCycleEventOnTaskStateChange"] = true;
- auto health = std::make_shared<HealthPopulate>(asyncResp);
- health->populate();
+ if constexpr (bmcwebEnableHealthPopulate)
+ {
+ auto health = std::make_shared<HealthPopulate>(asyncResp);
+ health->populate();
+ }
asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
asyncResp->res.jsonValue["ServiceEnabled"] = true;
asyncResp->res.jsonValue["Tasks"]["@odata.id"] =