]> granicus.if.org Git - icinga2/commitdiff
Fix race conditions in the config compiler.
authorGunnar Beutner <gunnar@beutner.name>
Sat, 14 Dec 2013 22:10:37 +0000 (23:10 +0100)
committerGunnar Beutner <gunnar@beutner.name>
Sun, 15 Dec 2013 10:54:22 +0000 (11:54 +0100)
Fixes #5335

lib/config/configitem.cpp
lib/config/configitem.h
lib/config/configtype.cpp
lib/icinga/host.cpp
lib/icinga/service-downtime.cpp
lib/icinga/service-notification.cpp

index 0b1f242b4bdef61a721e536e8419461592a80cc8..f2b2c72e42f5dfebeecf1be3231b453459f8f658 100644 (file)
@@ -103,12 +103,12 @@ ExpressionList::Ptr ConfigItem::GetExpressionList(void) const
        return m_ExpressionList;
 }
 
-void ConfigItem::Link(void)
+ExpressionList::Ptr ConfigItem::GetLinkedExpressionList(void)
 {
        ASSERT(OwnsLock());
 
        if (m_LinkedExpressionList)
-               return;
+               return m_LinkedExpressionList;
 
        m_LinkedExpressionList = make_shared<ExpressionList>();
 
@@ -121,31 +121,25 @@ void ConfigItem::Link(void)
                            " exist (" << m_DebugInfo << ")";
                        ConfigCompilerContext::GetInstance()->AddMessage(true, message.str());
                } else {
-                       parent->Link();
+                       ExpressionList::Ptr pexprl;
+
+                       {
+                               ObjectLock olock(parent);
+                               pexprl = parent->GetLinkedExpressionList();
+                       }
 
-                       ExpressionList::Ptr pexprl = parent->m_LinkedExpressionList;
                        m_LinkedExpressionList->AddExpression(Expression("", OperatorExecute, pexprl, m_DebugInfo));
                }
        }
 
        m_LinkedExpressionList->AddExpression(Expression("", OperatorExecute, m_ExpressionList, m_DebugInfo));
