Browse Source

[core] fdlog.[ch]; fdevent_*_logger_* -> fdlog_*

code move and rename fdevent_*_logger_*() to fdlog_*()
master
Glenn Strauss 3 months ago
parent
commit
243510dbb4
  1. 1
      src/CMakeLists.txt
  2. 2
      src/Makefile.am
  3. 1
      src/SConscript
  4. 11
      src/configfile.c
  5. 191
      src/fdevent.c
  6. 8
      src/fdevent.h
  7. 203
      src/fdlog.c
  8. 26
      src/fdlog.h
  9. 1
      src/meson.build
  10. 9
      src/mod_accesslog.c
  11. 11
      src/server.c

1
src/CMakeLists.txt

@ -768,6 +768,7 @@ set(COMMON_SRC
request.c
sock_addr.c
rand.c
fdlog.c
ck.c
)

2
src/Makefile.am

@ -89,6 +89,7 @@ common_src=base64.c buffer.c burl.c log.c \
rand.c \
request.c \
sock_addr.c \
fdlog.c \
ck.c
src = server.c response.c connections.c h2.c reqpool.c \
@ -474,6 +475,7 @@ hdr = base64.h buffer.h burl.h network.h log.h http_kv.h keyvalue.h \
first.h http_chunk.h \
algo_hmac.h \
algo_md.h algo_md5.h algo_sha1.h algo_splaytree.h algo_xxhash.h \
fdlog.h \
ck.h \
http_cgi.h http_date.h \
http_header.h http_range.h \

1
src/SConscript

@ -71,6 +71,7 @@ common_src = Split("base64.c buffer.c burl.c log.c \
request.c \
sock_addr.c \
rand.c \
fdlog.c \
ck.c \
")

11
src/configfile.c

