]> granicus.if.org Git - icinga2/commitdiff
Make sure we don't block on write() while holding locks.
authorGunnar Beutner <gunnar.beutner@netways.de>
Sun, 24 Feb 2013 11:47:24 +0000 (12:47 +0100)
committerGunnar Beutner <gunnar.beutner@netways.de>
Sun, 24 Feb 2013 11:47:24 +0000 (12:47 +0100)
components/compat/compatcomponent.cpp
components/compat/compatcomponent.h
lib/icinga/externalcommandprocessor.cpp
lib/icinga/notification.cpp
lib/icinga/notification.h
lib/icinga/pluginchecktask.cpp
lib/icinga/pluginchecktask.h
lib/icinga/service.cpp
lib/icinga/service.h

index 0fc59f6ca9902705dde70310d0a48ea2b175e363..eede038b0d39d2c253a4a8c00266f8f95d014b6c 100644 (file)
@@ -175,7 +175,7 @@ void CompatComponent::ProcessCommand(const String& command)
 }
 #endif /* _WIN32 */
 
-void CompatComponent::DumpComments(ofstream& fp, const Service::Ptr& owner, CompatObjectType type)
+void CompatComponent::DumpComments(ostream& fp, const Service::Ptr& owner, CompatObjectType type)
 {
        ObjectLock olock(owner);
 
@@ -212,7 +212,7 @@ void CompatComponent::DumpComments(ofstream& fp, const Service::Ptr& owner, Comp
        }
 }
 
-void CompatComponent::DumpDowntimes(ofstream& fp, const Service::Ptr& owner, CompatObjectType type)
+void CompatComponent::DumpDowntimes(ostream& fp, const Service::Ptr& owner, CompatObjectType type)
 {
        ObjectLock olock(owner);
 
@@ -255,7 +255,7 @@ void CompatComponent::DumpDowntimes(ofstream& fp, const Service::Ptr& owner, Com
        }
 }
 
-void CompatComponent::DumpHostStatus(ofstream& fp, const Host::Ptr& host)
+void CompatComponent::DumpHostStatus(ostream& fp, const Host::Ptr& host)
 {
        Service::Ptr hc;
 
@@ -294,7 +294,7 @@ void CompatComponent::DumpHostStatus(ofstream& fp, const Host::Ptr& host)
        }
 }
 
-void CompatComponent::DumpHostObject(ofstream& fp, const Host::Ptr& host)
+void CompatComponent::DumpHostObject(ostream& fp, const Host::Ptr& host)
 {
        ObjectLock olock(host);
 
@@ -319,7 +319,7 @@ void CompatComponent::DumpHostObject(ofstream& fp, const Host::Ptr& host)
           << "\n";
 }
 
-void CompatComponent::DumpServiceStatusAttrs(ofstream& fp, const Service::Ptr& service, CompatObjectType type)
+void CompatComponent::DumpServiceStatusAttrs(ostream& fp, const Service::Ptr& service, CompatObjectType type)
 {
        String output;
        String perfdata;
@@ -388,7 +388,7 @@ void CompatComponent::DumpServiceStatusAttrs(ofstream& fp, const Service::Ptr& s
        }
 }
 
