StartUnixWorker(): watch forked child via waitpid(), not SIGCHLD handler

Before:

On SIGCHLD from the forked worker the umbrella process sets a failure flag.
StartUnixWorker() recognises that and does waitpid(), failure message, etc..
On OpenBSD we can't tell the signal source, so we always set the failure flag.
That's not how our IPC shall work, that breaks the IPC sooner or later.

After:

No SIGCHLD handling and no failure flag setting.
Instead StartUnixWorker()'s wait loop uses waitpid(x,y,WNOHANG)
to avoid false positives while watching the forked worker.
This commit is contained in:
Alexander A. Klimov 2022-09-07 11:46:46 +02:00
parent 643e9cd48b
commit df9008bfc4
1 changed files with 12 additions and 26 deletions

View File

@ -381,13 +381,6 @@ static void UmbrellaSignalHandler(int num, siginfo_t *info, void*)
l_CurrentlyStartingUnixWorkerState.store(UnixWorkerState::LoadedConfig); l_CurrentlyStartingUnixWorkerState.store(UnixWorkerState::LoadedConfig);
} }
break; break;
case SIGCHLD:
if (l_CurrentlyStartingUnixWorkerState.load() == UnixWorkerState::Pending
&& (info->si_pid == 0 || info->si_pid == l_CurrentlyStartingUnixWorkerPid.load()) ) {
// The seamless worker currently being started by StartUnixWorker() failed
l_CurrentlyStartingUnixWorkerState.store(UnixWorkerState::Failed);
}
break;
case SIGINT: case SIGINT:
case SIGTERM: case SIGTERM:
// Someone requested our termination // Someone requested our termination
@ -570,28 +563,21 @@ static pid_t StartUnixWorker(const std::vector<std::string>& configs, bool close
NotifyWatchdog(); NotifyWatchdog();
#endif /* HAVE_SYSTEMD */ #endif /* HAVE_SYSTEMD */
switch (l_CurrentlyStartingUnixWorkerState.load()) { if (waitpid(pid, nullptr, WNOHANG) > 0) {
case UnixWorkerState::LoadedConfig: Log(LogNotice, "cli")
Log(LogNotice, "cli") << "Worker process couldn't load its config";
<< "Worker process successfully loaded its config";
break;
case UnixWorkerState::Failed:
Log(LogNotice, "cli")
<< "Worker process couldn't load its config";
while (waitpid(pid, nullptr, 0) == -1 && errno == EINTR) { pid = -2;
#ifdef HAVE_SYSTEMD break;
NotifyWatchdog();
#endif /* HAVE_SYSTEMD */
}
pid = -2;
break;
default:
Utility::Sleep(0.2);
continue;
} }
break; if (l_CurrentlyStartingUnixWorkerState.load() == UnixWorkerState::LoadedConfig) {
Log(LogNotice, "cli")
<< "Worker process successfully loaded its config";
break;
}
Utility::Sleep(0.2);
} }
// Reset flags for the next time // Reset flags for the next time