Browse Source

Report failure to start with state as STOPPING (or STOPPED)

Davin McCall 1 year ago
parent
commit
2e68846192
5 changed files with 14 additions and 3 deletions
  1. 0 1
      src/baseproc-service.cc
  2. 1 0
      src/control.cc
  3. 1 1
      src/includes/service.h
  4. 8 1
      src/proc-service.cc
  5. 4 0
      src/service.cc

+ 0 - 1
src/baseproc-service.cc

@@ -398,7 +398,6 @@ void base_process_service::timer_expired() noexcept
         interrupt_start();
         stop_reason = stopped_reason_t::TIMEDOUT;
         failed_to_start(false, false);
-	    //services->process_queues();
     }
     else {
         // STARTING / STARTED, and we have no pid: must be restarting (smooth recovery if STARTED)

+ 1 - 0
src/control.cc

@@ -564,6 +564,7 @@ static void fill_status_buffer(char *buffer, service_record *service)
         memcpy(buffer + 6, &proc_pid, sizeof(proc_pid));
     }
     else {
+        // These values only make sense in STOPPING/STOPPED, but we'll fill them in regardless:
         if (buffer[3] == (char)stopped_reason_t::EXECFAILED) {
             base_process_service *bsp = (base_process_service *)service;
             run_proc_err exec_err = bsp->get_exec_err_info();

+ 1 - 1
src/includes/service.h

@@ -317,7 +317,7 @@ class service_record
     // Service has successfully started
     void started() noexcept;
     
-    // Service failed to start (only called when in STARTING state).
+    // Service failed to start (should be called with state set to STOPPING or STOPPED).
     //   dep_failed: whether failure is recorded due to a dependency failing
     //   immediate_stop: whether to set state as STOPPED and handle complete stop.
     void failed_to_start(bool dep_failed = false, bool immediate_stop = true) noexcept;

+ 8 - 1
src/proc-service.cc

@@ -189,8 +189,8 @@ rearm ready_notify_watcher::fd_event(eventloop_t &, int fd, int flags) noexcept
                 service->process_timer.stop_timer(event_loop);
                 service->waiting_stopstart_timer = false;
             }
-            service->failed_to_start(false, false);
             service->set_state(service_state_t::STOPPING);
+            service->failed_to_start(false, false);
             service->bring_down();
         }
         service->services->process_queues();
@@ -295,6 +295,7 @@ void process_service::handle_exit_status(bp_sys::exit_status exit_status) noexce
         // If state is STARTING, we must be waiting for readiness notification; the process has
         // terminated before becoming ready.
         stop_reason = stopped_reason_t::FAILED;
+        service_state = service_state_t::STOPPING;
         failed_to_start();
     }
     else if (service_state == service_state_t::STOPPING) {
@@ -343,6 +344,7 @@ void process_service::exec_failed(run_proc_err errcode) noexcept
 
     if (get_state() == service_state_t::STARTING) {
         stop_reason = stopped_reason_t::EXECFAILED;
+        set_state(service_state_t::STOPPING);
         failed_to_start();
     }
     else {
@@ -465,6 +467,7 @@ void bgproc_service::handle_exit_status(bp_sys::exit_status exit_status) noexcep
                 case pid_result_t::FAILED:
                     // Failed startup: no auto-restart.
                     stop_reason = stopped_reason_t::FAILED;
+                    service_state = service_state_t::STOPPING;
                     failed_to_start();
                     break;
                 case pid_result_t::TERMINATED:
@@ -478,6 +481,7 @@ void bgproc_service::handle_exit_status(bp_sys::exit_status exit_status) noexcep
         }
         else {
             stop_reason = stopped_reason_t::FAILED;
+            service_state = service_state_t::STOPPING;
             failed_to_start();
         }
     }
@@ -521,6 +525,7 @@ void bgproc_service::exec_failed(run_proc_err errcode) noexcept
     else {
         // Only time we execute is for startup:
         stop_reason = stopped_reason_t::EXECFAILED;
+        set_state(service_state_t::STOPPING);
         failed_to_start();
     }
 }
@@ -602,6 +607,7 @@ void scripted_service::handle_exit_status(bp_sys::exit_status exit_status) noexc
                 log(loglevel_t::ERROR, "Service ", get_name(), " command terminated due to signal ",
                         exit_status.get_term_sig());
             }
+            service_state = service_state_t::STOPPED;
             stop_reason = stopped_reason_t::FAILED;
             failed_to_start();
         }
@@ -616,6 +622,7 @@ void scripted_service::exec_failed(run_proc_err errcode) noexcept
     auto service_state = get_state();
     if (service_state == service_state_t::STARTING) {
         stop_reason = stopped_reason_t::EXECFAILED;
+        service_state = service_state_t::STOPPING;
         failed_to_start();
     }
     else if (service_state == service_state_t::STOPPING) {

+ 4 - 0
src/service.cc

@@ -232,6 +232,7 @@ void service_record::do_propagation() noexcept
     if (prop_failure) {
         prop_failure = false;
         stop_reason = stopped_reason_t::DEPFAILED;
+        service_state = service_state_t::STOPPED;
         failed_to_start(true);
     }
 
@@ -363,6 +364,7 @@ void service_record::all_deps_started() noexcept
     waiting_for_deps = false;
 
     if (!bring_up()) {
+        service_state = service_state_t::STOPPING;
         failed_to_start();
     }
 }
@@ -419,6 +421,8 @@ void service_record::started() noexcept
 
 void service_record::failed_to_start(bool depfailed, bool immediate_stop) noexcept
 {
+    desired_state = service_state_t::STOPPED;
+
     if (waiting_for_console) {
         services->unqueue_console(this);
         waiting_for_console = false;