1 #include <fmt/format.h> 2 #include <unistd.h> 3 4 #include <phosphor-logging/log.hpp> 5 #include <watchdog_dbus.hpp> 6 #include <watchdog_logging.hpp> 7 8 #include <string> 9 #include <vector> 10 11 namespace watchdog 12 { 13 namespace dump 14 { 15 16 using namespace phosphor::logging; 17 18 int dbusMethod(const std::string& path, const std::string& interface, 19 const std::string& function, sdbusplus::message_t& method, 20 const std::string& extended) 21 { 22 int rc = RC_DBUS_ERROR; // assume error 23 24 try 25 { 26 constexpr auto serviceFind = "xyz.openbmc_project.ObjectMapper"; 27 constexpr auto pathFind = "/xyz/openbmc_project/object_mapper"; 28 constexpr auto interfaceFind = "xyz.openbmc_project.ObjectMapper"; 29 constexpr auto functionFind = "GetObject"; 30 31 auto bus = sdbusplus::bus::new_system(); // using system dbus 32 33 // method to find service from object path and object interface 34 auto newMethod = bus.new_method_call(serviceFind, pathFind, 35 interfaceFind, functionFind); 36 37 // find the service for specified object path and interface 38 newMethod.append(path.c_str()); 39 newMethod.append(std::vector<std::string>({interface})); 40 auto reply = bus.call(newMethod); 41 42 // dbus call results 43 std::map<std::string, std::vector<std::string>> responseFindService; 44 reply.read(responseFindService); 45 46 // If we successfully found the service associated with the dbus object 47 // path and interface then create a method for the specified interface 48 // and function. 49 if (!responseFindService.empty()) 50 { 51 auto service = responseFindService.begin()->first; 52 53 // Some methods (e.g. get attribute) take an extended parameter 54 if (extended == "") 55 { 56 // return the method 57 method = bus.new_method_call(service.c_str(), path.c_str(), 58 interface.c_str(), 59 function.c_str()); 60 } 61 else 62 { 63 // return extended method 64 method = bus.new_method_call(service.c_str(), path.c_str(), 65 extended.c_str(), 66 function.c_str()); 67 } 68 69 rc = RC_SUCCESS; 70 } 71 else 72 { 73 // This trace will be picked up in event log 74 log<level::INFO>("dbusMethod service not found"); 75 std::string traceMsgPath = std::string(path, maxTraceLen); 76 log<level::INFO>(traceMsgPath.c_str()); 77 std::string traceMsgIface = std::string(interface, maxTraceLen); 78 log<level::INFO>(traceMsgIface.c_str()); 79 } 80 } 81 catch (const sdbusplus::exception_t& e) 82 { 83 log<level::ERR>("Error in dbusMethod", entry("ERROR=%s", e.what())); 84 } 85 86 return rc; 87 } 88 89 uint32_t createPel(const std::string& eventType, 90 std::map<std::string, std::string>& additional, 91 const std::vector<FFDCTuple>& ffdc) 92 { 93 // Create returns plid 94 int plid = 0; 95 96 // Need to provide pid when using create or create-with-ffdc methods 97 additional.emplace("_PID", std::to_string(getpid())); 98 99 // Sdbus call specifics 100 constexpr auto interface = "org.open_power.Logging.PEL"; 101 constexpr auto function = "CreatePELWithFFDCFiles"; 102 103 sdbusplus::message_t method; 104 105 if (0 == dbusMethod(pathLogging, interface, function, method)) 106 { 107 try 108 { 109 // append additional dbus call paramaters 110 method.append(eventType, levelPelError, additional, ffdc); 111 112 // using system dbus 113 auto bus = sdbusplus::bus::new_system(); 114 auto response = bus.call(method); 115 116 // reply will be tuple containing bmc log id, platform log id 117 std::tuple<uint32_t, uint32_t> reply = {0, 0}; 118 119 // parse dbus response into reply 120 response.read(reply); 121 plid = std::get<1>(reply); // platform log id is tuple "second" 122 } 123 catch (const sdbusplus::exception_t& e) 124 { 125 log<level::ERR>("Error in createPel CreatePELWithFFDCFiles", 126 entry("ERROR=%s", e.what())); 127 } 128 } 129 130 return plid; // platform log id or 0 131 } 132 133 bool isHostStateRunning() 134 { 135 constexpr auto path = "/xyz/openbmc_project/state/host0"; 136 constexpr auto interface = "xyz.openbmc_project.State.Host"; 137 constexpr auto extended = "org.freedesktop.DBus.Properties"; 138 constexpr auto function = "Get"; 139 140 sdbusplus::message_t method; 141 142 if (0 == dbusMethod(path, interface, function, method, extended)) 143 { 144 try 145 { 146 method.append(interface, "CurrentHostState"); 147 auto bus = sdbusplus::bus::new_system(); 148 auto response = bus.call(method); 149 std::variant<std::string> reply; 150 151 response.read(reply); 152 std::string currentHostState(std::get<std::string>(reply)); 153 154 if (currentHostState == 155 "xyz.openbmc_project.State.Host.HostState.Running") 156 { 157 return true; 158 } 159 } 160 catch (const sdbusplus::exception_t& e) 161 { 162 log<level::ERR>( 163 fmt::format("Failed to read CurrentHostState property ({})", 164 e.what()) 165 .c_str()); 166 } 167 } 168 169 return false; 170 } 171 172 } // namespace dump 173 } // namespace watchdog 174