]> granicus.if.org Git - icinga2/commitdiff
Avoid dead-lock with config packages and active stages
authorMichael Friedrich <michael.friedrich@icinga.com>
Wed, 8 May 2019 14:06:46 +0000 (16:06 +0200)
committerMichael Friedrich <michael.friedrich@icinga.com>
Wed, 8 May 2019 14:06:46 +0000 (16:06 +0200)
lib/remote/configobjectutility.cpp
lib/remote/configpackageshandler.cpp
lib/remote/configpackageutility.cpp
lib/remote/configpackageutility.hpp
lib/remote/configstageshandler.cpp

index 77714e4a9b525978c7ec90c42e5b9466c0ffc10f..503cdbb45b21c48571e836d8da0056c811ff4b81 100644 (file)
@@ -85,7 +85,8 @@ bool ConfigObjectUtility::CreateObject(const Type::Ptr& type, const String& full
        const String& config, const Array::Ptr& errors, const Array::Ptr& diagnosticInformation)
 {
        {
-               boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex());
+               boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticPackageMutex());
+
                if (!ConfigPackageUtility::PackageExists("_api")) {
                        ConfigPackageUtility::CreatePackage("_api");
 
index d9cd9ec9b4f98d7715aa02f56b804768fcb14474..fd60661f71e146d59ffc8b742af2a6df40182e3d 100644 (file)
@@ -63,7 +63,8 @@ void ConfigPackagesHandler::HandleGet(
        ArrayData results;
 
        {
-               boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex());
+               boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticPackageMutex());
+
                for (const String& package : packages) {
                        results.emplace_back(new Dictionary({
                                { "name", package },
@@ -104,7 +105,8 @@ void ConfigPackagesHandler::HandlePost(
        }
 
        try {
-               boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex());
+               boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticPackageMutex());
+
                ConfigPackageUtility::CreatePackage(packageName);
        } catch (const std::exception& ex) {
                HttpUtility::SendJsonError(response, params, 500, "Could not create package '" + packageName + "'.",
index b56bbb9fc1deef468fd17dc17ac399c893e0f173..d0bf90061f2acc7defea886f244ee90fd02afff2 100644 (file)
@@ -186,7 +186,8 @@ void ConfigPackageUtility::TryActivateStageCallback(const ProcessResult& pr, con
        /* validation went fine, activate stage and reload */
        if (pr.ExitStatus == 0) {
                {
-                       boost::mutex::scoped_lock lock(GetStaticMutex());
+                       boost::mutex::scoped_lock lock(GetStaticPackageMutex());
+
                        ActivateStage(packageName, stageName);
                }
 
@@ -251,7 +252,7 @@ std::vector<String> ConfigPackageUtility::GetStages(const String& packageName)
 String ConfigPackageUtility::GetActiveStageFromFile(const String& packageName)
 {
        /* Lock the transaction, reading this only happens on startup or when something really is broken. */
-       boost::mutex::scoped_lock lock(GetStaticMutex());
+       boost::mutex::scoped_lock lock(GetStaticActiveStageMutex());
 
        String path = GetPackageDir() + "/" + packageName + "/active-stage";
 
@@ -271,7 +272,7 @@ String ConfigPackageUtility::GetActiveStageFromFile(const String& packageName)
 
 void ConfigPackageUtility::SetActiveStageToFile(const String& packageName, const String& stageName)
 {
-       boost::mutex::scoped_lock lock(GetStaticMutex());
+       boost::mutex::scoped_lock lock(GetStaticActiveStageMutex());
 
        String activeStagePath = GetPackageDir() + "/" + packageName + "/active-stage";
 
@@ -380,7 +381,13 @@ bool ConfigPackageUtility::ValidateName(const String& name)
        return (!boost::regex_search(name.GetData(), what, expr));
 }
 
-boost::mutex& ConfigPackageUtility::GetStaticMutex()
+boost::mutex& ConfigPackageUtility::GetStaticPackageMutex()
+{
+       static boost::mutex mutex;
+       return mutex;
+}
+
+boost::mutex& ConfigPackageUtility::GetStaticActiveStageMutex()
 {
        static boost::mutex mutex;
        return mutex;
index 11b2b9977a190f69dc486cd3a39ff6e5c37bc37e..9f105794ce7d96190ddd7eb0499f44b9b305abcd 100644 (file)
@@ -44,7 +44,8 @@ public:
        static bool ContainsDotDot(const String& path);
        static bool ValidateName(const String& name);
 
-       static boost::mutex& GetStaticMutex();
+       static boost::mutex& GetStaticPackageMutex();
+       static boost::mutex& GetStaticActiveStageMutex();
 
 private:
        static void CollectDirNames(const String& path, std::vector<String>& dirs);
index a3c570a2fe8264750cfad5adbc205e8244371c9f..2730ac37b1ff34f92720524d028b20d0018ff39a 100644 (file)
@@ -120,7 +120,8 @@ void ConfigStagesHandler::HandlePost(
                if (!files)
                        BOOST_THROW_EXCEPTION(std::invalid_argument("Parameter 'files' must be specified."));
 
-               boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticMutex());
+               boost::mutex::scoped_lock lock(ConfigPackageUtility::GetStaticPackageMutex());
+
                stageName = ConfigPackageUtility::CreateStage(packageName, files);
 
                /* validate the config. on success, activate stage and reload */