-void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& service)
+void CompatComponent::DumpServiceStatus(ostream& fp, const Service::Ptr& service)
 {
        String host_name, short_name;
        Host::Ptr host;
@@ -417,7 +417,7 @@ void CompatComponent::DumpServiceStatus(ofstream& fp, const Service::Ptr& servic
        DumpComments(fp, service, CompatTypeService);
 }
 
-void CompatComponent::DumpServiceObject(ofstream& fp, const Service::Ptr& service)
+void CompatComponent::DumpServiceObject(ostream& fp, const Service::Ptr& service)
 {
        set<Service::Ptr> parentServices;
        Host::Ptr host;
@@ -534,48 +534,64 @@ void CompatComponent::StatusTimerHandler(void)
        BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Host")) {
                Host::Ptr host = static_pointer_cast<Host>(object);
 
-               DumpHostStatus(statusfp, host);
-               DumpHostObject(objectfp, host);
+               stringstream tempstatusfp, tempobjectfp;
+
+               DumpHostStatus(tempstatusfp, host);
+               DumpHostObject(tempobjectfp, host);
+
+               statusfp << tempstatusfp.str();
+               objectfp << tempobjectfp.str();
        }
 
        BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("HostGroup")) {
                HostGroup::Ptr hg = static_pointer_cast<HostGroup>(object);
 
+               stringstream tempobjectfp;
+
                {
                        ObjectLock olock(hg);
 
-                       objectfp << "define hostgroup {" << "\n"
+                       tempobjectfp << "define hostgroup {" << "\n"
                                 << "\t" << "hostgroup_name" << "\t" << hg->GetName() << "\n"
                                 << "\t" << "notes_url" << "\t" << hg->GetNotesUrl() << "\n"
                                 << "\t" << "action_url" << "\t" << hg->GetActionUrl() << "\n";
                }
 
-               objectfp << "\t" << "members" << "\t";
-               DumpNameList(objectfp, HostGroup::GetMembers(hg));
-               objectfp << "\n"
+               tempobjectfp << "\t" << "members" << "\t";
+               DumpNameList(tempobjectfp, HostGroup::GetMembers(hg));
+               tempobjectfp << "\n"
                         << "}" << "\n";
+
+               objectfp << tempobjectfp.str();
        }
 
        BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("Service")) {
                Service::Ptr service = static_pointer_cast<Service>(object);
 
+               stringstream tempstatusfp, tempobjectfp;
+
                DumpServiceStatus(statusfp, service);
                DumpServiceObject(objectfp, service);
+
+               statusfp << tempstatusfp.str();
+               objectfp << tempobjectfp.str();
        }
 
        BOOST_FOREACH(const DynamicObject::Ptr& object, DynamicType::GetObjects("ServiceGroup")) {
                ServiceGroup::Ptr sg = static_pointer_cast<ServiceGroup>(object);
 
+               stringstream tempobjectfp;
+
                {
                        ObjectLock olock(sg);
 
-                       objectfp << "define servicegroup {" << "\n"
+                       tempobjectfp << "define servicegroup {" << "\n"
                                 << "\t" << "servicegroup_name" << "\t" << sg->GetName() << "\n"
                                 << "\t" << "notes_url" << "\t" << sg->GetNotesUrl() << "\n"
                                 << "\t" << "action_url" << "\t" << sg->GetActionUrl() << "\n";
                }
 
-               objectfp << "\t" << "members" << "\t";
+               tempobjectfp << "\t" << "members" << "\t";
 
                vector<String> sglist;
                BOOST_FOREACH(const Service::Ptr& service, ServiceGroup::GetMembers(sg)) {
@@ -597,10 +613,12 @@ void CompatComponent::StatusTimerHandler(void)
                        sglist.push_back(short_name);
                }
 
-               DumpStringList(objectfp, sglist);
+               DumpStringList(tempobjectfp, sglist);
 
-               objectfp << "\n"
+               tempobjectfp << "\n"
                         << "}" << "\n";
+
+               objectfp << tempobjectfp.str();
        }
 
        statusfp.close();
index 749801aea27c792d5fbde41f9e2a471bbc320ace..eda87c0434f51d2f2ddb35dab120d837451b89e0 100644 (file)
@@ -53,15 +53,15 @@ private:
        String GetLogPath(void) const;
        String GetCommandPath(void) const;
 
-       void DumpDowntimes(ofstream& fp, const Service::Ptr& owner, CompatObjectType type);
-       void DumpComments(ofstream& fp, const Service::Ptr& owner, CompatObjectType type);
-       void DumpHostStatus(ofstream& fp, const Host::Ptr& host);
-       void DumpHostObject(ofstream& fp, const Host::Ptr& host);
+       void DumpDowntimes(ostream& fp, const Service::Ptr& owner, CompatObjectType type);
+       void DumpComments(ostream& fp, const Service::Ptr& owner, CompatObjectType type);
+       void DumpHostStatus(ostream& fp, const Host::Ptr& host);
+       void DumpHostObject(ostream& fp, const Host::Ptr& host);
 
-       void DumpServiceStatusAttrs(ofstream& fp, const Service::Ptr& service, CompatObjectType type);
+       void DumpServiceStatusAttrs(ostream& fp, const Service::Ptr& service, CompatObjectType type);
 
        template<typename T>
-       void DumpNameList(ofstream& fp, const T& list)
+       void DumpNameList(ostream& fp, const T& list)
        {
                typename T::const_iterator it;
                bool first = true;
@@ -77,7 +77,7 @@ private:
        }
 
        template<typename T>
-       void DumpStringList(ofstream& fp, const T& list)
+       void DumpStringList(ostream& fp, const T& list)
        {
                typename T::const_iterator it;
                bool first = true;
@@ -91,8 +91,8 @@ private:
                }
        }
 
