blob: 6d39bef7b3b942c7d1a2bc30ac7e27bbb318fc8d [file] [log] [blame]
Jayanth Othayotha320c7c2017-06-14 07:17:21 -05001#pragma once
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -05002#include "dump_manager.hpp"
3
Jayanth Othayothd02153c2017-07-02 22:29:42 -05004#include <systemd/sd-event.h>
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -05005#include <unistd.h>
6
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -05007#include <phosphor-logging/elog-errors.hpp>
8#include <phosphor-logging/elog.hpp>
Dhruvaraj Subhashchandrand1f670f2023-06-05 22:19:25 -05009#include <phosphor-logging/lg2.hpp>
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060010#include <sdbusplus/bus.hpp>
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -050011#include <xyz/openbmc_project/Common/error.hpp>
12#include <xyz/openbmc_project/Dump/Create/server.hpp>
Ramesh Iyyar22793862020-12-04 04:03:03 -060013#include <xyz/openbmc_project/State/Boot/Progress/server.hpp>
Dhruvaraj Subhashchandran3a25e5b2022-03-22 08:06:20 -050014#include <xyz/openbmc_project/State/Host/server.hpp>
Jayanth Othayoth671fc7f2017-06-14 08:01:41 -050015
Jayanth Othayoth0af74a52021-04-08 03:55:21 -050016#include <memory>
17
Jayanth Othayotha320c7c2017-06-14 07:17:21 -050018namespace phosphor
19{
20namespace dump
21{
22
Ramesh Iyyar22793862020-12-04 04:03:03 -060023using BootProgress = sdbusplus::xyz::openbmc_project::State::Boot::server::
24 Progress::ProgressStages;
Dhruvaraj Subhashchandran3a25e5b2022-03-22 08:06:20 -050025using HostState =
26 sdbusplus::xyz::openbmc_project::State::server::Host::HostState;
Ramesh Iyyar22793862020-12-04 04:03:03 -060027
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -050028using namespace phosphor::logging;
29using namespace sdbusplus::xyz::openbmc_project::Common::Error;
30
Jayanth Othayoth671fc7f2017-06-14 08:01:41 -050031/* Need a custom deleter for freeing up sd_event */
32struct EventDeleter
33{
34 void operator()(sd_event* event) const
35 {
36 event = sd_event_unref(event);
37 }
38};
39using EventPtr = std::unique_ptr<sd_event, EventDeleter>;
40
Jayanth Othayotha320c7c2017-06-14 07:17:21 -050041/** @struct CustomFd
42 *
43 * RAII wrapper for file descriptor.
44 */
45struct CustomFd
46{
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050047 private:
48 /** @brief File descriptor */
49 int fd = -1;
Jayanth Othayotha320c7c2017-06-14 07:17:21 -050050
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050051 public:
52 CustomFd() = delete;
53 CustomFd(const CustomFd&) = delete;
54 CustomFd& operator=(const CustomFd&) = delete;
55 CustomFd(CustomFd&&) = delete;
56 CustomFd& operator=(CustomFd&&) = delete;
Jayanth Othayotha320c7c2017-06-14 07:17:21 -050057
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050058 /** @brief Saves File descriptor and uses it to do file operation
59 *
60 * @param[in] fd - File descriptor
61 */
Patrick Williams78e88402023-05-10 07:50:48 -050062 CustomFd(int fd) : fd(fd) {}
Jayanth Othayotha320c7c2017-06-14 07:17:21 -050063
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050064 ~CustomFd()
65 {
66 if (fd >= 0)
Jayanth Othayotha320c7c2017-06-14 07:17:21 -050067 {
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050068 close(fd);
Jayanth Othayotha320c7c2017-06-14 07:17:21 -050069 }
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050070 }
Jayanth Othayotha320c7c2017-06-14 07:17:21 -050071
Jayanth Othayothcb65ffc2018-10-16 08:29:32 -050072 int operator()() const
73 {
74 return fd;
75 }
Jayanth Othayotha320c7c2017-06-14 07:17:21 -050076};
77
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060078/**
79 * @brief Get the bus service
80 *
81 * @param[in] bus - Bus to attach to.
82 * @param[in] path - D-Bus path name.
83 * @param[in] interface - D-Bus interface name.
84 * @return the bus service as a string
Dhruvaraj Subhashchandran3a25e5b2022-03-22 08:06:20 -050085 *
86 * @throws sdbusplus::exception::SdBusError - If any D-Bus error occurs during
87 * the call.
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060088 **/
Patrick Williams9b18bf22022-07-22 19:26:55 -050089std::string getService(sdbusplus::bus_t& bus, const std::string& path,
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060090 const std::string& interface);
91
Ramesh Iyyar22793862020-12-04 04:03:03 -060092/**
Dhruvaraj Subhashchandran3a25e5b2022-03-22 08:06:20 -050093 * @brief Read property value from the specified object and interface
94 * @param[in] bus D-Bus handle
95 * @param[in] service service which has implemented the interface
96 * @param[in] object object having has implemented the interface
97 * @param[in] intf interface having the property
98 * @param[in] prop name of the property to read
99 * @throws sdbusplus::exception::SdBusError if an error occurs in the dbus call
100 * @return property value
101 */
102template <typename T>
103T readDBusProperty(sdbusplus::bus_t& bus, const std::string& service,
104 const std::string& object, const std::string& intf,
105 const std::string& prop)
106{
107 T retVal{};
108 try
109 {
110 auto properties = bus.new_method_call(service.c_str(), object.c_str(),
111 "org.freedesktop.DBus.Properties",
112 "Get");
113 properties.append(intf);
114 properties.append(prop);
115 auto result = bus.call(properties);
116 result.read(retVal);
117 }
118 catch (const std::exception& ex)
119 {
120 lg2::error(
121 "Failed to get the property: {PROPERTY} interface: {INTERFACE} "
122 "object path: {OBJECT_PATH} error: {ERROR} ",
123 "PROPERTY", prop, "INTERFACE", intf, "OBJECT_PATH", object, "ERROR",
124 ex);
125 throw;
126 }
127 return retVal;
128}
129
130/**
131 * @brief Get the state value
132 *
133 * @param[in] intf - Interface to get the value
134 * @param[in] objPath - Object path of the service
135 * @param[in] state - State name to get
136 *
137 * @return The state value as type T on successful retrieval.
138 *
139 * @throws sdbusplus::exception for D-Bus failures and std::bad_variant_access
140 * for invalid value
141 */
142template <typename T>
143T getStateValue(const std::string& intf, const std::string& objPath,
144 const std::string& state)
145{
146 try
147 {
148 auto bus = sdbusplus::bus::new_default();
149 auto service = getService(bus, objPath, intf);
150 return std::get<T>(readDBusProperty<std::variant<T>>(
151 bus, service, objPath, intf, state));
152 }
153 catch (const sdbusplus::exception_t& e)
154 {
155 lg2::error(
156 "D-Bus call exception, OBJPATH: {OBJPATH}, "
157 "INTERFACE: {INTERFACE}, PROPERTY: {PROPERTY}, error: {ERROR}",
158 "OBJPATH", objPath, "INTERFACE", intf, "PROPERTY", state, "ERROR",
159 e);
160 throw;
161 }
162 catch (const std::bad_variant_access& e)
163 {
164 lg2::error("Exception raised while read state: {STATE} property "
165 "value, OBJPATH: {OBJPATH}, INTERFACE: {INTERFACE}, "
166 "error: {ERROR}",
167 "STATE", state, "OBJPATH", objPath, "INTERFACE", intf,
168 "ERROR", e);
169 throw;
170 }
171}
172
173/**
174 * @brief Get the host state
175 *
176 * @return HostState on success
177 *
178 * @throws std::runtime_error - If getting the state property fails
179 */
180inline HostState getHostState()
181{
182 constexpr auto hostStateInterface = "xyz.openbmc_project.State.Host";
183 // TODO Need to change host instance if multiple instead "0"
184 constexpr auto hostStateObjPath = "/xyz/openbmc_project/state/host0";
185 return getStateValue<HostState>(hostStateInterface, hostStateObjPath,
186 "CurrentHostState");
187}
188
189/**
Ramesh Iyyar22793862020-12-04 04:03:03 -0600190 * @brief Get the host boot progress stage
191 *
192 * @return BootProgress on success
Ramesh Iyyar22793862020-12-04 04:03:03 -0600193 *
Dhruvaraj Subhashchandran3a25e5b2022-03-22 08:06:20 -0500194 * @throws std::runtime_error - If getting the state property fails
Ramesh Iyyar22793862020-12-04 04:03:03 -0600195 */
Dhruvaraj Subhashchandran3a25e5b2022-03-22 08:06:20 -0500196inline BootProgress getBootProgress()
197{
198 constexpr auto bootProgressInterface =
199 "xyz.openbmc_project.State.Boot.Progress";
200 // TODO Need to change host instance if multiple instead "0"
201 constexpr auto hostStateObjPath = "/xyz/openbmc_project/state/host0";
202 return getStateValue<BootProgress>(bootProgressInterface, hostStateObjPath,
203 "BootProgress");
204}
Ramesh Iyyar22793862020-12-04 04:03:03 -0600205
Dhruvaraj Subhashchandran6a54d9a2020-12-17 22:24:37 -0600206/**
207 * @brief Check whether host is running
208 *
209 * @return true if the host running else false.
Dhruvaraj Subhashchandran3a25e5b2022-03-22 08:06:20 -0500210 *
211 * @throws std::runtime_error - If getting the boot progress failed
Dhruvaraj Subhashchandran6a54d9a2020-12-17 22:24:37 -0600212 */
Dhruvaraj Subhashchandran3a25e5b2022-03-22 08:06:20 -0500213inline bool isHostRunning()
214{
215 // TODO #ibm-openbmc/dev/2858 Revisit the method for finding whether host
216 // is running.
217 BootProgress bootProgressStatus = getBootProgress();
218 if ((bootProgressStatus == BootProgress::SystemInitComplete) ||
219 (bootProgressStatus == BootProgress::SystemSetup) ||
220 (bootProgressStatus == BootProgress::OSStart) ||
221 (bootProgressStatus == BootProgress::OSRunning) ||
222 (bootProgressStatus == BootProgress::PCIInit))
223 {
224 return true;
225 }
226 return false;
227}
Dhruvaraj Subhashchandran6a54d9a2020-12-17 22:24:37 -0600228
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500229inline void extractOriginatorProperties(phosphor::dump::DumpCreateParams params,
230 std::string& originatorId,
231 originatorTypes& originatorType)
232{
233 using InvalidArgument =
234 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
235 using Argument = xyz::openbmc_project::Common::InvalidArgument;
236 using CreateParametersXYZ =
237 sdbusplus::xyz::openbmc_project::Dump::server::Create::CreateParameters;
238
239 auto iter = params.find(
240 sdbusplus::xyz::openbmc_project::Dump::server::Create::
241 convertCreateParametersToString(CreateParametersXYZ::OriginatorId));
242 if (iter == params.end())
243 {
Dhruvaraj Subhashchandrand1f670f2023-06-05 22:19:25 -0500244 lg2::info("OriginatorId is not provided");
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500245 }
246 else
247 {
248 try
249 {
250 originatorId = std::get<std::string>(iter->second);
251 }
252 catch (const std::bad_variant_access& e)
253 {
254 // Exception will be raised if the input is not string
Dhruvaraj Subhashchandrand1f670f2023-06-05 22:19:25 -0500255 lg2::error("An invalid originatorId passed. It should be a string, "
256 "errormsg: {ERROR}",
257 "ERROR", e);
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500258 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ORIGINATOR_ID"),
259 Argument::ARGUMENT_VALUE("INVALID INPUT"));
260 }
261 }
262
263 iter = params.find(sdbusplus::xyz::openbmc_project::Dump::server::Create::
264 convertCreateParametersToString(
265 CreateParametersXYZ::OriginatorType));
266 if (iter == params.end())
267 {
Dhruvaraj Subhashchandrand1f670f2023-06-05 22:19:25 -0500268 lg2::info("OriginatorType is not provided. Replacing the string "
269 "with the default value");
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500270 originatorType = originatorTypes::Internal;
271 }
272 else
273 {
274 try
275 {
276 std::string type = std::get<std::string>(iter->second);
277 originatorType = sdbusplus::xyz::openbmc_project::Common::server::
278 OriginatedBy::convertOriginatorTypesFromString(type);
279 }
280 catch (const std::bad_variant_access& e)
281 {
282 // Exception will be raised if the input is not string
Dhruvaraj Subhashchandrand1f670f2023-06-05 22:19:25 -0500283 lg2::error("An invalid originatorType passed, errormsg: {ERROR}",
284 "ERROR", e);
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500285 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ORIGINATOR_TYPE"),
286 Argument::ARGUMENT_VALUE("INVALID INPUT"));
287 }
288 }
289}
290
Dhruvaraj Subhashchandran3a25e5b2022-03-22 08:06:20 -0500291/**
292 * @brief Check whether host is quiesced
293 *
294 * @return true if the host is quiesced else false.
295 *
296 * @throws std::runtime_error - If getting the state failed
297 */
298inline bool isHostQuiesced()
299{
300 return (getHostState() == HostState::Quiesced);
301}
302
Jayanth Othayotha320c7c2017-06-14 07:17:21 -0500303} // namespace dump
304} // namespace phosphor