blob: 9a02c13093dafd3ecb9d6a2051852a2797cdb43d [file] [log] [blame]
Sampa Misraaea5dde2020-08-31 08:33:47 -05001#include "inband_code_update.hpp"
2
Sagar Srinivas78a225a2020-08-27 00:52:20 -05003#include "libpldm/entity.h"
4
5#include "libpldmresponder/pdr.hpp"
Sampa Misraaea5dde2020-08-31 08:33:47 -05006#include "oem_ibm_handler.hpp"
7#include "xyz/openbmc_project/Common/error.hpp"
8
Adriana Kobylak727f7382020-09-01 14:38:25 -05009#include <arpa/inet.h>
10
Sampa Misraaea5dde2020-08-31 08:33:47 -050011#include <sdbusplus/server.hpp>
12#include <xyz/openbmc_project/Dump/NewDump/server.hpp>
13
14#include <exception>
Adriana Kobylak727f7382020-09-01 14:38:25 -050015#include <fstream>
Sampa Misraaea5dde2020-08-31 08:33:47 -050016namespace pldm
17{
Brad Bishop5079ac42021-08-19 18:35:06 -040018using namespace utils;
19
Sampa Misraaea5dde2020-08-31 08:33:47 -050020namespace responder
21{
22using namespace oem_ibm_platform;
23
Adriana Kobylakfa810d72020-10-16 16:27:28 -050024/** @brief Directory where the lid files without a header are stored */
25auto lidDirPath = fs::path(LID_STAGING_DIR) / "lid";
26
Adriana Kobylaka1f158c2020-11-09 12:47:29 -060027/** @brief Directory where the image files are stored as they are built */
28auto imageDirPath = fs::path(LID_STAGING_DIR) / "image";
29
Adriana Kobylak837fb472020-10-16 16:53:42 -050030/** @brief Directory where the code update tarball files are stored */
31auto updateDirPath = fs::path(LID_STAGING_DIR) / "update";
32
Adriana Kobylaka1f158c2020-11-09 12:47:29 -060033/** @brief The file name of the code update tarball */
34constexpr auto tarImageName = "image.tar";
35
Adriana Kobylak837fb472020-10-16 16:53:42 -050036/** @brief The file name of the hostfw image */
Adriana Kobylak131327e2021-03-10 18:45:24 +000037constexpr auto hostfwImageName = "image-hostfw";
Adriana Kobylak837fb472020-10-16 16:53:42 -050038
Adriana Kobylaka1f158c2020-11-09 12:47:29 -060039/** @brief The path to the code update tarball file */
40auto tarImagePath = fs::path(imageDirPath) / tarImageName;
41
Adriana Kobylak837fb472020-10-16 16:53:42 -050042/** @brief The path to the hostfw image */
43auto hostfwImagePath = fs::path(imageDirPath) / hostfwImageName;
44
45/** @brief The path to the tarball file expected by the phosphor software
46 * manager */
47auto updateImagePath = fs::path("/tmp/images") / tarImageName;
48
Sampa Misraaea5dde2020-08-31 08:33:47 -050049std::string CodeUpdate::fetchCurrentBootSide()
50{
51 return currBootSide;
52}
53
54std::string CodeUpdate::fetchNextBootSide()
55{
56 return nextBootSide;
57}
58
59int CodeUpdate::setCurrentBootSide(const std::string& currSide)
60{
61 currBootSide = currSide;
62 return PLDM_SUCCESS;
63}
64
65int CodeUpdate::setNextBootSide(const std::string& nextSide)
66{
67 nextBootSide = nextSide;
68 std::string objPath{};
69 if (nextBootSide == currBootSide)
70 {
71 objPath = runningVersion;
72 }
73 else
74 {
75 objPath = nonRunningVersion;
76 }
77 if (objPath.empty())
78 {
79 std::cerr << "no nonRunningVersion present \n";
80 return PLDM_PLATFORM_INVALID_STATE_VALUE;
81 }
82
83 pldm::utils::DBusMapping dbusMapping{objPath, redundancyIntf, "Priority",
84 "uint8_t"};
85 uint8_t val = 0;
86 pldm::utils::PropertyValue value = static_cast<uint8_t>(val);
87 try
88 {
89 dBusIntf->setDbusProperty(dbusMapping, value);
90 }
91 catch (const std::exception& e)
92 {
93 std::cerr << "failed to set the next boot side to " << objPath.c_str()
94 << " ERROR=" << e.what() << "\n";
95 return PLDM_ERROR;
96 }
97 return PLDM_SUCCESS;
98}
99
Sagar Srinivascfdbca72020-09-22 10:03:35 -0500100int CodeUpdate::setRequestedApplyTime()
101{
102 int rc = PLDM_SUCCESS;
103 pldm::utils::PropertyValue value =
104 "xyz.openbmc_project.Software.ApplyTime.RequestedApplyTimes.OnReset";
105 DBusMapping dbusMapping;
106 dbusMapping.objectPath = "/xyz/openbmc_project/software/apply_time";
107 dbusMapping.interface = "xyz.openbmc_project.Software.ApplyTime";
108 dbusMapping.propertyName = "RequestedApplyTime";
109 dbusMapping.propertyType = "string";
110 try
111 {
112 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
113 }
114 catch (const std::exception& e)
115 {
116 std::cerr << "Failed To set RequestedApplyTime property "
117 << "ERROR=" << e.what() << std::endl;
118 rc = PLDM_ERROR;
119 }
120 return rc;
121}
122
123int CodeUpdate::setRequestedActivation()
124{
125 int rc = PLDM_SUCCESS;
126 pldm::utils::PropertyValue value =
127 "xyz.openbmc_project.Software.Activation.RequestedActivations.Active";
128 DBusMapping dbusMapping;
129 dbusMapping.objectPath = newImageId;
130 dbusMapping.interface = "xyz.openbmc_project.Software.Activation";
131 dbusMapping.propertyName = "RequestedActivation";
132 dbusMapping.propertyType = "string";
133 try
134 {
135 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
136 }
137 catch (const std::exception& e)
138 {
139 std::cerr << "Failed To set RequestedActivation property"
140 << "ERROR=" << e.what() << std::endl;
141 rc = PLDM_ERROR;
142 }
Sagar Srinivascfdbca72020-09-22 10:03:35 -0500143 return rc;
144}
145
Sampa Misraaea5dde2020-08-31 08:33:47 -0500146void CodeUpdate::setVersions()
147{
148 static constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper";
149 static constexpr auto functionalObjPath =
150 "/xyz/openbmc_project/software/functional";
151 static constexpr auto activeObjPath =
152 "/xyz/openbmc_project/software/active";
153 static constexpr auto propIntf = "org.freedesktop.DBus.Properties";
154
155 auto& bus = dBusIntf->getBus();
Sampa Misraaea5dde2020-08-31 08:33:47 -0500156 try
157 {
158 auto method = bus.new_method_call(mapperService, functionalObjPath,
159 propIntf, "Get");
160 method.append("xyz.openbmc_project.Association", "endpoints");
161 std::variant<std::vector<std::string>> paths;
162
163 auto reply = bus.call(method);
164 reply.read(paths);
165
166 runningVersion = std::get<std::vector<std::string>>(paths)[0];
167
168 auto method1 =
169 bus.new_method_call(mapperService, activeObjPath, propIntf, "Get");
170 method1.append("xyz.openbmc_project.Association", "endpoints");
171
172 auto reply1 = bus.call(method1);
173 reply1.read(paths);
174 for (const auto& path : std::get<std::vector<std::string>>(paths))
175 {
176 if (path != runningVersion)
177 {
178 nonRunningVersion = path;
179 break;
180 }
181 }
182 }
183 catch (const std::exception& e)
184 {
185 std::cerr << "failed to make a d-bus call to Object Mapper "
186 "Association, ERROR="
187 << e.what() << "\n";
188 return;
189 }
190
191 using namespace sdbusplus::bus::match::rules;
192 captureNextBootSideChange.push_back(
Patrick Williams84b790c2022-07-22 19:26:56 -0500193 std::make_unique<sdbusplus::bus::match_t>(
Sampa Misraaea5dde2020-08-31 08:33:47 -0500194 pldm::utils::DBusHandler::getBus(),
195 propertiesChanged(runningVersion, redundancyIntf),
Patrick Williams84b790c2022-07-22 19:26:56 -0500196 [this](sdbusplus::message_t& msg) {
Sampa Misraaea5dde2020-08-31 08:33:47 -0500197 DbusChangedProps props;
198 std::string iface;
199 msg.read(iface, props);
200 processPriorityChangeNotification(props);
201 }));
Patrick Williams84b790c2022-07-22 19:26:56 -0500202 fwUpdateMatcher.push_back(std::make_unique<sdbusplus::bus::match_t>(
Sampa Misraaea5dde2020-08-31 08:33:47 -0500203 pldm::utils::DBusHandler::getBus(),
204 "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
205 "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
Patrick Williams84b790c2022-07-22 19:26:56 -0500206 [this](sdbusplus::message_t& msg) {
Sampa Misraaea5dde2020-08-31 08:33:47 -0500207 DBusInterfaceAdded interfaces;
208 sdbusplus::message::object_path path;
209 msg.read(path, interfaces);
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600210
Sampa Misraaea5dde2020-08-31 08:33:47 -0500211 for (auto& interface : interfaces)
212 {
213 if (interface.first ==
214 "xyz.openbmc_project.Software.Activation")
215 {
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500216 auto imageInterface =
217 "xyz.openbmc_project.Software.Activation";
218 auto imageObjPath = path.str.c_str();
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600219
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500220 try
221 {
222 auto propVal = dBusIntf->getDbusPropertyVariant(
223 imageObjPath, "Activation", imageInterface);
224 const auto& imageProp = std::get<std::string>(propVal);
225 if (imageProp == "xyz.openbmc_project.Software."
226 "Activation.Activations.Ready" &&
227 isCodeUpdateInProgress())
228 {
229 newImageId = path.str;
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600230 if (!imageActivationMatch)
231 {
232 imageActivationMatch = std::make_unique<
Patrick Williams84b790c2022-07-22 19:26:56 -0500233 sdbusplus::bus::match_t>(
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600234 pldm::utils::DBusHandler::getBus(),
235 propertiesChanged(newImageId,
236 "xyz.openbmc_project."
237 "Software.Activation"),
Patrick Williams84b790c2022-07-22 19:26:56 -0500238 [this](sdbusplus::message_t& msg) {
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600239 DbusChangedProps props;
240 std::string iface;
241 msg.read(iface, props);
242 const auto itr =
243 props.find("Activation");
244 if (itr != props.end())
245 {
246 PropertyValue value = itr->second;
247 auto propVal =
248 std::get<std::string>(value);
249 if (propVal ==
250 "xyz.openbmc_project.Software."
251 "Activation.Activations.Active")
252 {
253 CodeUpdateState state =
254 CodeUpdateState::END;
255 setCodeUpdateProgress(false);
256 auto sensorId =
257 getFirmwareUpdateSensor();
258 sendStateSensorEvent(
259 sensorId,
260 PLDM_STATE_SENSOR_STATE, 0,
261 uint8_t(state),
262 uint8_t(CodeUpdateState::
263 START));
264 newImageId.clear();
265 }
266 else if (propVal ==
267 "xyz.openbmc_project."
268 "Software.Activation."
269 "Activations.Failed" ||
270 propVal ==
271 "xyz.openbmc_"
272 "project.Software."
273 "Activation."
274 "Activations."
275 "Invalid")
276 {
277 CodeUpdateState state =
278 CodeUpdateState::FAIL;
279 setCodeUpdateProgress(false);
280 auto sensorId =
281 getFirmwareUpdateSensor();
282 sendStateSensorEvent(
283 sensorId,
284 PLDM_STATE_SENSOR_STATE, 0,
285 uint8_t(state),
286 uint8_t(CodeUpdateState::
287 START));
288 newImageId.clear();
289 }
290 }
291 });
292 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500293 auto rc = setRequestedActivation();
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500294 if (rc != PLDM_SUCCESS)
295 {
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600296 CodeUpdateState state = CodeUpdateState::FAIL;
297 setCodeUpdateProgress(false);
298 auto sensorId = getFirmwareUpdateSensor();
299 sendStateSensorEvent(
300 sensorId, PLDM_STATE_SENSOR_STATE, 0,
301 uint8_t(state),
302 uint8_t(CodeUpdateState::START));
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500303 std::cerr
304 << "could not set RequestedActivation \n";
305 }
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500306 break;
307 }
308 }
Patrick Williams84b790c2022-07-22 19:26:56 -0500309 catch (const sdbusplus::exception_t& e)
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500310 {
311 std::cerr << "Error in getting Activation status \n";
312 }
Sampa Misraaea5dde2020-08-31 08:33:47 -0500313 }
314 }
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600315 }));
Sampa Misraaea5dde2020-08-31 08:33:47 -0500316}
317
318void CodeUpdate::processPriorityChangeNotification(
319 const DbusChangedProps& chProperties)
320{
321 static constexpr auto propName = "Priority";
322 const auto it = chProperties.find(propName);
323 if (it == chProperties.end())
324 {
325 return;
326 }
327 uint8_t newVal = std::get<uint8_t>(it->second);
328 nextBootSide = (newVal == 0) ? currBootSide
329 : ((currBootSide == Tside) ? Pside : Tside);
330}
331
332void CodeUpdate::setOemPlatformHandler(
333 pldm::responder::oem_platform::Handler* handler)
334{
335 oemPlatformHandler = handler;
336}
337
Varsha Kaverappa3ca29df2020-09-27 12:39:22 -0500338void CodeUpdate::clearDirPath(const std::string& dirPath)
339{
Manojkiran Eda78124cf2022-08-29 11:22:43 +0530340 if (!fs::is_directory(dirPath))
Varsha Kaverappa3ca29df2020-09-27 12:39:22 -0500341 {
Manojkiran Eda78124cf2022-08-29 11:22:43 +0530342 std::cerr << "The directory does not exist, dirPath = " << dirPath
343 << std::endl;
344 return;
Varsha Kaverappa3ca29df2020-09-27 12:39:22 -0500345 }
Manojkiran Eda78124cf2022-08-29 11:22:43 +0530346 for (const auto& iter : fs::directory_iterator(dirPath))
347 {
348 fs::remove_all(iter);
349 }
Varsha Kaverappa3ca29df2020-09-27 12:39:22 -0500350}
351
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500352void CodeUpdate::sendStateSensorEvent(
353 uint16_t sensorId, enum sensor_event_class_states sensorEventClass,
354 uint8_t sensorOffset, uint8_t eventState, uint8_t prevEventState)
355{
356 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
357 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
358 oemPlatformHandler);
359 oemIbmPlatformHandler->sendStateSensorEvent(
360 sensorId, sensorEventClass, sensorOffset, eventState, prevEventState);
361}
362
363void CodeUpdate::deleteImage()
364{
365 static constexpr auto UPDATER_SERVICE =
366 "xyz.openbmc_project.Software.BMC.Updater";
367 static constexpr auto SW_OBJ_PATH = "/xyz/openbmc_project/software";
368 static constexpr auto DELETE_INTF =
369 "xyz.openbmc_project.Collection.DeleteAll";
370
371 auto& bus = dBusIntf->getBus();
372 try
373 {
374 auto method = bus.new_method_call(UPDATER_SERVICE, SW_OBJ_PATH,
375 DELETE_INTF, "DeleteAll");
376 bus.call_noreply(method);
377 }
378 catch (const std::exception& e)
379 {
380 std::cerr << "Failed to delete image, ERROR=" << e.what() << "\n";
381 return;
382 }
383}
384
Sampa Misraaea5dde2020-08-31 08:33:47 -0500385uint8_t fetchBootSide(uint16_t entityInstance, CodeUpdate* codeUpdate)
386{
387 uint8_t sensorOpState = tSideNum;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500388 if (entityInstance == 0)
389 {
390 auto currSide = codeUpdate->fetchCurrentBootSide();
391 if (currSide == Pside)
392 {
393 sensorOpState = pSideNum;
394 }
395 }
396 else if (entityInstance == 1)
397 {
398 auto nextSide = codeUpdate->fetchNextBootSide();
399 if (nextSide == Pside)
400 {
401 sensorOpState = pSideNum;
402 }
403 }
404 else
405 {
406 sensorOpState = PLDM_SENSOR_UNKNOWN;
407 }
408
409 return sensorOpState;
410}
411
412int setBootSide(uint16_t entityInstance, uint8_t currState,
413 const std::vector<set_effecter_state_field>& stateField,
414 CodeUpdate* codeUpdate)
415{
416 int rc = PLDM_SUCCESS;
417 auto side = (stateField[currState].effecter_state == pSideNum) ? "P" : "T";
418
419 if (entityInstance == 0)
420 {
421 rc = codeUpdate->setCurrentBootSide(side);
422 }
423 else if (entityInstance == 1)
424 {
425 rc = codeUpdate->setNextBootSide(side);
426 }
427 else
428 {
429 rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
430 }
431 return rc;
432}
433
Adriana Kobylak837fb472020-10-16 16:53:42 -0500434template <typename... T>
435int executeCmd(T const&... t)
436{
437 std::stringstream cmd;
438 ((cmd << t << " "), ...) << std::endl;
439 FILE* pipe = popen(cmd.str().c_str(), "r");
440 if (!pipe)
441 {
442 throw std::runtime_error("popen() failed!");
443 }
444 int rc = pclose(pipe);
445 if (WEXITSTATUS(rc))
446 {
447 std::cerr << "Error executing: ";
448 ((std::cerr << " " << t), ...);
449 std::cerr << "\n";
450 return -1;
451 }
452
453 return 0;
454}
455
Adriana Kobylak727f7382020-09-01 14:38:25 -0500456int processCodeUpdateLid(const std::string& filePath)
457{
458 struct LidHeader
459 {
460 uint16_t magicNumber;
Adriana Kobylak86d14182020-10-16 16:11:08 -0500461 uint16_t headerVersion;
462 uint32_t lidNumber;
463 uint32_t lidDate;
464 uint16_t lidTime;
465 uint16_t lidClass;
466 uint32_t lidCrc;
467 uint32_t lidSize;
468 uint32_t headerSize;
Adriana Kobylak727f7382020-09-01 14:38:25 -0500469 };
470 LidHeader header;
471
472 std::ifstream ifs(filePath, std::ios::in | std::ios::binary);
473 if (!ifs)
474 {
475 std::cerr << "ifstream open error: " << filePath << "\n";
476 return PLDM_ERROR;
477 }
478 ifs.seekg(0);
479 ifs.read(reinterpret_cast<char*>(&header), sizeof(header));
Adriana Kobylak727f7382020-09-01 14:38:25 -0500480
Adriana Kobylak86d14182020-10-16 16:11:08 -0500481 // File size should be the value of lid size minus the header size
482 auto fileSize = fs::file_size(filePath);
483 fileSize -= htonl(header.headerSize);
484 if (fileSize < htonl(header.lidSize))
485 {
486 // File is not completely written yet
Adriana Kobylakfa810d72020-10-16 16:27:28 -0500487 ifs.close();
Adriana Kobylak86d14182020-10-16 16:11:08 -0500488 return PLDM_SUCCESS;
489 }
490
Adriana Kobylak727f7382020-09-01 14:38:25 -0500491 constexpr auto magicNumber = 0x0222;
492 if (htons(header.magicNumber) != magicNumber)
493 {
494 std::cerr << "Invalid magic number: " << filePath << "\n";
Adriana Kobylakfa810d72020-10-16 16:27:28 -0500495 ifs.close();
Adriana Kobylak727f7382020-09-01 14:38:25 -0500496 return PLDM_ERROR;
497 }
498
Adriana Kobylaka1f158c2020-11-09 12:47:29 -0600499 fs::create_directories(imageDirPath);
Adriana Kobylakfa810d72020-10-16 16:27:28 -0500500 fs::create_directories(lidDirPath);
501
Adriana Kobylaka1f158c2020-11-09 12:47:29 -0600502 constexpr auto bmcClass = 0x2000;
503 if (htons(header.lidClass) == bmcClass)
504 {
505 // Skip the header and concatenate the BMC LIDs into a tar file
506 std::ofstream ofs(tarImagePath,
507 std::ios::out | std::ios::binary | std::ios::app);
508 ifs.seekg(htonl(header.headerSize));
509 ofs << ifs.rdbuf();
510 ofs.flush();
511 ofs.close();
512 }
513 else
514 {
515 std::stringstream lidFileName;
516 lidFileName << std::hex << htonl(header.lidNumber) << ".lid";
517 auto lidNoHeaderPath = fs::path(lidDirPath) / lidFileName.str();
518 std::ofstream ofs(lidNoHeaderPath,
519 std::ios::out | std::ios::binary | std::ios::trunc);
520 ifs.seekg(htonl(header.headerSize));
521 ofs << ifs.rdbuf();
522 ofs.flush();
523 ofs.close();
524 }
Adriana Kobylakfa810d72020-10-16 16:27:28 -0500525
526 ifs.close();
527 fs::remove(filePath);
Adriana Kobylak727f7382020-09-01 14:38:25 -0500528 return PLDM_SUCCESS;
529}
530
Adriana Kobylak9296f242021-09-22 15:52:00 +0000531int CodeUpdate::assembleCodeUpdateImage()
Adriana Kobylak837fb472020-10-16 16:53:42 -0500532{
Adriana Kobylak9296f242021-09-22 15:52:00 +0000533 pid_t pid = fork();
534
535 if (pid == 0)
Adriana Kobylak837fb472020-10-16 16:53:42 -0500536 {
Adriana Kobylak9296f242021-09-22 15:52:00 +0000537 pid_t nextPid = fork();
538 if (nextPid == 0)
539 {
540 // Create the hostfw squashfs image from the LID files without
541 // header
542 auto rc = executeCmd("/usr/sbin/mksquashfs", lidDirPath.c_str(),
543 hostfwImagePath.c_str(), "-all-root",
544 "-no-recovery");
545 if (rc < 0)
546 {
547 std::cerr << "Error occurred during the mksqusquashfs call"
548 << std::endl;
549 setCodeUpdateProgress(false);
550 auto sensorId = getFirmwareUpdateSensor();
551 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
552 uint8_t(CodeUpdateState::FAIL),
553 uint8_t(CodeUpdateState::START));
554 exit(EXIT_FAILURE);
555 }
556
557 fs::create_directories(updateDirPath);
558
559 // Extract the BMC tarball content
560 rc = executeCmd("/bin/tar", "-xf", tarImagePath.c_str(), "-C",
561 updateDirPath);
562 if (rc < 0)
563 {
564 setCodeUpdateProgress(false);
565 auto sensorId = getFirmwareUpdateSensor();
566 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
567 uint8_t(CodeUpdateState::FAIL),
568 uint8_t(CodeUpdateState::START));
569 exit(EXIT_FAILURE);
570 }
571
572 // Add the hostfw image to the directory where the contents were
573 // extracted
574 fs::copy_file(hostfwImagePath,
575 fs::path(updateDirPath) / hostfwImageName,
576 fs::copy_options::overwrite_existing);
577
578 // Remove the tarball file, then re-generate it with so that the
579 // hostfw image becomes part of the tarball
580 fs::remove(tarImagePath);
581 rc = executeCmd("/bin/tar", "-cf", tarImagePath, ".", "-C",
582 updateDirPath);
583 if (rc < 0)
584 {
585 std::cerr
586 << "Error occurred during the generation of the tarball"
587 << std::endl;
588 setCodeUpdateProgress(false);
589 auto sensorId = getFirmwareUpdateSensor();
590 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
591 uint8_t(CodeUpdateState::FAIL),
592 uint8_t(CodeUpdateState::START));
593 exit(EXIT_FAILURE);
594 }
595
596 // Copy the tarball to the update directory to trigger the phosphor
597 // software manager to create a version interface
598 fs::copy_file(tarImagePath, updateImagePath,
599 fs::copy_options::overwrite_existing);
600
601 // Cleanup
602 fs::remove_all(updateDirPath);
603 fs::remove_all(lidDirPath);
604 fs::remove_all(imageDirPath);
605
606 exit(EXIT_SUCCESS);
607 }
608 else if (nextPid < 0)
609 {
610 std::cerr << "Error occurred during fork. ERROR=" << errno
611 << std::endl;
612 exit(EXIT_FAILURE);
613 }
614
615 // Do nothing as parent. When parent exits, child will be reparented
616 // under init and be reaped properly.
617 exit(0);
618 }
619 else if (pid > 0)
620 {
621 int status;
622 if (waitpid(pid, &status, 0) < 0)
623 {
624 std::cerr << "Error occurred during waitpid. ERROR=" << errno
625 << std::endl;
626 return PLDM_ERROR;
627 }
628 else if (WEXITSTATUS(status) != 0)
629 {
630 std::cerr
631 << "Failed to execute the assembling of the image. STATUS="
632 << status << std::endl;
633 return PLDM_ERROR;
634 }
635 }
636 else
637 {
638 std::cerr << "Error occurred during fork. ERROR=" << errno << std::endl;
Adriana Kobylak837fb472020-10-16 16:53:42 -0500639 return PLDM_ERROR;
640 }
641
Adriana Kobylak837fb472020-10-16 16:53:42 -0500642 return PLDM_SUCCESS;
643}
644
Sampa Misraaea5dde2020-08-31 08:33:47 -0500645} // namespace responder
646} // namespace pldm