journald-server.c revision 23ad4dd8844c582929115a11ed2830a1371568d6
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/***
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering This file is part of systemd.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Copyright 2011 Lennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering systemd is free software; you can redistribute it and/or modify it
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering under the terms of the GNU Lesser General Public License as published by
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering (at your option) any later version.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering systemd is distributed in the hope that it will be useful, but
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Lesser General Public License for more details.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering You should have received a copy of the GNU Lesser General Public License
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering***/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <sys/signalfd.h>
a9cdc94f7ff40f22a3cf9472f612a80730a1b010Dave Reisner#include <sys/ioctl.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <linux/sockios.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <sys/statvfs.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <sys/mman.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <sys/timerfd.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <libudev.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <systemd/sd-journal.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <systemd/sd-messages.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <systemd/sd-daemon.h>
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers#include "fileio.h"
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers#include "mkdir.h"
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers#include "hashmap.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "journal-file.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "socket-util.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "cgroup-util.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "list.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "virt.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "missing.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "conf-parser.h"
0affed79d2e30013f07cb94e6f07e3fcb81c02faLennart Poettering#include "journal-internal.h"
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek#include "journal-vacuum.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "journal-authenticate.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "journald-server.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "journald-rate-limit.h"
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers#include "journald-kmsg.h"
7085053a437456ab87d726f3697002dd811fdf7aDaniel Wallace#include "journald-syslog.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "journald-stream.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "journald-console.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include "journald-native.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#ifdef HAVE_ACL
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <sys/acl.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <acl/libacl.h>
1b12a7b5896f94bdf33b3a6661ebabd761ea6adcHarald Hoyer#include "acl-util.h"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#endif
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#ifdef HAVE_SELINUX
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#include <selinux/selinux.h>
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#endif
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#define USER_JOURNALS_MAX 1024
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering#define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE)
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering#define DEFAULT_RATE_LIMIT_INTERVAL (10*USEC_PER_SEC)
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering#define DEFAULT_RATE_LIMIT_BURST 200
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic const char* const storage_table[] = {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [STORAGE_AUTO] = "auto",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [STORAGE_VOLATILE] = "volatile",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [STORAGE_PERSISTENT] = "persistent",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [STORAGE_NONE] = "none"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering};
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_STRING_TABLE_LOOKUP(storage, Storage);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic const char* const split_mode_table[] = {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [SPLIT_NONE] = "none",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [SPLIT_UID] = "uid",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering [SPLIT_LOGIN] = "login"
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering};
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic uint64_t available_space(Server *s) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char ids[33];
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering _cleanup_free_ char *p = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *f;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering sd_id128_t machine;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct statvfs ss;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering uint64_t sum = 0, avail = 0, ss_avail = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering _cleanup_closedir_ DIR *d = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering usec_t ts;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering JournalMetrics *m;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ts = now(CLOCK_MONOTONIC);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return s->cached_available_space;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers r = sd_id128_get_machine(&machine);
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek if (r < 0)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return 0;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (s->system_journal) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers f = "/var/log/journal/";
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers m = &s->system_metrics;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers } else {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers f = "/run/log/journal/";
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers m = &s->runtime_metrics;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers assert(m);
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering p = strappend(f, sd_id128_to_string(machine, ids));
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers if (!p)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return 0;
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers d = opendir(p);
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers if (!d)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return 0;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (fstatvfs(dirfd(d), &ss) < 0)
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers return 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering for (;;) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers struct stat st;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers struct dirent *de;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering union dirent_storage buf;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = readdir_r(d, &buf.de, &de);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r != 0)
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers break;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (!de)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering break;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!endswith(de->d_name, ".journal") &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering !endswith(de->d_name, ".journal~"))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering continue;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers continue;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!S_ISREG(st.st_mode))
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering continue;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers sum += (uint64_t) st.st_blocks * 512UL;
94676f3e9352cbf1f72e0a512ee0d2ed83ff676dLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers avail = sum >= m->max_use ? 0 : m->max_use - sum;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
94676f3e9352cbf1f72e0a512ee0d2ed83ff676dLennart Poettering ss_avail = ss.f_bsize * ss.f_bavail;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers ss_avail = ss_avail < m->keep_free ? 0 : ss_avail - m->keep_free;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
94676f3e9352cbf1f72e0a512ee0d2ed83ff676dLennart Poettering if (ss_avail < avail)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering avail = ss_avail;
c49b30a23583ff39daaa26696bcab478d2fee0bbLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers s->cached_available_space = avail;
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering s->cached_available_space_timestamp = ts;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return avail;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic void server_read_file_gid(Server *s) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *g = "systemd-journal";
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(s);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (s->file_gid_valid)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = get_group_creds(&g, &s->file_gid);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to resolve '%s' group: %s", g, strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* if we couldn't read the gid, then it will be 0, but that's
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * fine and we shouldn't try to resolve the group again, so
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * let's just pretend it worked right-away. */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering s->file_gid_valid = true;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringvoid server_fix_perms(Server *s, JournalFile *f, uid_t uid) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#ifdef HAVE_ACL
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering acl_t acl;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering acl_entry_t entry;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering acl_permset_t permset;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#endif
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(f);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_read_file_gid(s);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = fchmod_and_fchown(f->fd, 0640, 0, s->file_gid);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to fix access mode/rights on %s, ignoring: %s", f->path, strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#ifdef HAVE_ACL
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (uid <= 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering acl = acl_get_fd(f->fd);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!acl) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to read ACL on %s, ignoring: %m", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = acl_find_uid(acl, uid, &entry);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r <= 0) {
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (acl_create_entry(&acl, &entry) < 0 ||
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering acl_set_tag_type(entry, ACL_USER) < 0 ||
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering acl_set_qualifier(entry, &uid) < 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering goto finish;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* We do not recalculate the mask unconditionally here,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * so that the fchmod() mask above stays intact. */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (acl_get_permset(entry, &permset) < 0 ||
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering acl_add_perm(permset, ACL_READ) < 0 ||
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering calc_acl_mask_if_needed(&acl) < 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering goto finish;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (acl_set_fd(f->fd, acl) < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to set ACL on %s, ignoring: %m", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringfinish:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering acl_free(acl);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#endif
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic JournalFile* find_journal(Server *s, uid_t uid) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *p;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering JournalFile *f;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering sd_id128_t machine;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(s);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* We split up user logs only on /var, not on /run. If the
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * runtime file is open, we write to it exclusively, in order
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * to guarantee proper order as soon as we flush /run to
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * /var and close the runtime file. */
2f7a4867babd3fd382e5495f21724358f30fa67dMichal Sekletar
2f7a4867babd3fd382e5495f21724358f30fa67dMichal Sekletar if (s->runtime_journal)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return s->runtime_journal;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (uid <= 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return s->system_journal;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = sd_id128_get_machine(&machine);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return s->system_journal;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
0affed79d2e30013f07cb94e6f07e3fcb81c02faLennart Poettering f = hashmap_get(s->user_journals, UINT32_TO_PTR(uid));
0affed79d2e30013f07cb94e6f07e3fcb81c02faLennart Poettering if (f)
0affed79d2e30013f07cb94e6f07e3fcb81c02faLennart Poettering return f;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/user-%lu.journal",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering SD_ID128_FORMAT_VAL(machine), (unsigned long) uid) < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return s->system_journal;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering while (hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek /* Too many open? Then let's close one */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering f = hashmap_steal_first(s->user_journals);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(f);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering journal_file_close(f);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, s->system_journal, &f);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna free(p);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (r < 0)
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna return s->system_journal;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna server_fix_perms(s, f, uid);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna r = hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (r < 0) {
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna journal_file_close(f);
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer return s->system_journal;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna }
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna return f;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna}
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagnavoid server_rotate(Server *s) {
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek JournalFile *f;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna void *k;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna Iterator i;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna int r;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_debug("Rotating...");
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (s->runtime_journal) {
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna r = journal_file_rotate(&s->runtime_journal, s->compress, false);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (r < 0)
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (s->runtime_journal)
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("Failed to rotate %s: %s", s->runtime_journal->path, strerror(-r));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna else
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("Failed to create new runtime journal: %s", strerror(-r));
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek else
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek server_fix_perms(s, s->runtime_journal, 0);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna }
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek if (s->system_journal) {
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek r = journal_file_rotate(&s->system_journal, s->compress, s->seal);
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek if (r < 0)
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (s->system_journal)
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("Failed to rotate %s: %s", s->system_journal->path, strerror(-r));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna else
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("Failed to create new system journal: %s", strerror(-r));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
8333c77edf8fd1654cd96f3f6ee0f078dd64b58bZbigniew Jędrzejewski-Szmek else
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna server_fix_perms(s, s->system_journal, 0);
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek }
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek r = journal_file_rotate(&f, s->compress, s->seal);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (r < 0)
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna if (f)
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers log_error("Failed to rotate %s: %s", f->path, strerror(-r));
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek else
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("Failed to create user journal: %s", strerror(-r));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna else {
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna hashmap_replace(s->user_journals, k, f);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna server_fix_perms(s, f, PTR_TO_UINT32(k));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna }
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna }
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna}
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagnavoid server_sync(Server *s) {
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek JournalFile *f;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna void *k;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna Iterator i;
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna int r;
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna static const struct itimerspec sync_timer_disable = {};
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek if (s->system_journal) {
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek r = journal_file_set_offline(s->system_journal);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to sync system journal: %s", strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
7c2d80944afb4196f2eff614e8da1450dffcbeaaThomas Hindoe Paaboel Andersen r = journal_file_set_offline(f);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek log_error("Failed to sync user journal: %s", strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers r = timerfd_settime(s->sync_timer_fd, 0, &sync_timer_disable, NULL);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to disable max timer: %m");
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering s->sync_scheduled = false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringvoid server_vacuum(Server *s) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *p;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char ids[33];
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering sd_id128_t machine;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("Vacuuming...");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering s->oldest_file_usec = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = sd_id128_get_machine(&machine);
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering if (r < 0) {
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering log_error("Failed to get machine ID: %s", strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering sd_id128_to_string(machine, ids);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (s->system_journal) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers p = strappend("/var/log/journal/", ids);
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering if (!p) {
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering log_oom();
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering return;
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0 && r != -ENOENT)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to vacuum %s: %s", p, strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(p);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (s->runtime_journal) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering p = strappend("/run/log/journal/", ids);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!p) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_oom();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0 && r != -ENOENT)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to vacuum %s: %s", p, strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(p);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2b6bf07dd23bb467099d213c97b3875c5e453491Zbigniew Jędrzejewski-Szmek s->cached_available_space_timestamp = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringbool shall_try_append_again(JournalFile *f, int r) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* -E2BIG Hit configured limit
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -EFBIG Hit fs limit
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -EDQUOT Quota limit hit
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -ENOSPC Disk full
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -EHOSTDOWN Other machine
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -EBUSY Unclean shutdown
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -EPROTONOSUPPORT Unsupported feature
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek -EBADMSG Corrupted
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek -ENODATA Truncated
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -ESHUTDOWN Already archived */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("%s: Allocation limit reached, rotating.", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else if (r == -EHOSTDOWN)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_info("%s: Journal file from other machine, rotating.", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else if (r == -EBUSY)
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers log_info("%s: Unclean shutdown, rotating.", f->path);
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer else if (r == -EPROTONOSUPPORT)
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek log_info("%s: Unsupported feature, rotating.", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("%s: Journal file corrupted, rotating.", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek return true;
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering JournalFile *f;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering bool vacuumed = false;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(s);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(iovec);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(n > 0);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering f = find_journal(s, uid);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!f)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (journal_file_rotate_suggested(f, s->max_file_usec)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_rotate(s);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_vacuum(s);
7c2d80944afb4196f2eff614e8da1450dffcbeaaThomas Hindoe Paaboel Andersen vacuumed = true;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering f = find_journal(s, uid);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!f)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers }
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering if (r >= 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_schedule_sync(s);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (vacuumed || !shall_try_append_again(f, r)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to write entry, ignoring: %s", strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_rotate(s);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_vacuum(s);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering f = find_journal(s, uid);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!f)
6b2b6f30e38d67b032d6bdc6b47ae05e143e96c5Michal Schmidt return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering log_debug("Retrying write.");
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to write entry, ignoring: %s", strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sieversstatic void dispatch_message_real(
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Server *s,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers struct iovec *iovec, unsigned n, unsigned m,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers struct ucred *ucred,
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering struct timeval *tv,
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering const char *label, size_t label_len,
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering const char *unit_id) {
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)],
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering uid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)],
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers gid[sizeof("_GID=") + DECIMAL_STR_MAX(gid_t)],
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering owner_uid[sizeof("_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)],
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)],
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering boot_id[sizeof("_BOOT_ID=") + 32] = "_BOOT_ID=",
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering machine_id[sizeof("_MACHINE_ID=") + 32] = "_MACHINE_ID=";
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering char *comm, *exe, *cmdline, *cgroup, *session, *unit, *hostname;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sd_id128_t id;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering int r;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering char *t, *c;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering uid_t realuid = 0, owner = 0, journal_uid;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering bool owner_valid = false;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering#ifdef HAVE_AUDIT
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering char audit_session[sizeof("_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)],
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering audit_loginuid[sizeof("_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)];
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering uint32_t audit;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering uid_t loginuid;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering#endif
c62e11ce3966c55d23520b9f0785c7e839cf7f37Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(s);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(iovec);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(n > 0);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(n + N_IOVEC_META_FIELDS <= m);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (ucred) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering realuid = ucred->uid;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sprintf(pid, "_PID=%lu", (unsigned long) ucred->pid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], pid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sprintf(uid, "_UID=%lu", (unsigned long) ucred->uid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], uid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sprintf(gid, "_GID=%lu", (unsigned long) ucred->gid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], gid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = get_process_comm(ucred->pid, &t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (r >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering comm = strappenda("_COMM=", t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering free(t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], comm);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = get_process_exe(ucred->pid, &t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (r >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering exe = strappenda("_EXE=", t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering free(t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], exe);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = get_process_cmdline(ucred->pid, 0, false, &t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (r >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering cmdline = strappenda("_CMDLINE=", t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering free(t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], cmdline);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering#ifdef HAVE_AUDIT
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = audit_session_from_pid(ucred->pid, &audit);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (r >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sprintf(audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], audit_session);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = audit_loginuid_from_pid(ucred->pid, &loginuid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (r >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sprintf(audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], audit_loginuid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering#endif
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = cg_pid_get_path_shifted(ucred->pid, NULL, &c);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (r >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering cgroup = strappenda("_SYSTEMD_CGROUP=", c);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], cgroup);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = cg_path_get_session(c, &t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (r >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering session = strappenda("_SYSTEMD_SESSION=", t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering free(t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], session);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (cg_path_get_owner_uid(c, &owner) >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering owner_valid = true;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sprintf(owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], owner_uid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (cg_path_get_unit(c, &t) >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering unit = strappenda("_SYSTEMD_UNIT=", t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering free(t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering } else if (cg_path_get_user_unit(c, &t) >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering unit = strappenda("_SYSTEMD_USER_UNIT=", t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering free(t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering } else if (unit_id) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (session)
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering unit = strappenda("_SYSTEMD_USER_UNIT=", unit_id);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering else
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering unit = strappenda("_SYSTEMD_UNIT=", unit_id);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering } else
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering unit = NULL;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (unit)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering IOVEC_SET_STRING(iovec[n++], unit);
82c1d8f4eb74ddd9be2c9b9b56d9dc564c599effLennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering free(c);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering#ifdef HAVE_SELINUX
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (label) {
a86a47ce1f63476631635fbcbc10af8877172114Lennart Poettering char *selinux_context = alloca(sizeof("_SELINUX_CONTEXT=") + label_len);
a86a47ce1f63476631635fbcbc10af8877172114Lennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *((char*) mempcpy(stpcpy(selinux_context, "_SELINUX_CONTEXT="), label, label_len)) = 0;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], selinux_context);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering } else {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering security_context_t con;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (getpidcon(ucred->pid, &con) >= 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *selinux_context = strappenda("_SELINUX_CONTEXT=", con);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering freecon(con);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], selinux_context);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering }
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering#endif
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (tv) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering sprintf(source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu", (unsigned long long) timeval_load(tv));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering IOVEC_SET_STRING(iovec[n++], source_time);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Note that strictly speaking storing the boot id here is
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * redundant since the entry includes this in-line
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * anyway. However, we need this indexed, too. */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = sd_id128_get_boot(&id);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r >= 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering sd_id128_to_string(id, boot_id + sizeof("_BOOT_ID=") - 1);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering IOVEC_SET_STRING(iovec[n++], boot_id);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers r = sd_id128_get_machine(&id);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (r >= 0) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers sd_id128_to_string(id, machine_id + sizeof("_MACHINE_ID=") - 1);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers IOVEC_SET_STRING(iovec[n++], machine_id);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers }
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering t = gethostname_malloc();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (t) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering hostname = strappenda("_HOSTNAME=", t);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(t);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering IOVEC_SET_STRING(iovec[n++], hostname);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering assert(n <= m);
4b4bec19582c3ad2b7d25116f3c22c783274feadThomas Hindoe Paaboel Andersen
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (s->split_mode == SPLIT_UID && realuid > 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Split up strictly by any UID */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering journal_uid = realuid;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else if (s->split_mode == SPLIT_LOGIN && realuid > 0 && owner_valid && owner > 0)
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering /* Split up by login UIDs, this avoids creation of
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * individual journals for system UIDs. We do this
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * only if the realuid is not root, in order not to
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * accidentally leak privileged information to the
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * user that is logged by a privileged process that is
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * part of an unprivileged session.*/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering journal_uid = owner;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering journal_uid = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering write_to_journal(s, journal_uid, iovec, n);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringvoid server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char mid[11 + 32 + 1];
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen char buffer[16 + LINE_MAX + 1];
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen struct iovec iovec[N_IOVEC_META_FIELDS + 4];
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen int n = 0;
546158bc6f46f8004cc11e81d19d223e0da56730Jan Janssen va_list ap;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers struct ucred ucred = {};
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers assert(s);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers assert(format);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers IOVEC_SET_STRING(iovec[n++], "PRIORITY=6");
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=driver");
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers memcpy(buffer, "MESSAGE=", 8);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers va_start(ap, format);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering vsnprintf(buffer + 8, sizeof(buffer) - 8, format, ap);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering va_end(ap);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char_array_0(buffer);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering IOVEC_SET_STRING(iovec[n++], buffer);
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!sd_id128_equal(message_id, SD_ID128_NULL)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering snprintf(mid, sizeof(mid), MESSAGE_ID(message_id));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char_array_0(mid);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering IOVEC_SET_STRING(iovec[n++], mid);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers ucred.pid = getpid();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ucred.uid = getuid();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering ucred.gid = getgid();
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringvoid server_dispatch_message(
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Server *s,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct iovec *iovec, unsigned n, unsigned m,
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers struct ucred *ucred,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct timeval *tv,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering const char *label, size_t label_len,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering const char *unit_id,
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering int priority) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering int rl, r;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering _cleanup_free_ char *path = NULL;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering char *c;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(s);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering assert(iovec || n == 0);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (n == 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (LOG_PRI(priority) > s->max_level_store)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!ucred)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering goto finish;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = cg_pid_get_path_shifted(ucred->pid, NULL, &path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering goto finish;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* example: /user/lennart/3/foobar
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * /system/dbus.service/foobar
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * So let's cut of everything past the third /, since that is
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * where user directories start */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering c = strchr(path, '/');
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (c) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering c = strchr(c+1, '/');
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (c) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering c = strchr(c+1, '/');
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (c)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *c = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering }
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering rl = journal_rate_limit_test(s->rate_limit, path,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering priority & LOG_PRIMASK, available_space(s));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (rl == 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Write a suppression message if we suppressed something */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (rl > 1)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_driver_message(s, SD_MESSAGE_JOURNAL_DROPPED,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "Suppressed %u messages from %s", rl - 1, path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringfinish:
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering}
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic int system_journal_open(Server *s) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering int r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *fn;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering sd_id128_t machine;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char ids[33];
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = sd_id128_get_machine(&machine);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return r;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering sd_id128_to_string(machine, ids);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!s->system_journal &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering access("/run/systemd/journal/flushed", F_OK) >= 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers /* If in auto mode: first try to create the machine
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers * path, but not the prefix.
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering *
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * If in persistent mode: create /var/log/journal and
a9cdc94f7ff40f22a3cf9472f612a80730a1b010Dave Reisner * the machine path */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (s->storage == STORAGE_PERSISTENT)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering (void) mkdir("/var/log/journal/", 0755);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering fn = strappend("/var/log/journal/", ids);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!fn)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering return -ENOMEM;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers (void) mkdir(fn, 0755);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers free(fn);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering fn = strjoin("/var/log/journal/", ids, "/system.journal", NULL);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!fn)
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers return -ENOMEM;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering free(fn);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering if (r >= 0) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char fb[FORMAT_BYTES_MAX];
server_fix_perms(s, s->system_journal, 0);
server_driver_message(s, SD_ID128_NULL, "Allowing system journal files to grow to %s.",
format_bytes(fb, sizeof(fb), s->system_metrics.max_use));
} else if (r < 0) {
if (r != -ENOENT && r != -EROFS)
log_warning("Failed to open system journal: %s", strerror(-r));
r = 0;
}
}
if (!s->runtime_journal &&
(s->storage != STORAGE_NONE)) {
fn = strjoin("/run/log/journal/", ids, "/system.journal", NULL);
if (!fn)
return -ENOMEM;
if (s->system_journal) {
/* Try to open the runtime journal, but only
* if it already exists, so that we can flush
* it into the system journal */
r = journal_file_open(fn, O_RDWR, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
free(fn);
if (r < 0) {
if (r != -ENOENT)
log_warning("Failed to open runtime journal: %s", strerror(-r));
r = 0;
}
} else {
/* OK, we really need the runtime journal, so create
* it if necessary. */
(void) mkdir_parents(fn, 0755);
r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
free(fn);
if (r < 0) {
log_error("Failed to open runtime journal: %s", strerror(-r));
return r;
}
}
if (s->runtime_journal) {
char fb[FORMAT_BYTES_MAX];
server_fix_perms(s, s->runtime_journal, 0);
server_driver_message(s, SD_ID128_NULL, "Allowing runtime journal files to grow to %s.",
format_bytes(fb, sizeof(fb), s->runtime_metrics.max_use));
}
}
return r;
}
int server_flush_to_var(Server *s) {
int r;
sd_id128_t machine;
sd_journal *j = NULL;
assert(s);
if (s->storage != STORAGE_AUTO &&
s->storage != STORAGE_PERSISTENT)
return 0;
if (!s->runtime_journal)
return 0;
system_journal_open(s);
if (!s->system_journal)
return 0;
log_debug("Flushing to /var...");
r = sd_id128_get_machine(&machine);
if (r < 0) {
log_error("Failed to get machine id: %s", strerror(-r));
return r;
}
r = sd_journal_open(&j, SD_JOURNAL_RUNTIME_ONLY);
if (r < 0) {
log_error("Failed to read runtime journal: %s", strerror(-r));
return r;
}
sd_journal_set_data_threshold(j, 0);
SD_JOURNAL_FOREACH(j) {
Object *o = NULL;
JournalFile *f;
f = j->current_file;
assert(f && f->current_offset > 0);
r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
if (r < 0) {
log_error("Can't read entry: %s", strerror(-r));
goto finish;
}
r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
if (r >= 0)
continue;
if (!shall_try_append_again(s->system_journal, r)) {
log_error("Can't write entry: %s", strerror(-r));
goto finish;
}
server_rotate(s);
server_vacuum(s);
if (!s->system_journal) {
log_notice("Didn't flush runtime journal since rotation of system journal wasn't successful.");
r = -EIO;
goto finish;
}
log_debug("Retrying write.");
r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
if (r < 0) {
log_error("Can't write entry: %s", strerror(-r));
goto finish;
}
}
finish:
journal_file_post_change(s->system_journal);
journal_file_close(s->runtime_journal);
s->runtime_journal = NULL;
if (r >= 0)
rm_rf("/run/log/journal", false, true, false);
sd_journal_close(j);
return r;
}
int process_event(Server *s, struct epoll_event *ev) {
assert(s);
assert(ev);
if (ev->data.fd == s->signal_fd) {
struct signalfd_siginfo sfsi;
ssize_t n;
if (ev->events != EPOLLIN) {
log_error("Got invalid event from epoll.");
return -EIO;
}
n = read(s->signal_fd, &sfsi, sizeof(sfsi));
if (n != sizeof(sfsi)) {
if (n >= 0)
return -EIO;
if (errno == EINTR || errno == EAGAIN)
return 1;
return -errno;
}
if (sfsi.ssi_signo == SIGUSR1) {
touch("/run/systemd/journal/flushed");
server_flush_to_var(s);
server_sync(s);
return 1;
}
if (sfsi.ssi_signo == SIGUSR2) {
server_rotate(s);
server_vacuum(s);
return 1;
}
log_info("Received SIG%s", signal_to_string(sfsi.ssi_signo));
return 0;
} else if (ev->data.fd == s->sync_timer_fd) {
int r;
uint64_t t;
log_debug("Got sync request from epoll.");
r = read(ev->data.fd, (void *)&t, sizeof(t));
if (r < 0)
return 0;
server_sync(s);
return 1;
} else if (ev->data.fd == s->dev_kmsg_fd) {
int r;
if (ev->events != EPOLLIN) {
log_error("Got invalid event from epoll.");
return -EIO;
}
r = server_read_dev_kmsg(s);
if (r < 0)
return r;
return 1;
} else if (ev->data.fd == s->native_fd ||
ev->data.fd == s->syslog_fd) {
if (ev->events != EPOLLIN) {
log_error("Got invalid event from epoll.");
return -EIO;
}
for (;;) {
struct msghdr msghdr;
struct iovec iovec;
struct ucred *ucred = NULL;
struct timeval *tv = NULL;
struct cmsghdr *cmsg;
char *label = NULL;
size_t label_len = 0;
union {
struct cmsghdr cmsghdr;
/* We use NAME_MAX space for the
* SELinux label here. The kernel
* currently enforces no limit, but
* according to suggestions from the
* SELinux people this will change and
* it will probably be identical to
* NAME_MAX. For now we use that, but
* this should be updated one day when
* the final limit is known.*/
uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
CMSG_SPACE(sizeof(struct timeval)) +
CMSG_SPACE(sizeof(int)) + /* fd */
CMSG_SPACE(NAME_MAX)]; /* selinux label */
} control;
ssize_t n;
int v;
int *fds = NULL;
unsigned n_fds = 0;
if (ioctl(ev->data.fd, SIOCINQ, &v) < 0) {
log_error("SIOCINQ failed: %m");
return -errno;
}
if (s->buffer_size < (size_t) v) {
void *b;
size_t l;
l = MAX(LINE_MAX + (size_t) v, s->buffer_size * 2);
b = realloc(s->buffer, l+1);
if (!b) {
log_error("Couldn't increase buffer.");
return -ENOMEM;
}
s->buffer_size = l;
s->buffer = b;
}
zero(iovec);
iovec.iov_base = s->buffer;
iovec.iov_len = s->buffer_size;
zero(control);
zero(msghdr);
msghdr.msg_iov = &iovec;
msghdr.msg_iovlen = 1;
msghdr.msg_control = &control;
msghdr.msg_controllen = sizeof(control);
n = recvmsg(ev->data.fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
if (n < 0) {
if (errno == EINTR || errno == EAGAIN)
return 1;
log_error("recvmsg() failed: %m");
return -errno;
}
for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
ucred = (struct ucred*) CMSG_DATA(cmsg);
else if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_SECURITY) {
label = (char*) CMSG_DATA(cmsg);
label_len = cmsg->cmsg_len - CMSG_LEN(0);
} else if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SO_TIMESTAMP &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
tv = (struct timeval*) CMSG_DATA(cmsg);
else if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
fds = (int*) CMSG_DATA(cmsg);
n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
}
}
if (ev->data.fd == s->syslog_fd) {
char *e;
if (n > 0 && n_fds == 0) {
e = memchr(s->buffer, '\n', n);
if (e)
*e = 0;
else
s->buffer[n] = 0;
server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len);
} else if (n_fds > 0)
log_warning("Got file descriptors via syslog socket. Ignoring.");
} else {
if (n > 0 && n_fds == 0)
server_process_native_message(s, s->buffer, n, ucred, tv, label, label_len);
else if (n == 0 && n_fds == 1)
server_process_native_file(s, fds[0], ucred, tv, label, label_len);
else if (n_fds > 0)
log_warning("Got too many file descriptors via native socket. Ignoring.");
}
close_many(fds, n_fds);
}
return 1;
} else if (ev->data.fd == s->stdout_fd) {
if (ev->events != EPOLLIN) {
log_error("Got invalid event from epoll.");
return -EIO;
}
stdout_stream_new(s);
return 1;
} else {
StdoutStream *stream;
if ((ev->events|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
log_error("Got invalid event from epoll.");
return -EIO;
}
/* If it is none of the well-known fds, it must be an
* stdout stream fd. Note that this is a bit ugly here
* (since we rely that none of the well-known fds
* could be interpreted as pointer), but nonetheless
* safe, since the well-known fds would never get an
* fd > 4096, i.e. beyond the first memory page */
stream = ev->data.ptr;
if (stdout_stream_process(stream) <= 0)
stdout_stream_free(stream);
return 1;
}
log_error("Unknown event.");
return 0;
}
static int open_signalfd(Server *s) {
sigset_t mask;
struct epoll_event ev;
assert(s);
assert_se(sigemptyset(&mask) == 0);
sigset_add_many(&mask, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, -1);
assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
if (s->signal_fd < 0) {
log_error("signalfd(): %m");
return -errno;
}
zero(ev);
ev.events = EPOLLIN;
ev.data.fd = s->signal_fd;
if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->signal_fd, &ev) < 0) {
log_error("epoll_ctl(): %m");
return -errno;
}
return 0;
}
static int server_parse_proc_cmdline(Server *s) {
_cleanup_free_ char *line = NULL;
char *w, *state;
int r;
size_t l;
if (detect_container(NULL) > 0)
return 0;
r = read_one_line_file("/proc/cmdline", &line);
if (r < 0) {
log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
return 0;
}
FOREACH_WORD_QUOTED(w, l, line, state) {
_cleanup_free_ char *word;
word = strndup(w, l);
if (!word)
return -ENOMEM;
if (startswith(word, "systemd.journald.forward_to_syslog=")) {
r = parse_boolean(word + 35);
if (r < 0)
log_warning("Failed to parse forward to syslog switch %s. Ignoring.", word + 35);
else
s->forward_to_syslog = r;
} else if (startswith(word, "systemd.journald.forward_to_kmsg=")) {
r = parse_boolean(word + 33);
if (r < 0)
log_warning("Failed to parse forward to kmsg switch %s. Ignoring.", word + 33);
else
s->forward_to_kmsg = r;
} else if (startswith(word, "systemd.journald.forward_to_console=")) {
r = parse_boolean(word + 36);
if (r < 0)
log_warning("Failed to parse forward to console switch %s. Ignoring.", word + 36);
else
s->forward_to_console = r;
} else if (startswith(word, "systemd.journald"))
log_warning("Invalid systemd.journald parameter. Ignoring.");
}
return 0;
}
static int server_parse_config_file(Server *s) {
static const char fn[] = "/etc/systemd/journald.conf";
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(s);
f = fopen(fn, "re");
if (!f) {
if (errno == ENOENT)
return 0;
log_warning("Failed to open configuration file %s: %m", fn);
return -errno;
}
r = config_parse(NULL, fn, f, "Journal\0", config_item_perf_lookup,
(void*) journald_gperf_lookup, false, false, s);
if (r < 0)
log_warning("Failed to parse configuration file: %s", strerror(-r));
return r;
}
static int server_open_sync_timer(Server *s) {
int r;
struct epoll_event ev;
assert(s);
s->sync_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
if (s->sync_timer_fd < 0)
return -errno;
zero(ev);
ev.events = EPOLLIN;
ev.data.fd = s->sync_timer_fd;
r = epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->sync_timer_fd, &ev);
if (r < 0) {
log_error("Failed to add idle timer fd to epoll object: %m");
return -errno;
}
return 0;
}
int server_schedule_sync(Server *s) {
int r;
assert(s);
if (s->sync_scheduled)
return 0;
if (s->sync_interval_usec) {
struct itimerspec sync_timer_enable = {};
timespec_store(&sync_timer_enable.it_value, s->sync_interval_usec);
r = timerfd_settime(s->sync_timer_fd, 0, &sync_timer_enable, NULL);
if (r < 0)
return -errno;
}
s->sync_scheduled = true;
return 0;
}
int server_init(Server *s) {
int n, r, fd;
assert(s);
zero(*s);
s->sync_timer_fd = s->syslog_fd = s->native_fd = s->stdout_fd =
s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1;
s->compress = true;
s->seal = true;
s->sync_interval_usec = DEFAULT_SYNC_INTERVAL_USEC;
s->sync_scheduled = false;
s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL;
s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST;
s->forward_to_syslog = true;
s->max_level_store = LOG_DEBUG;
s->max_level_syslog = LOG_DEBUG;
s->max_level_kmsg = LOG_NOTICE;
s->max_level_console = LOG_INFO;
memset(&s->system_metrics, 0xFF, sizeof(s->system_metrics));
memset(&s->runtime_metrics, 0xFF, sizeof(s->runtime_metrics));
server_parse_config_file(s);
server_parse_proc_cmdline(s);
if (!!s->rate_limit_interval ^ !!s->rate_limit_burst) {
log_debug("Setting both rate limit interval and burst from %llu,%u to 0,0",
(long long unsigned) s->rate_limit_interval,
s->rate_limit_burst);
s->rate_limit_interval = s->rate_limit_burst = 0;
}
mkdir_p("/run/systemd/journal", 0755);
s->user_journals = hashmap_new(trivial_hash_func, trivial_compare_func);
if (!s->user_journals)
return log_oom();
s->mmap = mmap_cache_new();
if (!s->mmap)
return log_oom();
s->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (s->epoll_fd < 0) {
log_error("Failed to create epoll object: %m");
return -errno;
}
n = sd_listen_fds(true);
if (n < 0) {
log_error("Failed to read listening file descriptors from environment: %s", strerror(-n));
return n;
}
for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/run/systemd/journal/socket", 0) > 0) {
if (s->native_fd >= 0) {
log_error("Too many native sockets passed.");
return -EINVAL;
}
s->native_fd = fd;
} else if (sd_is_socket_unix(fd, SOCK_STREAM, 1, "/run/systemd/journal/stdout", 0) > 0) {
if (s->stdout_fd >= 0) {
log_error("Too many stdout sockets passed.");
return -EINVAL;
}
s->stdout_fd = fd;
} else if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/dev/log", 0) > 0) {
if (s->syslog_fd >= 0) {
log_error("Too many /dev/log sockets passed.");
return -EINVAL;
}
s->syslog_fd = fd;
} else {
log_error("Unknown socket passed.");
return -EINVAL;
}
}
r = server_open_syslog_socket(s);
if (r < 0)
return r;
r = server_open_native_socket(s);
if (r < 0)
return r;
r = server_open_stdout_socket(s);
if (r < 0)
return r;
r = server_open_dev_kmsg(s);
if (r < 0)
return r;
r = server_open_kernel_seqnum(s);
if (r < 0)
return r;
r = server_open_sync_timer(s);
if (r < 0)
return r;
r = open_signalfd(s);
if (r < 0)
return r;
s->udev = udev_new();
if (!s->udev)
return -ENOMEM;
s->rate_limit = journal_rate_limit_new(s->rate_limit_interval,
s->rate_limit_burst);
if (!s->rate_limit)
return -ENOMEM;
r = system_journal_open(s);
if (r < 0)
return r;
return 0;
}
void server_maybe_append_tags(Server *s) {
#ifdef HAVE_GCRYPT
JournalFile *f;
Iterator i;
usec_t n;
n = now(CLOCK_REALTIME);
if (s->system_journal)
journal_file_maybe_append_tag(s->system_journal, n);
HASHMAP_FOREACH(f, s->user_journals, i)
journal_file_maybe_append_tag(f, n);
#endif
}
void server_done(Server *s) {
JournalFile *f;
assert(s);
while (s->stdout_streams)
stdout_stream_free(s->stdout_streams);
if (s->system_journal)
journal_file_close(s->system_journal);
if (s->runtime_journal)
journal_file_close(s->runtime_journal);
while ((f = hashmap_steal_first(s->user_journals)))
journal_file_close(f);
hashmap_free(s->user_journals);
if (s->epoll_fd >= 0)
close_nointr_nofail(s->epoll_fd);
if (s->signal_fd >= 0)
close_nointr_nofail(s->signal_fd);
if (s->syslog_fd >= 0)
close_nointr_nofail(s->syslog_fd);
if (s->native_fd >= 0)
close_nointr_nofail(s->native_fd);
if (s->stdout_fd >= 0)
close_nointr_nofail(s->stdout_fd);
if (s->dev_kmsg_fd >= 0)
close_nointr_nofail(s->dev_kmsg_fd);
if (s->sync_timer_fd >= 0)
close_nointr_nofail(s->sync_timer_fd);
if (s->rate_limit)
journal_rate_limit_free(s->rate_limit);
if (s->kernel_seqnum)
munmap(s->kernel_seqnum, sizeof(uint64_t));
free(s->buffer);
free(s->tty_path);
if (s->mmap)
mmap_cache_unref(s->mmap);
if (s->udev)
udev_unref(s->udev);
}