Skip to content

Commit b4100da

Browse files
codeupdate: Fix to boot always from temp side (#619)
Added missed code and traces from 1060 in code update path. The problem faced during existing code update code is the delay in receiving the system type. PLDM was setting the fw_boot_side and fw_boot_side_current before building the bios table. So those values where not getting set. To fix the issue saving the pending bios attributes before setting biostable and resetting it after biostable update. With the Fix pldm is booting from Temp side after codeupdate. Signed-off-by: Archana Kakani <[email protected]>
1 parent 0348897 commit b4100da

File tree

7 files changed

+129
-16
lines changed

7 files changed

+129
-16
lines changed

common/utils.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ void setBiosAttr(const BiosAttributeList& biosAttrList)
895895
method.append(
896896
biosConfigIntf, "PendingAttributes",
897897
std::variant<PendingAttributesType>(pendingAttributes));
898-
bus.call_noreply(method);
898+
bus.call_noreply(method, dbusTimeout);
899899
}
900900
catch (const sdbusplus::exception::SdBusError& e)
901901
{

host-bmc/host_pdr_handler.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ HostPDRHandler::HostPDRHandler(
130130
auto propVal = std::get<std::string>(value);
131131
if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
132132
{
133+
if (oemPlatformHandler)
134+
{
135+
oemPlatformHandler->startStopTimer(false);
136+
}
133137
// Delete all the remote terminus information
134138
std::erase_if(tlPDRInfo, [](const auto& item) {
135139
const auto& [key, value] = item;
@@ -1239,7 +1243,6 @@ void HostPDRHandler::getFRURecordTableMetadataByRemote()
12391243
"RC", lg2::hex, rc, "CC", cc);
12401244
return;
12411245
}
1242-
info("Fru RecordTable length {LEN}", "LEN", total);
12431246
// pass total to getFRURecordTableByRemote
12441247
this->getFRURecordTableByRemote(total);
12451248
};
@@ -1264,7 +1267,6 @@ void HostPDRHandler::getFRURecordTableByRemote(uint16_t& totalTableRecords)
12641267

12651268
if (!totalTableRecords)
12661269
{
1267-
error("Failed to get fru record table");
12681270
return;
12691271
}
12701272

libpldmresponder/bios_config.cpp

+48-4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ constexpr auto stringTableFile = "stringTable";
3939
constexpr auto attrTableFile = "attributeTable";
4040
constexpr auto attrValueTableFile = "attributeValueTable";
4141

42+
constexpr auto biosObjPath = "/xyz/openbmc_project/bios_config/manager";
43+
constexpr auto biosInterface = "xyz.openbmc_project.BIOSConfig.Manager";
4244
} // namespace
4345

4446
BIOSConfig::BIOSConfig(
@@ -60,8 +62,6 @@ BIOSConfig::BIOSConfig(
6062
#else
6163
initBIOSAttributes(sysType, false);
6264
#endif
63-
64-
listenPendingAttributes();
6565
}
6666

6767
void BIOSConfig::checkSystemTypeAvailability()
@@ -100,7 +100,53 @@ void BIOSConfig::initBIOSAttributes(const std::string& systemType,
100100
return;
101101
}
102102
constructAttributes();
103+
104+
using PendingAttributesType = std::vector<std::pair<
105+
std::string, std::tuple<std::string, std::variant<std::string>>>>;
106+
PendingAttributesType pendingAttributes;
107+
std::variant<PendingAttributesType> varPendingAttributes;
108+
auto& bus = dbusHandler->getBus();
109+
auto service = dbusHandler->getService(biosObjPath, biosInterface);
110+
111+
try
112+
{
113+
info("Getting Pending Attributes");
114+
auto method = bus.new_method_call(service.c_str(), biosObjPath,
115+
"org.freedesktop.DBus.Properties",
116+
"Get");
117+
method.append(biosInterface, "PendingAttributes");
118+
auto reply = bus.call(method, dbusTimeout);
119+
reply.read(varPendingAttributes);
120+
pendingAttributes =
121+
std::get<PendingAttributesType>(varPendingAttributes);
122+
}
123+
catch (const std::exception& e)
124+
{
125+
error("Failed to read PendingAttributes property, error - {ERROR}",
126+
"ERROR", e);
127+
}
128+
103129
buildTables();
130+
131+
if (pendingAttributes.size())
132+
{
133+
try
134+
{
135+
info("Setting Pending Attributes");
136+
auto method = bus.new_method_call(service.c_str(), biosObjPath,
137+
dbusProperties, "Set");
138+
method.append(biosInterface, "PendingAttributes",
139+
varPendingAttributes);
140+
bus.call_noreply(method, dbusTimeout);
141+
}
142+
catch (const std::exception& e)
143+
{
144+
error("Failed to update PendingAttribute property, error - {ERROR}",
145+
"ERROR", e);
146+
}
147+
}
148+
info("Register listenPendingAttributes");
149+
listenPendingAttributes();
104150
if (registerService)
105151
{
106152
requestPLDMServiceName();
@@ -582,8 +628,6 @@ void BIOSConfig::buildAndStoreAttrTables(const Table& stringTable)
582628
}
583629

584630
BaseBIOSTable biosTable{};
585-
constexpr auto biosObjPath = "/xyz/openbmc_project/bios_config/manager";
586-
constexpr auto biosInterface = "xyz.openbmc_project.BIOSConfig.Manager";
587631

588632
try
589633
{

oem/ibm/libpldmresponder/inband_code_update.cpp

+51-6
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,23 @@ int CodeUpdate::setCurrentBootSide(const std::string& currSide)
6666

6767
int CodeUpdate::setNextBootSide(const std::string& nextSide)
6868
{
69+
info("setNextBootSide, nextSide={NXT_SIDE}", "NXT_SIDE", nextSide);
6970
pldm_boot_side_data pldmBootSideData = readBootSideFile();
70-
currBootSide = pldmBootSideData.current_boot_side;
71+
currBootSide = (pldmBootSideData.current_boot_side == "Perm" ? Pside
72+
: Tside);
7173
nextBootSide = nextSide;
72-
pldmBootSideData.next_boot_side = nextSide;
74+
pldmBootSideData.next_boot_side = (nextSide == Pside ? "Perm" : "Temp");
7375
std::string objPath{};
7476
if (nextBootSide == currBootSide)
7577
{
78+
info("Current bootside is same as next boot side");
79+
info("setting priority of running version 0");
7680
objPath = runningVersion;
7781
}
7882
else
7983
{
84+
info("Current bootside is not same as next boot side");
85+
info("setting priority of non running version 0");
8086
objPath = nonRunningVersion;
8187
}
8288
if (objPath.empty())
@@ -99,7 +105,9 @@ int CodeUpdate::setNextBootSide(const std::string& nextSide)
99105
catch (const std::exception& e)
100106
{
101107
// Alternate side may not be present due to a failed code update
102-
info("Alternate side not present due to failed code update");
108+
error(
109+
"Alternate side may not be present due to a failed code update. ERROR = {ERR}",
110+
"ERR", e);
103111
return PLDM_PLATFORM_INVALID_STATE_VALUE;
104112
}
105113

@@ -218,6 +226,19 @@ void CodeUpdate::setVersions()
218226
pldm_boot_side_data pldmBootSideData;
219227
std::string nextBootSideBiosValue =
220228
getBiosAttrValue("fw_boot_side");
229+
230+
// We enter this path during Genesis boot/boot after Factory reset.
231+
// PLDM waits for Entity manager to populate System Type. After
232+
// receiving system Type from EM it populates the bios attributes
233+
// specific to that system We do not have bios attributes populated
234+
// when we reach here so setting it to default value of the
235+
// attribute as mentioned in the json files.
236+
if (nextBootSideBiosValue.empty())
237+
{
238+
info(
239+
"Boot side is not initialized yet, so setting default value");
240+
nextBootSideBiosValue = "Temp";
241+
}
221242
pldmBootSideData.current_boot_side = nextBootSideBiosValue;
222243
pldmBootSideData.next_boot_side = nextBootSideBiosValue;
223244
pldmBootSideData.running_version_object = runningPath;
@@ -304,15 +325,16 @@ void CodeUpdate::setVersions()
304325
}));
305326
fwUpdateMatcher.push_back(std::make_unique<sdbusplus::bus::match_t>(
306327
pldm::utils::DBusHandler::getBus(),
307-
"interface='org.freedesktop.DBus.ObjectManager',type='signal',"
328+
"sender='xyz.openbmc_project.Software.BMC.Updater',interface='org.freedesktop.DBus.ObjectManager',type='signal',"
308329
"member='InterfacesAdded',path='/xyz/openbmc_project/software'",
309330
[this](sdbusplus::message_t& msg) {
310331
DBusInterfaceAdded interfaces;
311332
sdbusplus::message::object_path path;
312333
msg.read(path, interfaces);
313-
334+
info("Software interface got added");
314335
for (auto& interface : interfaces)
315336
{
337+
info("Interface is {I}", "I", interface.first);
316338
if (interface.first == "xyz.openbmc_project.Software.Activation")
317339
{
318340
auto imageInterface = "xyz.openbmc_project.Software.Activation";
@@ -468,6 +490,7 @@ void CodeUpdate::processRenameEvent()
468490
nextBootSide = Pside;
469491

470492
auto sensorId = getBootSideRenameStateSensor();
493+
info("Received sendor id for rename {ID}", "ID", sensorId);
471494
sendStateSensorEvent(sensorId, PLDM_STATE_SENSOR_STATE, 0,
472495
PLDM_BOOT_SIDE_HAS_BEEN_RENAMED,
473496
PLDM_BOOT_SIDE_NOT_RENAMED);
@@ -481,6 +504,7 @@ void CodeUpdate::processRenameEvent()
481504

482505
void CodeUpdate::writeBootSideFile(const pldm_boot_side_data& pldmBootSideData)
483506
{
507+
fs::create_directories(bootSideDirPath.parent_path());
484508
std::ofstream writeFile(bootSideDirPath.string(),
485509
std::ios::out | std::ios::binary);
486510
if (writeFile)
@@ -713,6 +737,16 @@ int processCodeUpdateLid(const std::string& filePath)
713737
fs::create_directories(imageDirPath);
714738
fs::create_directories(lidDirPath);
715739

740+
// Set the lid directory permissions to 777
741+
std::error_code ec;
742+
fs::permissions(lidDirPath, fs::perms::all, fs::perm_options::replace, ec);
743+
if (ec)
744+
{
745+
error("Failed to set the lid directory permissions:{ERR}", "ERR",
746+
ec.message());
747+
return PLDM_ERROR;
748+
}
749+
716750
constexpr auto bmcClass = 0x2000;
717751
if (htons(header.lidClass) == bmcClass)
718752
{
@@ -735,6 +769,17 @@ int processCodeUpdateLid(const std::string& filePath)
735769
ofs << ifs.rdbuf();
736770
ofs.flush();
737771
ofs.close();
772+
// Set the lid file permissions to 440
773+
std::error_code ec;
774+
fs::permissions(lidNoHeaderPath,
775+
fs::perms::owner_read | fs::perms::group_read,
776+
fs::perm_options::replace, ec);
777+
if (ec)
778+
{
779+
error("Failed to set the lid file permissions: {ERR}", "ERR",
780+
ec.message());
781+
return PLDM_ERROR;
782+
}
738783
}
739784

740785
ifs.close();
@@ -757,7 +802,7 @@ int CodeUpdate::assembleCodeUpdateImage()
757802
auto method = bus.new_method_call(UPDATER_SERVICE, SOFTWARE_PATH,
758803
LID_INTERFACE,
759804
"AssembleCodeUpdateImage");
760-
bus.call_noreply(method);
805+
bus.call_noreply(method, dbusTimeout);
761806
}
762807
catch (const std::exception& e)
763808
{

oem/ibm/libpldmresponder/oem_ibm_handler.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,10 @@ void pldm::responder::oem_ibm_platform::Handler::buildOEMPDR(
919919
this, PLDM_OEM_IBM_CHASSIS_POWER_CONTROLLER, ENTITY_INSTANCE_0,
920920
PLDM_STATE_SET_SYSTEM_POWER_STATE, repo);
921921

922+
pldm_entity fwUpEntity = {PLDM_OEM_IBM_ENTITY_FIRMWARE_UPDATE, 0, 1};
923+
attachOemEntityToEntityAssociationPDR(
924+
this, bmcEntityTree, "/xyz/openbmc_project/inventory/system", repo,
925+
fwUpEntity);
922926
pldm_entity saiEntity = {PLDM_OEM_IBM_ENTITY_REAL_SAI, 1, 1};
923927
attachOemEntityToEntityAssociationPDR(
924928
this, bmcEntityTree, "/xyz/openbmc_project/inventory/system", repo,

oem/ibm/libpldmresponder/oem_ibm_handler.hpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ class Handler : public oem_platform::Handler
156156
else if (propVal ==
157157
"xyz.openbmc_project.State.Host.HostState.Running")
158158
{
159+
hostOff = false;
159160
hostTransitioningToOff = false;
160161
}
161162
else if (
@@ -183,6 +184,9 @@ class Handler : public oem_platform::Handler
183184
if (propVal ==
184185
"xyz.openbmc_project.State.Chassis.PowerState.Off")
185186
{
187+
startStopTimer(false);
188+
handleBootTypesAtChassisOff();
189+
186190
static constexpr auto searchpath =
187191
"/xyz/openbmc_project/inventory/system/chassis/motherboard";
188192
int depth = 0;
@@ -271,8 +275,10 @@ class Handler : public oem_platform::Handler
271275
if (it.first == "fw_boot_side")
272276
{
273277
auto& [attributeType, attributevalue] = it.second;
274-
std::string nextBootSide =
278+
std::string nextBootSideAttr =
275279
std::get<std::string>(attributevalue);
280+
std::string nextBootSide =
281+
(nextBootSideAttr == "Perm" ? Pside : Tside);
276282
codeUpdate->setNextBootSide(nextBootSide);
277283
}
278284
}

oem/ibm/libpldmresponder/platform_oem_ibm.cpp

+14-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,9 @@ int sendBiosAttributeUpdateEvent(
7171
auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
7272

7373
auto rc = encode_bios_attribute_update_event_req(
74-
instanceId, PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION, TERMINUS_ID,
75-
handles.size(), reinterpret_cast<const uint8_t*>(handles.data()),
74+
instanceId, PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION,
75+
pldm::responder::pdr::BmcMctpEid, handles.size(),
76+
reinterpret_cast<const uint8_t*>(handles.data()),
7677
requestMsg.size() - sizeof(pldm_msg_hdr), request);
7778
if (rc != PLDM_SUCCESS)
7879
{
@@ -83,6 +84,17 @@ int sendBiosAttributeUpdateEvent(
8384
return rc;
8485
}
8586

87+
if (requestMsg.size())
88+
{
89+
std::ostringstream tempStream;
90+
for (int byte : requestMsg)
91+
{
92+
tempStream << std::setfill('0') << std::setw(2) << std::hex << byte
93+
<< " ";
94+
}
95+
std::cout << "platformEventMessage for BIOS Attribute "
96+
<< tempStream.str() << std::endl;
97+
}
8698
auto platformEventMessageResponseHandler =
8799
[](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
88100
if (response == nullptr || !respMsgLen)

0 commit comments

Comments
 (0)