xref: /openbmc/openpower-vpd-parser/wait-vpd-parser/src/wait_vpd_parser.cpp (revision 445819fc74795c53cb3061468c24310d352e327c)
1 #include "config.h"
2 
3 #include "constants.hpp"
4 #include "logger.hpp"
5 #include "prime_inventory.hpp"
6 #include "utility/dbus_utility.hpp"
7 
8 #include <CLI/CLI.hpp>
9 
10 #include <chrono>
11 #include <thread>
12 
13 /**
14  * @brief API to check for VPD collection status
15  *
16  * This API checks for VPD manager collection status by reading the
17  * collection "Status" property exposed by vpd-manager on Dbus. The read logic
18  * uses a retry loop with a specific number of retries with specific sleep time
19  * between each retry.
20  *
21  * @param[in] i_retryLimit - Maximum number of retries
22  * @param[in] i_sleepDurationInSeconds - Sleep time in seconds between each
23  * retry
24  *
25  * @return If "CollectionStatus" property is "Completed", returns 0, otherwise
26  * returns 1.
27  */
checkVpdCollectionStatus(const unsigned i_retryLimit,const unsigned i_sleepDurationInSeconds)28 int checkVpdCollectionStatus(const unsigned i_retryLimit,
29                              const unsigned i_sleepDurationInSeconds) noexcept
30 {
31     auto l_logger = vpd::Logger::getLoggerInstance();
32 
33     try
34     {
35         l_logger->logMessage(
36             "Checking every " + std::to_string(i_sleepDurationInSeconds) +
37             "s for VPD collection status ....");
38 
39         for (unsigned l_retries = i_retryLimit;
40              l_retries != vpd::constants::VALUE_0; --l_retries)
41         {
42             // check at specified time interval
43             std::this_thread::sleep_for(
44                 std::chrono::seconds(i_sleepDurationInSeconds));
45 
46             const auto l_propValue = vpd::dbusUtility::readDbusProperty(
47                 IFACE, OBJPATH, vpd::constants::vpdCollectionInterface,
48                 "Status");
49 
50             if (auto l_val = std::get_if<std::string>(&l_propValue))
51             {
52                 if (*l_val == vpd::constants::vpdCollectionCompleted)
53                 {
54                     l_logger->logMessage("VPD collection is completed");
55                     return vpd::constants::VALUE_0;
56                 }
57             }
58 
59             l_logger->logMessage(
60                 "Waiting for VPD status update. Retries remaining: " +
61                 std::to_string(l_retries));
62         }
63 
64         l_logger->logMessage(
65             "Exit wait for VPD services to finish with timeout");
66     }
67     catch (const std::exception& l_ex)
68     {
69         l_logger->logMessage("Error while checking VPD collection status: " +
70                              std::string(l_ex.what()));
71     }
72 
73     return vpd::constants::VALUE_1;
74 }
75 
76 /**
77  * @brief API to trigger VPD collection for all FRUs.
78  *
79  * This API triggers VPD collection for all FRUs by calling Dbus API
80  * "CollectAllFRUVPD" exposed by vpd-manager
81  *
82  * @return - On success returns true, otherwise returns false
83  */
collectAllFruVpd()84 inline bool collectAllFruVpd() noexcept
85 {
86     bool l_rc{true};
87     try
88     {
89         auto l_bus = sdbusplus::bus::new_default();
90         auto l_method =
91             l_bus.new_method_call(IFACE, OBJPATH, IFACE, "CollectAllFRUVPD");
92 
93         l_bus.call_noreply(l_method);
94     }
95     catch (const std::exception& l_ex)
96     {
97         auto l_logger = vpd::Logger::getLoggerInstance();
98         l_logger->logMessage(
99             "Failed to trigger all FRU VPD collection. Error: " +
100             std::string(l_ex.what()));
101         l_rc = false;
102     }
103     return l_rc;
104 }
105 
main(int argc,char ** argv)106 int main(int argc, char** argv)
107 {
108     try
109     {
110         CLI::App l_app{"Wait VPD parser app"};
111 
112         // default retry limit and sleep duration values
113         unsigned l_retryLimit{100};
114         unsigned l_sleepDurationInSeconds{2};
115 
116         l_app.add_option("--retryLimit, -r", l_retryLimit, "Retry limit");
117         l_app.add_option("--sleepDurationInSeconds, -s",
118                          l_sleepDurationInSeconds,
119                          "Sleep duration in seconds between each retry");
120 
121         CLI11_PARSE(l_app, argc, argv);
122 
123         PrimeInventory l_primeObj;
124         l_primeObj.primeSystemBlueprint();
125 
126         return collectAllFruVpd()
127                    ? checkVpdCollectionStatus(l_retryLimit,
128                                               l_sleepDurationInSeconds)
129                    : vpd::constants::VALUE_1;
130     }
131     catch (const std::exception& l_ex)
132     {
133         const auto l_logger = vpd::Logger::getLoggerInstance();
134         l_logger->logMessage("Exiting from wait-vpd-parser, reason: " +
135                              std::string(l_ex.what()));
136         return vpd::constants::VALUE_1;
137     }
138 }
139