blob: cb37791e0cb89bc9eefa29a78eb292dfa7b6a713 [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>
Tom Tung043af592023-11-24 13:37:05 +080022#include <optional>
John Wedig2098dab2021-09-14 13:56:28 -070023#include <string>
24
John Wedigd32b9662022-04-13 18:12:25 -070025/*
26 * Get the configuration objects from Entity Manager and create new D-Bus
27 * objects for each one. This function can be called multiple times, in case
28 * new configuration objects show up later.
29 *
30 * Note: Currently, eStoraged can only support 1 eMMC device.
31 * Additional changes will be needed to support more than 1 eMMC, or to support
32 * more types of storage devices.
33 */
34void createStorageObjects(
John Wedig61cf4262023-03-17 14:32:04 -070035 sdbusplus::asio::object_server& objectServer,
John Wedigd32b9662022-04-13 18:12:25 -070036 boost::container::flat_map<
37 std::string, std::unique_ptr<estoraged::EStoraged>>& storageObjects,
38 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
John Wedig2098dab2021-09-14 13:56:28 -070039{
John Wedigd32b9662022-04-13 18:12:25 -070040 auto getter = std::make_shared<estoraged::GetStorageConfiguration>(
41 dbusConnection,
John Wedig61cf4262023-03-17 14:32:04 -070042 [&objectServer, &storageObjects](
John Wedigd32b9662022-04-13 18:12:25 -070043 const estoraged::ManagedStorageType& storageConfigurations) {
Patrick Williams04c28fa2023-05-10 07:51:24 -050044 size_t numConfigObj = storageConfigurations.size();
45 if (numConfigObj > 1)
46 {
47 lg2::error("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())
John Wedigd32b9662022-04-13 18:12:25 -070060 {
Patrick Williams04c28fa2023-05-10 07:51:24 -050061 /*
62 * We've already created this object, or at least
63 * attempted to.
64 */
65 continue;
John Wedigd32b9662022-04-13 18:12:25 -070066 }
67
Patrick Williams04c28fa2023-05-10 07:51:24 -050068 /* 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"};
Tom Tung043af592023-11-24 13:37:05 +080073 auto deviceInfo = estoraged::util::findDevice(data, blockDevDir);
74 if (!deviceInfo)
John Wedigd32b9662022-04-13 18:12:25 -070075 {
Patrick Williams04c28fa2023-05-10 07:51:24 -050076 lg2::error("Device not found for path {PATH}", "PATH", path,
77 "REDFISH_MESSAGE_ID",
78 std::string("OpenBMC.0.1.CreateStorageObjectsFail"));
79 /*
80 * Set a NULL pointer as a placeholder, so that we don't
81 * try and fail again later.
82 */
83 storageObjects[path] = nullptr;
84 continue;
John Wedigd32b9662022-04-13 18:12:25 -070085 }
Patrick Williams04c28fa2023-05-10 07:51:24 -050086
Tom Tung043af592023-11-24 13:37:05 +080087 std::filesystem::path deviceFile =
88 std::move(deviceInfo->deviceFile);
89 std::filesystem::path sysfsDir = std::move(deviceInfo->sysfsDir);
90 std::string luksName = std::move(deviceInfo->luksName);
91 std::string locationCode = std::move(deviceInfo->locationCode);
92 uint64_t eraseMaxGeometry = deviceInfo->eraseMaxGeometry;
93 uint64_t eraseMinGeometry = deviceInfo->eraseMinGeometry;
94
Patrick Williams04c28fa2023-05-10 07:51:24 -050095 uint64_t size = estoraged::util::findSizeOfBlockDevice(deviceFile);
96
97 uint8_t lifeleft =
98 estoraged::util::findPredictedMediaLifeLeftPercent(sysfsDir);
99 std::string partNumber = estoraged::util::getPartNumber(sysfsDir);
100 std::string serialNumber =
101 estoraged::util::getSerialNumber(sysfsDir);
John Wedigd7be42b2024-01-19 16:07:19 -0800102 std::string driveType = deviceInfo->driveType;
Patrick Williams04c28fa2023-05-10 07:51:24 -0500103 /* Create the storage object. */
104 storageObjects[path] = std::make_unique<estoraged::EStoraged>(
105 objectServer, path, deviceFile, luksName, size, lifeleft,
Tom Tung043af592023-11-24 13:37:05 +0800106 partNumber, serialNumber, locationCode, eraseMaxGeometry,
John Wedigd7be42b2024-01-19 16:07:19 -0800107 eraseMinGeometry, driveType);
Patrick Williams04c28fa2023-05-10 07:51:24 -0500108 lg2::info("Created eStoraged object for path {PATH}", "PATH", path,
109 "REDFISH_MESSAGE_ID",
110 std::string("OpenBMC.0.1.CreateStorageObjects"));
111 }
Patrick Williamsff1b64f2023-10-20 11:19:56 -0500112 });
John Wedigd32b9662022-04-13 18:12:25 -0700113 getter->getConfiguration();
John Wedig2098dab2021-09-14 13:56:28 -0700114}
115
John Wedigd32b9662022-04-13 18:12:25 -0700116int main(void)
John Wedig2098dab2021-09-14 13:56:28 -0700117{
Ed Tanous82897c32022-02-21 14:11:59 -0800118 try
John Wedig2098dab2021-09-14 13:56:28 -0700119 {
John Wedig67a47442022-04-05 17:21:29 -0700120 // setup connection to dbus
121 boost::asio::io_context io;
122 auto conn = std::make_shared<sdbusplus::asio::connection>(io);
123 // request D-Bus server name.
John Wedigd32b9662022-04-13 18:12:25 -0700124 conn->request_name("xyz.openbmc_project.eStoraged");
125 sdbusplus::asio::object_server server(conn);
126 boost::container::flat_map<std::string,
127 std::unique_ptr<estoraged::EStoraged>>
128 storageObjects;
Ed Tanous82897c32022-02-21 14:11:59 -0800129
John Wedig61cf4262023-03-17 14:32:04 -0700130 boost::asio::post(
131 io, [&]() { createStorageObjects(server, storageObjects, conn); });
John Wedigd32b9662022-04-13 18:12:25 -0700132
133 /*
134 * Set up an event handler to process any new configuration objects
135 * that show up later.
136 */
137 boost::asio::deadline_timer filterTimer(io);
Patrick Williamse3ef7652022-07-22 19:26:57 -0500138 std::function<void(sdbusplus::message_t&)> eventHandler =
139 [&](sdbusplus::message_t& message) {
Patrick Williams04c28fa2023-05-10 07:51:24 -0500140 if (message.is_method_error())
141 {
142 lg2::error("eventHandler callback method error");
143 return;
144 }
145 /*
146 * This implicitly cancels the timer, if it's already pending.
147 * If there's a burst of events within a short period, we want
148 * to handle them all at once. So, we will wait this long for no
149 * more events to occur, before processing them.
150 */
151 filterTimer.expires_from_now(boost::posix_time::seconds(1));
152
153 filterTimer.async_wait([&](const boost::system::error_code& ec) {
154 if (ec == boost::asio::error::operation_aborted)
John Wedigd32b9662022-04-13 18:12:25 -0700155 {
Patrick Williams04c28fa2023-05-10 07:51:24 -0500156 /* we were canceled */
John Wedigd32b9662022-04-13 18:12:25 -0700157 return;
158 }
Patrick Williams04c28fa2023-05-10 07:51:24 -0500159 if (ec)
160 {
161 lg2::error("timer error");
162 return;
163 }
164 createStorageObjects(server, storageObjects, conn);
165 });
166 };
John Wedigd32b9662022-04-13 18:12:25 -0700167
Patrick Williamse3ef7652022-07-22 19:26:57 -0500168 auto match = std::make_unique<sdbusplus::bus::match_t>(
169 static_cast<sdbusplus::bus_t&>(*conn),
John Wedigd32b9662022-04-13 18:12:25 -0700170 "type='signal',member='PropertiesChanged',path_namespace='" +
171 std::string("/xyz/openbmc_project/inventory") +
172 "',arg0namespace='" + estoraged::emmcConfigInterface + "'",
173 eventHandler);
174
Ed Tanous82897c32022-02-21 14:11:59 -0800175 lg2::info("Storage management service is running", "REDFISH_MESSAGE_ID",
176 std::string("OpenBMC.1.0.ServiceStarted"));
177
John Wedig67a47442022-04-05 17:21:29 -0700178 io.run();
179 return 0;
John Wedig2098dab2021-09-14 13:56:28 -0700180 }
Ed Tanous82897c32022-02-21 14:11:59 -0800181 catch (const std::exception& e)
John Wedig2098dab2021-09-14 13:56:28 -0700182 {
Ed Tanous82897c32022-02-21 14:11:59 -0800183 lg2::error(e.what(), "REDFISH_MESSAGE_ID",
184 std::string("OpenBMC.1.0.ServiceException"));
John Wedig2098dab2021-09-14 13:56:28 -0700185
Ed Tanous82897c32022-02-21 14:11:59 -0800186 return 2;
187 }
John Wedig2098dab2021-09-14 13:56:28 -0700188 return 1;
189}