diff options
Diffstat (limited to 'src/lib/log/log.c')
-rw-r--r-- | src/lib/log/log.c | 97 |
1 files changed, 53 insertions, 44 deletions
diff --git a/src/lib/log/log.c b/src/lib/log/log.c index c53db46a8c..eb81515746 100644 --- a/src/lib/log/log.c +++ b/src/lib/log/log.c @@ -1,7 +1,7 @@ /* Copyright (c) 2001, Matej Pfajfar. * Copyright (c) 2001-2004, Roger Dingledine. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. - * Copyright (c) 2007-2019, The Tor Project, Inc. */ + * Copyright (c) 2007-2020, The Tor Project, Inc. */ /* See LICENSE for licensing information */ /** @@ -276,8 +276,8 @@ static int log_time_granularity = 1; /** Define log time granularity for all logs to be <b>granularity_msec</b> * milliseconds. */ -void -set_log_time_granularity(int granularity_msec) +MOCK_IMPL(void, +set_log_time_granularity,(int granularity_msec)) { log_time_granularity = granularity_msec; tor_log_sigsafe_err_set_granularity(granularity_msec); @@ -523,7 +523,7 @@ logfile_deliver(logfile_t *lf, const char *buf, size_t msg_len, * pass them, and some very old ones do not detect overflow so well. * Regrettably, they call their maximum line length MAXLINE. */ #if MAXLINE < 64 -#warn "MAXLINE is a very low number; it might not be from syslog.h after all" +#warning "MAXLINE is a very low number; it might not be from syslog.h." #endif char *m = msg_after_prefix; if (msg_len >= MAXLINE) @@ -665,20 +665,15 @@ tor_log_update_sigsafe_err_fds(void) const logfile_t *lf; int found_real_stderr = 0; - /* log_fds and err_fds contain matching entries: log_fds are the fds used by - * the log module, and err_fds are the fds used by the err module. - * For stdio logs, the log_fd and err_fd values are identical. - * For file logs, the err_fd is a dup() of the log_fd. - */ - int log_fds[TOR_SIGSAFE_LOG_MAX_FDS]; - int err_fds[TOR_SIGSAFE_LOG_MAX_FDS]; + /* The fds are the file descriptors of tor's stdout, stderr, and file + * logs. The log and err modules flush these fds during their shutdowns. */ + int fds[TOR_SIGSAFE_LOG_MAX_FDS]; int n_fds; LOCK_LOGS(); /* Reserve the first one for stderr. This is safe because when we daemonize, - * we dup2 /dev/null to stderr. - * For stderr, log_fds and err_fds are the same. */ - log_fds[0] = err_fds[0] = STDERR_FILENO; + * we dup2 /dev/null to stderr. */ + fds[0] = STDERR_FILENO; n_fds = 1; for (lf = logfiles; lf; lf = lf->next) { @@ -693,19 +688,11 @@ tor_log_update_sigsafe_err_fds(void) (LD_BUG|LD_GENERAL)) { if (lf->fd == STDERR_FILENO) found_real_stderr = 1; - /* Avoid duplicates by checking the log module fd against log_fds */ - if (int_array_contains(log_fds, n_fds, lf->fd)) + /* Avoid duplicates by checking the log module fd against fds */ + if (int_array_contains(fds, n_fds, lf->fd)) continue; - /* Update log_fds using the log module's fd */ - log_fds[n_fds] = lf->fd; - if (lf->needs_close) { - /* File log fds are duplicated, because close_log() closes the log - * module's fd. Both refer to the same file. */ - err_fds[n_fds] = dup(lf->fd); - } else { - /* stdio log fds are not closed by the log module. */ - err_fds[n_fds] = lf->fd; - } + /* Update fds using the log module's fd */ + fds[n_fds] = lf->fd; n_fds++; if (n_fds == TOR_SIGSAFE_LOG_MAX_FDS) break; @@ -713,20 +700,19 @@ tor_log_update_sigsafe_err_fds(void) } if (!found_real_stderr && - int_array_contains(log_fds, n_fds, STDOUT_FILENO)) { + int_array_contains(fds, n_fds, STDOUT_FILENO)) { /* Don't use a virtual stderr when we're also logging to stdout. * If we reached max_fds logs, we'll now have (max_fds - 1) logs. * That's ok, max_fds is large enough that most tor instances don't exceed * it. */ raw_assert(n_fds >= 2); /* Don't tor_assert inside log fns */ --n_fds; - log_fds[0] = log_fds[n_fds]; - err_fds[0] = err_fds[n_fds]; + fds[0] = fds[n_fds]; } UNLOCK_LOGS(); - tor_log_set_sigsafe_err_fds(err_fds, n_fds); + tor_log_set_sigsafe_err_fds(fds, n_fds); } /** Add to <b>out</b> a copy of every currently configured log file name. Used @@ -835,6 +821,32 @@ logs_free_all(void) * log mutex. */ } +/** Flush the signal-safe log files. + * + * This function is safe to call from a signal handler. It is currenly called + * by the BUG() macros, when terminating the process on an abnormal condition. + */ +void +logs_flush_sigsafe(void) +{ + /* If we don't have fsync() in unistd.h, we can't flush the logs. */ +#ifdef HAVE_FSYNC + logfile_t *victim, *next; + /* We can't LOCK_LOGS() in a signal handler, because it may call + * signal-unsafe functions. And we can't deallocate memory, either. */ + next = logfiles; + logfiles = NULL; + while (next) { + victim = next; + next = next->next; + if (victim->needs_close) { + /* We can't do anything useful if the flush fails. */ + (void)fsync(victim->fd); + } + } +#endif /* defined(HAVE_FSYNC) */ +} + /** Remove and free the log entry <b>victim</b> from the linked-list * logfiles (it is probably present, but it might not be due to thread * racing issues). After this function is called, the caller shouldn't @@ -907,9 +919,9 @@ set_log_severity_config(int loglevelMin, int loglevelMax, /** Add a log handler named <b>name</b> to send all messages in <b>severity</b> * to <b>fd</b>. Copies <b>severity</b>. Helper: does no locking. */ -static void -add_stream_log_impl(const log_severity_list_t *severity, - const char *name, int fd) +MOCK_IMPL(STATIC void, +add_stream_log_impl,(const log_severity_list_t *severity, + const char *name, int fd)) { logfile_t *lf; lf = tor_malloc_zero(sizeof(logfile_t)); @@ -965,18 +977,16 @@ logs_set_domain_logging(int enabled) UNLOCK_LOGS(); } -/** Add a log handler to receive messages during startup (before the real - * logs are initialized). +/** Add a log handler to accept messages when no other log is configured. */ void -add_temp_log(int min_severity) +add_default_log(int min_severity) { log_severity_list_t *s = tor_malloc_zero(sizeof(log_severity_list_t)); set_log_severity_config(min_severity, LOG_ERR, s); LOCK_LOGS(); - add_stream_log_impl(s, "<temp>", fileno(stdout)); + add_stream_log_impl(s, "<default>", fileno(stdout)); tor_free(s); - logfiles->is_temporary = 1; UNLOCK_LOGS(); } @@ -1119,8 +1129,7 @@ flush_log_messages_from_startup(void) UNLOCK_LOGS(); } -/** Close any log handlers added by add_temp_log() or marked by - * mark_logs_temp(). */ +/** Close any log handlers marked by mark_logs_temp(). */ void close_temp_logs(void) { @@ -1172,10 +1181,10 @@ mark_logs_temp(void) * opening the logfile failed, -1 is returned and errno is set appropriately * (by open(2)). Takes ownership of fd. */ -int -add_file_log(const log_severity_list_t *severity, - const char *filename, - int fd) +MOCK_IMPL(int, +add_file_log,(const log_severity_list_t *severity, + const char *filename, + int fd)) { logfile_t *lf; |