]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3993: main: fix signals handling after failed started instances
authorYurii Chalov -X (ychalov - SOFTSERVE INC at Cisco) <ychalov@cisco.com>
Wed, 20 Sep 2023 08:03:48 +0000 (08:03 +0000)
committerOleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) <oshumeik@cisco.com>
Wed, 20 Sep 2023 08:03:48 +0000 (08:03 +0000)
Merge in SNORT/snort3 from ~YCHALOV/snort3:all_pthreads_fix to master

Squashed commit of the following:

commit a5fb3c19fd3654946f66fc0786826791c34460f7
Author: Yurii Chalov <ychalov@cisco.com>
Date:   Mon Sep 11 14:51:22 2023 +0200

    main: fix signals handling after failed started instances

src/main.cc
src/main/analyzer.cc
src/main/analyzer.h

index 0cae62646319b79779f66d9c8e1163185355d924..64d0a7060047e9394fd63175ac8a7e19ffba6066 100644 (file)
@@ -73,7 +73,7 @@ using namespace snort;
 static bool exit_requested = false;
 static int main_exit_code = 0;
 static bool paused = false;
-static bool all_pthreads_started = false;
+static bool pthreads_started = false;
 static std::queue<AnalyzerCommand*> orphan_commands;
 
 static std::mutex poke_mutex;
@@ -284,6 +284,7 @@ void Pig::reap_commands()
 static bool* pigs_started = nullptr;
 static Pig* pigs = nullptr;
 static unsigned max_pigs = 0;
+static unsigned pigs_failed = 0;
 
 static Pig* get_lazy_pig(unsigned max)
 {
@@ -873,7 +874,7 @@ static void reap_commands()
 // FIXIT-L return true if something was done to avoid sleeping
 static bool house_keeping()
 {
-    if (all_pthreads_started)
+    if (pthreads_started)
         signal_check();
 
     reap_commands();
@@ -888,7 +889,7 @@ static bool house_keeping()
 static void service_check()
 {
 #ifdef SHELL
-    if (all_pthreads_started && ControlMgmt::service_users() )
+    if (pthreads_started && ControlMgmt::service_users())
         return;
 #endif
 
@@ -1049,6 +1050,9 @@ static void handle(Pig& pig, unsigned& swine, unsigned& pending_privileges)
         }
         break;
 
+    case Analyzer::State::FAILED:
+        pigs_failed++;
+        // fallthrough
     case Analyzer::State::STOPPED:
         pig.stop();
         --swine;
@@ -1061,7 +1065,7 @@ static void handle(Pig& pig, unsigned& swine, unsigned& pending_privileges)
 
 static void main_loop()
 {
-    unsigned swine = 0, pending_privileges = 0;
+    unsigned max_swine = 0, swine = 0, pending_privileges = 0;
 
     if (SnortConfig::get_conf()->change_privileges())
         pending_privileges = max_pigs;
@@ -1075,7 +1079,7 @@ static void main_loop()
                 return;
         }
 
-        swine += max_pigs;
+        max_swine = swine += max_pigs;
     }
 
     // Iterate over the drove, spawn them as allowed, and handle their deaths.
@@ -1096,6 +1100,9 @@ static void main_loop()
                 if (!pigs_started[idx] && pig.analyzer && (pig.analyzer->get_state() ==
                     Analyzer::State::STARTED))
                     pigs_started[idx] = true;
+                if (pigs_started[idx] && (!pig.analyzer || pig.analyzer->get_state() ==
+                    Analyzer::State::FAILED))
+                    pigs_started[idx] = false;
             }
             else if ( pending_privileges )
                 pending_privileges--;
@@ -1106,13 +1113,19 @@ static void main_loop()
             continue;
         }
 
-        if (!all_pthreads_started)
+        if (!pthreads_started)
         {
-            all_pthreads_started = true;
-            const unsigned num_threads = (!Trough::has_next()) ? swine : max_pigs;
+            const unsigned num_threads = (!Trough::has_next()) ? max_swine : max_pigs;
+            unsigned pigs_started_count = 0;
             for (unsigned i = 0; i < num_threads; i++)
-                all_pthreads_started &= pigs_started[i];
-            if (all_pthreads_started)
+            {
+                if (pigs_started[i])
+                    pigs_started_count++;
+            }
+
+            pthreads_started = pigs_started_count && num_threads <= pigs_started_count + pigs_failed;
+
+            if (pthreads_started)
             {
 #ifdef REG_TEST
                 LogMessage("All pthreads started\n");
@@ -1131,7 +1144,11 @@ static void main_loop()
         {
             Pig* pig = get_lazy_pig(max_pigs);
             if (pig->prep(src))
+            {
                 ++swine;
+                if (max_swine < swine)
+                    max_swine = swine;
+            }
             continue;
         }
         service_check();
index 5897c341c5c73d7eca1fddfb0cf4afb00741095d..e955ec62675350f2a983a85da4797ed81232d2b4 100644 (file)
@@ -561,6 +561,7 @@ const char* Analyzer::get_state_string()
         case State::RUNNING:     return "RUNNING";
         case State::PAUSED:      return "PAUSED";
         case State::STOPPED:     return "STOPPED";
+        case State::FAILED:      return "FAILED";
         default: assert(false);
     }
 
@@ -778,7 +779,8 @@ void Analyzer::operator()(Swapper* ps, uint16_t run_num)
     Profiler::stop(pc.analyzed_pkts);
     term();
 
-    set_state(State::STOPPED);
+    if (state != State::FAILED)
+        set_state(State::STOPPED);
 
     oops_handler->tterm();
 }
@@ -971,6 +973,8 @@ void Analyzer::start()
     {
         ErrorMessage("Analyzer: Failed to start DAQ instance\n");
         exit_requested = true;
+        set_state(State::FAILED);
+        return;
     }
     set_state(State::STARTED);
 }
index aaaeebcbb0df504c9072678c1b14cbccf17cf185..1b0f37bdf26a5bbb0568c08774230458db0d1e7e 100644 (file)
@@ -72,6 +72,7 @@ public:
         RUNNING,
         PAUSED,
         STOPPED,
+        FAILED,
         NUM_STATES
     };