summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Geissler <geissonator@yahoo.com>2019-04-09 16:01:01 -0500
committerAndrew Geissler <geissonator@yahoo.com>2019-04-10 14:29:16 -0500
commit624161cd2e922e790a2aa855c595b9074dc766c2 (patch)
tree929891e5c17bda7b562127f667a8d77db76c61a4
parent19096267d41544379b403dff1283f0cb925990f1 (diff)
downloadphosphor-state-manager-master.tar.gz
phosphor-state-manager-master.zip
Handle mapper introspect race conditionHEADmaster
There is a pervasive issue within OpenBMC where a dbus service may be started and on the bus, but before mapper can introspect it, a dependent service queries mapper for that objects information. In most situations a service writer can avoid this by using the Wants=mapper-wait@-xyz* syntax. This does not work however if two or more dbus services implement the same dbus object path. The host_check_main application is one service that is hitting this issue. It requires the /xyz/openbmc_project/control/host0 object path which is implemented by two dbus services. The solution here is to first try mapper, but if that fails to use a hard coded dbus service name. The value of mapper for this type of function is up for debate within the community but for now, get a compromise in that first tries mapper, and if not available tries the hard coded well-known service name. Tested: Verified the following within QEMU: - Good path works as expected, mapper response used - GetObject fails for mapper call, successfully used hard coded path - Service not available on dbus, verified exception reported Change-Id: I14dfaf2ce43392a19a2a5a3131534f55c6eb6f4a Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
-rw-r--r--host_check_main.cpp22
1 files changed, 13 insertions, 9 deletions
diff --git a/host_check_main.cpp b/host_check_main.cpp
index 311e6e2..182c501 100644
--- a/host_check_main.cpp
+++ b/host_check_main.cpp
@@ -18,6 +18,7 @@ using sdbusplus::exception::SdBusError;
constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
+constexpr auto CONTROL_HOST_DEFAULT_SVC = "xyz.openbmc_project.Control.Host";
constexpr auto CONTROL_HOST_PATH = "/xyz/openbmc_project/control/host0";
constexpr auto CONTROL_HOST_INTERFACE = "xyz.openbmc_project.Control.Host";
@@ -71,19 +72,22 @@ void sendHeartbeat(sdbusplus::bus::bus& bus)
}
catch (const SdBusError& e)
{
- log<level::ERR>("Error in mapper call for control host",
- entry("ERROR=%s", e.what()));
- throw;
+ log<level::INFO>("Error in mapper call for control host, use default "
+ "service",
+ entry("ERROR=%s", e.what()));
}
- if (mapperResponse.empty())
+ std::string host;
+ if (!mapperResponse.empty())
{
- log<level::ERR>("Error reading mapper resp for control host");
- // TODO openbmc/openbmc#851 - Once available, throw returned error
- throw std::runtime_error("Error reading mapper resp for control host");
+ log<level::DEBUG>("Use mapper response");
+ host = mapperResponse.begin()->first;
+ }
+ else
+ {
+ log<level::DEBUG>("Use hard coded host");
+ host = CONTROL_HOST_DEFAULT_SVC;
}
-
- const auto& host = mapperResponse.begin()->first;
auto method = bus.new_method_call(host.c_str(), CONTROL_HOST_PATH,
CONTROL_HOST_INTERFACE, "Execute");
OpenPOWER on IntegriCloud