diff options
-rw-r--r-- | item_updater.cpp | 4 | ||||
-rw-r--r-- | serialize.cpp | 41 | ||||
-rw-r--r-- | serialize.hpp | 7 |
3 files changed, 52 insertions, 0 deletions
diff --git a/item_updater.cpp b/item_updater.cpp index df73fc5..a4198ab 100644 --- a/item_updater.cpp +++ b/item_updater.cpp @@ -575,6 +575,10 @@ void ItemUpdater::updateUbootEnvVars(const std::string& versionId) log<level::ERR>("Failed to update u-boot env variables", entry("VERSIONID=%s", versionId.c_str())); } + + // On average this service takes about 5 seconds. Therefore setting + // it to 3x average time should be more than sufficient. + waitForServiceFile(updateEnvVarsFile, 15); } void ItemUpdater::resetUbootEnvVars() diff --git a/serialize.cpp b/serialize.cpp index b59ff46..29bd640 100644 --- a/serialize.cpp +++ b/serialize.cpp @@ -2,8 +2,11 @@ #include <experimental/filesystem> #include <cereal/archives/json.hpp> #include <fstream> +#include <unistd.h> #include "serialize.hpp" #include <sdbusplus/server.hpp> +#include <phosphor-logging/log.hpp> +#include <chrono> namespace phosphor { @@ -14,6 +17,9 @@ namespace updater namespace fs = std::experimental::filesystem; +using namespace phosphor::logging; +using namespace std::chrono_literals; + void storeToFile(std::string versionId, uint8_t priority) { auto bus = sdbusplus::bus::new_default(); @@ -34,6 +40,10 @@ void storeToFile(std::string versionId, uint8_t priority) SYSTEMD_INTERFACE, "StartUnit"); method.append(serviceFile, "replace"); bus.call_noreply(method); + + // On average it takes 1-2 seconds for the service to complete. + // Therefore timeout is set to 3x average completion time. + waitForServiceFile(serviceFile, 6); } bool restoreFromFile(std::string versionId, uint8_t& priority) @@ -104,6 +114,37 @@ void removeFile(std::string versionId) } } +void waitForServiceFile(const std::string& serviceFile, int timeout) +{ + auto bus = sdbusplus::bus::new_default(); + + std::time_t start = time(0); + std::time_t end = time(0); + + while (end - start < timeout) + { + auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, + SYSTEMD_INTERFACE, "GetUnit"); + method.append(serviceFile); + auto result = bus.call(method); + + // "GetUnit" returns the unit object path for a unit name. + // If the unit is not found because it hasn't been loaded yet, + // or in this case because it has finished and exited, the call + // will fail. + if (result.is_method_error()) + { + return; + } + + std::this_thread::sleep_for(1s); + end = time(0); + } + + log<level::ERR>("Service file timed out!", + entry("FILENAME=%s", serviceFile.c_str())); +} + } // namespace phosphor } // namespace software } // namespace openpower diff --git a/serialize.hpp b/serialize.hpp index 03eea99..604aada 100644 --- a/serialize.hpp +++ b/serialize.hpp @@ -30,6 +30,13 @@ bool restoreFromFile(std::string versionId, uint8_t& priority); **/ void removeFile(std::string versionId); +/** @brief Delays until the completion of the supplied service file or until + * specified timeout is reached. + * @param[in] serviceFile - Service file to wait for. + * @param[in] timeout - Fallback timeout so we don't get stuck. + **/ +void waitForServiceFile(const std::string& serviceFile, int timeout); + } // namespace phosphor } // namespace software } // namespace openpower |