Improve Redbean shutdown (#506)

* Update redbean shutdown to call OnServerStop when all shutdown/logging is done

* Move closing file descriptors during daemonization earlier

This should fix using opened file descriptors, for example, SQLite DB
files and redbean itself when StoreAsset is used. Fixes #182.

* Move opening logs earlier to capture logs from Listen and .init.lua

* Move pidpath handling outside of daemonize, as it can be used independently
This commit is contained in:
Paul Kulchenko 2022-07-23 18:58:31 -07:00 committed by GitHub
parent 03dd14c298
commit 638e14bbf3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1012,6 +1012,8 @@ static void ProgramHeader(const char *s) {
static void ProgramLogPath(const char *s) { static void ProgramLogPath(const char *s) {
logpath = strdup(s); logpath = strdup(s);
close(2);
open(logpath, O_APPEND | O_WRONLY | O_CREAT, 0640);
} }
static void ProgramPidPath(const char *s) { static void ProgramPidPath(const char *s) {
@ -1043,27 +1045,10 @@ static void ChangeUser(void) {
} }
static void Daemonize(void) { static void Daemonize(void) {
char ibuf[21]; if (fork() > 0) exit(0);
int i, fd, pid;
for (i = 0; i < 256; ++i) {
if (!IsServerFd(i)) {
close(i);
}
}
if ((pid = fork()) > 0) exit(0);
setsid(); setsid();
if ((pid = fork()) > 0) _exit(0); if (fork() > 0) _exit(0);
umask(0); umask(0);
if (pidpath) {
fd = open(pidpath, O_CREAT | O_WRONLY, 0644);
WRITE(fd, ibuf, FormatInt32(ibuf, getpid()) - ibuf);
close(fd);
}
if (!logpath) ProgramLogPath("/dev/null");
open("/dev/null", O_RDONLY);
open(logpath, O_APPEND | O_WRONLY | O_CREAT, 0640);
dup2(1, 2);
ChangeUser();
} }
static void LogLuaError(char *hook, char *err) { static void LogLuaError(char *hook, char *err) {
@ -7058,6 +7043,7 @@ static void HandleShutdown(void) {
KillGroup(); KillGroup();
} }
WaitAll(); WaitAll();
INFOF("(srvr) shutdown complete");
} }
// this function coroutines with linenoise // this function coroutines with linenoise
@ -7294,6 +7280,8 @@ static void GetOpts(int argc, char *argv[]) {
} }
void RedBean(int argc, char *argv[]) { void RedBean(int argc, char *argv[]) {
char ibuf[21];
int fd;
if (IsLinux()) { if (IsLinux()) {
// disable weird linux capabilities // disable weird linux capabilities
for (int e = errno, i = 0;; ++i) { for (int e = errno, i = 0;; ++i) {
@ -7315,6 +7303,15 @@ void RedBean(int argc, char *argv[]) {
(shared = mmap(NULL, ROUNDUP(sizeof(struct Shared), FRAMESIZE), (shared = mmap(NULL, ROUNDUP(sizeof(struct Shared), FRAMESIZE),
PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
-1, 0))); -1, 0)));
if (daemonize) {
for (int i = 0; i < 256; ++i) {
if (!IsServerFd(i)) {
close(i);
}
}
open("/dev/null", O_RDONLY);
open("/dev/null", O_WRONLY);
}
zpath = GetProgramExecutableName(); zpath = GetProgramExecutableName();
CHECK_NE(-1, (zfd = open(zpath, O_RDONLY))); CHECK_NE(-1, (zfd = open(zpath, O_RDONLY)));
CHECK_NE(-1, fstat(zfd, &zst)); CHECK_NE(-1, fstat(zfd, &zst));
@ -7332,6 +7329,10 @@ void RedBean(int argc, char *argv[]) {
if (uniprocess) { if (uniprocess) {
shared->workers = 1; shared->workers = 1;
} }
if (daemonize) {
if (!logpath) ProgramLogPath("/dev/null");
dup2(2, 1);
}
SigInit(); SigInit();
Listen(); Listen();
TlsInit(); TlsInit();
@ -7340,13 +7341,13 @@ void RedBean(int argc, char *argv[]) {
} }
if (daemonize) { if (daemonize) {
Daemonize(); Daemonize();
} else { }
if (logpath) { if (pidpath) {
close(2); fd = open(pidpath, O_CREAT | O_WRONLY, 0644);
open(logpath, O_APPEND | O_WRONLY | O_CREAT, 0640); WRITE(fd, ibuf, FormatInt32(ibuf, getpid()) - ibuf);
close(fd);
} }
ChangeUser(); ChangeUser();
}
UpdateCurrentDate(nowl()); UpdateCurrentDate(nowl());
CollectGarbage(); CollectGarbage();
hdrbuf.n = 4 * 1024; hdrbuf.n = 4 * 1024;
@ -7378,15 +7379,6 @@ void RedBean(int argc, char *argv[]) {
ReplEventLoop(); ReplEventLoop();
} }
#endif #endif
if (!isexitingworker) {
HandleShutdown();
CallSimpleHookIfDefined("OnServerStop");
}
if (!IsTiny()) {
LuaDestroy();
TlsDestroy();
MemDestroy();
}
if (!isexitingworker) { if (!isexitingworker) {
if (!IsTiny()) { if (!IsTiny()) {
terminatemonitor = true; terminatemonitor = true;
@ -7395,9 +7387,13 @@ void RedBean(int argc, char *argv[]) {
#ifndef STATIC #ifndef STATIC
_join(&replth); _join(&replth);
#endif #endif
HandleShutdown();
CallSimpleHookIfDefined("OnServerStop");
} }
if (!isexitingworker) { if (!IsTiny()) {
INFOF("(srvr) shutdown complete"); LuaDestroy();
TlsDestroy();
MemDestroy();
} }
} }