Retry for file visibility in user space
In some corner cases, there is a delay between the parser code coming
up against udev generated due to binding the driver, and the file
appearing in user space.
As a result the check for file existence fails for those situations and
post fail action gets executed. This removes the GPIO line to the file.
Whereas, parser code will be in process of reading that file at the
same time. Hence closing the GPIO line causes file read error on
parser side.
The timer is to buy some time for file to appear in user space before
cutting off the GPIO line to it.
Test:
This was a script driven testing where system was brought down and
again restarted after random time interval.
Code has been tested against that script and it is working fine.
Change-Id: I8383372b27e48bf1cbc569562e396a0bceb908e5
Signed-off-by: Sunny Srivastava <sunnsr25@in.ibm.com>
diff --git a/const.hpp b/const.hpp
index bbe6ee9..86adcb8 100644
--- a/const.hpp
+++ b/const.hpp
@@ -98,6 +98,8 @@
static constexpr auto VALUE_6 = 6;
static constexpr auto VALUE_7 = 7;
static constexpr auto VALUE_8 = 8;
+static constexpr auto VALUE_10 = 10;
+static constexpr auto VALUE_100000 = 100000;
static constexpr auto MASK_BYTE_BITS_6 = 0x40;
static constexpr auto MASK_BYTE_BITS_7 = 0x80;
diff --git a/vpd-manager/manager.cpp b/vpd-manager/manager.cpp
index 98e9238..767ea0b 100644
--- a/vpd-manager/manager.cpp
+++ b/vpd-manager/manager.cpp
@@ -10,6 +10,8 @@
#include "reader_impl.hpp"
#include "vpd_exceptions.hpp"
+#include <unistd.h>
+
#include <phosphor-logging/elog-errors.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
@@ -597,33 +599,56 @@
// required.
if (prePostActionRequired)
{
- // Check if device showed up (test for file)
- if (!filesystem::exists(item))
+ // The sleep of 1sec is sliced up in 10 retries of 10 miliseconds
+ // each.
+ for (auto retryCounter = VALUE_0; retryCounter <= VALUE_10;
+ retryCounter++)
{
- try
+ // sleep for 10 milisecond
+ if (usleep(VALUE_100000) != VALUE_0)
{
- // If not, then take failure postAction
- executePostFailAction(jsonFile, item);
+ std::cout << "Sleep failed before accessing the file"
+ << std::endl;
}
- catch (const GpioException& e)
- {
- PelAdditionalData additionalData{};
- additionalData.emplace("DESCRIPTION", e.what());
- createPEL(additionalData, PelSeverity::WARNING,
- errIntfForGpioError, sdBus);
- }
- }
- else
- {
- // bind the LED driver
- string chipAddr = singleFru.value("pcaChipAddress", "");
- cout << "performVPDRecollection: Executing driver binding for "
- "chip "
- "address - "
- << chipAddr << endl;
- executeCmd(createBindUnbindDriverCmnd(chipAddr, "i2c",
- "leds-pca955x", "/bind"));
+ // Check if file showed up
+ if (!filesystem::exists(item))
+ {
+ // Do we need to retry?
+ if (retryCounter < VALUE_10)
+ {
+ continue;
+ }
+
+ try
+ {
+ // If not, then take failure postAction
+ executePostFailAction(jsonFile, item);
+ }
+ catch (const GpioException& e)
+ {
+ PelAdditionalData additionalData{};
+ additionalData.emplace("DESCRIPTION", e.what());
+ createPEL(additionalData, PelSeverity::WARNING,
+ errIntfForGpioError, sdBus);
+ }
+ }
+ else
+ {
+ // bind the LED driver
+ string chipAddr = singleFru.value("pcaChipAddress", "");
+ cout
+ << "performVPDRecollection: Executing driver binding for "
+ "chip "
+ "address - "
+ << chipAddr << endl;
+
+ executeCmd(createBindUnbindDriverCmnd(
+ chipAddr, "i2c", "leds-pca955x", "/bind"));
+
+ // File has been found, kill the retry loop.
+ break;
+ }
}
}
}