xref: /openbmc/openpower-vpd-parser/wait-vpd-parser/src/wait_vpd_parser.cpp (revision 480807cf8a3ef27eef4063bac422d69343b123d1)
1 #include "config.h"
2 
3 #include "constants.hpp"
4 #include "logger.hpp"
5 #include "utility/dbus_utility.hpp"
6 
7 #include <CLI/CLI.hpp>
8 
9 #include <chrono>
10 #include <thread>
11 
12 /**
13  * @brief API to check for VPD collection status
14  *
15  * This API checks for VPD manager collection status by reading the
16  * collection "Status" property exposed by vpd-manager on Dbus. The read logic
17  * uses a retry loop with a specific number of retries with specific sleep time
18  * between each retry.
19  *
20  * @param[in] i_retryLimit - Maximum number of retries
21  * @param[in] i_sleepDurationInSeconds - Sleep time in seconds between each
22  * retry
23  *
24  * @return If "CollectionStatus" property is "Completed", returns 0, otherwise
25  * returns 1.
26  */
27 int checkVpdCollectionStatus(const unsigned i_retryLimit,
28                              const unsigned i_sleepDurationInSeconds) noexcept
29 {
30     auto l_logger = vpd::Logger::getLoggerInstance();
31 
32     try
33     {
34         l_logger->logMessage(
35             "Checking every " + std::to_string(i_sleepDurationInSeconds) +
36             "s for VPD collection status ....");
37 
38         for (unsigned l_retries = i_retryLimit;
39              l_retries != vpd::constants::VALUE_0; --l_retries)
40         {
41             // check at specified time interval
42             std::this_thread::sleep_for(
43                 std::chrono::seconds(i_sleepDurationInSeconds));
44 
45             const auto l_propValue = vpd::dbusUtility::readDbusProperty(
46                 IFACE, OBJPATH, vpd::constants::vpdCollectionInterface,
47                 "Status");
48 
49             if (auto l_val = std::get_if<std::string>(&l_propValue))
50             {
51                 if (*l_val == vpd::constants::vpdCollectionCompleted)
52                 {
53                     l_logger->logMessage("VPD collection is completed");
54                     return vpd::constants::VALUE_0;
55                 }
56             }
57 
58             l_logger->logMessage(
59                 "Waiting for VPD status update. Retries remaining: " +
60                 std::to_string(l_retries));
61         }
62 
63         l_logger->logMessage(
64             "Exit wait for VPD services to finish with timeout");
65     }
66     catch (const std::exception& l_ex)
67     {
68         l_logger->logMessage("Error while checking VPD collection status: " +
69                              std::string(l_ex.what()));
70     }
71 
72     return vpd::constants::VALUE_1;
73 }
74 
75 int main(int argc, char** argv)
76 {
77     CLI::App l_app{"Wait VPD parser app"};
78 
79     // default retry limit and sleep duration values
80     unsigned l_retryLimit{100};
81     unsigned l_sleepDurationInSeconds{2};
82 
83     l_app.add_option("--retryLimit, -r", l_retryLimit, "Retry limit");
84     l_app.add_option("--sleepDurationInSeconds, -s", l_sleepDurationInSeconds,
85                      "Sleep duration in seconds between each retry");
86 
87     CLI11_PARSE(l_app, argc, argv);
88 
89     return checkVpdCollectionStatus(l_retryLimit, l_sleepDurationInSeconds);
90 }
91