diff options
author | Andrew Geissler <geissonator@yahoo.com> | 2019-04-09 16:01:01 -0500 |
---|---|---|
committer | Andrew Geissler <geissonator@yahoo.com> | 2019-04-10 14:29:16 -0500 |
commit | 624161cd2e922e790a2aa855c595b9074dc766c2 (patch) | |
tree | 929891e5c17bda7b562127f667a8d77db76c61a4 | |
parent | 19096267d41544379b403dff1283f0cb925990f1 (diff) | |
download | phosphor-state-manager-master.tar.gz phosphor-state-manager-master.zip |
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.cpp | 22 |
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"); |