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 */ 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 */ 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 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