dbus-sensors: gpiosensor service: Add dbus retries
When the gpiosensor service starts, it makes a dbus call to get all the
dbus objects managed by Entity Manager. This dbus call sometimes fails,
and as a result, the gpiosensor service doesn't create dbus objects for
any GPIOs.
This commit updates the gpiosensor service to add dbus retries, if
needed.
Tested:
Ran the misseated_connection test 1000 times. Failure rate 1%.
http://sponge2/cb9b071d-3adb-42a4-8f54-3da18ff8d3d7
https://fusion2.corp.google.com/7e37c674-f1fd-3237-b8c0-d7d5f0ef9a28
https://fusion2.corp.google.com/89047ff5-446a-3525-8b42-e991e8dc7619
https://fusion2.corp.google.com/84d2983a-a18b-3de8-a616-84c1dc39b625
https://fusion2.corp.google.com/80a23722-ec58-33d2-bd5b-de685ce093f6
https://fusion2.corp.google.com/3e4c4b89-b96c-3a71-8e32-9a20a39eb809
Google-Bug-Id: 422474823
Platforms-Affected: All
Change-Id: I55abf9299ebe67d24ff2ce7bf85206a3f724f566
Signed-off-by: John Wedig <johnwedig@google.com>
(cherry picked from commit 029a4995388f1a7a5dfdf38fb3ca54ce7e0ec1dd)
diff --git a/recipes-phosphor/sensors/dbus-sensors/0003-gpiosensor-a-dedicated-daemon-to-report-gpio-status-.patch b/recipes-phosphor/sensors/dbus-sensors/0003-gpiosensor-a-dedicated-daemon-to-report-gpio-status-.patch
index aa6c60d..447fd0b 100644
--- a/recipes-phosphor/sensors/dbus-sensors/0003-gpiosensor-a-dedicated-daemon-to-report-gpio-status-.patch
+++ b/recipes-phosphor/sensors/dbus-sensors/0003-gpiosensor-a-dedicated-daemon-to-report-gpio-status-.patch
@@ -1,7 +1,8 @@
-From 2ed7f3bdd3900102d8dd333bc2c6ad6c2ef83688 Mon Sep 17 00:00:00 2001
+From cebbcd890ac479429811fc2c5858f8e13099e8a3 Mon Sep 17 00:00:00 2001
From: Gaurav Gandhi <gauravgandhi@google.com>
Date: Mon, 13 Feb 2023 18:23:56 -0800
-Subject: [PATCH] gpiosensor: a dedicated daemon to report gpio status to dbus
+Subject: [PATCH 1/2] gpiosensor: a dedicated daemon to report gpio status to
+ dbus
The daemon will read the given gpio status and report to dbus. One can
consume the gpio signal and behave differently.
@@ -19,16 +20,17 @@
Signed-off-by: Cody Smith <scody@google.com>
In-Review: https://gerrit.openbmc-project.xyz/c/openbmc/dbus-sensors/+/45997/37
Change-Id: Ife901358751eac46b4a52a878feabcb556fb1224
+Signed-off-by: John Wedig <johnwedig@google.com>
---
- docs/gpio-based-presence-detection.md | 120 +++++++++++
- include/GPIOPresenceSensor.hpp | 110 ++++++++++
+ docs/gpio-based-presence-detection.md | 120 ++++++++++
+ include/GPIOPresenceSensor.hpp | 110 +++++++++
meson.options | 1 +
service_files/meson.build | 1 +
- .../xyz.openbmc_project.gpiosensor.service | 13 ++
- src/GPIOPresenceSensor.cpp | 105 ++++++++++
- src/GPIOPresenceSensorMain.cpp | 188 ++++++++++++++++++
+ .../xyz.openbmc_project.gpiosensor.service | 13 +
+ src/GPIOPresenceSensor.cpp | 105 ++++++++
+ src/GPIOPresenceSensorMain.cpp | 225 ++++++++++++++++++
src/meson.build | 16 ++
- 8 files changed, 554 insertions(+)
+ 8 files changed, 591 insertions(+)
create mode 100644 docs/gpio-based-presence-detection.md
create mode 100644 include/GPIOPresenceSensor.hpp
create mode 100644 service_files/xyz.openbmc_project.gpiosensor.service
@@ -433,15 +435,19 @@
+} // namespace gpiopresencesensing
diff --git a/src/GPIOPresenceSensorMain.cpp b/src/GPIOPresenceSensorMain.cpp
new file mode 100644
-index 0000000..8b22d25
+index 0000000..02c7ed5
--- /dev/null
+++ b/src/GPIOPresenceSensorMain.cpp
-@@ -0,0 +1,188 @@
+@@ -0,0 +1,225 @@
+#include "Utils.hpp"
+
++#include <boost/asio/steady_timer.hpp>
+#include <GPIOPresenceSensor.hpp>
+
++#include <chrono>
+#include <iostream>
++#include <mutex>
++#include <utility>
+
+namespace gpiopresencesensing
+{
@@ -474,6 +480,62 @@
+ /*present*/ false, pollRate};
+}
+
++void handleExistingDevices(sdbusplus::asio::connection* conn,
++ OnInterfaceAddedCallback&& cb, size_t retries)
++{
++ conn->async_method_call(
++ [conn, callback = std::move(cb), retries]
++ (const boost::system::error_code ec, ManagedObjectType managedObjs) {
++ if (ec)
++ {
++ std::cerr << "Error getting Entity Manager managed objects; "
++ << retries << " retries remaining." << std::endl;
++ if (retries == 0)
++ {
++ return;
++ }
++ auto timer = std::make_shared<boost::asio::steady_timer>(
++ conn->get_io_context());
++ timer->expires_after(std::chrono::seconds(10));
++ timer->async_wait(
++ [conn, callback = std::move(callback), retries, timer]
++ (boost::system::error_code ec) mutable {
++ if (ec)
++ {
++ std::cerr << "Timer error!";
++ return;
++ }
++ handleExistingDevices(
++ conn,
++ std::move(callback),
++ retries - 1);
++ });
++ return;
++ }
++ for (auto& obj : managedObjs)
++ {
++ auto& item = obj.second;
++ auto found = item.find(interfaces::emGPIOCableSensingIfc);
++ if (found != item.end())
++ {
++ Config config;
++ try
++ {
++ config = getConfig(found->second);
++ callback(obj.first.str, found->first, config);
++ }
++ catch (std::exception& e)
++ {
++ std::cerr << "Incomplete config found: " << e.what()
++ << " obj = " << obj.first.str << std::endl;
++ }
++ }
++ }
++ },
++ "xyz.openbmc_project.EntityManager", "/xyz/openbmc_project/inventory",
++ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
++}
++
+void setupInterfaceAdded(sdbusplus::asio::connection* conn,
+ OnInterfaceAddedCallback&& cb)
+{
@@ -500,35 +562,7 @@
+ };
+
+ // call the user callback for all the device that is already available
-+ conn->async_method_call(
-+ [cb](const boost::system::error_code ec,
-+ ManagedObjectType managedObjs) {
-+ if (ec)
-+ {
-+ return;
-+ }
-+ for (auto& obj : managedObjs)
-+ {
-+ auto& item = obj.second;
-+ auto found = item.find(interfaces::emGPIOCableSensingIfc);
-+ if (found != item.end())
-+ {
-+ Config config;
-+ try
-+ {
-+ config = getConfig(found->second);
-+ cb(obj.first.str, found->first, config);
-+ }
-+ catch (std::exception& e)
-+ {
-+ std::cerr << "Incomplete config found: " << e.what()
-+ << " obj = " << obj.first.str << std::endl;
-+ }
-+ }
-+ }
-+ },
-+ "xyz.openbmc_project.EntityManager", "/xyz/openbmc_project/inventory",
-+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
++ handleExistingDevices(conn, std::forward<OnInterfaceAddedCallback>(cb), 5);
+
+ ifcAdded = std::make_unique<sdbusplus::bus::match::match>(
+ static_cast<sdbusplus::bus::bus&>(*conn),
@@ -593,6 +627,11 @@
+ [&controller, &systemBus,
+ &objectServer](std::string_view, std::string_view,
+ const gpiopresencesensing::Config& config) {
++ static std::mutex callbackMutex;
++ // Make sure we don't have multiple threads running this callback.
++ // Otherwise, it could try to add the same dbus object multiple times.
++ const std::lock_guard<std::mutex> lock(callbackMutex);
++
+ sdbusplus::message::object_path inventoryPath(
+ gpiopresencesensing::inventoryObjPath);
+ sdbusplus::message::object_path objPath = inventoryPath / config.name;
@@ -653,5 +692,5 @@
executable(
'externalsensor',
--
-2.44.0.rc1.240.g4c46232300-goog
+2.50.0.rc2.696.g1fc2a0284f-goog
diff --git a/recipes-phosphor/sensors/dbus-sensors/0004-Feature-Add-association-interfaces-to-a-target-EM.patch b/recipes-phosphor/sensors/dbus-sensors/0004-Feature-Add-association-interfaces-to-a-target-EM.patch
index 8b1f3dd..385d5db 100644
--- a/recipes-phosphor/sensors/dbus-sensors/0004-Feature-Add-association-interfaces-to-a-target-EM.patch
+++ b/recipes-phosphor/sensors/dbus-sensors/0004-Feature-Add-association-interfaces-to-a-target-EM.patch
@@ -1,7 +1,7 @@
-From febe200fdf9115bd327a86ad621e963def1b5f09 Mon Sep 17 00:00:00 2001
+From 9735639177b72d30adff67957fbd13fb0313e97e Mon Sep 17 00:00:00 2001
From: Cody Smith <scody@google.com>
Date: Fri, 18 Feb 2022 13:20:45 +0000
-Subject: [PATCH] Feature: Add association interfaces to a target EM
+Subject: [PATCH 2/2] Feature: Add association interfaces to a target EM
This change gives the `gpiopresence` daemon in `dbus-sensors`
the ability to, upon request via configuration EM, generate am
@@ -32,10 +32,10 @@
In-Review: https://gerrit.openbmc-project.xyz/c/openbmc/dbus-sensors/+/51360/12
Change-Id: I0572d124a8e9b9fedbdfb30d41fe399e005f5c03
---
- include/GPIOPresenceSensor.hpp | 17 +++++-
+ include/GPIOPresenceSensor.hpp | 17 ++++++-
src/GPIOPresenceSensor.cpp | 4 +-
- src/GPIOPresenceSensorMain.cpp | 94 +++++++++++++++++++++++++++++-----
- 3 files changed, 101 insertions(+), 14 deletions(-)
+ src/GPIOPresenceSensorMain.cpp | 88 ++++++++++++++++++++++++++++++----
+ 3 files changed, 98 insertions(+), 11 deletions(-)
diff --git a/include/GPIOPresenceSensor.hpp b/include/GPIOPresenceSensor.hpp
index a9f49a0..fa32a20 100644
@@ -51,7 +51,7 @@
+static constexpr inline const char* propertyAssociationReverse =
+ "AssociationReverse";
} // namespace Properties
-
+
namespace interfaces
@@ -50,8 +55,15 @@ struct Config
bool activeLow;
@@ -68,10 +68,10 @@
+ // (Internal) Parent path
+ std::string parentPath;
};
-
+
// Actively listen to the config information from EntityManager and calls the
@@ -65,9 +77,11 @@ class GPIOPresence
-
+
// Add a dbus object to the reference list.
// @params statusIfc: pointer to object status interface.
+ // @params associationIfc: Optional pointer to object association interface
@@ -80,7 +80,7 @@
void addObj(std::unique_ptr<sdbusplus::asio::dbus_interface> statusIfc,
+ std::unique_ptr<sdbusplus::asio::dbus_interface> associationIfc,
std::string_view objPath, const Config& config);
-
+
// Remove a object from the object reference list.
@@ -89,6 +103,7 @@ class GPIOPresence
struct ObjIfaces
@@ -89,13 +89,13 @@
+ std::unique_ptr<sdbusplus::asio::dbus_interface> associationIfc;
Config config;
};
-
+
diff --git a/src/GPIOPresenceSensor.cpp b/src/GPIOPresenceSensor.cpp
index 870b4b4..2d48491 100644
--- a/src/GPIOPresenceSensor.cpp
+++ b/src/GPIOPresenceSensor.cpp
@@ -26,10 +26,12 @@ int GPIOPresence::readLine(std::string_view lineLabel)
-
+
void GPIOPresence::addObj(
std::unique_ptr<sdbusplus::asio::dbus_interface> statusIfc,
+ std::unique_ptr<sdbusplus::asio::dbus_interface> associationIfc,
@@ -106,25 +106,22 @@
+ objIfaces[std::string(objPath)] = {std::move(statusIfc),
+ std::move(associationIfc), config};
}
-
+
void GPIOPresence::removeObj(std::string_view objPath)
diff --git a/src/GPIOPresenceSensorMain.cpp b/src/GPIOPresenceSensorMain.cpp
-index 8b22d25..f556900 100644
+index 02c7ed5..576f3c0 100644
--- a/src/GPIOPresenceSensorMain.cpp
+++ b/src/GPIOPresenceSensorMain.cpp
-@@ -1,8 +1,10 @@
- #include "Utils.hpp"
-
+@@ -2,6 +2,7 @@
+
+ #include <boost/asio/steady_timer.hpp>
#include <GPIOPresenceSensor.hpp>
+#include <sdbusplus/bus/match.hpp>
-
+
+ #include <chrono>
#include <iostream>
-+#include <utility>
-
- namespace gpiopresencesensing
- {
-@@ -15,7 +17,7 @@ using OnInterfaceRemovedCallback = std::function<void(std::string_view)>;
-
+@@ -19,7 +20,7 @@ using OnInterfaceRemovedCallback = std::function<void(std::string_view)>;
+
// Helper function to convert dbus property to struct
// @param[in] properties: dbus properties
-Config getConfig(const SensorBaseConfigMap& properties)
@@ -132,7 +129,7 @@
{
auto name = loadVariant<std::string>(properties, Properties::propertyName);
auto gpioLine =
-@@ -31,8 +33,48 @@ Config getConfig(const SensorBaseConfigMap& properties)
+@@ -35,8 +36,48 @@ Config getConfig(const SensorBaseConfigMap& properties)
pollRate =
loadVariant<uint32_t>(properties, Properties::propertyPollRate);
}
@@ -181,9 +178,28 @@
+ associationReverse,
+ std::move(parentPath)};
}
-
- void setupInterfaceAdded(sdbusplus::asio::connection* conn,
-@@ -49,7 +91,7 @@ void setupInterfaceAdded(sdbusplus::asio::connection* conn,
+
+ void handleExistingDevices(sdbusplus::asio::connection* conn,
+@@ -73,14 +114,16 @@ void handleExistingDevices(sdbusplus::asio::connection* conn,
+ }
+ for (auto& obj : managedObjs)
+ {
+- auto& item = obj.second;
++ SensorData& item = obj.second;
++
+ auto found = item.find(interfaces::emGPIOCableSensingIfc);
+ if (found != item.end())
+ {
+ Config config;
+ try
+ {
+- config = getConfig(found->second);
++ config = getConfig(found->second,
++ obj.first.parent_path());
+ callback(obj.first.str, found->first, config);
+ }
+ catch (std::exception& e)
+@@ -109,7 +152,7 @@ void setupInterfaceAdded(sdbusplus::asio::connection* conn,
Config config;
try
{
@@ -192,37 +208,7 @@
callback(objPath.str, found->first, config);
}
catch (std::exception& e)
-@@ -62,23 +104,24 @@ void setupInterfaceAdded(sdbusplus::asio::connection* conn,
-
- // call the user callback for all the device that is already available
- conn->async_method_call(
-- [cb](const boost::system::error_code ec,
-- ManagedObjectType managedObjs) {
-+ [callback = cb](const boost::system::error_code ec,
-+ ManagedObjectType managedObjs) {
- if (ec)
- {
- return;
- }
- for (auto& obj : managedObjs)
- {
-- auto& item = obj.second;
-+ SensorData& item = obj.second;
-+
- auto found = item.find(interfaces::emGPIOCableSensingIfc);
- if (found != item.end())
- {
- Config config;
- try
- {
-- config = getConfig(found->second);
-- cb(obj.first.str, found->first, config);
-+ config = getConfig(found->second, obj.first.parent_path());
-+ callback(obj.first.str, found->first, config);
- }
- catch (std::exception& e)
- {
-@@ -103,7 +146,7 @@ void setupInterfaceRemoved(sdbusplus::asio::connection* conn,
+@@ -135,7 +178,7 @@ void setupInterfaceRemoved(sdbusplus::asio::connection* conn,
OnInterfaceRemovedCallback&& cb)
{
// Listen to the interface removed event.
@@ -231,7 +217,7 @@
[callback = std::move(cb)](sdbusplus::message::message msg) {
sdbusplus::message::object_path objPath;
msg.read(objPath);
-@@ -162,14 +205,41 @@ int main()
+@@ -199,14 +242,41 @@ int main()
{
controller->removeObj(objPath.str);
}
@@ -275,6 +261,6 @@
controller->setMinPollRate(config.pollRate);
// It is possible there are more EM config in the pipeline.
// Therefore, delay the main loop by 10 seconds to wait for more
---
-2.40.1.521.gf1e218fcd8-goog
+--
+2.50.0.rc2.696.g1fc2a0284f-goog