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