From ce3275d27f710bc239b914204e15ecae5540637f Mon Sep 17 00:00:00 2001 From: Yonas Habteab Date: Tue, 22 Jul 2025 11:25:03 +0200 Subject: [PATCH] Disallow stage deletions during reload Once the new worker process has read the config, it also includes a `include */include.conf` statement within the config packages root directory, and from there on we must not allow to delete any stage directory from the config package. Otherwise, when the worker actually evaluates that include statement, it will fail to find the directory where the include file is located, or the `active.conf` file, which is included from each stage's `include.conf` file, thus causing the worker fail. Co-Authored-By: Johannes Schmidt --- lib/remote/configpackageshandler.cpp | 13 +++++++++++++ lib/remote/configstageshandler.cpp | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/remote/configpackageshandler.cpp b/lib/remote/configpackageshandler.cpp index 7987092bc..f24f5b1d2 100644 --- a/lib/remote/configpackageshandler.cpp +++ b/lib/remote/configpackageshandler.cpp @@ -2,6 +2,7 @@ #include "remote/configpackageshandler.hpp" #include "remote/configpackageutility.hpp" +#include "remote/configobjectslock.hpp" #include "remote/httputility.hpp" #include "remote/filterutility.hpp" #include "base/exception.hpp" @@ -111,6 +112,12 @@ void ConfigPackagesHandler::HandlePost( return; } + ConfigObjectsSharedLock configObjectsSharedLock(std::try_to_lock); + if (!configObjectsSharedLock) { + HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading"); + return; + } + try { std::unique_lock lock(ConfigPackageUtility::GetStaticPackageMutex()); @@ -157,6 +164,12 @@ void ConfigPackagesHandler::HandleDelete( return; } + ConfigObjectsSharedLock lock(std::try_to_lock); + if (!lock) { + HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading"); + return; + } + try { ConfigPackageUtility::DeletePackage(packageName); } catch (const std::exception& ex) { diff --git a/lib/remote/configstageshandler.cpp b/lib/remote/configstageshandler.cpp index 95d1b1b6e..451ba1dbf 100644 --- a/lib/remote/configstageshandler.cpp +++ b/lib/remote/configstageshandler.cpp @@ -2,6 +2,7 @@ #include "remote/configstageshandler.hpp" #include "remote/configpackageutility.hpp" +#include "remote/configobjectslock.hpp" #include "remote/httputility.hpp" #include "remote/filterutility.hpp" #include "base/application.hpp" @@ -135,6 +136,12 @@ void ConfigStagesHandler::HandlePost( if (reload && !activate) BOOST_THROW_EXCEPTION(std::invalid_argument("Parameter 'reload' must be false when 'activate' is false.")); + ConfigObjectsSharedLock configObjectsSharedLock(std::try_to_lock); + if (!configObjectsSharedLock) { + HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading"); + return; + } + { std::lock_guard runningPackageUpdatesLock(l_RunningPackageUpdatesMutex); double currentReloadFailedTime = Application::GetLastReloadFailed(); @@ -228,6 +235,12 @@ void ConfigStagesHandler::HandleDelete( if (!ConfigPackageUtility::ValidateStageName(stageName)) return HttpUtility::SendJsonError(response, params, 400, "Invalid stage name '" + stageName + "'."); + ConfigObjectsSharedLock lock(std::try_to_lock); + if (!lock) { + HttpUtility::SendJsonError(response, params, 503, "Icinga is reloading"); + return; + } + try { ConfigPackageUtility::DeleteStage(packageName, stageName); } catch (const std::exception& ex) {