]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: fix race condition during startup of a service with ExitType=cgroup
authorFuminobu TAKEYAMA <ftake@geeko.jp>
Mon, 10 Jul 2023 15:30:27 +0000 (00:30 +0900)
committerMike Yuan <me@yhndnzj.com>
Fri, 14 Jul 2023 02:51:41 +0000 (10:51 +0800)
This commit allows service_sigchld_event() is executed before
service_dispatch_exec_io(), which might happen when a main process exits
very quickly.

Also do not check PID for service goodness because the main process have
already been exited in this case.

Fix: #27919

src/core/service.c

index c6178cf2cd71a7882e3180695a005c4d16a09d17..8e1b227a8bffff7b4de6a781749def6ebcedec32 100644 (file)
@@ -2231,7 +2231,7 @@ static bool service_good(Service *s) {
         main_pid_ok = main_pid_good(s);
         if (main_pid_ok > 0) /* It's alive */
                 return true;
-        if (main_pid_ok == 0) /* It's dead */
+        if (main_pid_ok == 0 && s->exit_type == SERVICE_EXIT_MAIN) /* It's dead */
                 return false;
 
         /* OK, we don't know anything about the main PID, maybe
@@ -3879,7 +3879,12 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                 default:
                                         assert_not_reached();
                                 }
-                        }
+                        } else if (s->exit_type == SERVICE_EXIT_CGROUP && s->state == SERVICE_START)
+                                /* If a main process exits very quickly, this function might be executed
+                                 * before service_dispatch_exec_io(). Since this function disabled IO events
+                                 * to monitor the main process above, we need to update the state here too.
+                                 * Let's consider the process is successfully launched and exited. */
+                                service_enter_start_post(s);
                 }
 
         } else if (s->control_pid == pid) {