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