blob: 2f93899ea1de6254ba74226521458d46025f67d5 [file] [log] [blame]
John Wedig2098dab2021-09-14 13:56:28 -07001
2#include "estoraged.hpp"
John Wedigd32b9662022-04-13 18:12:25 -07003#include "getConfig.hpp"
4#include "util.hpp"
John Wedig2098dab2021-09-14 13:56:28 -07005
John Wedigd32b9662022-04-13 18:12:25 -07006#include <boost/asio/deadline_timer.hpp>
John Wedig67a47442022-04-05 17:21:29 -07007#include <boost/asio/io_context.hpp>
John Wedigd32b9662022-04-13 18:12:25 -07008#include <boost/asio/post.hpp>
9#include <boost/container/flat_map.hpp>
10#include <boost/container/throw_exception.hpp>
John Edward Broadbent4e13b0a2021-11-15 15:21:59 -080011#include <phosphor-logging/lg2.hpp>
John Wedig67a47442022-04-05 17:21:29 -070012#include <sdbusplus/asio/connection.hpp>
13#include <sdbusplus/asio/object_server.hpp>
John Wedig2098dab2021-09-14 13:56:28 -070014#include <sdbusplus/bus.hpp>
John Wedigd32b9662022-04-13 18:12:25 -070015#include <sdbusplus/bus/match.hpp>
John Edward Broadbente35e7362022-03-22 16:14:24 -070016#include <util.hpp>
John Wedig2098dab2021-09-14 13:56:28 -070017
John Wedigd32b9662022-04-13 18:12:25 -070018#include <cstdlib>
John Wedig2098dab2021-09-14 13:56:28 -070019#include <filesystem>
20#include <iostream>
John Wedig67a47442022-04-05 17:21:29 -070021#include <memory>
John Wedig2098dab2021-09-14 13:56:28 -070022#include <string>
23
John Wedigd32b9662022-04-13 18:12:25 -070024/*
25 * Get the configuration objects from Entity Manager and create new D-Bus
26 * objects for each one. This function can be called multiple times, in case
27 * new configuration objects show up later.
28 *
29 * Note: Currently, eStoraged can only support 1 eMMC device.
30 * Additional changes will be needed to support more than 1 eMMC, or to support
31 * more types of storage devices.
32 */
33void createStorageObjects(
34 boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
35 boost::container::flat_map<
36 std::string, std::unique_ptr<estoraged::EStoraged>>& storageObjects,
37 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
John Wedig2098dab2021-09-14 13:56:28 -070038{
John Wedigd32b9662022-04-13 18:12:25 -070039 auto getter = std::make_shared<estoraged::GetStorageConfiguration>(
40 dbusConnection,
41 [&io, &objectServer, &storageObjects](
42 const estoraged::ManagedStorageType& storageConfigurations) {
43 size_t numConfigObj = storageConfigurations.size();
44 if (numConfigObj > 1)
45 {
46 lg2::error(
47 "eStoraged can only manage 1 eMMC device; found {NUM}",
48 "NUM", numConfigObj, "REDFISH_MESSAGE_ID",
49 std::string("OpenBMC.0.1.CreateStorageObjectsFail"));
50 return;
51 }
52
53 for (const std::pair<sdbusplus::message::object_path,
54 estoraged::StorageData>& storage :
55 storageConfigurations)
56 {
57 const std::string& path = storage.first.str;
58
59 if (storageObjects.find(path) != storageObjects.end())
60 {
61 /*
62 * We've already created this object, or at least
63 * attempted to.
64 */
65 continue;
66 }
67
68 /* Get the properties from the config object. */
69 const estoraged::StorageData& data = storage.second;
70
71 /* Look for the device file. */
72 const std::filesystem::path blockDevDir{"/sys/block"};
73 std::filesystem::path deviceFile, sysfsDir;
74 std::string luksName;
75 bool found = estoraged::util::findDevice(
76 data, blockDevDir, deviceFile, sysfsDir, luksName);
77 if (!found)
78 {
79 lg2::error(
80 "Device not found for path {PATH}", "PATH", path,
81 "REDFISH_MESSAGE_ID",
82 std::string("OpenBMC.0.1.CreateStorageObjectsFail"));
83 /*
84 * Set a NULL pointer as a placeholder, so that we don't
85 * try and fail again later.
86 */
87 storageObjects[path] = nullptr;
88 continue;
89 }
90
91 uint64_t size =
92 estoraged::util::findSizeOfBlockDevice(deviceFile);
93
94 uint8_t lifeleft =
95 estoraged::util::findPredictedMediaLifeLeftPercent(
96 sysfsDir);
John Wedigb4838302022-07-22 13:51:16 -070097 std::string partNumber =
98 estoraged::util::getPartNumber(sysfsDir);
99 std::string serialNumber =
100 estoraged::util::getSerialNumber(sysfsDir);
John Wedigd32b9662022-04-13 18:12:25 -0700101 /* Create the storage object. */
102 storageObjects[path] = std::make_unique<estoraged::EStoraged>(
John Wedigb4838302022-07-22 13:51:16 -0700103 objectServer, path, deviceFile, luksName, size, lifeleft,
104 partNumber, serialNumber);
John Wedigd32b9662022-04-13 18:12:25 -0700105 lg2::info("Created eStoraged object for path {PATH}", "PATH",
106 path, "REDFISH_MESSAGE_ID",
107 std::string("OpenBMC.0.1.CreateStorageObjects"));
108 }
109 });
110 getter->getConfiguration();
John Wedig2098dab2021-09-14 13:56:28 -0700111}
112
John Wedigd32b9662022-04-13 18:12:25 -0700113int main(void)
John Wedig2098dab2021-09-14 13:56:28 -0700114{
Ed Tanous82897c32022-02-21 14:11:59 -0800115 try
John Wedig2098dab2021-09-14 13:56:28 -0700116 {
John Wedig67a47442022-04-05 17:21:29 -0700117 // setup connection to dbus
118 boost::asio::io_context io;
119 auto conn = std::make_shared<sdbusplus::asio::connection>(io);
120 // request D-Bus server name.
John Wedigd32b9662022-04-13 18:12:25 -0700121 conn->request_name("xyz.openbmc_project.eStoraged");
122 sdbusplus::asio::object_server server(conn);
123 boost::container::flat_map<std::string,
124 std::unique_ptr<estoraged::EStoraged>>
125 storageObjects;
Ed Tanous82897c32022-02-21 14:11:59 -0800126
John Wedigd32b9662022-04-13 18:12:25 -0700127 boost::asio::post(io, [&]() {
128 createStorageObjects(io, server, storageObjects, conn);
129 });
130
131 /*
132 * Set up an event handler to process any new configuration objects
133 * that show up later.
134 */
135 boost::asio::deadline_timer filterTimer(io);
Patrick Williamse3ef7652022-07-22 19:26:57 -0500136 std::function<void(sdbusplus::message_t&)> eventHandler =
137 [&](sdbusplus::message_t& message) {
John Wedigd32b9662022-04-13 18:12:25 -0700138 if (message.is_method_error())
139 {
140 lg2::error("eventHandler callback method error");
141 return;
142 }
143 /*
144 * This implicitly cancels the timer, if it's already pending.
145 * If there's a burst of events within a short period, we want
146 * to handle them all at once. So, we will wait this long for no
147 * more events to occur, before processing them.
148 */
149 filterTimer.expires_from_now(boost::posix_time::seconds(1));
150
151 filterTimer.async_wait(
152 [&](const boost::system::error_code& ec) {
153 if (ec == boost::asio::error::operation_aborted)
154 {
155 /* we were canceled */
156 return;
157 }
158 if (ec)
159 {
160 lg2::error("timer error");
161 return;
162 }
163 createStorageObjects(io, server, storageObjects, conn);
164 });
165 };
166
Patrick Williamse3ef7652022-07-22 19:26:57 -0500167 auto match = std::make_unique<sdbusplus::bus::match_t>(
168 static_cast<sdbusplus::bus_t&>(*conn),
John Wedigd32b9662022-04-13 18:12:25 -0700169 "type='signal',member='PropertiesChanged',path_namespace='" +
170 std::string("/xyz/openbmc_project/inventory") +
171 "',arg0namespace='" + estoraged::emmcConfigInterface + "'",
172 eventHandler);
173
Ed Tanous82897c32022-02-21 14:11:59 -0800174 lg2::info("Storage management service is running", "REDFISH_MESSAGE_ID",
175 std::string("OpenBMC.1.0.ServiceStarted"));
176
John Wedig67a47442022-04-05 17:21:29 -0700177 io.run();
178 return 0;
John Wedig2098dab2021-09-14 13:56:28 -0700179 }
Ed Tanous82897c32022-02-21 14:11:59 -0800180 catch (const std::exception& e)
John Wedig2098dab2021-09-14 13:56:28 -0700181 {
Ed Tanous82897c32022-02-21 14:11:59 -0800182 lg2::error(e.what(), "REDFISH_MESSAGE_ID",
183 std::string("OpenBMC.1.0.ServiceException"));
John Wedig2098dab2021-09-14 13:56:28 -0700184
Ed Tanous82897c32022-02-21 14:11:59 -0800185 return 2;
186 }
John Wedig2098dab2021-09-14 13:56:28 -0700187 return 1;
188}