]> granicus.if.org Git - icinga2/commitdiff
Try to queue all PROCESS_FILE commands instead of exploding the stack
authorVytenis Darulis <vytenis@uber.com>
Tue, 27 Oct 2015 17:00:55 +0000 (17:00 +0000)
committerMichael Friedrich <michael.friedrich@netways.de>
Wed, 24 Feb 2016 22:25:22 +0000 (23:25 +0100)
fixes #10426

Signed-off-by: Michael Friedrich <michael.friedrich@netways.de>
lib/icinga/externalcommandprocessor.cpp
lib/icinga/externalcommandprocessor.hpp

index e0a6b317efd2deb4a5a84e0008745af46e7fb103..226044e5e58658393828d7db39e7c47f8a3f26e5 100644 (file)
@@ -290,6 +290,44 @@ void ExternalCommandProcessor::StaticInitialize(void)
        RegisterCommand("DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS", &ExternalCommandProcessor::DisableServicegroupSvcNotifications, 1);
 }
 
+void ExternalCommandProcessor::ExecuteFromFile(const String& line, std::deque< std::vector<String> >& file_queue)
+{
+       if (line.IsEmpty())
+               return;
+
+       if (line[0] != '[')
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Missing timestamp in command: " + line));
+
+       size_t pos = line.FindFirstOf("]");
+
+       if (pos == String::NPos)
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Missing timestamp in command: " + line));
+
+       String timestamp = line.SubStr(1, pos - 1);
+       String args = line.SubStr(pos + 2, String::NPos);
+
+       double ts = Convert::ToDouble(timestamp);
+
+       if (ts == 0)
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid timestamp in command: " + line));
+
+       std::vector<String> argv;
+       boost::algorithm::split(argv, args, boost::is_any_of(";"));
+
+       if (argv.empty())
+               BOOST_THROW_EXCEPTION(std::invalid_argument("Missing arguments in command: " + line));
+
+       std::vector<String> argvExtra(argv.begin() + 1, argv.end());
+
+       if (argv[0] == "PROCESS_FILE") {
+               Log(LogDebug, "ExternalCommandProcessor")
+                       << "Enqueing external command file " << argvExtra[0];
+               file_queue.push_back(argvExtra);
+       } else {
+               Execute(ts, argv[0], argvExtra);
+       }
+}
+
 void ExternalCommandProcessor::ProcessHostCheckResult(double time, const std::vector<String>& arguments)
 {
        Host::Ptr host = Host::GetByName(arguments[0]);
@@ -893,33 +931,41 @@ void ExternalCommandProcessor::DisableHostgroupPassiveSvcChecks(double, const st
 
 void ExternalCommandProcessor::ProcessFile(double, const std::vector<String>& arguments)
 {
-       String file = arguments[0];
-       int del = Convert::ToLong(arguments[1]);
+       std::deque< std::vector<String> > file_queue;
+       file_queue.push_back(arguments);
 
-       std::ifstream ifp;
-       ifp.exceptions(std::ifstream::badbit);
+       while (!file_queue.empty()) {
+               std::vector<String> argument = file_queue.front();
+               file_queue.pop_front();
 
-       ifp.open(file.CStr(), std::ifstream::in);
+               String file = argument[0];
+               int to_delete = Convert::ToLong(argument[1]);
 
-       while (ifp.good()) {
-               std::string line;
-               std::getline(ifp, line);
+               std::ifstream ifp;
+               ifp.exceptions(std::ifstream::badbit);
 
-               try {
-                       Log(LogNotice, "compat")
-                           << "Executing external command: " << line;
+               ifp.open(file.CStr(), std::ifstream::in);
 
-                       Execute(line);
-               } catch (const std::exception& ex) {
-                       Log(LogWarning, "ExternalCommandProcessor")
-                           << "External command failed: " << DiagnosticInformation(ex);
+               while (ifp.good()) {
+                       std::string line;
+                       std::getline(ifp, line);
+
+                       try {
+                               Log(LogNotice, "compat")
+                                   << "Executing external command: " << line;
+
+                               ExecuteFromFile(line, file_queue);
+                       } catch (const std::exception& ex) {
+                               Log(LogWarning, "ExternalCommandProcessor")
+                                   << "External command failed: " << DiagnosticInformation(ex);
+                       }
                }
-       }
 
-       ifp.close();
+               ifp.close();
 
-       if (del > 0)
-               (void) unlink(file.CStr());
+               if (to_delete > 0)
+                       (void) unlink(file.CStr());
+       }
 }
 
 void ExternalCommandProcessor::ScheduleSvcDowntime(double, const std::vector<String>& arguments)
index 836b241ca97823513e26b6259a5cda2f3e17b4b2..059653295003c0e245ba92a6bad53e33dbf3d48f 100644 (file)
@@ -42,6 +42,8 @@ public:
 private:
        ExternalCommandProcessor(void);
 
+       static void ExecuteFromFile(const String& line, std::deque< std::vector<String> >& file_queue);
+
        static void ProcessHostCheckResult(double time, const std::vector<String>& arguments);
        static void ProcessServiceCheckResult(double time, const std::vector<String>& arguments);
        static void ScheduleHostCheck(double time, const std::vector<String>& arguments);