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