-}
-
-ExpressionList::Ptr ConfigItem::GetLinkedExpressionList(void)
-{
-       ASSERT(OwnsLock());
-
-       if (!m_LinkedExpressionList)
-               Link();
 
        return m_LinkedExpressionList;
 }
 
 Dictionary::Ptr ConfigItem::GetProperties(void)
 {
-       ASSERT(!OwnsLock());
-
-       ObjectLock olock(this);
+       ASSERT(OwnsLock());
 
        if (!m_Properties) {
                m_Properties = make_shared<Dictionary>();
@@ -181,7 +175,13 @@ DynamicObject::Ptr ConfigItem::Commit(void)
        if (IsAbstract())
                return DynamicObject::Ptr();
 
-       Dictionary::Ptr properties = GetProperties();
+       Dictionary::Ptr properties;
+
+       {
+               ObjectLock olock(this);
+
+               properties = GetProperties();
+       }
 
        DynamicObject::Ptr dobj = dtype->CreateObject(properties);
        dobj->Register();
index bd69daff4a64150be6829a57fe7c4ee8b6b9e652..69b66a392a754abfa25a15c65b4c529fb82e563c 100644 (file)
@@ -65,7 +65,6 @@ public:
        static void DiscardItems(void);
 
 private:
-       void Link(void);
        ExpressionList::Ptr GetExpressionList(void) const;
 
        String m_Type; /**< The object type. */
index 5c18ddcfacee9d4082887be61b0d35ca59b3f195..30a2a766f1d27c7bb583ad364ecb43aaa2e8b30b 100644 (file)
@@ -79,11 +79,21 @@ void ConfigType::ValidateItem(const ConfigItem::Ptr& item)
        if (item->IsAbstract())
                return;
 
-       Dictionary::Ptr attrs = item->GetProperties();
+       Dictionary::Ptr attrs;
+       DebugInfo debugInfo;
+       String type, name;
+
+       {
+               ObjectLock olock(item);
+
+               attrs = item->GetProperties();
+               debugInfo = item->GetDebugInfo();
+               type = item->GetType();
+               name = item->GetName();
+       }
 
        std::vector<String> locations;
-       DebugInfo debugInfo  = item->GetDebugInfo();
-       locations.push_back("Object '" + item->GetName() + "' (Type: '" + item->GetType() + "') at " + debugInfo.Path + ":" + Convert::ToString(debugInfo.FirstLine));
+       locations.push_back("Object '" + name + "' (Type: '" + type + "') at " + debugInfo.Path + ":" + Convert::ToString(debugInfo.FirstLine));
 
        std::vector<TypeRuleList::Ptr> ruleLists;
        AddParentRules(ruleLists, GetSelf());
index adf476771cd0deb457c096906ccf822e9743d4dd..74e3a9c53b7429b66105ccca79d6d96e9ba9a7b7 100644 (file)
@@ -155,8 +155,16 @@ void Host::UpdateSlaveServices(void)
                path.push_back("services");
                path.push_back(kv.first);
 
+               ExpressionList::Ptr exprl;
+
+               {
+                       ObjectLock ilock(item);
+
+                       exprl = item->GetLinkedExpressionList();
+               }
+
                DebugInfo di;
-               item->GetLinkedExpressionList()->FindDebugInfoPath(path, di);
+               exprl->FindDebugInfoPath(path, di);
 
                if (di.Path.IsEmpty())
                        di = item->GetDebugInfo();
@@ -185,7 +193,7 @@ void Host::UpdateSlaveServices(void)
 
                /* Clone attributes from the service expression list. */
                ExpressionList::Ptr svc_exprl = make_shared<ExpressionList>();
-               item->GetLinkedExpressionList()->ExtractPath(path, svc_exprl);
+               exprl->ExtractPath(path, svc_exprl);
 
                builder->AddExpressionList(svc_exprl);
 
index 793452799a13418d7ae56103eec0a276c739b6dc..f014ab262cb5c0c9168044e47ffd3c3c96832257 100644 (file)
@@ -335,8 +335,16 @@ void Service::UpdateSlaveScheduledDowntimes(void)
                path.push_back("scheduled_downtimes");
                path.push_back(kv.first);
 
+               ExpressionList::Ptr exprl;
+
+               {
+                       ObjectLock ilock(item);
+
+                       exprl = item->GetLinkedExpressionList();
+               }
+
                DebugInfo di;
-               item->GetLinkedExpressionList()->FindDebugInfoPath(path, di);
+               exprl->FindDebugInfoPath(path, di);
 
                if (di.Path.IsEmpty())
                        di = item->GetDebugInfo();
@@ -361,7 +369,7 @@ void Service::UpdateSlaveScheduledDowntimes(void)
 
                /* Clone attributes from the scheduled downtime expression list. */
                ExpressionList::Ptr sd_exprl = make_shared<ExpressionList>();
-               item->GetLinkedExpressionList()->ExtractPath(path, sd_exprl);
+               exprl->ExtractPath(path, sd_exprl);
 
                builder->AddExpressionList(sd_exprl);
 
index b4808659c1ca80f247ef9404e73d211ffbf6ba1b..083b1d52e2ce860713936bba82d200fed1c1b714 100644 (file)
@@ -114,8 +114,16 @@ void Service::UpdateSlaveNotifications(void)
                path.push_back("notifications");
                path.push_back(kv.first);
 
+               ExpressionList::Ptr exprl;
+
+               {
+                       ObjectLock ilock(exprl);
+
+                       exprl = item->GetLinkedExpressionList();
+               }
+
                DebugInfo di;
-               item->GetLinkedExpressionList()->FindDebugInfoPath(path, di);
+               exprl->FindDebugInfoPath(path, di);
 
                if (di.Path.IsEmpty())
                        di = item->GetDebugInfo();
@@ -140,7 +148,7 @@ void Service::UpdateSlaveNotifications(void)
 
                /* Clone attributes from the notification expression list. */
                ExpressionList::Ptr nfc_exprl = make_shared<ExpressionList>();
-               item->GetLinkedExpressionList()->ExtractPath(path, nfc_exprl);
+               exprl->ExtractPath(path, nfc_exprl);
 
                builder->AddExpressionList(nfc_exprl);