@ -5,6 +5,7 @@
#include "chunk.h"
#include "ck.h"
#include "fdevent.h"
#include "fdlog.h"
#include "http_etag.h"
#include "keyvalue.h"
#include "log.h"
@ -1508,7 +1509,7 @@ static void config_log_error_open_syslog(server *srv, log_error_st *errh, const
}
static int config_log_error_open_fn(server *srv, log_error_st *errh, const char *fn) {
int fd = fdevent_open_logger(fn);
int fd = fdlog_open(fn);
if (-1 == fd) {
log_perror(srv->errh, __FILE__, __LINE__,
"opening errorlog '%s' failed", fn);
@ -1595,7 +1596,7 @@ int config_log_error_open(server *srv) {
}
errfd = serrh->errorlog_fd;
if (*serrh->fn == '|') fdevent_breakagelog_logger_pipe(errfd);
if (*serrh->fn == '|') fdlog_pipe_serrh(errfd); /* breakagelog */
}
else if (!srv->srvconf.dont_daemonize) {
/* move STDERR_FILENO to /dev/null */
@ -1655,7 +1656,7 @@ void config_log_error_cycle(server *srv) {
case 32:/* server.breakagelog */
errh = cpv->v.v; /* cycle only if the error log is a file */
if (errh->errorlog_mode != ERRORLOG_FILE) continue;
if (-1 == fdevent_cycle_logger(errh->fn, &errh->errorlog_fd)) {
if (-1 == fdlog_cycle(errh->fn, &errh->errorlog_fd)) {
/* write to top-level error log
* (the prior log if srv->errh is the one being cycled) */
log_perror(srv->errh, __FILE__, __LINE__,
@ -1713,7 +1714,7 @@ void config_log_error_close(server *srv) {
case ERRORLOG_FD:
if (-1 != errh->errorlog_fd) {
/* don't close STDERR */
/* fdevent_close_logger_pipes() closes ERRORLOG_PIPE */
/* fdlog_pipes_close() closes ERRORLOG_PIPE */
if (STDERR_FILENO != errh->errorlog_fd
&& ERRORLOG_PIPE != errh->errorlog_mode) {
close(errh->errorlog_fd);
@ -1732,7 +1733,7 @@ void config_log_error_close(server *srv) {
}
}
fdevent_close_logger_pipes();
fdlog_pipes_close();
if (srv->errh->errorlog_mode == ERRORLOG_SYSLOG) {
srv->errh->errorlog_mode = ERRORLOG_FD;

191
src/fdevent.c

@ -824,197 +824,6 @@ int fdevent_waitpid_intr(pid_t pid, int * const status) {
}
typedef struct fdevent_cmd_pipe {
pid_t pid;
int fds[2];
const char *cmd;
unix_time64_t start;
} fdevent_cmd_pipe;
typedef struct fdevent_cmd_pipes {
fdevent_cmd_pipe *ptr;
uint32_t used;
uint32_t size;
} fdevent_cmd_pipes;
static fdevent_cmd_pipes cmd_pipes;
static pid_t fdevent_open_logger_pipe_spawn(const char *logger, int rfd) {
char *args[4];
int devnull = fdevent_open_devnull();
pid_t pid;
if (-1 == devnull) {
return -1;
}
*(const char **)&args[0] = "/bin/sh";
*(const char **)&args[1] = "-c";
*(const char **)&args[2] = logger;
args[3] = NULL;
pid = fdevent_fork_execve(args[0], args, NULL, rfd, devnull, devnull, -1);
if (pid > 0) {
close(devnull);
}
else {
int errnum = errno;
close(devnull);
errno = errnum;
}
return pid;
}
static void fdevent_restart_logger_pipe(fdevent_cmd_pipe *fcp, unix_time64_t ts) {
if (fcp->pid > 0) return; /* assert */
if (fcp->start + 5 < ts) { /* limit restart to once every 5 sec */
/* restart child process using existing pipe fds */
fcp->start = ts;
fcp->pid = fdevent_open_logger_pipe_spawn(fcp->cmd, fcp->fds[0]);
}
}
void fdevent_restart_logger_pipes(unix_time64_t ts) {
for (uint32_t i = 0; i < cmd_pipes.used; ++i) {
fdevent_cmd_pipe * const fcp = cmd_pipes.ptr+i;
if (fcp->pid > 0) continue;
fdevent_restart_logger_pipe(fcp, ts);
}
}
int fdevent_waitpid_logger_pipe_pid(pid_t pid, unix_time64_t ts) {
for (uint32_t i = 0; i < cmd_pipes.used; ++i) {
fdevent_cmd_pipe * const fcp = cmd_pipes.ptr+i;
if (pid != fcp->pid) continue;
fcp->pid = -1;
fdevent_restart_logger_pipe(fcp, ts);
return 1;
}
return 0;
}
void fdevent_clr_logger_pipe_pids(void) {
for (uint32_t i = 0; i < cmd_pipes.used; ++i) {
fdevent_cmd_pipe *fcp = cmd_pipes.ptr+i;
fcp->pid = -1;
}
}
int fdevent_reaped_logger_pipe(pid_t pid) {
for (uint32_t i = 0; i < cmd_pipes.used; ++i) {
fdevent_cmd_pipe *fcp = cmd_pipes.ptr+i;
if (fcp->pid == pid) {
unix_time64_t ts = log_monotonic_secs;
if (fcp->start + 5 < ts) { /* limit restart to once every 5 sec */
fcp->start = ts;
fcp->pid = fdevent_open_logger_pipe_spawn(fcp->cmd,fcp->fds[0]);
return (fcp->pid > 0) ? 1 : -1;
}
else {
fcp->pid = -1;
return -1;
}
}
}
return 0;
}
void fdevent_close_logger_pipes(void) {
for (uint32_t i = 0; i < cmd_pipes.used; ++i) {
fdevent_cmd_pipe *fcp = cmd_pipes.ptr+i;
close(fcp->fds[0]);
if (fcp->fds[1] != STDERR_FILENO) close(fcp->fds[1]);
}
free(cmd_pipes.ptr);
cmd_pipes.ptr = NULL;
cmd_pipes.used = 0;
cmd_pipes.size = 0;
}
void fdevent_breakagelog_logger_pipe(int fd) {
for (uint32_t i = 0; i < cmd_pipes.used; ++i) {
fdevent_cmd_pipe *fcp = cmd_pipes.ptr+i;
if (fcp->fds[1] != fd) continue;
fcp->fds[1] = STDERR_FILENO;
break;
}
}
static void fdevent_init_logger_pipe(const char *cmd, int fds[2], pid_t pid) {
fdevent_cmd_pipe *fcp;
if (cmd_pipes.used == cmd_pipes.size) {
cmd_pipes.size += 4;
cmd_pipes.ptr =
realloc(cmd_pipes.ptr, cmd_pipes.size * sizeof(fdevent_cmd_pipe));
force_assert(cmd_pipes.ptr);
}
fcp = cmd_pipes.ptr + cmd_pipes.used++;
fcp->cmd = cmd; /* note: cmd must persist in memory (or else copy here) */
fcp->fds[0] = fds[0];
fcp->fds[1] = fds[1];
fcp->pid = pid;
fcp->start = log_monotonic_secs;
}
static int fdevent_open_logger_pipe(const char *logger) {
int fds[2];
pid_t pid;
if (pipe(fds)) {
return -1;
}
fdevent_setfd_cloexec(fds[0]);
fdevent_setfd_cloexec(fds[1]);
/*(nonblocking write() from lighttpd)*/
if (0 != fdevent_fcntl_set_nb(fds[1])) { /*(ignore)*/ }
pid = fdevent_open_logger_pipe_spawn(logger, fds[0]);
if (pid > 0) {
fdevent_init_logger_pipe(logger, fds, pid);
return fds[1];
}
else {
int errnum = errno;
close(fds[0]);
close(fds[1]);
errno = errnum;
return -1;
}
}
int fdevent_open_logger(const char *logger) {
if (logger[0] != '|') { /*(permit symlinks)*/
int flags = O_APPEND | O_WRONLY | O_CREAT;
return fdevent_open_cloexec(logger, 1, flags, 0644);
}
else {
return fdevent_open_logger_pipe(logger+1); /*(skip the '|')*/
}
}
int fdevent_cycle_logger(const char *logger, int *curfd) {
if (logger[0] != '|') {
int fd = fdevent_open_logger(logger);
if (-1 == fd) return -1; /*(error; leave *curfd as-is)*/
if (-1 != *curfd) close(*curfd);
*curfd = fd;
}
return *curfd;
}
#ifndef MSG_DONTWAIT
#define MSG_DONTWAIT 0
#endif

8
src/fdevent.h

@ -101,14 +101,6 @@ int fdevent_set_stdin_stdout_stderr(int fdin, int fdout, int fderr);
pid_t fdevent_fork_execve(const char *name, char *argv[], char *envp[], int fdin, int fdout, int fderr, int dfd);
int fdevent_waitpid(pid_t pid, int *status, int nb);
int fdevent_waitpid_intr(pid_t pid, int *status);
int fdevent_open_logger(const char *logger);
int fdevent_cycle_logger(const char *logger, int *curfd);
int fdevent_reaped_logger_pipe(pid_t pid);
int fdevent_waitpid_logger_pipe_pid(pid_t pid, unix_time64_t ts);
void fdevent_restart_logger_pipes(unix_time64_t ts);
void fdevent_close_logger_pipes(void);
void fdevent_breakagelog_logger_pipe(int fd);
void fdevent_clr_logger_pipe_pids(void);
ssize_t fdevent_socket_read_discard (int fd, char *buf, size_t sz, int family, int so_type);

203
src/fdlog.c

@ -0,0 +1,203 @@
#include "first.h"
#include "fdlog.h"
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include "fdevent.h"
#include "log.h"
typedef struct fdlog_pipe {
pid_t pid;
int fds[2];
const char *cmd;
unix_time64_t start;
} fdlog_pipe;
struct fdlog_pipes_t {
fdlog_pipe *ptr;
uint32_t used;
uint32_t size;
};
static struct fdlog_pipes_t fdlog_pipes;
static pid_t
fdlog_pipe_spawn (const char * const fn, const int rfd)
{
char *args[4];
int devnull = fdevent_open_devnull();
pid_t pid;
if (-1 == devnull) {
return -1;
}
*(const char **)&args[0] = "/bin/sh";
*(const char **)&args[1] = "-c";
*(const char **)&args[2] = fn;
args[3] = NULL;
pid = fdevent_fork_execve(args[0], args, NULL, rfd, devnull, devnull, -1);
if (pid > 0) {
close(devnull);
}
else {
int errnum = errno;
close(devnull);
errno = errnum;
}
return pid;
}
__attribute_noinline__
static int
fdlog_pipe_restart (fdlog_pipe * const fdp, const unix_time64_t ts)
{
if (fdp->start + 5 < ts) { /* limit restart to once every 5 sec */
/* restart child process using existing pipe fds */
fdp->start = ts;
fdp->pid = fdlog_pipe_spawn(fdp->cmd, fdp->fds[0]);
}
return (fdp->pid > 0) ? 1 : -1;
}
void
fdlog_pipes_restart (const unix_time64_t ts)
{
for (uint32_t i = 0; i < fdlog_pipes.used; ++i) {
fdlog_pipe * const fdp = fdlog_pipes.ptr+i;
if (fdp->pid > 0) continue;
fdlog_pipe_restart(fdp, ts);
}
}
int
fdlog_pipes_waitpid_cb (const pid_t pid)
{
for (uint32_t i = 0; i < fdlog_pipes.used; ++i) {
fdlog_pipe * const fdp = fdlog_pipes.ptr+i;
if (fdp->pid != pid) continue;
fdp->pid = -1;
return fdlog_pipe_restart(fdp, log_monotonic_secs);
}
return 0;
}
void
fdlog_pipes_close (void)
{
for (uint32_t i = 0; i < fdlog_pipes.used; ++i) {
fdlog_pipe * const fdp = fdlog_pipes.ptr+i;
close(fdp->fds[0]);
if (fdp->fds[1] != STDERR_FILENO) close(fdp->fds[1]);
}
free(fdlog_pipes.ptr);
fdlog_pipes.ptr = NULL;
fdlog_pipes.used = 0;
fdlog_pipes.size = 0;
}
void
fdlog_pipes_abandon_pids (void)
{
for (uint32_t i = 0; i < fdlog_pipes.used; ++i) {
fdlog_pipe * const fdp = fdlog_pipes.ptr+i;
fdp->pid = -1;
}
}
void
fdlog_pipe_serrh (const int fd)
{
for (uint32_t i = 0; i < fdlog_pipes.used; ++i) {
fdlog_pipe * const fdp = fdlog_pipes.ptr+i;
if (fdp->fds[1] != fd) continue;
fdp->fds[1] = STDERR_FILENO;
break;
}
}
static void
fdlog_pipe_init (const char * const cmd, const int fds[2], const pid_t pid)
{
if (fdlog_pipes.used == fdlog_pipes.size) {
fdlog_pipes.size += 4;
fdlog_pipes.ptr =
realloc(fdlog_pipes.ptr, fdlog_pipes.size * sizeof(fdlog_pipe));
force_assert(fdlog_pipes.ptr);
}
fdlog_pipe * const fdp = fdlog_pipes.ptr + fdlog_pipes.used++;
fdp->cmd = cmd; /* note: cmd must persist in memory (or else copy here) */
fdp->fds[0] = fds[0];
fdp->fds[1] = fds[1];
fdp->pid = pid;
fdp->start = log_monotonic_secs;
}
static int
fdlog_pipe_open (const char * const fn)
{
int fds[2];
if (pipe(fds))
return -1;
fdevent_setfd_cloexec(fds[0]);
fdevent_setfd_cloexec(fds[1]);
pid_t pid = fdlog_pipe_spawn(fn, fds[0]);
if (pid > 0) {
/*(nonblocking write() from lighttpd)*/
if (0 != fdevent_fcntl_set_nb(fds[1])) { /*(ignore)*/ }
fdlog_pipe_init(fn, fds, pid);
return fds[1];
}
else {
int errnum = errno;
close(fds[0]);
close(fds[1]);
errno = errnum;
return -1;
}
}
int
fdlog_open (const char * const fn)
{
if (fn[0] != '|') { /*(permit symlinks)*/
int flags = O_APPEND | O_WRONLY | O_CREAT;
return fdevent_open_cloexec(fn, 1, flags, 0644);
}
else {
return fdlog_pipe_open(fn+1); /*(skip the '|')*/
}
}
int
fdlog_cycle (const char * const fn, int * const curfd)
{
if (fn[0] != '|') {
int fd = fdlog_open(fn);
if (-1 == fd) return -1; /*(error; leave *curfd as-is)*/
if (-1 != *curfd) close(*curfd);
*curfd = fd;
}
return *curfd;
}

26
src/fdlog.h

@ -0,0 +1,26 @@
#ifndef INCLUDED_FDLOG_H
#define INCLUDED_FDLOG_H
#include "first.h"
__attribute_cold__
int fdlog_open (const char *fn);
__attribute_cold__
int fdlog_cycle (const char *fn, int *curfd);
__attribute_cold__
int fdlog_pipes_waitpid_cb (pid_t pid);
__attribute_cold__
void fdlog_pipes_restart (unix_time64_t ts);
__attribute_cold__
void fdlog_pipes_close (void);
__attribute_cold__
void fdlog_pipes_abandon_pids (void);
__attribute_cold__
void fdlog_pipe_serrh (int fd);
#endif

1
src/meson.build

@ -730,6 +730,7 @@ common_src = [
'fdevent_solaris_devpoll.c',
'fdevent_solaris_port.c',
'fdevent.c',
'fdlog.c',
'gw_backend.c',
'http_cgi.c',
'http_chunk.c',

9
src/mod_accesslog.c

@ -4,6 +4,7 @@
#include "base.h"
#include "fdevent.h"
#include "fdlog.h"
#include "log.h"
#include "buffer.h"
#include "http_header.h"
@ -421,7 +422,7 @@ static format_fields * accesslog_parse_format(const char * const format, const s
}
static void mod_accesslog_free_accesslog(accesslog_st * const x, plugin_data *p) {
/*(piped loggers are closed in fdevent_close_logger_pipes())*/
/*(piped loggers are closed in fdlog_pipes_close())*/
if (!x->piped_logger && -1 != x->log_access_fd) {
if (!accesslog_write_all(x->log_access_fd, &x->access_logbuffer)) {
log_perror(p->errh, __FILE__, __LINE__,
@ -595,7 +596,7 @@ SETDEFAULTS_FUNC(mod_accesslog_set_defaults) {
if (use_syslog) continue; /* ignore the next checks */
if (NULL == x || buffer_is_blank(x->access_logfile)) continue;
x->log_access_fd = fdevent_open_logger(x->access_logfile->ptr);
x->log_access_fd = fdlog_open(x->access_logfile->ptr);
if (-1 == x->log_access_fd) {
log_perror(srv->errh, __FILE__, __LINE__,
"opening log '%s' failed", x->access_logfile->ptr);
@ -772,8 +773,8 @@ SIGHUP_FUNC(log_access_cycle) {
accesslog_st * const x = cpv->v.v;
if (x->piped_logger) continue;
if (buffer_is_blank(x->access_logfile)) continue;
if (-1 == fdevent_cycle_logger(x->access_logfile->ptr,
&x->log_access_fd)) {
if (-1 == fdlog_cycle(x->access_logfile->ptr,
&x->log_access_fd)) {
log_perror(srv->errh, __FILE__, __LINE__,
"cycling access log failed: %s", x->access_logfile->ptr);
}

11
src/server.c

@ -8,6 +8,7 @@
#include "chunk.h"
#include "h2.h" /* h2_send_1xx() */
#include "fdevent.h"
#include "fdlog.h"
#include "connections.h"
#include "sock_addr.h"
#include "stat_cache.h"
@ -1633,7 +1634,7 @@ static int server_main_setup (server * const srv, int argc, char **argv) {
if (!timer) alarm((timer = 5));
continue;
}
switch (fdevent_reaped_logger_pipe(pid)) {
switch (fdlog_pipes_waitpid_cb(pid)) {
default: break;
case -1: if (!timer) alarm((timer = 5));
__attribute_fallthrough__
@ -1672,7 +1673,7 @@ static int server_main_setup (server * const srv, int argc, char **argv) {
handle_sig_alarm = 0;
timer = 0;
plugins_call_handle_trigger(srv);
fdevent_restart_logger_pipes(log_monotonic_secs);
fdlog_pipes_restart(log_monotonic_secs);
}
break;
default:
@ -1722,7 +1723,7 @@ static int server_main_setup (server * const srv, int argc, char **argv) {
}
if (srv->srvconf.pid_file) buffer_clear(srv->srvconf.pid_file);
fdevent_clr_logger_pipe_pids();
fdlog_pipes_abandon_pids();
srv->pid = getpid();
li_rand_reseed();
}
@ -1887,7 +1888,7 @@ static void server_handle_sigalrm (server * const srv, unix_time64_t mono_ts, un
#endif
/* attempt to restart dead piped loggers every 64 secs */
if (0 == srv->srvconf.max_worker)
fdevent_restart_logger_pipes(mono_ts);
fdlog_pipes_restart(mono_ts);
}
/* cleanup stat-cache */
stat_cache_trigger_cleanup();
@ -1911,7 +1912,7 @@ static void server_handle_sigchld (server * const srv) {
}
if (0 == srv->srvconf.max_worker) {
/* check piped-loggers and restart, even if shutting down */
if (fdevent_waitpid_logger_pipe_pid(pid, log_monotonic_secs)) {
if (fdlog_pipes_waitpid_cb(pid)) {
continue;
}
}

Loading…
Cancel
Save