journald-console.c revision 6482f6269c87d2249e52e889a63adbdd50f2d691
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/***
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2011 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering***/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <time.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <fcntl.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <sys/socket.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen#include "fileio.h"
71d35b6b5563817dfbe757ab9e3b9f018b2db491Thomas Hindoe Paaboel Andersen#include "journald-server.h"
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering#include "journald-console.h"
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering#include "formats-util.h"
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool prefix_timestamp(void) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering static int cached_printk_time = -1;
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (_unlikely_(cached_printk_time < 0)) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *p = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cached_printk_time =
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering read_one_line_file("/sys/module/printk/parameters/time", &p) >= 0
b93312f5960b276bae915906ccde36f545bae3e0Zbigniew Jędrzejewski-Szmek && parse_boolean(p) > 0;
b93312f5960b276bae915906ccde36f545bae3e0Zbigniew Jędrzejewski-Szmek }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return cached_printk_time;
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering}
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poetteringvoid server_forward_console(
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering Server *s,
23502de3b0891455c8ce499a9eb61b69d060a829Daniel Mack int priority,
23502de3b0891455c8ce499a9eb61b69d060a829Daniel Mack const char *identifier,
23502de3b0891455c8ce499a9eb61b69d060a829Daniel Mack const char *message,
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering const struct ucred *ucred) {
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering struct iovec iovec[5];
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering struct timespec ts;
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering char tbuf[sizeof("[] ")-1 + DECIMAL_STR_MAX(ts.tv_sec) + DECIMAL_STR_MAX(ts.tv_nsec)-3 + 1];
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering char header_pid[sizeof("[]: ")-1 + DECIMAL_STR_MAX(pid_t)];
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering int n = 0, fd;
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering _cleanup_free_ char *ident_buf = NULL;
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering const char *tty;
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering assert(s);
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering assert(message);
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering if (LOG_PRI(priority) > s->max_level_console)
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering return;
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering /* First: timestamp */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering if (prefix_timestamp()) {
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering xsprintf(tbuf, "[%5"PRI_TIME".%06ld] ",
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering ts.tv_sec,
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering ts.tv_nsec / 1000);
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering IOVEC_SET_STRING(iovec[n++], tbuf);
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering }
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering /* Second: identifier and PID */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering if (ucred) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!identifier) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering get_process_comm(ucred->pid, &ident_buf);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering identifier = ident_buf;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering }
23502de3b0891455c8ce499a9eb61b69d060a829Daniel Mack
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering xsprintf(header_pid, "["PID_FMT"]: ", ucred->pid);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering if (identifier)
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering IOVEC_SET_STRING(iovec[n++], identifier);
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering IOVEC_SET_STRING(iovec[n++], header_pid);
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering } else if (identifier) {
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering IOVEC_SET_STRING(iovec[n++], identifier);
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering IOVEC_SET_STRING(iovec[n++], ": ");
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering }
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering /* Fourth: message */
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering IOVEC_SET_STRING(iovec[n++], message);
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering IOVEC_SET_STRING(iovec[n++], "\n");
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering tty = s->tty_path ? s->tty_path : "/dev/console";
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering fd = open_terminal(tty, O_WRONLY|O_NOCTTY|O_CLOEXEC);
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering if (fd < 0) {
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering log_debug_errno(errno, "Failed to open %s for logging: %m", tty);
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering return;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (writev(fd, iovec, n) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug_errno(errno, "Failed to write to %s for logging: %m", tty);
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering safe_close(fd);
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering}
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering