system_configuration: Fix new hostname updates
This allows changes outside of phosphor-networkd to be processed and
handled correctly.
Change-Id: I0bb8e90fe502a6d69f451a45cfecbee1bc89eb66
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/system_configuration.cpp b/src/system_configuration.cpp
index 0ba4d82..bccdb02 100644
--- a/src/system_configuration.cpp
+++ b/src/system_configuration.cpp
@@ -9,26 +9,61 @@
namespace network
{
-// systemd service to kick start a target.
-constexpr auto HOSTNAMED_SERVICE = "org.freedesktop.hostname1";
-constexpr auto HOSTNAMED_SERVICE_PATH = "/org/freedesktop/hostname1";
-constexpr auto HOSTNAMED_INTERFACE = "org.freedesktop.hostname1";
-constexpr auto PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
-constexpr auto METHOD_GET = "Get";
-constexpr auto METHOD_SET = "SetStaticHostname";
+static constexpr char HOSTNAMED_SVC[] = "org.freedesktop.hostname1";
+static constexpr char HOSTNAMED_OBJ[] = "/org/freedesktop/hostname1";
+static constexpr char HOSTNAMED_INTF[] = "org.freedesktop.hostname1";
using namespace phosphor::logging;
using namespace sdbusplus::xyz::openbmc_project::Common::Error;
-using SystemConfigIntf =
- sdbusplus::xyz::openbmc_project::Network::server::SystemConfiguration;
+static constexpr char propMatch[] =
+ "type='signal',sender='org.freedesktop.hostname1',"
+ "path='/org/freedesktop/hostname1',"
+ "interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',"
+ "arg0='org.freedesktop.hostname1'";
SystemConfiguration::SystemConfiguration(sdbusplus::bus_t& bus,
stdplus::const_zstring objPath) :
Iface(bus, objPath.c_str(), Iface::action::defer_emit),
- bus(bus)
+ bus(bus), hostnamePropMatch(bus, propMatch, [&](sdbusplus::message_t& m) {
+ std::string intf;
+ std::unordered_map<std::string, std::variant<std::string>> values;
+ try
+ {
+ m.read(intf, values);
+ auto it = values.find("Hostname");
+ if (it == values.end())
+ {
+ return;
+ }
+ Iface::hostName(std::get<std::string>(it->second));
+ }
+ catch (const std::exception& e)
+ {
+ log<level::ERR>(
+ fmt::format("Hostname match parsing failed: {}", e.what())
+ .c_str(),
+ entry("ERROR=%s", e.what()));
+ }
+ })
{
- SystemConfigIntf::hostName(getHostNameFromSystem(), true);
+ try
+ {
+ std::variant<std::string> name;
+ auto req =
+ bus.new_method_call(HOSTNAMED_SVC, HOSTNAMED_OBJ,
+ "org.freedesktop.DBus.Properties", "Get");
+
+ req.append(HOSTNAMED_INTF, "Hostname");
+ auto reply = bus.call(req);
+ reply.read(name);
+ SystemConfigIntf::hostName(std::get<std::string>(name), true);
+ }
+ catch (const std::exception& e)
+ {
+ auto msg = fmt::format("Failed to get hostname: {}", e.what());
+ log<level::ERR>(msg.c_str(), entry("ERROR=%s", e.what()));
+ }
emit_object_added();
}
@@ -39,44 +74,20 @@
{
return name;
}
- auto method = bus.new_method_call(HOSTNAMED_SERVICE, HOSTNAMED_SERVICE_PATH,
- HOSTNAMED_INTERFACE, METHOD_SET);
-
- method.append(name, true);
-
- if (!bus.call(method))
- {
- log<level::ERR>("Failed to set the hostname");
- report<InternalFailure>();
- return SystemConfigIntf::hostName();
- }
-
- return SystemConfigIntf::hostName(name);
-}
-
-std::string SystemConfiguration::getHostNameFromSystem() const
-{
try
{
- std::variant<std::string> name;
- auto method =
- bus.new_method_call(HOSTNAMED_SERVICE, HOSTNAMED_SERVICE_PATH,
- PROPERTY_INTERFACE, METHOD_GET);
-
- method.append(HOSTNAMED_INTERFACE, "Hostname");
-
- auto reply = bus.call(method);
-
- reply.read(name);
- return std::get<std::string>(name);
+ auto method = bus.new_method_call(HOSTNAMED_SVC, HOSTNAMED_OBJ,
+ HOSTNAMED_INTF, "SetStaticHostname");
+ method.append(name, /*interactive=*/false);
+ bus.call_noreply(method);
+ return SystemConfigIntf::hostName(std::move(name));
}
- catch (const sdbusplus::exception_t& ex)
+ catch (const std::exception& e)
{
- log<level::ERR>(
- "Failed to get the hostname from systemd-hostnamed service",
- entry("ERR=%s", ex.what()));
+ auto msg = fmt::format("Failed to set hostname: {}", e.what());
+ log<level::ERR>(msg.c_str(), entry("ERROR=%s", e.what()));
}
- return "";
+ return SystemConfigIntf::hostName();
}
} // namespace network
diff --git a/src/system_configuration.hpp b/src/system_configuration.hpp
index 6bbb83f..b3d91d3 100644
--- a/src/system_configuration.hpp
+++ b/src/system_configuration.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/server/object.hpp>
#include <stdplus/zstring.hpp>
#include <string>
@@ -46,13 +47,11 @@
std::string hostName(std::string name) override;
private:
- /** @brief get the hostname from the system by doing
- * dbus call to hostnamed service.
- */
- std::string getHostNameFromSystem() const;
-
/** @brief Persistent sdbusplus DBus bus connection. */
sdbusplus::bus_t& bus;
+
+ /** @brief Monitor for hostname changes */
+ sdbusplus::bus::match_t hostnamePropMatch;
};
} // namespace network