From 6f5978d0fcf00b1a251d8c148e69482ca075d81e Mon Sep 17 00:00:00 2001 From: Anupama B R Date: Wed, 23 Oct 2024 06:16:23 -0500 Subject: [PATCH] Handle existing sym link with no devTree tag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit vpd-manager application is crashing while coming up when INVENTORY_JSON_SYM_LINK symbolic link exists already and pointing to the config JSON file having no ‘devTree’ tag in it. This commit adds the code to handle the above issue in the Worker class and handles the following scenarios as well, • If creating sym link fails with “File exists” error message, will try to delete the existing sym link and create sym link again with the system config JSON found for that system. - In case if deleting of sym link fails, will run the application with the existing configuration file itself. • getParsedJson API from jsonUtility is being used to parse the system config JSON file instead of nlohmann::json::parse API. As this API needs file stream object as an input. • In case, loaded system config JSON file from the above scenario doesn’t have ‘devTree’ tag again, application is allowed to run with that configuration. Signed-off-by: Anupama B R --- src/worker.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/src/worker.cpp b/src/worker.cpp index 82f25f646..69991bc68 100644 --- a/src/worker.cpp +++ b/src/worker.cpp @@ -448,6 +448,9 @@ void Worker::setDeviceTreeAndJson() types::VPDMapVariant parsedVpdMap; fillVPDMap(SYSTEM_VPD_FILE_PATH, parsedVpdMap); + // ToDo: Need to check is INVENTORY_JSON_SYM_LINK pointing to correct system + // JSON or not, if the sym link exists already. + // Do we have the entry for device tree in parsed JSON? if (m_parsedJson.find("devTree") == m_parsedJson.end()) { @@ -466,14 +469,47 @@ void Worker::setDeviceTreeAndJson() ec); if (ec) { - throw std::runtime_error( - "create_symlink system call failed with error" + ec.message()); + if (ec.message().compare("File exists") == + constants::STR_CMP_SUCCESS) + { + ec.clear(); + logging::logMessage( + "Sym link already exists, file [" + + std::string(INVENTORY_JSON_SYM_LINK) + + "] deleting and creating sym link again, target file: " + + systemJson); + + if (std::filesystem::remove(INVENTORY_JSON_SYM_LINK, ec)) + { + std::filesystem::create_symlink( + systemJson, INVENTORY_JSON_SYM_LINK, ec); + if (ec) + { + throw std::runtime_error( + "create_symlink system call failed with error: " + + ec.message()); + } + } + else + { + logging::logMessage( + "remove system call failed for file[" + + std::string(INVENTORY_JSON_SYM_LINK) + "], error[" + + ec.message() + "], continuing with existing sym link."); + } + } + else + { + throw std::runtime_error( + "create_symlink system call failed with error: " + + ec.message()); + } } // re-parse the JSON once appropriate JSON has been selected. try { - m_parsedJson = nlohmann::json::parse(INVENTORY_JSON_SYM_LINK); + m_parsedJson = jsonUtility::getParsedJson(INVENTORY_JSON_SYM_LINK); } catch (const nlohmann::json::parse_error& ex) { @@ -481,16 +517,23 @@ void Worker::setDeviceTreeAndJson() } } - auto devTreeFromJson = m_parsedJson["devTree"]; - if (devTreeFromJson.empty()) + std::string devTreeFromJson; + if (m_parsedJson.contains("devTree")) { - throw JsonException("Mandatory value for device tree missing from JSON", - INVENTORY_JSON_SYM_LINK); + devTreeFromJson = m_parsedJson["devTree"]; + + if (devTreeFromJson.empty()) + { + throw JsonException( + "Mandatory value for device tree missing from JSON", + INVENTORY_JSON_SYM_LINK); + } } auto fitConfigVal = readFitConfigValue(); - if (fitConfigVal.find(devTreeFromJson) != std::string::npos) + if (devTreeFromJson.empty() || + fitConfigVal.find(devTreeFromJson) != std::string::npos) { // fitconfig is updated and correct JSON is set. if (isSystemVPDOnDBus() && @@ -504,7 +547,6 @@ void Worker::setDeviceTreeAndJson() return; } - // Set fitconfig even if it is read as empty. setEnvAndReboot("fitconfig", devTreeFromJson); exit(EXIT_SUCCESS); }