3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering/***
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering This file is part of systemd.
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering Copyright 2011 Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering (at your option) any later version.
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering systemd is distributed in the hope that it will be useful, but
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering Lesser General Public License for more details.
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering***/
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering#include <fcntl.h>
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell#include <sys/socket.h>
cf0fbc49e67b55f8d346fc94de28c90113505297Thomas Hindoe Paaboel Andersen#include <time.h>
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "fd-util.h"
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog#include "fileio.h"
6482f6269c87d2249e52e889a63adbdd50f2d691Ronny Chevalier#include "formats-util.h"
afc5dbf37fd2399d37976388d9dd9ab470ecf446Lennart Poettering#include "io-util.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "journald-console.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "journald-server.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "parse-util.h"
0b452006de98294d1690f045f6ea2f7f6630ec3bRonny Chevalier#include "process-util.h"
15a5e95075a7f6007dd97b2a165c8ed16fe683dfLennart Poettering#include "stdio-util.h"
288a74cce597f81d3ba01d8a5ca7d2ba5b654b7eRonny Chevalier#include "terminal-util.h"
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskogstatic bool prefix_timestamp(void) {
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog static int cached_printk_time = -1;
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog if (_unlikely_(cached_printk_time < 0)) {
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog _cleanup_free_ char *p = NULL;
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog cached_printk_time =
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog read_one_line_file("/sys/module/printk/parameters/time", &p) >= 0
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog && parse_boolean(p) > 0;
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog }
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog return cached_printk_time;
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog}
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poetteringvoid server_forward_console(
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering Server *s,
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering int priority,
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering const char *identifier,
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering const char *message,
3b3154df7e2773332bb814e167187367a0ccae4aLennart Poettering const struct ucred *ucred) {
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog struct iovec iovec[5];
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog struct timespec ts;
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek char tbuf[sizeof("[] ")-1 + DECIMAL_STR_MAX(ts.tv_sec) + DECIMAL_STR_MAX(ts.tv_nsec)-3 + 1];
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek char header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t)];
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering int n = 0, fd;
fb4729006a7174472e8a435b0887e532cd6217fcZbigniew Jędrzejewski-Szmek _cleanup_free_ char *ident_buf = NULL;
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering const char *tty;
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering assert(s);
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering assert(message);
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering if (LOG_PRI(priority) > s->max_level_console)
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering return;
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog /* First: timestamp */
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog if (prefix_timestamp()) {
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek xsprintf(tbuf, "[%5"PRI_TIME".%06ld] ",
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek ts.tv_sec,
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek ts.tv_nsec / 1000);
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog IOVEC_SET_STRING(iovec[n++], tbuf);
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog }
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog /* Second: identifier and PID */
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering if (ucred) {
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering if (!identifier) {
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering get_process_comm(ucred->pid, &ident_buf);
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering identifier = ident_buf;
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering }
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek xsprintf(header_pid, "["PID_FMT"]: ", ucred->pid);
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering if (identifier)
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering IOVEC_SET_STRING(iovec[n++], identifier);
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering IOVEC_SET_STRING(iovec[n++], header_pid);
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering } else if (identifier) {
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering IOVEC_SET_STRING(iovec[n++], identifier);
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering IOVEC_SET_STRING(iovec[n++], ": ");
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering }
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
ad79565d6b37bcc93cf773a39b975e5b85d122daUmut Tezduyar Lindskog /* Fourth: message */
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering IOVEC_SET_STRING(iovec[n++], message);
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering IOVEC_SET_STRING(iovec[n++], "\n");
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering tty = s->tty_path ? s->tty_path : "/dev/console";
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering fd = open_terminal(tty, O_WRONLY|O_NOCTTY|O_CLOEXEC);
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering if (fd < 0) {
709f6e46a35ec492b70eb92943d82a8d838ce918Michal Schmidt log_debug_errno(fd, "Failed to open %s for logging: %m", tty);
fb4729006a7174472e8a435b0887e532cd6217fcZbigniew Jędrzejewski-Szmek return;
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering }
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering if (writev(fd, iovec, n) < 0)
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_debug_errno(errno, "Failed to write to %s for logging: %m", tty);
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering safe_close(fd);
3b7124a8db56ed57525b9ecfd19cfdc8c9facba0Lennart Poettering}