blob: 4c8b4162d893db3aed5aa4136d0e5406f3474665 [file] [log] [blame]
SunnySrivastava1984b59fd092020-02-03 09:58:56 -06001#include "config.h"
2
3#include "manager.hpp"
4
Santosh Puranikbf78ed82022-04-20 13:17:04 +05305#include "common_utility.hpp"
SunnySrivastava1984d076da82020-03-05 05:33:35 -06006#include "editor_impl.hpp"
Sunny Srivastava6c71c9d2021-04-15 04:43:54 -05007#include "ibm_vpd_utils.hpp"
SunnySrivastava1984e12b1812020-05-26 02:23:11 -05008#include "ipz_parser.hpp"
Santosh Puranik6b2b5372022-06-02 20:49:02 +05309#include "parser_factory.hpp"
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050010#include "reader_impl.hpp"
SunnySrivastava19849a195542020-09-07 06:04:50 -050011#include "vpd_exceptions.hpp"
12
Santosh Puranikd40e42d2022-03-23 13:58:06 +053013#include <filesystem>
SunnySrivastava19849a195542020-09-07 06:04:50 -050014#include <phosphor-logging/elog-errors.hpp>
Sunny Srivastava28abd6e2021-07-28 02:58:28 -050015#include <xyz/openbmc_project/Common/error.hpp>
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060016
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060017using namespace openpower::vpd::constants;
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050018using namespace openpower::vpd::inventory;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060019using namespace openpower::vpd::manager::editor;
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050020using namespace openpower::vpd::manager::reader;
SunnySrivastava19849a195542020-09-07 06:04:50 -050021using namespace std;
22using namespace openpower::vpd::parser;
Santosh Puranik6b2b5372022-06-02 20:49:02 +053023using namespace openpower::vpd::parser::factory;
24using namespace openpower::vpd::ipz::parser;
SunnySrivastava19849a195542020-09-07 06:04:50 -050025using namespace openpower::vpd::exceptions;
26using namespace phosphor::logging;
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060027
28namespace openpower
29{
30namespace vpd
31{
32namespace manager
33{
Sunny Srivastava523af2e2022-02-14 07:30:10 -060034Manager::Manager(std::shared_ptr<boost::asio::io_context>& ioCon,
35 std::shared_ptr<sdbusplus::asio::dbus_interface>& iFace,
36 std::shared_ptr<sdbusplus::asio::connection>& conn) :
37 ioContext(ioCon),
38 interface(iFace), conn(conn)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060039{
Sunny Srivastava523af2e2022-02-14 07:30:10 -060040 interface->register_method(
41 "WriteKeyword",
42 [this](const sdbusplus::message::object_path& path,
43 const std::string& recordName, const std::string& keyword,
44 const Binary& value) {
45 this->writeKeyword(path, recordName, keyword, value);
46 });
47
48 interface->register_method(
49 "GetFRUsByUnexpandedLocationCode",
50 [this](const std::string& locationCode,
51 const uint16_t nodeNumber) -> inventory::ListOfPaths {
52 return this->getFRUsByUnexpandedLocationCode(locationCode,
53 nodeNumber);
54 });
55
56 interface->register_method(
57 "GetFRUsByExpandedLocationCode",
58 [this](const std::string& locationCode) -> inventory::ListOfPaths {
59 return this->getFRUsByExpandedLocationCode(locationCode);
60 });
61
62 interface->register_method(
63 "GetExpandedLocationCode",
64 [this](const std::string& locationCode,
65 const uint16_t nodeNumber) -> std::string {
66 return this->getExpandedLocationCode(locationCode, nodeNumber);
67 });
68
69 interface->register_method("PerformVPDRecollection",
70 [this]() { this->performVPDRecollection(); });
71
Sunny Srivastava28abd6e2021-07-28 02:58:28 -050072 interface->register_method(
73 "deleteFRUVPD", [this](const sdbusplus::message::object_path& path) {
74 this->deleteFRUVPD(path);
75 });
76
Sunny Srivastavafdf9ff22022-06-15 11:15:54 -050077 sd_bus_default(&sdBus);
Sunny Srivastava523af2e2022-02-14 07:30:10 -060078 initManager();
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060079}
80
Sunny Srivastava523af2e2022-02-14 07:30:10 -060081void Manager::initManager()
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060082{
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060083 try
84 {
85 processJSON();
Santosh Puranik6b2b5372022-06-02 20:49:02 +053086 restoreSystemVpd();
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -050087 listenHostState();
Santosh Puranikb62f6052022-04-06 18:37:54 +053088 listenAssetTag();
Alpana Kumarib17dd3b2020-10-01 00:18:10 -050089
Santosh Puranikf2d3b532022-04-19 06:44:07 -050090 // Create an instance of the BIOS handler
Sunny Srivastava523af2e2022-02-14 07:30:10 -060091 biosHandler = std::make_shared<BiosHandler>(conn, *this);
Santosh Puranikf2d3b532022-04-19 06:44:07 -050092
Sunny Srivastava523af2e2022-02-14 07:30:10 -060093 // instantiate gpioMonitor class
94 gpioMon = std::make_shared<GpioMonitor>(jsonFile, ioContext);
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060095 }
96 catch (const std::exception& e)
97 {
98 std::cerr << e.what() << "\n";
99 }
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -0600100}
101
Santosh Puranik6b2b5372022-06-02 20:49:02 +0530102/**
103 * @brief An api to get list of blank system VPD properties.
104 * @param[in] vpdMap - IPZ vpd map.
105 * @param[in] objectPath - Object path for the FRU.
106 * @param[out] blankPropertyList - Properties which are blank in System VPD and
107 * needs to be updated as standby.
108 */
109static void
110 getListOfBlankSystemVpd(Parsed& vpdMap, const string& objectPath,
111 std::vector<RestoredEeproms>& blankPropertyList)
112{
113 for (const auto& systemRecKwdPair : svpdKwdMap)
114 {
115 auto it = vpdMap.find(systemRecKwdPair.first);
116
117 // check if record is found in map we got by parser
118 if (it != vpdMap.end())
119 {
120 const auto& kwdListForRecord = systemRecKwdPair.second;
121 for (const auto& keyword : kwdListForRecord)
122 {
123 DbusPropertyMap& kwdValMap = it->second;
124 auto iterator = kwdValMap.find(keyword);
125
126 if (iterator != kwdValMap.end())
127 {
128 string& kwdValue = iterator->second;
129
130 // check bus data
131 const string& recordName = systemRecKwdPair.first;
132 const string& busValue = readBusProperty(
133 objectPath, ipzVpdInf + recordName, keyword);
134
135 if (busValue.find_first_not_of(' ') != string::npos)
136 {
137 if (kwdValue.find_first_not_of(' ') == string::npos)
138 {
139 // implies data is blank on EEPROM but not on cache.
140 // So EEPROM vpd update is required.
141 Binary busData(busValue.begin(), busValue.end());
142
143 blankPropertyList.push_back(std::make_tuple(
144 objectPath, recordName, keyword, busData));
145 }
146 }
147 }
148 }
149 }
150 }
151}
152
153void Manager::restoreSystemVpd()
154{
155 std::cout << "Attempting system VPD restore" << std::endl;
156 ParserInterface* parser = nullptr;
157 try
158 {
159 auto vpdVector = getVpdDataInVector(jsonFile, systemVpdFilePath);
Sunny Srivastavaf31a91b2022-06-09 08:11:29 -0500160 const auto& inventoryPath =
161 jsonFile["frus"][systemVpdFilePath][0]["inventoryPath"]
162 .get_ref<const nlohmann::json::string_t&>();
163
164 parser = ParserFactory::getParser(vpdVector, (pimPath + inventoryPath));
Santosh Puranik6b2b5372022-06-02 20:49:02 +0530165 auto parseResult = parser->parse();
166
167 if (auto pVal = std::get_if<Store>(&parseResult))
168 {
169 // map to hold all the keywords whose value is blank and
170 // needs to be updated at standby.
171 std::vector<RestoredEeproms> blankSystemVpdProperties{};
172 getListOfBlankSystemVpd(pVal->getVpdMap(), SYSTEM_OBJECT,
173 blankSystemVpdProperties);
174
175 // if system VPD restore is required, update the
176 // EEPROM
177 for (const auto& item : blankSystemVpdProperties)
178 {
179 std::cout << "Restoring keyword: " << std::get<2>(item)
180 << std::endl;
181 writeKeyword(std::get<0>(item), std::get<1>(item),
182 std::get<2>(item), std::get<3>(item));
183 }
184 }
185 else
186 {
187 std::cerr << "Not a valid format to restore system VPD"
188 << std::endl;
189 }
190 }
191 catch (const std::exception& e)
192 {
193 std::cerr << "Failed to restore system VPD due to exception: "
194 << e.what() << std::endl;
195 }
196 // release the parser object
197 ParserFactory::freeParser(parser);
198}
199
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500200void Manager::listenHostState()
201{
Patrick Williams2eb01762022-07-22 19:26:56 -0500202 static std::shared_ptr<sdbusplus::bus::match_t> hostState =
203 std::make_shared<sdbusplus::bus::match_t>(
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600204 *conn,
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500205 sdbusplus::bus::match::rules::propertiesChanged(
206 "/xyz/openbmc_project/state/host0",
207 "xyz.openbmc_project.State.Host"),
Patrick Williams2eb01762022-07-22 19:26:56 -0500208 [this](sdbusplus::message_t& msg) { hostStateCallBack(msg); });
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500209}
210
Sunny Srivastavafdf9ff22022-06-15 11:15:54 -0500211void Manager::checkEssentialFrus()
212{
213 for (const auto& invPath : essentialFrus)
214 {
215 const auto res = readBusProperty(invPath, invItemIntf, "Present");
216
217 // implies the essential FRU is missing. Log PEL.
218 if (res == "false")
219 {
220 auto rc = sd_bus_call_method_async(
221 sdBus, NULL, loggerService, loggerObjectPath,
222 loggerCreateInterface, "Create", NULL, NULL, "ssa{ss}",
223 errIntfForEssentialFru,
224 "xyz.openbmc_project.Logging.Entry.Level.Warning", 2,
225 "DESCRIPTION", "Essential fru missing from the system.",
226 "CALLOUT_INVENTORY_PATH", (pimPath + invPath).c_str());
227
228 if (rc < 0)
229 {
230 log<level::ERR>("Error calling sd_bus_call_method_async",
231 entry("RC=%d", rc),
232 entry("MSG=%s", strerror(-rc)));
233 }
234 }
235 }
236}
237
Patrick Williams7a975f02022-12-07 03:19:53 -0600238void Manager::hostStateCallBack(sdbusplus::message_t& msg)
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500239{
240 if (msg.is_method_error())
241 {
242 std::cerr << "Error in reading signal " << std::endl;
243 }
244
245 Path object;
246 PropertyMap propMap;
247 msg.read(object, propMap);
248 const auto itr = propMap.find("CurrentHostState");
249 if (itr != propMap.end())
250 {
251 if (auto hostState = std::get_if<std::string>(&(itr->second)))
252 {
253 // implies system is moving from standby to power on state
254 if (*hostState == "xyz.openbmc_project.State.Host.HostState."
255 "TransitioningToRunning")
256 {
Sunny Srivastavafdf9ff22022-06-15 11:15:54 -0500257 // detect if essential frus are present in the system.
258 checkEssentialFrus();
259
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500260 // check and perfrom recollection for FRUs replaceable at
261 // standby.
262 performVPDRecollection();
263 return;
264 }
265 }
266 std::cerr << "Failed to read Host state" << std::endl;
267 }
268}
269
Santosh Puranikb62f6052022-04-06 18:37:54 +0530270void Manager::listenAssetTag()
271{
Patrick Williams2eb01762022-07-22 19:26:56 -0500272 static std::shared_ptr<sdbusplus::bus::match_t> assetMatcher =
273 std::make_shared<sdbusplus::bus::match_t>(
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600274 *conn,
Santosh Puranikb62f6052022-04-06 18:37:54 +0530275 sdbusplus::bus::match::rules::propertiesChanged(
276 "/xyz/openbmc_project/inventory/system",
277 "xyz.openbmc_project.Inventory.Decorator.AssetTag"),
Patrick Williams2eb01762022-07-22 19:26:56 -0500278 [this](sdbusplus::message_t& msg) { assetTagCallback(msg); });
Santosh Puranikb62f6052022-04-06 18:37:54 +0530279}
280
Patrick Williams2eb01762022-07-22 19:26:56 -0500281void Manager::assetTagCallback(sdbusplus::message_t& msg)
Santosh Puranikb62f6052022-04-06 18:37:54 +0530282{
283 if (msg.is_method_error())
284 {
285 std::cerr << "Error in reading signal " << std::endl;
286 }
287
288 Path object;
289 PropertyMap propMap;
290 msg.read(object, propMap);
291 const auto itr = propMap.find("AssetTag");
292 if (itr != propMap.end())
293 {
294 if (auto assetTag = std::get_if<std::string>(&(itr->second)))
295 {
296 // Call Notify to persist the AssetTag
297 inventory::ObjectMap objectMap = {
298 {std::string{"/system"},
299 {{"xyz.openbmc_project.Inventory.Decorator.AssetTag",
300 {{"AssetTag", *assetTag}}}}}};
301
302 common::utility::callPIM(std::move(objectMap));
303 }
304 else
305 {
306 std::cerr << "Failed to read asset tag" << std::endl;
307 }
308 }
309}
310
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -0600311void Manager::processJSON()
312{
Santosh Puranik0246a4d2020-11-04 16:57:39 +0530313 std::ifstream json(INVENTORY_JSON_SYM_LINK, std::ios::binary);
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -0600314
315 if (!json)
316 {
317 throw std::runtime_error("json file not found");
318 }
319
320 jsonFile = nlohmann::json::parse(json);
321 if (jsonFile.find("frus") == jsonFile.end())
322 {
323 throw std::runtime_error("frus group not found in json");
324 }
325
326 const nlohmann::json& groupFRUS =
327 jsonFile["frus"].get_ref<const nlohmann::json::object_t&>();
328 for (const auto& itemFRUS : groupFRUS.items())
329 {
330 const std::vector<nlohmann::json>& groupEEPROM =
331 itemFRUS.value().get_ref<const nlohmann::json::array_t&>();
332 for (const auto& itemEEPROM : groupEEPROM)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600333 {
SunnySrivastava198443306542020-04-01 02:50:20 -0500334 bool isMotherboard = false;
Santosh Puranika0b23912022-02-10 13:37:09 +0530335 std::string redundantPath;
336
SunnySrivastava198443306542020-04-01 02:50:20 -0500337 if (itemEEPROM["extraInterfaces"].find(
338 "xyz.openbmc_project.Inventory.Item.Board.Motherboard") !=
339 itemEEPROM["extraInterfaces"].end())
340 {
341 isMotherboard = true;
342 }
Santosh Puranika0b23912022-02-10 13:37:09 +0530343 if (itemEEPROM.find("redundantEeprom") != itemEEPROM.end())
344 {
345 redundantPath = itemEEPROM["redundantEeprom"]
346 .get_ref<const nlohmann::json::string_t&>();
347 }
348 frus.emplace(
349 itemEEPROM["inventoryPath"]
350 .get_ref<const nlohmann::json::string_t&>(),
351 std::make_tuple(itemFRUS.key(), redundantPath, isMotherboard));
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -0500352
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000353 if (itemEEPROM["extraInterfaces"].find(IBM_LOCATION_CODE_INF) !=
Alpana Kumari920408d2020-05-14 00:07:03 -0500354 itemEEPROM["extraInterfaces"].end())
355 {
356 fruLocationCode.emplace(
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000357 itemEEPROM["extraInterfaces"][IBM_LOCATION_CODE_INF]
Alpana Kumari920408d2020-05-14 00:07:03 -0500358 ["LocationCode"]
359 .get_ref<const nlohmann::json::string_t&>(),
360 itemEEPROM["inventoryPath"]
361 .get_ref<const nlohmann::json::string_t&>());
362 }
SunnySrivastava19849a195542020-09-07 06:04:50 -0500363
Sunny Srivastavaecb5c7d2021-09-02 07:20:24 -0500364 if (itemEEPROM.value("replaceableAtStandby", false))
SunnySrivastava19849a195542020-09-07 06:04:50 -0500365 {
366 replaceableFrus.emplace_back(itemFRUS.key());
367 }
Sunny Srivastavafdf9ff22022-06-15 11:15:54 -0500368
369 if (itemEEPROM.value("essentialFru", false))
370 {
371 essentialFrus.emplace_back(itemEEPROM["inventoryPath"]);
372 }
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600373 }
374 }
375}
376
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600377void Manager::writeKeyword(const sdbusplus::message::object_path& path,
378 const std::string& recordName,
379 const std::string& keyword, const Binary& value)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600380{
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600381 try
382 {
Santosh Puranik8c796812021-12-01 19:17:56 +0530383 std::string objPath{path};
384 // Strip any inventory prefix in path
385 if (objPath.find(INVENTORY_PATH) == 0)
386 {
387 objPath = objPath.substr(sizeof(INVENTORY_PATH) - 1);
388 }
389
390 if (frus.find(objPath) == frus.end())
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600391 {
392 throw std::runtime_error("Inventory path not found");
393 }
394
Santosh Puranika0b23912022-02-10 13:37:09 +0530395 inventory::Path vpdFilePath = std::get<0>(frus.find(objPath)->second);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600396
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500397 // instantiate editor class to update the data
Santosh Puranik8c796812021-12-01 19:17:56 +0530398 EditorImpl edit(vpdFilePath, jsonFile, recordName, keyword, objPath);
Santosh Puranika0b23912022-02-10 13:37:09 +0530399
400 uint32_t offset = 0;
401 // Setup offset, if any
402 for (const auto& item : jsonFile["frus"][vpdFilePath])
403 {
404 if (item.find("offset") != item.end())
405 {
406 offset = item["offset"];
407 break;
408 }
409 }
410
411 edit.updateKeyword(value, offset, true);
412
413 // If we have a redundant EEPROM to update, then update just the EEPROM,
414 // not the cache since that is already done when we updated the primary
415 if (!std::get<1>(frus.find(objPath)->second).empty())
416 {
417 EditorImpl edit(std::get<1>(frus.find(objPath)->second), jsonFile,
Sunny Srivastavaf31a91b2022-06-09 08:11:29 -0500418 recordName, keyword, objPath);
Santosh Puranika0b23912022-02-10 13:37:09 +0530419 edit.updateKeyword(value, offset, false);
420 }
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600421
SunnySrivastava198443306542020-04-01 02:50:20 -0500422 // if it is a motehrboard FRU need to check for location expansion
Santosh Puranika0b23912022-02-10 13:37:09 +0530423 if (std::get<2>(frus.find(objPath)->second))
SunnySrivastava198443306542020-04-01 02:50:20 -0500424 {
425 if (recordName == "VCEN" && (keyword == "FC" || keyword == "SE"))
426 {
427 edit.expandLocationCode("fcs");
428 }
429 else if (recordName == "VSYS" &&
430 (keyword == "TM" || keyword == "SE"))
431 {
432 edit.expandLocationCode("mts");
433 }
434 }
435
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500436 return;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600437 }
438 catch (const std::exception& e)
439 {
440 std::cerr << e.what() << std::endl;
441 }
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600442}
443
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500444ListOfPaths
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600445 Manager::getFRUsByUnexpandedLocationCode(const LocationCode& locationCode,
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500446 const NodeNumber nodeNumber)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600447{
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500448 ReaderImpl read;
449 return read.getFrusAtLocation(locationCode, nodeNumber, fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600450}
451
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500452ListOfPaths
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600453 Manager::getFRUsByExpandedLocationCode(const LocationCode& locationCode)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600454{
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500455 ReaderImpl read;
456 return read.getFRUsByExpandedLocationCode(locationCode, fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600457}
458
Sunny Srivastava523af2e2022-02-14 07:30:10 -0600459LocationCode Manager::getExpandedLocationCode(const LocationCode& locationCode,
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500460 const NodeNumber nodeNumber)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600461{
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -0500462 ReaderImpl read;
463 return read.getExpandedLocationCode(locationCode, nodeNumber,
464 fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600465}
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -0600466
SunnySrivastava19849a195542020-09-07 06:04:50 -0500467void Manager::performVPDRecollection()
468{
469 // get list of FRUs replaceable at standby
470 for (const auto& item : replaceableFrus)
471 {
472 const vector<nlohmann::json>& groupEEPROM = jsonFile["frus"][item];
473 const nlohmann::json& singleFru = groupEEPROM[0];
474
475 const string& inventoryPath =
476 singleFru["inventoryPath"]
477 .get_ref<const nlohmann::json::string_t&>();
478
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530479 bool prePostActionRequired = false;
480
481 if ((jsonFile["frus"][item].at(0)).find("preAction") !=
482 jsonFile["frus"][item].at(0).end())
483 {
Sunny Srivastavaa2ddc962022-06-29 08:53:16 -0500484 try
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530485 {
Sunny Srivastavaa2ddc962022-06-29 08:53:16 -0500486 if (!executePreAction(jsonFile, item))
487 {
488 // if the FRU has preAction defined then its execution
489 // should pass to ensure bind/unbind of data.
490 // preAction execution failed. should not call
491 // bind/unbind.
492 log<level::ERR>(
493 "Pre-Action execution failed for the FRU",
494 entry("ERROR=%s",
495 ("Inventory path: " + inventoryPath).c_str()));
496 continue;
497 }
498 }
499 catch (const GpioException& e)
500 {
501 log<level::ERR>(e.what());
502 PelAdditionalData additionalData{};
503 additionalData.emplace("DESCRIPTION", e.what());
504 createPEL(additionalData, PelSeverity::WARNING,
505 errIntfForGpioError, sdBus);
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530506 continue;
507 }
508 prePostActionRequired = true;
509 }
510
SunnySrivastava19849a195542020-09-07 06:04:50 -0500511 if ((singleFru.find("devAddress") == singleFru.end()) ||
512 (singleFru.find("driverType") == singleFru.end()) ||
513 (singleFru.find("busType") == singleFru.end()))
514 {
515 // The FRUs is marked for replacement but missing mandatory
516 // fields for recollection. Skip to another replaceable fru.
517 log<level::ERR>(
518 "Recollection Failed as mandatory field missing in Json",
519 entry("ERROR=%s",
520 ("Recollection failed for " + inventoryPath).c_str()));
521 continue;
522 }
523
524 string str = "echo ";
525 string deviceAddress = singleFru["devAddress"];
526 const string& driverType = singleFru["driverType"];
527 const string& busType = singleFru["busType"];
528
529 // devTreeStatus flag is present in json as false to mention
530 // that the EEPROM is not mentioned in device tree. If this flag
531 // is absent consider the value to be true, i.e EEPROM is
532 // mentioned in device tree
533 if (!singleFru.value("devTreeStatus", true))
534 {
535 auto pos = deviceAddress.find('-');
536 if (pos != string::npos)
537 {
538 string busNum = deviceAddress.substr(0, pos);
539 deviceAddress =
540 "0x" + deviceAddress.substr(pos + 1, string::npos);
541
542 string deleteDevice = str + deviceAddress + " > /sys/bus/" +
543 busType + "/devices/" + busType + "-" +
544 busNum + "/delete_device";
545 executeCmd(deleteDevice);
546
547 string addDevice = str + driverType + " " + deviceAddress +
548 " > /sys/bus/" + busType + "/devices/" +
549 busType + "-" + busNum + "/new_device";
550 executeCmd(addDevice);
551 }
552 else
553 {
554 log<level::ERR>(
555 "Wrong format of device address in Json",
556 entry(
557 "ERROR=%s",
558 ("Recollection failed for " + inventoryPath).c_str()));
559 continue;
560 }
561 }
562 else
563 {
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500564 executeCmd(createBindUnbindDriverCmnd(deviceAddress, busType,
565 driverType, "/unbind"));
566 executeCmd(createBindUnbindDriverCmnd(deviceAddress, busType,
567 driverType, "/bind"));
SunnySrivastava19849a195542020-09-07 06:04:50 -0500568 }
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530569
570 // this check is added to avoid file system expensive call in case not
571 // required.
572 if (prePostActionRequired)
573 {
574 // Check if device showed up (test for file)
575 if (!filesystem::exists(item))
576 {
Sunny Srivastavaa2ddc962022-06-29 08:53:16 -0500577 try
578 {
579 // If not, then take failure postAction
580 executePostFailAction(jsonFile, item);
581 }
582 catch (const GpioException& e)
583 {
584 PelAdditionalData additionalData{};
585 additionalData.emplace("DESCRIPTION", e.what());
586 createPEL(additionalData, PelSeverity::WARNING,
587 errIntfForGpioError, sdBus);
588 }
Santosh Puranikd40e42d2022-03-23 13:58:06 +0530589 }
590 }
SunnySrivastava19849a195542020-09-07 06:04:50 -0500591 }
592}
593
Sunny Srivastava28abd6e2021-07-28 02:58:28 -0500594void Manager::deleteFRUVPD(const sdbusplus::message::object_path& path)
595{
596 using InvalidArgument =
597 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
598 using Argument = xyz::openbmc_project::Common::InvalidArgument;
599
600 // if path not found in Json.
601 if (frus.find(path) == frus.end())
602 {
603 elog<InvalidArgument>(
604 Argument::ARGUMENT_NAME("Object Path"),
605 Argument::ARGUMENT_VALUE(std::string(path).c_str()));
606 }
607
608 // if the FRU is not present then log error
609 if (readBusProperty(path, "xyz.openbmc_project.Inventory.Item",
610 "Present") == "false")
611 {
612 elog<InvalidArgument>(
613 Argument::ARGUMENT_NAME("FRU not preset"),
614 Argument::ARGUMENT_VALUE(std::string(path).c_str()));
615 }
616 else
617 {
618 inventory::ObjectMap objectMap = {
619 {path,
620 {{"xyz.openbmc_project.Inventory.Item", {{"Present", false}}}}}};
621
622 common::utility::callPIM(move(objectMap));
623 }
624}
625
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600626} // namespace manager
627} // namespace vpd
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500628} // namespace openpower