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 /** 76 * @brief API to trigger VPD collection for all FRUs. 77 * 78 * This API triggers VPD collection for all FRUs by calling Dbus API 79 * "CollectAllFRUVPD" exposed by vpd-manager 80 * 81 * @return - On success returns true, otherwise returns false 82 */ 83 inline bool collectAllFruVpd() noexcept 84 { 85 bool l_rc{true}; 86 try 87 { 88 auto l_bus = sdbusplus::bus::new_default(); 89 auto l_method = 90 l_bus.new_method_call(IFACE, OBJPATH, IFACE, "CollectAllFRUVPD"); 91 92 l_bus.call_noreply(l_method); 93 } 94 catch (const std::exception& l_ex) 95 { 96 auto l_logger = vpd::Logger::getLoggerInstance(); 97 l_logger->logMessage( 98 "Failed to trigger all FRU VPD collection. Error: " + 99 std::string(l_ex.what())); 100 l_rc = false; 101 } 102 return l_rc; 103 } 104 105 int main(int argc, char** argv) 106 { 107 CLI::App l_app{"Wait VPD parser app"}; 108 109 // default retry limit and sleep duration values 110 unsigned l_retryLimit{100}; 111 unsigned l_sleepDurationInSeconds{2}; 112 113 l_app.add_option("--retryLimit, -r", l_retryLimit, "Retry limit"); 114 l_app.add_option("--sleepDurationInSeconds, -s", l_sleepDurationInSeconds, 115 "Sleep duration in seconds between each retry"); 116 117 CLI11_PARSE(l_app, argc, argv); 118 119 return collectAllFruVpd() 120 ? checkVpdCollectionStatus(l_retryLimit, 121 l_sleepDurationInSeconds) 122 : vpd::constants::VALUE_1; 123 } 124