pfr-manager: stop pfr-manager service if PFR not supported
Add support to stop the PFR manager service if PFR CPLD not available
and pfr not provisioned.
Tested:
1. When PFR CPLD is available and pfr provisioned.
Command: busctl introspect xyz.openbmc_project.PFR.Manager /xyz/
openbmc_project/pfr
Response:
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
xyz.openbmc_project.PFR.Attributes interface - -
.UfmLocked property b false
.UfmProvisioned property b true
.UfmSupport property b true
2. When PFR CPLD not available.
PFR service has been stopped.
Command: busctl tree xyz.openbmc_project.PFR.Manager.service
Response: No objects discovered.
CPLD version is displayed.
Command: GET: https://<BMC_IP/redfish/v1/UpdateService/FirmwareInventory
/cpld_active
Response:
{
"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/
cpld_active",
"@odata.type": "#SoftwareInventory.v1_1_0.SoftwareInventory",
"Description": "Other image",
"Id": "cpld_active",
"Name": "Software Inventory",
"Status": {
"Health": "OK",
"HealthRollup": "OK",
"State": "Enabled"
},
"Updateable": false,
"Version": "0.7"
}
3. When PFR CPLD available and PFR not provisioned.
PFR service has been stopped.
Command: busctl tree xyz.openbmc_project.PFR.Manager.service
Response: No objects discovered.
CPLD version is displayed.
Command: GET: https://<BMC_IP/redfish/v1/UpdateService/FirmwareInventory
/cpld_active
Response:
{
"@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/
cpld_active",
"@odata.type": "#SoftwareInventory.v1_1_0.SoftwareInventory",
"Description": "Other image",
"Id": "cpld_active",
"Name": "Software Inventory",
"Status": {
"Health": "OK",
"HealthRollup": "OK",
"State": "Enabled"
},
"Updateable": false,
"Version": "44.0-2.0-
508eaac356f28be18791eb6027a663b01dcfbe3101bc2777ccfb9101289b97c5"
}
Signed-off-by: Chalapathi Venkataramashetty <chalapathix.venkataramashetty@intel.com>
Change-Id: I93945033df6f4381923000973e57f346dad87e30
diff --git a/service/src/mainapp.cpp b/service/src/mainapp.cpp
index f39c4e0..bf6cbef 100644
--- a/service/src/mainapp.cpp
+++ b/service/src/mainapp.cpp
@@ -18,6 +18,7 @@
#include "pfr_mgr.hpp"
#include <systemd/sd-journal.h>
+#include <unistd.h>
#include <boost/asio.hpp>
#include <sdbusplus/asio/property.hpp>
@@ -27,6 +28,7 @@
{
static bool i2cConfigLoaded = false;
+static int retrCount = 10;
static bool stateTimerRunning = false;
bool finishedSettingChkPoint = false;
@@ -34,7 +36,7 @@
std::unique_ptr<boost::asio::steady_timer> stateTimer = nullptr;
std::unique_ptr<boost::asio::steady_timer> initTimer = nullptr;
-
+std::unique_ptr<boost::asio::steady_timer> pfrObjTimer = nullptr;
std::vector<std::unique_ptr<PfrVersion>> pfrVersionObjects;
std::unique_ptr<PfrConfig> pfrConfigObject;
@@ -328,7 +330,7 @@
if (std::get<uint64_t>(value))
{
phosphor::logging::log<phosphor::logging::level::INFO>(
- "PFR: BMC boot completed. Setting checkpoint 9.");
+ "BMC boot completed. Setting checkpoint 9.");
if (!finishedSettingChkPoint)
{
finishedSettingChkPoint = true;
@@ -342,7 +344,7 @@
// Failed to get data from systemd. System might not
// be ready yet. Attempt again for data.
phosphor::logging::log<phosphor::logging::level::ERR>(
- "PFR: aync call failed to get FinishTimestamp.",
+ "aync call failed to get FinishTimestamp.",
phosphor::logging::entry("MSG=%s", ec.message().c_str()));
}
// FIX-ME: Latest up-stream sync caused issue in receiving
@@ -351,23 +353,23 @@
// properly.
constexpr size_t pollTimeout = 10; // seconds
initTimer->expires_after(std::chrono::seconds(pollTimeout));
- initTimer->async_wait([&server,
- &conn](const boost::system::error_code& ec) {
- if (ec == boost::asio::error::operation_aborted)
- {
- // Timer reset.
- phosphor::logging::log<phosphor::logging::level::INFO>(
- "PFR: Set boot Checkpoint - Timer aborted or stopped.");
- return;
- }
- if (ec)
- {
- phosphor::logging::log<phosphor::logging::level::ERR>(
- "PFR: Set boot Checkpoint - async wait error.");
- return;
- }
- checkAndSetCheckpoint(server, conn);
- });
+ initTimer->async_wait(
+ [&server, &conn](const boost::system::error_code& ec) {
+ if (ec == boost::asio::error::operation_aborted)
+ {
+ // Timer reset.
+ phosphor::logging::log<phosphor::logging::level::INFO>(
+ "Set boot Checkpoint - Timer aborted or stopped.");
+ return;
+ }
+ if (ec)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Set boot Checkpoint - async wait error.");
+ return;
+ }
+ checkAndSetCheckpoint(server, conn);
+ });
},
"org.freedesktop.systemd1", "/org/freedesktop/systemd1",
"org.freedesktop.DBus.Properties", "Get",
@@ -388,7 +390,7 @@
if (!finishedSettingChkPoint)
{
phosphor::logging::log<phosphor::logging::level::INFO>(
- "PFR: BMC boot completed(StartupFinished). Setting "
+ "BMC boot completed(StartupFinished). Setting "
"checkpoint 9.");
finishedSettingChkPoint = true;
setBMCBootCheckpoint(bmcBootFinishedChkPoint);
@@ -547,6 +549,89 @@
return;
}
+void checkPfrInterface(std::shared_ptr<sdbusplus::asio::connection> conn)
+{
+ if (!i2cConfigLoaded)
+ {
+ init(conn, i2cConfigLoaded);
+ if (retrCount > 0)
+ {
+ // pfr object not loaded yet. query again.
+ return;
+ }
+ else
+ {
+ // Platform does not contain pfr object. Stop the service.
+ phosphor::logging::log<phosphor::logging::level::INFO>(
+ "Platform does not support PFR, hence stop the "
+ "service.");
+ std::exit(EXIT_SUCCESS);
+ return;
+ }
+ }
+ else
+ {
+ retrCount = 0;
+
+ bool locked = false;
+ bool prov = false;
+ bool support = false;
+ pfr::getProvisioningStatus(locked, prov, support);
+ if (support && prov)
+ {
+ // pfr provisioned.
+ phosphor::logging::log<phosphor::logging::level::INFO>(
+ "PFR Supported.");
+ return;
+ }
+ else
+ {
+ // pfr not supported, stop the service
+ phosphor::logging::log<phosphor::logging::level::INFO>(
+ "PFR not Supported. Hence stop the service");
+ std::exit(EXIT_SUCCESS);
+ }
+ }
+}
+void checkPFRandAddObjects(sdbusplus::asio::object_server& server,
+ std::shared_ptr<sdbusplus::asio::connection>& conn)
+{
+ checkPfrInterface(conn);
+
+ constexpr size_t timeout = 10; // seconds
+ pfrObjTimer->expires_after(std::chrono::seconds(timeout));
+ pfrObjTimer->async_wait([&conn,
+ &server](const boost::system::error_code& ec) {
+ if (ec)
+ {
+ if (ec == boost::asio::error::operation_aborted)
+ {
+ // Timer reset.
+ phosphor::logging::log<phosphor::logging::level::INFO>(
+ "pfr object found. Hence Object Timer aborted or stopped.");
+ }
+ else
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "pfr object timer error.");
+ }
+ }
+ if (retrCount > 0)
+ {
+ checkPFRandAddObjects(server, conn);
+ }
+ else
+ {
+ pfr::monitorSignals(server, conn);
+
+ // Update the D-Bus properties.
+ updateDbusPropertiesCache();
+ // Update CPLD Version to cpld_active object in settings.
+ updateCPLDversion(conn);
+ }
+ retrCount--;
+ });
+}
} // namespace pfr
int main()
@@ -556,9 +641,11 @@
auto conn = std::make_shared<sdbusplus::asio::connection>(io);
pfr::stateTimer = std::make_unique<boost::asio::steady_timer>(io);
pfr::initTimer = std::make_unique<boost::asio::steady_timer>(io);
+ pfr::pfrObjTimer = std::make_unique<boost::asio::steady_timer>(io);
auto server = sdbusplus::asio::object_server(conn, true);
pfr::init(conn, pfr::i2cConfigLoaded);
- pfr::monitorSignals(server, conn);
+
+ pfr::checkPFRandAddObjects(server, conn);
// Update CPLD Version to cpld_active object in settings.
pfr::updateCPLDversion(conn);