1 #include "system_configuration.hpp" 2 3 #include <phosphor-logging/elog-errors.hpp> 4 #include <phosphor-logging/lg2.hpp> 5 #include <stdplus/pinned.hpp> 6 #include <xyz/openbmc_project/Common/error.hpp> 7 8 namespace phosphor 9 { 10 namespace network 11 { 12 13 static constexpr char HOSTNAMED_SVC[] = "org.freedesktop.hostname1"; 14 static constexpr char HOSTNAMED_OBJ[] = "/org/freedesktop/hostname1"; 15 static constexpr char HOSTNAMED_INTF[] = "org.freedesktop.hostname1"; 16 17 using namespace phosphor::logging; 18 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 19 using Argument = xyz::openbmc_project::Common::InvalidArgument; 20 21 static constexpr char propMatch[] = 22 "type='signal',sender='org.freedesktop.hostname1'," 23 "path='/org/freedesktop/hostname1'," 24 "interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'," 25 "arg0='org.freedesktop.hostname1'"; 26 27 SystemConfiguration::SystemConfiguration( 28 stdplus::PinnedRef<sdbusplus::bus_t> bus, stdplus::const_zstring objPath) : 29 Iface(bus, objPath.c_str(), Iface::action::defer_emit), bus(bus), 30 hostnamePropMatch( 31 bus, propMatch, 32 [sc = stdplus::PinnedRef(*this)](sdbusplus::message_t& m) { 33 std::string intf; 34 std::unordered_map<std::string, std::variant<std::string>> values; 35 try 36 { 37 m.read(intf, values); 38 auto it = values.find("Hostname"); 39 if (it == values.end()) 40 { 41 return; 42 } 43 sc.get().Iface::hostName(std::get<std::string>(it->second)); 44 } 45 catch (const std::exception& e) 46 { 47 lg2::error("Hostname match parsing failed: {ERROR}", "ERROR", 48 e); 49 } 50 }) 51 { 52 try 53 { 54 std::variant<std::string> name; 55 auto req = 56 bus.get().new_method_call(HOSTNAMED_SVC, HOSTNAMED_OBJ, 57 "org.freedesktop.DBus.Properties", "Get"); 58 59 req.append(HOSTNAMED_INTF, "Hostname"); 60 auto reply = req.call(); 61 reply.read(name); 62 SystemConfigIntf::hostName(std::get<std::string>(name), true); 63 } 64 catch (const std::exception& e) 65 { 66 lg2::error("Failed to get hostname: {ERROR}", "ERROR", e); 67 } 68 69 emit_object_added(); 70 } 71 72 std::string SystemConfiguration::hostName(std::string name) 73 { 74 if (SystemConfigIntf::hostName() == name) 75 { 76 return name; 77 } 78 try 79 { 80 auto method = bus.get().new_method_call( 81 HOSTNAMED_SVC, HOSTNAMED_OBJ, HOSTNAMED_INTF, "SetStaticHostname"); 82 method.append(name, /*interactive=*/false); 83 method.call(); 84 return SystemConfigIntf::hostName(std::move(name)); 85 } 86 catch (const sdbusplus::exception::SdBusError& e) 87 { 88 lg2::error("Failed to set hostname {HOSTNAME}: {ERROR} ", "HOSTNAME", 89 name, "ERROR", e); 90 auto dbusError = e.get_error(); 91 if ((dbusError != nullptr) && 92 (strcmp(dbusError->name, 93 "org.freedesktop.DBus.Error.InvalidArgs") == 0)) 94 { 95 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Hostname"), 96 Argument::ARGUMENT_VALUE(name.c_str())); 97 } 98 } 99 return SystemConfigIntf::hostName(); 100 } 101 102 } // namespace network 103 } // namespace phosphor 104