-       void DumpServiceStatus(ofstream& fp, const Service::Ptr& service);
-       void DumpServiceObject(ofstream& fp, const Service::Ptr& service);
+       void DumpServiceStatus(ostream& fp, const Service::Ptr& service);
+       void DumpServiceObject(ostream& fp, const Service::Ptr& service);
 
        void StatusTimerHandler(void);
 };
index ed9621cb64dc39d07e54da1fb10966e1d5eaab7b..4bcb33e437da7f2ee57456ee1a0eec69340db1ae 100644 (file)
@@ -306,8 +306,7 @@ void ExternalCommandProcessor::AcknowledgeSvcProblem(double, const vector<String
                BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' is OK."));
 
        Logger::Write(LogInformation, "icinga", "Setting acknowledgement for service '" + service->GetName() + "'");
-       service->SetAcknowledgement(sticky ? AcknowledgementSticky : AcknowledgementNormal);
-       service->SetAcknowledgementExpiry(0);
+       service->AcknowledgeProblem(sticky ? AcknowledgementSticky : AcknowledgementNormal);
 }
 
 void ExternalCommandProcessor::AcknowledgeSvcProblemExpire(double, const vector<String>& arguments)
@@ -324,8 +323,7 @@ void ExternalCommandProcessor::AcknowledgeSvcProblemExpire(double, const vector<
                BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' is OK."));
 
        Logger::Write(LogInformation, "icinga", "Setting timed acknowledgement for service '" + service->GetName() + "'");
-       service->SetAcknowledgement(sticky ? AcknowledgementSticky : AcknowledgementNormal);
-       service->SetAcknowledgementExpiry(timestamp);
+       service->AcknowledgeProblem(sticky ? AcknowledgementSticky : AcknowledgementNormal, timestamp);
 }
 
 void ExternalCommandProcessor::RemoveSvcAcknowledgement(double, const vector<String>& arguments)
@@ -336,8 +334,7 @@ void ExternalCommandProcessor::RemoveSvcAcknowledgement(double, const vector<Str
        Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
 
        Logger::Write(LogInformation, "icinga", "Removing acknowledgement for service '" + service->GetName() + "'");
-       service->SetAcknowledgement(AcknowledgementNone);
-       service->SetAcknowledgementExpiry(0);
+       service->ClearAcknowledgement();
 }
 
 void ExternalCommandProcessor::AcknowledgeHostProblem(double, const vector<String>& arguments)
@@ -355,8 +352,7 @@ void ExternalCommandProcessor::AcknowledgeHostProblem(double, const vector<Strin
                if (service->GetState() == StateOK)
                        BOOST_THROW_EXCEPTION(invalid_argument("The host '" + arguments[0] + "' is OK."));
 
-               service->SetAcknowledgement(sticky ? AcknowledgementSticky : AcknowledgementNormal);
-               service->SetAcknowledgementExpiry(0);
+               service->AcknowledgeProblem(sticky ? AcknowledgementSticky : AcknowledgementNormal);
        }
 }
 
@@ -376,8 +372,7 @@ void ExternalCommandProcessor::AcknowledgeHostProblemExpire(double, const vector
                if (service->GetState() == StateOK)
                        BOOST_THROW_EXCEPTION(invalid_argument("The host '" + arguments[0] + "' is OK."));
 
-               service->SetAcknowledgement(sticky ? AcknowledgementSticky : AcknowledgementNormal);
-               service->SetAcknowledgementExpiry(timestamp);
+               service->AcknowledgeProblem(sticky ? AcknowledgementSticky : AcknowledgementNormal, timestamp);
        }
 }
 
@@ -391,8 +386,7 @@ void ExternalCommandProcessor::RemoveHostAcknowledgement(double, const vector<St
        Logger::Write(LogInformation, "icinga", "Removing acknowledgement for host '" + host->GetName() + "'");
        Service::Ptr service = host->GetHostCheckService();
        if (service) {
-               service->SetAcknowledgement(AcknowledgementNone);
-               service->SetAcknowledgementExpiry(0);
+               service->ClearAcknowledgement();
        }
 }
 
index 4e8e574e9873ef193156d9f86e2c22b2850ae4e6..0625f7f6f1366673d3ce138c05758e45c8b52ba6 100644 (file)
@@ -96,7 +96,9 @@ String Notification::NotificationTypeToString(NotificationType type)
                case NotificationDowntimeRemoved:
                        return "DOWNTIMECANCELLED";
                case NotificationCustom:
