X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Flog.c;h=8d1067c63bf7f894589fefc1bf9adeca8f4197eb;hp=2517f5d780d406bfc030fae123a09c99a8daae35;hb=4de33e7f3238a6fe616e61139ab87e221572e5e5;hpb=919ce0b7affc6fbd68598b709faf477f56c22ac1 diff --git a/src/shared/log.c b/src/shared/log.c index 2517f5d78..8d1067c63 100644 --- a/src/shared/log.c +++ b/src/shared/log.c @@ -126,7 +126,10 @@ static int create_log_socket(int type) { /* We need a blocking fd here since we'd otherwise lose messages way too early. However, let's not hang forever in the unlikely case of a deadlock. */ - timeval_store(&tv, 1*USEC_PER_MINUTE); + if (getpid() == 1) + timeval_store(&tv, 10 * USEC_PER_MSEC); + else + timeval_store(&tv, 10 * USEC_PER_SEC); setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); return fd; @@ -272,8 +275,6 @@ int log_open(void) { log_close_journal(); log_close_syslog(); - /* Get the real /dev/console if we are PID=1, hence reopen */ - log_close_console(); return log_open_console(); } @@ -337,8 +338,25 @@ static int write_to_console( IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF); IOVEC_SET_STRING(iovec[n++], "\n"); - if (writev(console_fd, iovec, n) < 0) - return -errno; + if (writev(console_fd, iovec, n) < 0) { + + if (errno == EIO && getpid() == 1) { + + /* If somebody tried to kick us from our + * console tty (via vhangup() or suchlike), + * try to reconnect */ + + log_close_console(); + log_open_console(); + + if (console_fd < 0) + return 0; + + if (writev(console_fd, iovec, n) < 0) + return -errno; + } else + return -errno; + } return 1; } @@ -685,22 +703,21 @@ int log_meta_object( return r; } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wformat-nonliteral" static void log_assert(int level, const char *text, const char *file, int line, const char *func, const char *format) { static char buffer[LINE_MAX]; if (_likely_(LOG_PRI(level) > log_max_level)) return; + DISABLE_WARNING_FORMAT_NONLITERAL; snprintf(buffer, sizeof(buffer), format, text, file, line, func); + REENABLE_WARNING; char_array_0(buffer); log_abort_msg = buffer; log_dispatch(level, file, line, func, NULL, NULL, buffer); } -#pragma GCC diagnostic pop noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) { log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting."); @@ -861,7 +878,24 @@ int log_set_max_level_from_string(const char *e) { } void log_parse_environment(void) { + _cleanup_free_ char *line = NULL; const char *e; + int r; + + r = proc_cmdline(&line); + if (r < 0) + log_warning("Failed to read /proc/cmdline. Ignoring: %s", strerror(-r)); + else if (r > 0) { + char *w, *state; + size_t l; + + FOREACH_WORD_QUOTED(w, l, line, state) { + if (l == 5 && startswith(w, "debug")) { + log_set_max_level(LOG_DEBUG); + break; + } + } + } e = secure_getenv("SYSTEMD_LOG_TARGET"); if (e && log_set_target_from_string(e) < 0) @@ -892,10 +926,18 @@ void log_show_color(bool b) { show_color = b; } +bool log_get_show_color(void) { + return show_color; +} + void log_show_location(bool b) { show_location = b; } +bool log_get_show_location(void) { + return show_location; +} + int log_show_color_from_string(const char *e) { int t; @@ -938,3 +980,20 @@ static const char *const log_target_table[] = { }; DEFINE_STRING_TABLE_LOOKUP(log_target, LogTarget); + +void log_received_signal(int level, const struct signalfd_siginfo *si) { + if (si->ssi_pid > 0) { + _cleanup_free_ char *p = NULL; + + get_process_comm(si->ssi_pid, &p); + + log_full(level, + "Received SIG%s from PID "PID_FMT" (%s).", + signal_to_string(si->ssi_signo), + si->ssi_pid, strna(p)); + } else + log_full(level, + "Received SIG%s.", + signal_to_string(si->ssi_signo)); + +}