journald-server.c revision fc7b7e2e74ed0c4ce2bda91d693240c9dcd0d526
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt/***
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt This file is part of systemd.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt Copyright 2011 Lennart Poettering
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt systemd is free software; you can redistribute it and/or modify it
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt under the terms of the GNU Lesser General Public License as published by
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt the Free Software Foundation; either version 2.1 of the License, or
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt (at your option) any later version.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt systemd is distributed in the hope that it will be useful, but
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt WITHOUT ANY WARRANTY; without even the implied warranty of
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt Lesser General Public License for more details.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt You should have received a copy of the GNU Lesser General Public License
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt along with systemd; If not, see <http://www.gnu.org/licenses/>.
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt***/
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include <sys/signalfd.h>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include <sys/ioctl.h>
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt#include <linux/sockios.h>
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams#include <sys/statvfs.h>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include <sys/mman.h>
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt#include <libudev.h>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include <systemd/sd-journal.h>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include <systemd/sd-messages.h>
3df3e884ae1237ef0d4d23b0e80f4ffda95ac135Ronny Chevalier#include <systemd/sd-daemon.h>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt#ifdef HAVE_LOGIND
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include <systemd/sd-login.h>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#endif
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt#include "fileio.h"
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen#include "mkdir.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "hashmap.h"
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams#include "journal-file.h"
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams#include "socket-util.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "cgroup-util.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "list.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "virt.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "missing.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "conf-parser.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "journal-internal.h"
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#include "journal-vacuum.h"
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams#include "journal-authenticate.h"
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams#include "journald-server.h"
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams#include "journald-rate-limit.h"
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt#include "journald-kmsg.h"
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt#include "journald-syslog.h"
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt#include "journald-stream.h"
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt#include "journald-console.h"
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt#include "journald-native.h"
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt#ifdef HAVE_ACL
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt#include <sys/acl.h>
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt#include <acl/libacl.h>
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt#include "acl-util.h"
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt#endif
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt#ifdef HAVE_SELINUX
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt#include <selinux/selinux.h>
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#endif
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen#define USER_JOURNALS_MAX 1024
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#define DEFAULT_RATE_LIMIT_INTERVAL (10*USEC_PER_SEC)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt#define DEFAULT_RATE_LIMIT_BURST 200
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt#define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC)
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flyktstatic const char* const storage_table[] = {
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt [STORAGE_AUTO] = "auto",
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt [STORAGE_VOLATILE] = "volatile",
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt [STORAGE_PERSISTENT] = "persistent",
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt [STORAGE_NONE] = "none"
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt};
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik FlyktDEFINE_STRING_TABLE_LOOKUP(storage, Storage);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik FlyktDEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic const char* const split_mode_table[] = {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt [SPLIT_NONE] = "none",
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt [SPLIT_UID] = "uid",
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt [SPLIT_LOGIN] = "login"
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt};
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik FlyktDEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik FlyktDEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting");
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flyktstatic uint64_t available_space(Server *s) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt char ids[33];
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt char _cleanup_free_ *p = NULL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt const char *f;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt sd_id128_t machine;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt struct statvfs ss;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt uint64_t sum = 0, avail = 0, ss_avail = 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt int r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt DIR _cleanup_closedir_ *d = NULL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt usec_t ts;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt JournalMetrics *m;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt ts = now(CLOCK_MONOTONIC);
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts)
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt return s->cached_available_space;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt r = sd_id128_get_machine(&machine);
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt if (r < 0)
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt return 0;
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (s->system_journal) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt f = "/var/log/journal/";
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt m = &s->system_metrics;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt } else {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt f = "/run/log/journal/";
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt m = &s->runtime_metrics;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(m);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt p = strappend(f, sd_id128_to_string(machine, ids));
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (!p)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 0;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt d = opendir(p);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (!d)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 0;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (fstatvfs(dirfd(d), &ss) < 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 0;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams for (;;) {
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams struct stat st;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt struct dirent *de;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt union dirent_storage buf;
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams r = readdir_r(d, &buf.de, &de);
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams if (r != 0)
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams break;
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams if (!de)
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams break;
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (!endswith(de->d_name, ".journal") &&
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams !endswith(de->d_name, ".journal~"))
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams continue;
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams continue;
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams if (!S_ISREG(st.st_mode))
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams continue;
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt sum += (uint64_t) st.st_blocks * 512UL;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt avail = sum >= m->max_use ? 0 : m->max_use - sum;
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller ss_avail = ss.f_bsize * ss.f_bavail;
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller ss_avail = ss_avail < m->keep_free ? 0 : ss_avail - m->keep_free;
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller if (ss_avail < avail)
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller avail = ss_avail;
ebe207d4acf38165adbc45298662982eecdb9e9fTom Gundersen
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams s->cached_available_space = avail;
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams s->cached_available_space_timestamp = ts;
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams return avail;
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams}
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersenstatic void server_read_file_gid(Server *s) {
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen const char *adm = "adm";
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen int r;
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen assert(s);
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen if (s->file_gid_valid)
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen return;
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen r = get_group_creds(&adm, &s->file_gid);
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen if (r < 0)
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen log_warning("Failed to resolve 'adm' group: %s", strerror(-r));
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen /* if we couldn't read the gid, then it will be 0, but that's
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen * fine and we shouldn't try to resolve the group again, so
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen * let's just pretend it worked right-away. */
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen s->file_gid_valid = true;
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen}
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersenvoid server_fix_perms(Server *s, JournalFile *f, uid_t uid) {
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen int r;
fe4b2156256c5bdf52341576571ce9f095d9f085Tom Gundersen#ifdef HAVE_ACL
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen acl_t acl;
ebe207d4acf38165adbc45298662982eecdb9e9fTom Gundersen acl_entry_t entry;
764aad6258eec3bd4ae62ea341ea507bd69ce628Tom Gundersen acl_permset_t permset;
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams#endif
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams assert(f);
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt server_read_file_gid(s);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt r = fchmod_and_fchown(f->fd, 0640, 0, s->file_gid);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (r < 0)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt log_warning("Failed to fix access mode/rights on %s, ignoring: %s", f->path, strerror(-r));
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt#ifdef HAVE_ACL
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (uid <= 0)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt acl = acl_get_fd(f->fd);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (!acl) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt log_warning("Failed to read ACL on %s, ignoring: %m", f->path);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt r = acl_find_uid(acl, uid, &entry);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (r <= 0) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt if (acl_create_entry(&acl, &entry) < 0 ||
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt acl_set_tag_type(entry, ACL_USER) < 0 ||
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt acl_set_qualifier(entry, &uid) < 0) {
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt goto finish;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt }
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt }
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt if (acl_get_permset(entry, &permset) < 0 ||
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt acl_add_perm(permset, ACL_READ) < 0 ||
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt acl_calc_mask(&acl) < 0) {
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt goto finish;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt }
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt if (acl_set_fd(f->fd, acl) < 0)
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt log_warning("Failed to set ACL on %s, ignoring: %m", f->path);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flyktfinish:
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt acl_free(acl);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt#endif
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt}
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flyktstatic JournalFile* find_journal(Server *s, uid_t uid) {
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt char *p;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt int r;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt JournalFile *f;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt sd_id128_t machine;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt assert(s);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt /* We split up user logs only on /var, not on /run. If the
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt * runtime file is open, we write to it exclusively, in order
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt * to guarantee proper order as soon as we flush /run to
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt * /var and close the runtime file. */
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt if (s->runtime_journal)
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt return s->runtime_journal;
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt if (uid <= 0)
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt return s->system_journal;
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt
ea3b3a75abb3f8b853f7da454b9b8e258a120eeaPatrik Flykt r = sd_id128_get_machine(&machine);
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt if (r < 0)
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt return s->system_journal;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt f = hashmap_get(s->user_journals, UINT32_TO_PTR(uid));
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (f)
c806ffb9592fa9a2b13a1f9f9be4c77cd5b211aaZbigniew Jędrzejewski-Szmek return f;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/user-%lu.journal",
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt SD_ID128_FORMAT_VAL(machine), (unsigned long) uid) < 0)
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt return s->system_journal;
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt while (hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
4e3e6679e8f73b83d38e4b20d8b025e12991d1cbPatrik Flykt /* Too many open? Then let's close one */
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt f = hashmap_steal_first(s->user_journals);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt assert(f);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt journal_file_close(f);
c806ffb9592fa9a2b13a1f9f9be4c77cd5b211aaZbigniew Jędrzejewski-Szmek }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, s->system_journal, &f);
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt free(p);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt if (r < 0)
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt return s->system_journal;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt server_fix_perms(s, f, uid);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (r < 0) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt journal_file_close(f);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return s->system_journal;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return f;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt}
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktvoid server_rotate(Server *s) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt JournalFile *f;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt void *k;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt Iterator i;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt int r;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_debug("Rotating...");
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt if (s->runtime_journal) {
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt r = journal_file_rotate(&s->runtime_journal, s->compress, false);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (r < 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (s->runtime_journal)
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt log_error("Failed to rotate %s: %s", s->runtime_journal->path, strerror(-r));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt else
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt log_error("Failed to create new runtime journal: %s", strerror(-r));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt else
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt server_fix_perms(s, s->runtime_journal, 0);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (s->system_journal) {
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt r = journal_file_rotate(&s->system_journal, s->compress, s->seal);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (r < 0)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (s->system_journal)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt log_error("Failed to rotate %s: %s", s->system_journal->path, strerror(-r));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt else
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt log_error("Failed to create new system journal: %s", strerror(-r));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt else
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt server_fix_perms(s, s->system_journal, 0);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt r = journal_file_rotate(&f, s->compress, s->seal);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (r < 0)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (f)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt log_error("Failed to rotate %s: %s", f->path, strerror(-r));
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt else
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt log_error("Failed to create user journal: %s", strerror(-r));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt else {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt hashmap_replace(s->user_journals, k, f);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt server_fix_perms(s, f, PTR_TO_UINT32(k));
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt }
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt }
926695f1b5f9395eeb416cc2f478a9cf75fdbeb4Thomas Hindoe Paaboel Andersen}
926695f1b5f9395eeb416cc2f478a9cf75fdbeb4Thomas Hindoe Paaboel Andersen
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flyktvoid server_vacuum(Server *s) {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt char *p;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt char ids[33];
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt sd_id128_t machine;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt int r;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt log_debug("Vacuuming...");
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt s->oldest_file_usec = 0;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt r = sd_id128_get_machine(&machine);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (r < 0) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt log_error("Failed to get machine ID: %s", strerror(-r));
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt }
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt sd_id128_to_string(machine, ids);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (s->system_journal) {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt p = strappend("/var/log/journal/", ids);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (!p) {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt log_oom();
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (r < 0 && r != -ENOENT)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt log_error("Failed to vacuum %s: %s", p, strerror(-r));
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt free(p);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt }
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (s->runtime_journal) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt p = strappend("/run/log/journal/", ids);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (!p) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt log_oom();
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (r < 0 && r != -ENOENT)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt log_error("Failed to vacuum %s: %s", p, strerror(-r));
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt free(p);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt }
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt s->cached_available_space_timestamp = 0;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt}
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Hallerstatic char *shortened_cgroup_path(pid_t pid) {
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt int r;
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams char _cleanup_free_ *process_path = NULL, *init_path = NULL;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt char *path;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt assert(pid > 0);
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, pid, &process_path);
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (r < 0)
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt return NULL;
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt r = cg_get_by_pid(SYSTEMD_CGROUP_CONTROLLER, 1, &init_path);
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (r < 0)
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt return NULL;
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (endswith(init_path, "/system"))
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt init_path[strlen(init_path) - 7] = 0;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt else if (streq(init_path, "/"))
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt init_path[0] = 0;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (startswith(process_path, init_path)) {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt path = strdup(process_path + strlen(init_path));
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt } else {
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt path = process_path;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt process_path = NULL;
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt }
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return path;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt}
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktbool shall_try_append_again(JournalFile *f, int r) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt /* -E2BIG Hit configured limit
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt -EFBIG Hit fs limit
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt -EDQUOT Quota limit hit
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt -ENOSPC Disk full
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt -EHOSTDOWN Other machine
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt -EBUSY Unclean shutdown
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt -EPROTONOSUPPORT Unsupported feature
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt -EBADMSG Corrupted
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt -ENODATA Truncated
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt -ESHUTDOWN Already archived */
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_debug("%s: Allocation limit reached, rotating.", f->path);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt else if (r == -EHOSTDOWN)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_info("%s: Journal file from other machine, rotating.", f->path);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt else if (r == -EBUSY)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_info("%s: Unclean shutdown, rotating.", f->path);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt else if (r == -EPROTONOSUPPORT)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_info("%s: Unsupported feature, rotating.", f->path);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_warning("%s: Journal file corrupted, rotating.", f->path);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt else
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return false;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return true;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt}
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flyktstatic void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt JournalFile *f;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt bool vacuumed = false;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt int r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(s);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(iovec);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt assert(n > 0);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt f = find_journal(s, uid);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (!f)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (journal_file_rotate_suggested(f, s->max_file_usec)) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->path);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt server_rotate(s);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt server_vacuum(s);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt vacuumed = true;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt f = find_journal(s, uid);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (!f)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt return;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt }
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (r >= 0)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (vacuumed || !shall_try_append_again(f, r)) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt log_error("Failed to write entry, ignoring: %s", strerror(-r));
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt return;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt server_rotate(s);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt server_vacuum(s);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
4b4923e65423e60d755841b5b264730e8f3deab3Tom Gundersen f = find_journal(s, uid);
5e91345094a9e983e7abb2313334e7808bcd2cc2Tom Gundersen if (!f)
513a6fa8679510ea1b55967bdb482dd5f8a39f21Ronny Chevalier return;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt log_debug("Retrying write.");
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (r < 0)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt log_error("Failed to write entry, ignoring: %s", strerror(-r));
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt}
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flyktstatic void dispatch_message_real(
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt Server *s,
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt struct iovec *iovec, unsigned n, unsigned m,
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt struct ucred *ucred,
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt struct timeval *tv,
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt const char *label, size_t label_len,
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt const char *unit_id) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt char _cleanup_free_ *pid = NULL, *uid = NULL, *gid = NULL,
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt *source_time = NULL, *boot_id = NULL, *machine_id = NULL,
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt *comm = NULL, *cmdline = NULL, *hostname = NULL,
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt *audit_session = NULL, *audit_loginuid = NULL,
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt *exe = NULL, *cgroup = NULL, *session = NULL,
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt *owner_uid = NULL, *unit = NULL, *selinux_context = NULL;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt char idbuf[33];
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt sd_id128_t id;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt int r;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt char *t;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt uid_t realuid = 0, owner = 0, journal_uid;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt bool owner_valid = false;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt assert(s);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt assert(iovec);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt assert(n > 0);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt assert(n + N_IOVEC_META_FIELDS <= m);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (ucred) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt uint32_t audit;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt uid_t loginuid;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt realuid = ucred->uid;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (asprintf(&pid, "_PID=%lu", (unsigned long) ucred->pid) >= 0)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt IOVEC_SET_STRING(iovec[n++], pid);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (asprintf(&uid, "_UID=%lu", (unsigned long) ucred->uid) >= 0)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt IOVEC_SET_STRING(iovec[n++], uid);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (asprintf(&gid, "_GID=%lu", (unsigned long) ucred->gid) >= 0)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt IOVEC_SET_STRING(iovec[n++], gid);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt r = get_process_comm(ucred->pid, &t);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (r >= 0) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt comm = strappend("_COMM=", t);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt free(t);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (comm)
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt IOVEC_SET_STRING(iovec[n++], comm);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt }
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt r = get_process_exe(ucred->pid, &t);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt if (r >= 0) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt exe = strappend("_EXE=", t);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt free(t);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (exe)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt IOVEC_SET_STRING(iovec[n++], exe);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = get_process_cmdline(ucred->pid, 0, false, &t);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (r >= 0) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt cmdline = strappend("_CMDLINE=", t);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt free(t);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen if (cmdline)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt IOVEC_SET_STRING(iovec[n++], cmdline);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt r = audit_session_from_pid(ucred->pid, &audit);
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (r >= 0)
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt if (asprintf(&audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit) >= 0)
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt IOVEC_SET_STRING(iovec[n++], audit_session);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt r = audit_loginuid_from_pid(ucred->pid, &loginuid);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (r >= 0)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (asprintf(&audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid) >= 0)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt IOVEC_SET_STRING(iovec[n++], audit_loginuid);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt t = shortened_cgroup_path(ucred->pid);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (t) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt cgroup = strappend("_SYSTEMD_CGROUP=", t);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt free(t);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (cgroup)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt IOVEC_SET_STRING(iovec[n++], cgroup);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt#ifdef HAVE_LOGIND
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (sd_pid_get_session(ucred->pid, &t) >= 0) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt session = strappend("_SYSTEMD_SESSION=", t);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt free(t);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen if (session)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt IOVEC_SET_STRING(iovec[n++], session);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (sd_pid_get_owner_uid(ucred->uid, &owner) >= 0) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt owner_valid = true;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (asprintf(&owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner) >= 0)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt IOVEC_SET_STRING(iovec[n++], owner_uid);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt#endif
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (cg_pid_get_unit(ucred->pid, &t) >= 0) {
356779df90a2ecab5da2cb310ad0f8ebc9ca9f46Lennart Poettering unit = strappend("_SYSTEMD_UNIT=", t);
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen free(t);
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen } else if (cg_pid_get_user_unit(ucred->pid, &t) >= 0) {
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen unit = strappend("_SYSTEMD_USER_UNIT=", t);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt free(t);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt } else if (unit_id) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (session)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt unit = strappend("_SYSTEMD_USER_UNIT=", unit_id);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt else
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt unit = strappend("_SYSTEMD_UNIT=", unit_id);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (unit)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt IOVEC_SET_STRING(iovec[n++], unit);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt#ifdef HAVE_SELINUX
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (label) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt selinux_context = malloc(sizeof("_SELINUX_CONTEXT=") + label_len);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (selinux_context) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt *((char*) mempcpy(stpcpy(selinux_context, "_SELINUX_CONTEXT="), label, label_len)) = 0;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt IOVEC_SET_STRING(iovec[n++], selinux_context);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen } else {
356779df90a2ecab5da2cb310ad0f8ebc9ca9f46Lennart Poettering security_context_t con;
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen if (getpidcon(ucred->pid, &con) >= 0) {
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt selinux_context = strappend("_SELINUX_CONTEXT=", con);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt if (selinux_context)
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt IOVEC_SET_STRING(iovec[n++], selinux_context);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt freecon(con);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt#endif
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt if (tv) {
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen if (asprintf(&source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu",
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt (unsigned long long) timeval_load(tv)) >= 0)
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt IOVEC_SET_STRING(iovec[n++], source_time);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt }
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt /* Note that strictly speaking storing the boot id here is
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt * redundant since the entry includes this in-line
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * anyway. However, we need this indexed, too. */
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen r = sd_id128_get_boot(&id);
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen if (r >= 0)
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt if (asprintf(&boot_id, "_BOOT_ID=%s", sd_id128_to_string(id, idbuf)) >= 0)
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt IOVEC_SET_STRING(iovec[n++], boot_id);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt r = sd_id128_get_machine(&id);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (r >= 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (asprintf(&machine_id, "_MACHINE_ID=%s", sd_id128_to_string(id, idbuf)) >= 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt IOVEC_SET_STRING(iovec[n++], machine_id);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek t = gethostname_malloc();
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (t) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt hostname = strappend("_HOSTNAME=", t);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt free(t);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (hostname)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt IOVEC_SET_STRING(iovec[n++], hostname);
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek }
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek
44481a8b537839cd9ffead4d261491641f5b5260Zbigniew Jędrzejewski-Szmek assert(n <= m);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->split_mode == SPLIT_UID && realuid > 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Split up strictly by any UID */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt journal_uid = realuid;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else if (s->split_mode == SPLIT_LOGIN && realuid > 0 && owner_valid && owner > 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Split up by login UIDs, this avoids creation of
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * individual journals for system UIDs. We do this
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * only if the realuid is not root, in order not to
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * accidentally leak privileged information to the
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * user that is logged by a privileged process that is
66eac1201a9c1596f5901f8dbbf24bda7e350878Dan Williams * part of an unprivileged session.*/
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt journal_uid = owner;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt else
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt journal_uid = 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt write_to_journal(s, journal_uid, iovec, n);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktvoid server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt char mid[11 + 32 + 1];
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt char buffer[16 + LINE_MAX + 1];
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt struct iovec iovec[N_IOVEC_META_FIELDS + 4];
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt int n = 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt va_list ap;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt struct ucred ucred;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(format);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt IOVEC_SET_STRING(iovec[n++], "PRIORITY=6");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=driver");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt memcpy(buffer, "MESSAGE=", 8);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt va_start(ap, format);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt vsnprintf(buffer + 8, sizeof(buffer) - 8, format, ap);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt va_end(ap);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt char_array_0(buffer);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt IOVEC_SET_STRING(iovec[n++], buffer);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!sd_id128_equal(message_id, SD_ID128_NULL)) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt snprintf(mid, sizeof(mid), MESSAGE_ID(message_id));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt char_array_0(mid);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt IOVEC_SET_STRING(iovec[n++], mid);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt zero(ucred);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt ucred.pid = getpid();
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt ucred.uid = getuid();
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt ucred.gid = getgid();
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktvoid server_dispatch_message(
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt Server *s,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt struct iovec *iovec, unsigned n, unsigned m,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt struct ucred *ucred,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt struct timeval *tv,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt const char *label, size_t label_len,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt const char *unit_id,
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt int priority) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt int rl;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt char _cleanup_free_ *path = NULL;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt char *c;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(iovec || n == 0);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (n == 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (LOG_PRI(priority) > s->max_level_store)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!ucred)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt goto finish;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt path = shortened_cgroup_path(ucred->pid);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!path)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt goto finish;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt /* example: /user/lennart/3/foobar
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt * /system/dbus.service/foobar
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt *
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt * So let's cut of everything past the third /, since that is
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt * where user directories start */
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt c = strchr(path, '/');
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (c) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt c = strchr(c+1, '/');
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (c) {
c47e8936a43ce546e8a74fa569e9fbfae6c64be7Patrik Flykt c = strchr(c+1, '/');
c47e8936a43ce546e8a74fa569e9fbfae6c64be7Patrik Flykt if (c)
c47e8936a43ce546e8a74fa569e9fbfae6c64be7Patrik Flykt *c = 0;
c47e8936a43ce546e8a74fa569e9fbfae6c64be7Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt rl = journal_rate_limit_test(s->rate_limit, path,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt priority & LOG_PRIMASK, available_space(s));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (rl == 0)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt /* Write a suppression message if we suppressed something */
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (rl > 1)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt server_driver_message(s, SD_MESSAGE_JOURNAL_DROPPED,
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt "Suppressed %u messages from %s", rl - 1, path);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktfinish:
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt}
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktstatic int system_journal_open(Server *s) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt int r;
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt char *fn;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt sd_id128_t machine;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt char ids[33];
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = sd_id128_get_machine(&machine);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (r < 0)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt sd_id128_to_string(machine, ids);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (!s->system_journal &&
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt access("/run/systemd/journal/flushed", F_OK) >= 0) {
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt /* If in auto mode: first try to create the machine
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt * path, but not the prefix.
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt *
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt * If in persistent mode: create /var/log/journal and
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt * the machine path */
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt if (s->storage == STORAGE_PERSISTENT)
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt (void) mkdir("/var/log/journal/", 0755);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
5364f729ba9616cd9fdab8d5413fbc25a1af3a57Lennart Poettering fn = strappend("/var/log/journal/", ids);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (!fn)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return -ENOMEM;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt (void) mkdir(fn, 0755);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt free(fn);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt fn = strjoin("/var/log/journal/", ids, "/system.journal", NULL);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (!fn)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return -ENOMEM;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt free(fn);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (r >= 0) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt char fb[FORMAT_BYTES_MAX];
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt server_fix_perms(s, s->system_journal, 0);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt server_driver_message(s, SD_ID128_NULL, "Allowing system journal files to grow to %s.",
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt format_bytes(fb, sizeof(fb), s->system_metrics.max_use));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt } else if (r < 0) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (r != -ENOENT && r != -EROFS)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_warning("Failed to open system journal: %s", strerror(-r));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!s->runtime_journal &&
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt (s->storage != STORAGE_NONE)) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt fn = strjoin("/run/log/journal/", ids, "/system.journal", NULL);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (!fn)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return -ENOMEM;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->system_journal) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* Try to open the runtime journal, but only
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * if it already exists, so that we can flush
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * it into the system journal */
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt r = journal_file_open(fn, O_RDWR, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt free(fn);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (r < 0) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (r != -ENOENT)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt log_warning("Failed to open runtime journal: %s", strerror(-r));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = 0;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt } else {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt /* OK, we really need the runtime journal, so create
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt * it if necessary. */
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt (void) mkdir_parents(fn, 0755);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt free(fn);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (r < 0) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_error("Failed to open runtime journal: %s", strerror(-r));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->runtime_journal) {
6ec60d20724d2a32e20d25ef75d2af178c242bc2Ronny Chevalier char fb[FORMAT_BYTES_MAX];
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt server_fix_perms(s, s->runtime_journal, 0);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt server_driver_message(s, SD_ID128_NULL, "Allowing runtime journal files to grow to %s.",
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt format_bytes(fb, sizeof(fb), s->runtime_metrics.max_use));
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt }
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt}
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktint server_flush_to_var(Server *s) {
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt int r;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt sd_id128_t machine;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt sd_journal *j = NULL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt assert(s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (s->storage != STORAGE_AUTO &&
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt s->storage != STORAGE_PERSISTENT)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!s->runtime_journal)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt system_journal_open(s);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (!s->system_journal)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt return 0;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt log_debug("Flushing to /var...");
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt r = sd_id128_get_machine(&machine);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (r < 0) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt log_error("Failed to get machine id: %s", strerror(-r));
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return r;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt r = sd_journal_open(&j, SD_JOURNAL_RUNTIME_ONLY);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (r < 0) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt log_error("Failed to read runtime journal: %s", strerror(-r));
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return r;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt sd_journal_set_data_threshold(j, 0);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt SD_JOURNAL_FOREACH(j) {
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt Object *o = NULL;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt JournalFile *f;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt f = j->current_file;
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt assert(f && f->current_offset > 0);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
ed6ee21953dac9c78383da00bc4514ece6b75ab5Patrik Flykt r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (r < 0) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt log_error("Can't read entry: %s", strerror(-r));
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt goto finish;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (r >= 0)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt continue;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (!shall_try_append_again(s->system_journal, r)) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_error("Can't write entry: %s", strerror(-r));
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt goto finish;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt server_rotate(s);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt server_vacuum(s);
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_debug("Retrying write.");
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (r < 0) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_error("Can't write entry: %s", strerror(-r));
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt goto finish;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flyktfinish:
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt journal_file_post_change(s->system_journal);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt journal_file_close(s->runtime_journal);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt s->runtime_journal = NULL;
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt if (r >= 0)
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt rm_rf("/run/log/journal", false, true, false);
631bbe71298ec892f77f44f94feb612646fe6853Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (j)
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt sd_journal_close(j);
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt return r;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt}
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flyktint process_event(Server *s, struct epoll_event *ev) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt assert(s);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt assert(ev);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt if (ev->data.fd == s->signal_fd) {
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt struct signalfd_siginfo sfsi;
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt ssize_t n;
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt if (ev->events != EPOLLIN) {
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt log_error("Got invalid event from epoll.");
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt return -EIO;
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt }
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt n = read(s->signal_fd, &sfsi, sizeof(sfsi));
38a03f06a7393d2721c23f23f0589d2f6d0904afLennart Poettering if (n != sizeof(sfsi)) {
38a03f06a7393d2721c23f23f0589d2f6d0904afLennart Poettering
38a03f06a7393d2721c23f23f0589d2f6d0904afLennart Poettering if (n >= 0)
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt return -EIO;
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt if (errno == EINTR || errno == EAGAIN)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return 1;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt return -errno;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen log_info("Received SIG%s", signal_to_string(sfsi.ssi_signo));
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (sfsi.ssi_signo == SIGUSR1) {
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt touch("/run/systemd/journal/flushed");
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt server_flush_to_var(s);
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt return 1;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt if (sfsi.ssi_signo == SIGUSR2) {
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt server_rotate(s);
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt server_vacuum(s);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return 1;
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt }
7246333cb803b03440d3bd0bdaa233564d09b5aePatrik Flykt
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt return 0;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt } else if (ev->data.fd == s->dev_kmsg_fd) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt int r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (ev->events != EPOLLIN) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_error("Got invalid event from epoll.");
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return -EIO;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt r = server_read_dev_kmsg(s);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (r < 0)
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return r;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return 1;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt } else if (ev->data.fd == s->native_fd ||
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt ev->data.fd == s->syslog_fd) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (ev->events != EPOLLIN) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_error("Got invalid event from epoll.");
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return -EIO;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt for (;;) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt struct msghdr msghdr;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt struct iovec iovec;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt struct ucred *ucred = NULL;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt struct timeval *tv = NULL;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt struct cmsghdr *cmsg;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt char *label = NULL;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt size_t label_len = 0;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt union {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt struct cmsghdr cmsghdr;
356779df90a2ecab5da2cb310ad0f8ebc9ca9f46Lennart Poettering
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen /* We use NAME_MAX space for the
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen * SELinux label here. The kernel
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen * currently enforces no limit, but
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * according to suggestions from the
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * SELinux people this will change and
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * it will probably be identical to
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * NAME_MAX. For now we use that, but
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * this should be updated one day when
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt * the final limit is known.*/
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt CMSG_SPACE(sizeof(struct timeval)) +
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt CMSG_SPACE(sizeof(int)) + /* fd */
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen CMSG_SPACE(NAME_MAX)]; /* selinux label */
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt } control;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt ssize_t n;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt int v;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt int *fds = NULL;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt unsigned n_fds = 0;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt if (ioctl(ev->data.fd, SIOCINQ, &v) < 0) {
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt log_error("SIOCINQ failed: %m");
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt return -errno;
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt }
356779df90a2ecab5da2cb310ad0f8ebc9ca9f46Lennart Poettering
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen if (s->buffer_size < (size_t) v) {
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen void *b;
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen size_t l;
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt
3dc34fcc97b41f8b7b019027225b121dfbb9871dPatrik Flykt l = MAX(LINE_MAX + (size_t) v, s->buffer_size * 2);
a34b57c0d43b8bf819ccd4f62c314b41b625454dPatrik Flykt b = realloc(s->buffer, l+1);
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt
a9aff3615b430f86bd0a824214d95f634efaf894Patrik Flykt if (!b) {
c3e2adeaba8e043caed0ef139eeaea016bd152d0Patrik Flykt log_error("Couldn't increase buffer.");
346e13a25dc6f76d3bc9d8decd40dc4782b02d2aPatrik Flykt return -ENOMEM;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
fa94c34b083b5b4019975624453e53d0cbad2a5dTom Gundersen s->buffer_size = l;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt s->buffer = b;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt }
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt zero(iovec);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt iovec.iov_base = s->buffer;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt iovec.iov_len = s->buffer_size;
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt zero(control);
d1b0afe3653b4316a6361d204169620726d468a0Patrik Flykt zero(msghdr);
356779df90a2ecab5da2cb310ad0f8ebc9ca9f46Lennart Poettering msghdr.msg_iov = &iovec;
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen msghdr.msg_iovlen = 1;
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen msghdr.msg_control = &control;
9021bb9f935c93b516b10c88db2a212a9e3a8140Tom Gundersen msghdr.msg_controllen = sizeof(control);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt n = recvmsg(ev->data.fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt if (n < 0) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (errno == EINTR || errno == EAGAIN)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 1;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_error("recvmsg() failed: %m");
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return -errno;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (cmsg->cmsg_level == SOL_SOCKET &&
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt cmsg->cmsg_type == SCM_CREDENTIALS &&
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt ucred = (struct ucred*) CMSG_DATA(cmsg);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt else if (cmsg->cmsg_level == SOL_SOCKET &&
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt cmsg->cmsg_type == SCM_SECURITY) {
c806ffb9592fa9a2b13a1f9f9be4c77cd5b211aaZbigniew Jędrzejewski-Szmek label = (char*) CMSG_DATA(cmsg);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt label_len = cmsg->cmsg_len - CMSG_LEN(0);
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt } else if (cmsg->cmsg_level == SOL_SOCKET &&
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt cmsg->cmsg_type == SO_TIMESTAMP &&
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt tv = (struct timeval*) CMSG_DATA(cmsg);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt else if (cmsg->cmsg_level == SOL_SOCKET &&
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt cmsg->cmsg_type == SCM_RIGHTS) {
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller fds = (int*) CMSG_DATA(cmsg);
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller }
cc22955cfefb4bd6e7a135f1ec95fb5a07ba9ce3Thomas Haller }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (ev->data.fd == s->syslog_fd) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt char *e;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (n > 0 && n_fds == 0) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt e = memchr(s->buffer, '\n', n);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (e)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt *e = 0;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt else
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt s->buffer[n] = 0;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt } else if (n_fds > 0)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt log_warning("Got file descriptors via syslog socket. Ignoring.");
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt } else {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (n > 0 && n_fds == 0)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt server_process_native_message(s, s->buffer, n, ucred, tv, label, label_len);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt else if (n == 0 && n_fds == 1)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt server_process_native_file(s, fds[0], ucred, tv, label, label_len);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt else if (n_fds > 0)
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt log_warning("Got too many file descriptors via native socket. Ignoring.");
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt close_many(fds, n_fds);
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt }
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return 1;
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt } else if (ev->data.fd == s->stdout_fd) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt if (ev->events != EPOLLIN) {
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt log_error("Got invalid event from epoll.");
bbfa43ca37df0718287c25a8e39ee7477ebf33f6Patrik Flykt return -EIO;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt stdout_stream_new(s);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 1;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt } else {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt StdoutStream *stream;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if ((ev->events|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_error("Got invalid event from epoll.");
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return -EIO;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt /* If it is none of the well-known fds, it must be an
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * stdout stream fd. Note that this is a bit ugly here
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * (since we rely that none of the well-known fds
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * could be interpreted as pointer), but nonetheless
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * safe, since the well-known fds would never get an
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt * fd > 4096, i.e. beyond the first memory page */
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt stream = ev->data.ptr;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (stdout_stream_process(stream) <= 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt stdout_stream_free(stream);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 1;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_error("Unknown event.");
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 0;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt}
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic int open_signalfd(Server *s) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt sigset_t mask;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt struct epoll_event ev;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert(s);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert_se(sigemptyset(&mask) == 0);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt sigset_add_many(&mask, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, -1);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (s->signal_fd < 0) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_error("signalfd(): %m");
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return -errno;
f0c4b1c3fd827b429ba36aa45fd39e0a023cbf2cTom Gundersen }
c806ffb9592fa9a2b13a1f9f9be4c77cd5b211aaZbigniew Jędrzejewski-Szmek
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt zero(ev);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt ev.events = EPOLLIN;
62e3d1aed512d68cab1fc9b509e813a1fa2b3790Lennart Poettering ev.data.fd = s->signal_fd;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->signal_fd, &ev) < 0) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_error("epoll_ctl(): %m");
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return -errno;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 0;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt}
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flyktstatic int server_parse_proc_cmdline(Server *s) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt char _cleanup_free_ *line = NULL;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt char *w, *state;
3f0c075f8ef3344da5a6bda524540201f9204e61Patrik Flykt int r;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt size_t l;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (detect_container(NULL) > 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 0;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt r = read_one_line_file("/proc/cmdline", &line);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (r < 0) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt return 0;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt }
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt
f12abb48fc510b8b349c05e35ba048134debaf25Patrik Flykt FOREACH_WORD_QUOTED(w, l, line, state) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt char _cleanup_free_ *word;
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt
c806ffb9592fa9a2b13a1f9f9be4c77cd5b211aaZbigniew Jędrzejewski-Szmek word = strndup(w, l);
c806ffb9592fa9a2b13a1f9f9be4c77cd5b211aaZbigniew Jędrzejewski-Szmek if (!word)
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt return -ENOMEM;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt if (startswith(word, "systemd.journald.forward_to_syslog=")) {
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt r = parse_boolean(word + 35);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt if (r < 0)
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt log_warning("Failed to parse forward to syslog switch %s. Ignoring.", word + 35);
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt else
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt s->forward_to_syslog = r;
da6fe470e17fa02f3adedc779585caf8669252bdPatrik Flykt } else if (startswith(word, "systemd.journald.forward_to_kmsg=")) {
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt r = parse_boolean(word + 33);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt if (r < 0)
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt log_warning("Failed to parse forward to kmsg switch %s. Ignoring.", word + 33);
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt else
139b011ab81ccea1d51f09e0261a1c390115c6ffPatrik Flykt 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";
FILE _cleanup_fclose_ *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(fn, f, "Journal\0", config_item_perf_lookup,
(void*) journald_gperf_lookup, false, s);
if (r < 0)
log_warning("Failed to parse configuration file: %s", strerror(-r));
return r;
}
int server_init(Server *s) {
int n, r, fd;
assert(s);
zero(*s);
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->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 = 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->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);
}