-                       return "DOWNTIMECUSTOM";
+                       return "CUSTOM";
+               case NotificationAcknowledgement:
+                       return "ACKNOWLEDGEMENT";
                case NotificationProblem:
                        return "PROBLEM";
                case NotificationRecovery:
index 176fbee8f76f2d3251bf5a5cce3568300d89125d..0a989c65c32b22a98dda7150c4a831556207a50f 100644 (file)
@@ -34,6 +34,7 @@ enum NotificationType
        NotificationDowntimeEnd,
        NotificationDowntimeRemoved,
        NotificationCustom,
+       NotificationAcknowledgement,
        NotificationProblem,
        NotificationRecovery
 };
index 6870ceb83e28b8f94f98dd871fb13cc233de9bbf..f3ab963d6236e9e113db619483f2bb5e8436cbd2 100644 (file)
@@ -23,8 +23,8 @@ using namespace icinga;
 
 REGISTER_SCRIPTFUNCTION("PluginCheck",  &PluginCheckTask::ScriptFunc);
 
-PluginCheckTask::PluginCheckTask(const ScriptTask::Ptr& task, const Process::Ptr& process)
-       : m_Task(task), m_Process(process)
+PluginCheckTask::PluginCheckTask(const ScriptTask::Ptr& task, const Process::Ptr& process, const Value& command)
+       : m_Task(task), m_Process(process), m_Command(command)
 { }
 
 void PluginCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value>& arguments)
@@ -49,7 +49,7 @@ void PluginCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value
 
        Process::Ptr process = boost::make_shared<Process>(Process::SplitCommand(command), macros);
 
-       PluginCheckTask ct(task, process);
+       PluginCheckTask ct(task, process, command);
 
        process->Start(boost::bind(&PluginCheckTask::ProcessFinishedHandler, ct));
 }
@@ -71,6 +71,7 @@ void PluginCheckTask::ProcessFinishedHandler(PluginCheckTask ct)
        String output = pr.Output;
        output.Trim();
        Dictionary::Ptr result = ParseCheckOutput(output);
+       result->Set("command", ct.m_Command);
        result->Set("state", ExitStatusToState(pr.ExitStatus));
        result->Set("execution_start", pr.ExecutionStart);
        result->Set("execution_end", pr.ExecutionEnd);
index e282e27f305e43ee8c76e09e93724909db505967..ddbd35a4e603b634cc924c13bfd8b11b3736e12c 100644 (file)
@@ -39,10 +39,11 @@ public:
 private:
        static void ProcessFinishedHandler(PluginCheckTask ct);
 
-       PluginCheckTask(const ScriptTask::Ptr& task, const Process::Ptr& process);
+       PluginCheckTask(const ScriptTask::Ptr& task, const Process::Ptr& process, const Value& command);
 
        ScriptTask::Ptr m_Task;
        Process::Ptr m_Process;
+       Value m_Command;
 };
 
 }
index 291e795174a4ad0e91450363ede8f228465ef6a6..dd12b62fc6a49ba74aaca1a59a2e06f357b02ec1 100644 (file)
@@ -258,6 +258,20 @@ void Service::SetAcknowledgementExpiry(double timestamp)
        Set("acknowledgement_expiry", timestamp);
 }
 
+void Service::AcknowledgeProblem(AcknowledgementType type, double expiry)
+{
+       SetAcknowledgement(type);
+       SetAcknowledgementExpiry(expiry);
+
+       RequestNotifications(NotificationAcknowledgement);
+}
+
+void Service::ClearAcknowledgement(void)
+{
+       SetAcknowledgement(AcknowledgementNone);
+       SetAcknowledgementExpiry(0);
+}
+
 void Service::OnAttributeChanged(const String& name, const Value& oldValue)
 {
        if (name == "checker")
index 7dba9058ceda2b0f57b12a29ac761327172a25e6..9ff744fe2bc2eafced7756835c0b5c092424ceb5 100644 (file)
@@ -171,6 +171,9 @@ public:
        void ApplyCheckResult(const Dictionary::Ptr& cr);
        static void UpdateStatistics(const Dictionary::Ptr& cr);
 
+       void AcknowledgeProblem(AcknowledgementType type, double expiry = 0);
+       void ClearAcknowledgement(void);
+
        static void BeginExecuteCheck(const Service::Ptr& self, const function<void (void)>& callback);
        void ProcessCheckResult(const Dictionary::Ptr& cr);