blob: dc83af86497cf46f5ff64c09d8db87ca4e68fcbf [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(
193 std::make_unique<sdbusplus::bus::match::match>(
194 pldm::utils::DBusHandler::getBus(),
195 propertiesChanged(runningVersion, redundancyIntf),
196 [this](sdbusplus::message::message& msg) {
197 DbusChangedProps props;
198 std::string iface;
199 msg.read(iface, props);
200 processPriorityChangeNotification(props);
201 }));
Sagar Srinivas9a64b4a2021-02-09 07:55:38 -0600202 fwUpdateMatcher.push_back(std::make_unique<sdbusplus::bus::match::match>(
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'",
206 [this](sdbusplus::message::message& msg) {
207 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<
233 sdbusplus::bus::match::match>(
234 pldm::utils::DBusHandler::getBus(),
235 propertiesChanged(newImageId,
236 "xyz.openbmc_project."
237 "Software.Activation"),
238 [this](sdbusplus::message::message& msg) {
239 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 Williams4fea7a22021-09-02 09:54:12 -0500309 catch (const sdbusplus::exception::exception& 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{
340 for (auto& path : fs::directory_iterator(dirPath.c_str()))
341 {
342 fs::remove_all(path);
343 }
344 return;
345}
346
Sampa Misra3a0e3b92020-10-21 05:58:00 -0500347void CodeUpdate::sendStateSensorEvent(
348 uint16_t sensorId, enum sensor_event_class_states sensorEventClass,
349 uint8_t sensorOffset, uint8_t eventState, uint8_t prevEventState)
350{
351 pldm::responder::oem_ibm_platform::Handler* oemIbmPlatformHandler =
352 dynamic_cast<pldm::responder::oem_ibm_platform::Handler*>(
353 oemPlatformHandler);
354 oemIbmPlatformHandler->sendStateSensorEvent(
355 sensorId, sensorEventClass, sensorOffset, eventState, prevEventState);
356}
357
358void CodeUpdate::deleteImage()
359{
360 static constexpr auto UPDATER_SERVICE =
361 "xyz.openbmc_project.Software.BMC.Updater";
362 static constexpr auto SW_OBJ_PATH = "/xyz/openbmc_project/software";
363 static constexpr auto DELETE_INTF =
364 "xyz.openbmc_project.Collection.DeleteAll";
365
366 auto& bus = dBusIntf->getBus();
367 try
368 {
369 auto method = bus.new_method_call(UPDATER_SERVICE, SW_OBJ_PATH,
370 DELETE_INTF, "DeleteAll");
371 bus.call_noreply(method);
372 }
373 catch (const std::exception& e)
374 {
375 std::cerr << "Failed to delete image, ERROR=" << e.what() << "\n";
376 return;
377 }
378}
379
Sampa Misraaea5dde2020-08-31 08:33:47 -0500380uint8_t fetchBootSide(uint16_t entityInstance, CodeUpdate* codeUpdate)
381{
382 uint8_t sensorOpState = tSideNum;
Sampa Misraaea5dde2020-08-31 08:33:47 -0500383 if (entityInstance == 0)
384 {
385 auto currSide = codeUpdate->fetchCurrentBootSide();
386 if (currSide == Pside)
387 {
388 sensorOpState = pSideNum;
389 }
390 }
391 else if (entityInstance == 1)
392 {
393 auto nextSide = codeUpdate->fetchNextBootSide();
394 if (nextSide == Pside)
395 {
396 sensorOpState = pSideNum;
397 }
398 }
399 else
400 {
401 sensorOpState = PLDM_SENSOR_UNKNOWN;
402 }
403
404 return sensorOpState;
405}
406
407int setBootSide(uint16_t entityInstance, uint8_t currState,
408 const std::vector<set_effecter_state_field>& stateField,
409 CodeUpdate* codeUpdate)
410{
411 int rc = PLDM_SUCCESS;
412 auto side = (stateField[currState].effecter_state == pSideNum) ? "P" : "T";
413
414 if (entityInstance == 0)
415 {
416 rc = codeUpdate->setCurrentBootSide(side);
417 }
418 else if (entityInstance == 1)
419 {
420 rc = codeUpdate->setNextBootSide(side);
421 }
422 else
423 {
424 rc = PLDM_PLATFORM_INVALID_STATE_VALUE;
425 }
426 return rc;
427}
428
Adriana Kobylak837fb472020-10-16 16:53:42 -0500429template <typename... T>
430int executeCmd(T const&... t)
431{
432 std::stringstream cmd;
433 ((cmd << t << " "), ...) << std::endl;
434 FILE* pipe = popen(cmd.str().c_str(), "r");
435 if (!pipe)
436 {
437 throw std::runtime_error("popen() failed!");
438 }
439 int rc = pclose(pipe);
440 if (WEXITSTATUS(rc))
441 {
442 std::cerr << "Error executing: ";
443 ((std::cerr << " " << t), ...);
444 std::cerr << "\n";
445 return -1;
446 }
447
448 return 0;
449}
450
Adriana Kobylak727f7382020-09-01 14:38:25 -0500451int processCodeUpdateLid(const std::string& filePath)
452{
453 struct LidHeader
454 {
455 uint16_t magicNumber;
Adriana Kobylak86d14182020-10-16 16:11:08 -0500456 uint16_t headerVersion;
457 uint32_t lidNumber;
458 uint32_t lidDate;
459 uint16_t lidTime;
460 uint16_t lidClass;
461 uint32_t lidCrc;
462 uint32_t lidSize;
463 uint32_t headerSize;
Adriana Kobylak727f7382020-09-01 14:38:25 -0500464 };
465 LidHeader header;
466
467 std::ifstream ifs(filePath, std::ios::in | std::ios::binary);
468 if (!ifs)
469 {
470 std::cerr << "ifstream open error: " << filePath << "\n";
471 return PLDM_ERROR;
472 }
473 ifs.seekg(0);
474 ifs.read(reinterpret_cast<char*>(&header), sizeof(header));
Adriana Kobylak727f7382020-09-01 14:38:25 -0500475
Adriana Kobylak86d14182020-10-16 16:11:08 -0500476 // File size should be the value of lid size minus the header size
477 auto fileSize = fs::file_size(filePath);
478 fileSize -= htonl(header.headerSize);
479 if (fileSize < htonl(header.lidSize))
480 {
481 // File is not completely written yet
Adriana Kobylakfa810d72020-10-16 16:27:28 -0500482 ifs.close();
Adriana Kobylak86d14182020-10-16 16:11:08 -0500483 return PLDM_SUCCESS;
484 }
485
Adriana Kobylak727f7382020-09-01 14:38:25 -0500486 constexpr auto magicNumber = 0x0222;
487 if (htons(header.magicNumber) != magicNumber)
488 {
489 std::cerr << "Invalid magic number: " << filePath << "\n";
Adriana Kobylakfa810d72020-10-16 16:27:28 -0500490 ifs.close();
Adriana Kobylak727f7382020-09-01 14:38:25 -0500491 return PLDM_ERROR;
492 }
493
Adriana Kobylaka1f158c2020-11-09 12:47:29 -0600494 fs::create_directories(imageDirPath);
Adriana Kobylakfa810d72020-10-16 16:27:28 -0500495 fs::create_directories(lidDirPath);
496
Adriana Kobylaka1f158c2020-11-09 12:47:29 -0600497 constexpr auto bmcClass = 0x2000;
498 if (htons(header.lidClass) == bmcClass)
499 {
500 // Skip the header and concatenate the BMC LIDs into a tar file
501 std::ofstream ofs(tarImagePath,
502 std::ios::out | std::ios::binary | std::ios::app);
503 ifs.seekg(htonl(header.headerSize));
504 ofs << ifs.rdbuf();
505 ofs.flush();
506 ofs.close();
507 }
508 else
509 {
510 std::stringstream lidFileName;
511 lidFileName << std::hex << htonl(header.lidNumber) << ".lid";
512 auto lidNoHeaderPath = fs::path(lidDirPath) / lidFileName.str();
513 std::ofstream ofs(lidNoHeaderPath,
514 std::ios::out | std::ios::binary | std::ios::trunc);
515 ifs.seekg(htonl(header.headerSize));
516 ofs << ifs.rdbuf();
517 ofs.flush();
518 ofs.close();
519 }
Adriana Kobylakfa810d72020-10-16 16:27:28 -0500520
521 ifs.close();
522 fs::remove(filePath);
Adriana Kobylak727f7382020-09-01 14:38:25 -0500523 return PLDM_SUCCESS;
524}
525
Adriana Kobylak9296f242021-09-22 15:52:00 +0000526int CodeUpdate::assembleCodeUpdateImage()
Adriana Kobylak837fb472020-10-16 16:53:42 -0500527{
Adriana Kobylak9296f242021-09-22 15:52:00 +0000528 pid_t pid = fork();
529
530 if (pid == 0)
Adriana Kobylak837fb472020-10-16 16:53:42 -0500531 {
Adriana Kobylak9296f242021-09-22 15:52:00 +0000532 pid_t nextPid = fork();
533 if (nextPid == 0)
534 {
535 // Create the hostfw squashfs image from the LID files without
536 // header
537 auto rc = executeCmd("/usr/sbin/mksquashfs", lidDirPath.c_str(),
538 hostfwImagePath.c_str(), "-all-root",
539 "-no-recovery");
540 if (rc < 0)
541 {
542 std::cerr << "Error occurred during the mksqusquashfs call"
543 << std::endl;
544 setCodeUpdateProgress(false);
545 auto sensorId = getFirmwareUpdateSensor();
546 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
547 uint8_t(CodeUpdateState::FAIL),
548 uint8_t(CodeUpdateState::START));
549 exit(EXIT_FAILURE);
550 }
551
552 fs::create_directories(updateDirPath);
553
554 // Extract the BMC tarball content
555 rc = executeCmd("/bin/tar", "-xf", tarImagePath.c_str(), "-C",
556 updateDirPath);
557 if (rc < 0)
558 {
559 setCodeUpdateProgress(false);
560 auto sensorId = getFirmwareUpdateSensor();
561 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
562 uint8_t(CodeUpdateState::FAIL),
563 uint8_t(CodeUpdateState::START));
564 exit(EXIT_FAILURE);
565 }
566
567 // Add the hostfw image to the directory where the contents were
568 // extracted
569 fs::copy_file(hostfwImagePath,
570 fs::path(updateDirPath) / hostfwImageName,
571 fs::copy_options::overwrite_existing);
572
573 // Remove the tarball file, then re-generate it with so that the
574 // hostfw image becomes part of the tarball
575 fs::remove(tarImagePath);
576 rc = executeCmd("/bin/tar", "-cf", tarImagePath, ".", "-C",
577 updateDirPath);
578 if (rc < 0)
579 {
580 std::cerr
581 << "Error occurred during the generation of the tarball"
582 << std::endl;
583 setCodeUpdateProgress(false);
584 auto sensorId = getFirmwareUpdateSensor();
585 sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
586 uint8_t(CodeUpdateState::FAIL),
587 uint8_t(CodeUpdateState::START));
588 exit(EXIT_FAILURE);
589 }
590
591 // Copy the tarball to the update directory to trigger the phosphor
592 // software manager to create a version interface
593 fs::copy_file(tarImagePath, updateImagePath,
594 fs::copy_options::overwrite_existing);
595
596 // Cleanup
597 fs::remove_all(updateDirPath);
598 fs::remove_all(lidDirPath);
599 fs::remove_all(imageDirPath);
600
601 exit(EXIT_SUCCESS);
602 }
603 else if (nextPid < 0)
604 {
605 std::cerr << "Error occurred during fork. ERROR=" << errno
606 << std::endl;
607 exit(EXIT_FAILURE);
608 }
609
610 // Do nothing as parent. When parent exits, child will be reparented
611 // under init and be reaped properly.
612 exit(0);
613 }
614 else if (pid > 0)
615 {
616 int status;
617 if (waitpid(pid, &status, 0) < 0)
618 {
619 std::cerr << "Error occurred during waitpid. ERROR=" << errno
620 << std::endl;
621 return PLDM_ERROR;
622 }
623 else if (WEXITSTATUS(status) != 0)
624 {
625 std::cerr
626 << "Failed to execute the assembling of the image. STATUS="
627 << status << std::endl;
628 return PLDM_ERROR;
629 }
630 }
631 else
632 {
633 std::cerr << "Error occurred during fork. ERROR=" << errno << std::endl;
Adriana Kobylak837fb472020-10-16 16:53:42 -0500634 return PLDM_ERROR;
635 }
636
Adriana Kobylak837fb472020-10-16 16:53:42 -0500637 return PLDM_SUCCESS;
638}
639
Sampa Misraaea5dde2020-08-31 08:33:47 -0500640} // namespace responder
641} // namespace pldm