journald-server.c revision a315ac4e076c4ce7ce3e5c95792cf916d5e918c5
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen/***
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen This file is part of systemd.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen Copyright 2011 Lennart Poettering
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen systemd is free software; you can redistribute it and/or modify it
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen under the terms of the GNU Lesser General Public License as published by
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen (at your option) any later version.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen systemd is distributed in the hope that it will be useful, but
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen Lesser General Public License for more details.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen You should have received a copy of the GNU Lesser General Public License
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen***/
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen#include <sys/signalfd.h>
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen#include <sys/ioctl.h>
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen#include <linux/sockios.h>
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen#include <sys/statvfs.h>
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen#include <sys/mman.h>
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen#ifdef HAVE_SELINUX
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen#include <selinux/selinux.h>
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen#endif
d122f9ee3a0e3c02ff8100a3dcd1866e90a6537aTom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen#include <libudev.h>
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen#include "sd-journal.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "sd-messages.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "sd-daemon.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "mkdir.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "rm-rf.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "hashmap.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "journal-file.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "socket-util.h"
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen#include "cgroup-util.h"
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen#include "missing.h"
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen#include "conf-parser.h"
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen#include "selinux-util.h"
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen#include "acl-util.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "formats-util.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "process-util.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "hostname-util.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "signal-util.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "journal-internal.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "journal-vacuum.h"
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#include "journal-authenticate.h"
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen#include "journald-rate-limit.h"
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen#include "journald-kmsg.h"
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen#include "journald-syslog.h"
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen#include "journald-stream.h"
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen#include "journald-native.h"
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen#include "journald-audit.h"
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen#include "journald-server.h"
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen#define USER_JOURNALS_MAX 1024
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen#define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE)
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen#define DEFAULT_RATE_LIMIT_INTERVAL (30*USEC_PER_SEC)
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen#define DEFAULT_RATE_LIMIT_BURST 1000
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen#define DEFAULT_MAX_FILE_USEC USEC_PER_MONTH
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen
7c16313f11e3953f3fe4dbf544f2d36f58d14138Tom Gundersen#define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC)
756775814cf69471f74ce853745bba69f2ba94efThomas Hindoe Paaboel Andersen
7c16313f11e3953f3fe4dbf544f2d36f58d14138Tom Gundersenstatic const char* const storage_table[_STORAGE_MAX] = {
7c16313f11e3953f3fe4dbf544f2d36f58d14138Tom Gundersen [STORAGE_AUTO] = "auto",
7c16313f11e3953f3fe4dbf544f2d36f58d14138Tom Gundersen [STORAGE_VOLATILE] = "volatile",
7c16313f11e3953f3fe4dbf544f2d36f58d14138Tom Gundersen [STORAGE_PERSISTENT] = "persistent",
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen [STORAGE_NONE] = "none"
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen};
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom GundersenDEFINE_STRING_TABLE_LOOKUP(storage, Storage);
b44cd8821087f2afebf85fec5b588f5720a9415cTom GundersenDEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersenstatic const char* const split_mode_table[_SPLIT_MAX] = {
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen [SPLIT_LOGIN] = "login",
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen [SPLIT_UID] = "uid",
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen [SPLIT_NONE] = "none",
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen};
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom GundersenDEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom GundersenDEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting");
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersenstatic uint64_t available_space(Server *s, bool verbose) {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen char ids[33];
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen _cleanup_free_ char *p = NULL;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen sd_id128_t machine;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen struct statvfs ss;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen uint64_t sum = 0, ss_avail = 0, avail = 0;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen int r;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen _cleanup_closedir_ DIR *d = NULL;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen usec_t ts;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen const char *f;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen JournalMetrics *m;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen ts = now(CLOCK_MONOTONIC);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen && !verbose)
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen return s->cached_available_space;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen r = sd_id128_get_machine(&machine);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (r < 0)
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen return 0;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt if (s->system_journal) {
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt f = "/var/log/journal/";
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt m = &s->system_metrics;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt } else {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen f = "/run/log/journal/";
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen m = &s->runtime_metrics;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen assert(m);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen p = strappend(f, sd_id128_to_string(machine, ids));
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (!p)
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen return 0;
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen d = opendir(p);
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering if (!d)
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering return 0;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering if (fstatvfs(dirfd(d), &ss) < 0)
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering return 0;
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering for (;;) {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen struct stat st;
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering struct dirent *de;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering errno = 0;
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering de = readdir(d);
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering if (!de && errno != 0)
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering return 0;
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering if (!de)
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering break;
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering if (!endswith(de->d_name, ".journal") &&
3bdace9bf779ce051f00c14914b35c3a26164aa9Lennart Poettering !endswith(de->d_name, ".journal~"))
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen continue;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen continue;
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (!S_ISREG(st.st_mode))
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen continue;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen sum += (uint64_t) st.st_blocks * 512UL;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen }
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen ss_avail = ss.f_bsize * ss.f_bavail;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen /* If we reached a high mark, we will always allow this much
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen * again, unless usage goes above max_use. This watermark
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen * value is cached so that we don't give up space on pressure,
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen * but hover below the maximum usage. */
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen if (m->use < sum)
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen m->use = sum;
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen avail = LESS_BY(ss_avail, m->keep_free);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen s->cached_available_space = LESS_BY(MIN(m->max_use, avail), sum);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen s->cached_available_space_timestamp = ts;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (verbose) {
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen char fb1[FORMAT_BYTES_MAX], fb2[FORMAT_BYTES_MAX], fb3[FORMAT_BYTES_MAX],
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen fb4[FORMAT_BYTES_MAX], fb5[FORMAT_BYTES_MAX];
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen server_driver_message(s, SD_MESSAGE_JOURNAL_USAGE,
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen "%s journal is using %s (max allowed %s, "
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen "trying to leave %s free of %s available → current limit %s).",
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen s->system_journal ? "Permanent" : "Runtime",
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen format_bytes(fb1, sizeof(fb1), sum),
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen format_bytes(fb2, sizeof(fb2), m->max_use),
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen format_bytes(fb3, sizeof(fb3), m->keep_free),
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen format_bytes(fb4, sizeof(fb4), ss_avail),
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen format_bytes(fb5, sizeof(fb5), s->cached_available_space + sum));
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen }
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen return s->cached_available_space;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen}
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersenvoid server_fix_perms(Server *s, JournalFile *f, uid_t uid) {
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen int r;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen#ifdef HAVE_ACL
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen acl_t acl;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen acl_entry_t entry;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen acl_permset_t permset;
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen#endif
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen assert(f);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen r = fchmod(f->fd, 0640);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (r < 0)
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen log_warning_errno(r, "Failed to fix access mode on %s, ignoring: %m", f->path);
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen#ifdef HAVE_ACL
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen if (uid <= SYSTEM_UID_MAX)
b44cd8821087f2afebf85fec5b588f5720a9415cTom Gundersen return;
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen acl = acl_get_fd(f->fd);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (!acl) {
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen log_warning_errno(errno, "Failed to read ACL on %s, ignoring: %m", f->path);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen return;
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen }
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen r = acl_find_uid(acl, uid, &entry);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (r <= 0) {
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (acl_create_entry(&acl, &entry) < 0 ||
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen acl_set_tag_type(entry, ACL_USER) < 0 ||
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen acl_set_qualifier(entry, &uid) < 0) {
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen log_warning_errno(errno, "Failed to patch ACL on %s, ignoring: %m", f->path);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen goto finish;
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen }
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen /* We do not recalculate the mask unconditionally here,
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen * so that the fchmod() mask above stays intact. */
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (acl_get_permset(entry, &permset) < 0 ||
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen acl_add_perm(permset, ACL_READ) < 0 ||
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen calc_acl_mask_if_needed(&acl) < 0) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_warning_errno(errno, "Failed to patch ACL on %s, ignoring: %m", f->path);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen goto finish;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (acl_set_fd(f->fd, acl) < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_warning_errno(errno, "Failed to set ACL on %s, ignoring: %m", f->path);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersenfinish:
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen acl_free(acl);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen#endif
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen}
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersenstatic JournalFile* find_journal(Server *s, uid_t uid) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen _cleanup_free_ char *p = NULL;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen int r;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen JournalFile *f;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen sd_id128_t machine;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(s);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen /* We split up user logs only on /var, not on /run. If the
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen * runtime file is open, we write to it exclusively, in order
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen * to guarantee proper order as soon as we flush /run to
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen * /var and close the runtime file. */
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (s->runtime_journal)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return s->runtime_journal;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (uid <= SYSTEM_UID_MAX)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return s->system_journal;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = sd_id128_get_machine(&machine);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return s->system_journal;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen f = ordered_hashmap_get(s->user_journals, UINT32_TO_PTR(uid));
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (f)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return f;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/user-"UID_FMT".journal",
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen SD_ID128_FORMAT_VAL(machine), uid) < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return s->system_journal;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen while (ordered_hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen /* Too many open? Then let's close one */
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen f = ordered_hashmap_steal_first(s->user_journals);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(f);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen journal_file_close(f);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &f);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return s->system_journal;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen server_fix_perms(s, f, uid);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = ordered_hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen journal_file_close(f);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return s->system_journal;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return f;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen}
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersenstatic int do_rotate(
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen Server *s,
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen JournalFile **f,
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen const char* name,
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen bool seal,
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen uint32_t uid) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen int r;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen assert(s);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (!*f)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return -EINVAL;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = journal_file_rotate(f, s->compress, seal);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (*f)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error_errno(r, "Failed to rotate %s: %m", (*f)->path);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen else
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error_errno(r, "Failed to create new %s journal: %m", name);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen else
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen server_fix_perms(s, *f, uid);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen return r;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen}
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersenvoid server_rotate(Server *s) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen JournalFile *f;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen void *k;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen Iterator i;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen int r;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_debug("Rotating...");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen do_rotate(s, &s->runtime_journal, "runtime", false, 0);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen do_rotate(s, &s->system_journal, "system", s->seal, 0);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen ORDERED_HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = do_rotate(s, &f, "user", s->seal, PTR_TO_UINT32(k));
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r >= 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen ordered_hashmap_replace(s->user_journals, k, f);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen else if (!f)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen /* Old file has been closed and deallocated */
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen ordered_hashmap_remove(s->user_journals, k);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen}
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersenvoid server_sync(Server *s) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen JournalFile *f;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen void *k;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen Iterator i;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen int r;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (s->system_journal) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = journal_file_set_offline(s->system_journal);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error_errno(r, "Failed to sync system journal: %m");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen ORDERED_HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = journal_file_set_offline(f);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error_errno(r, "Failed to sync user journal: %m");
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (s->sync_event_source) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen r = sd_event_source_set_enabled(s->sync_event_source, SD_EVENT_OFF);
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen if (r < 0)
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen log_error_errno(r, "Failed to disable sync timer source: %m");
d6bd972d061af306ede2affd2c9340a1660f7996Tom Gundersen }
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen s->sync_scheduled = false;
d6bd972d061af306ede2affd2c9340a1660f7996Tom Gundersen}
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersenstatic void do_vacuum(
d6bd972d061af306ede2affd2c9340a1660f7996Tom Gundersen Server *s,
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen const char *id,
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen JournalFile *f,
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen const char* path,
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen JournalMetrics *metrics) {
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen const char *p;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen int r;
969b009d9416806911b9b52e7e7bc619c0c1a931Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (!f)
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen return;
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen p = strjoina(path, id);
1231c4d238844e77018caf5b5852f01d96373c47Tom Gundersen r = journal_directory_vacuum(p, metrics->max_use, s->max_retention_usec, &s->oldest_file_usec, false);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (r < 0 && r != -ENOENT)
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen log_error_errno(r, "Failed to vacuum %s: %m", p);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen}
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersenvoid server_vacuum(Server *s) {
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen char ids[33];
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen sd_id128_t machine;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen int r;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen log_debug("Vacuuming...");
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen s->oldest_file_usec = 0;
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams r = sd_id128_get_machine(&machine);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (r < 0) {
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen log_error_errno(r, "Failed to get machine ID: %m");
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen return;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen }
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen sd_id128_to_string(machine, ids);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen do_vacuum(s, ids, s->system_journal, "/var/log/journal/", &s->system_metrics);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen do_vacuum(s, ids, s->runtime_journal, "/run/log/journal/", &s->runtime_metrics);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen s->cached_available_space_timestamp = 0;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen}
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersenstatic void server_cache_machine_id(Server *s) {
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen sd_id128_t id;
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen int r;
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen assert(s);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen r = sd_id128_get_machine(&id);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (r < 0)
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen return;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen sd_id128_to_string(id, stpcpy(s->machine_id_field, "_MACHINE_ID="));
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen}
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersenstatic void server_cache_boot_id(Server *s) {
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen sd_id128_t id;
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen int r;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen assert(s);
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen r = sd_id128_get_boot(&id);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (r < 0)
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen return;
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen sd_id128_to_string(id, stpcpy(s->boot_id_field, "_BOOT_ID="));
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen}
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersenstatic void server_cache_hostname(Server *s) {
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen _cleanup_free_ char *t = NULL;
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen char *x;
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen assert(s);
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen t = gethostname_malloc();
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (!t)
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen return;
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen x = strappend("_HOSTNAME=", t);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (!x)
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen return;
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen free(s->hostname_field);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen s->hostname_field = x;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen}
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersenstatic bool shall_try_append_again(JournalFile *f, int r) {
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen /* -E2BIG Hit configured limit
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen -EFBIG Hit fs limit
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen -EDQUOT Quota limit hit
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen -ENOSPC Disk full
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen -EIO I/O error of some kind (mmap)
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen -EHOSTDOWN Other machine
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen -EBUSY Unclean shutdown
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen -EPROTONOSUPPORT Unsupported feature
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen -EBADMSG Corrupted
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen -ENODATA Truncated
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen -ESHUTDOWN Already archived
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen -EIDRM Journal file has been deleted */
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen log_debug("%s: Allocation limit reached, rotating.", f->path);
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen else if (r == -EHOSTDOWN)
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen log_info("%s: Journal file from other machine, rotating.", f->path);
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen else if (r == -EBUSY)
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen log_info("%s: Unclean shutdown, rotating.", f->path);
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen else if (r == -EPROTONOSUPPORT)
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen log_info("%s: Unsupported feature, rotating.", f->path);
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN)
59b8f6b628145586e87b8a4f6e29c755ad7d61edTom Gundersen log_warning("%s: Journal file corrupted, rotating.", f->path);
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering else if (r == -EIO)
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering log_warning("%s: IO error, rotating.", f->path);
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering else if (r == -EIDRM)
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering log_warning("%s: Journal file has been deleted, rotating.", f->path);
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering else
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering return false;
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering return true;
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering}
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersenstatic void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n, int priority) {
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen JournalFile *f;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen bool vacuumed = false;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen int r;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen assert(s);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen assert(iovec);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen assert(n > 0);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen f = find_journal(s, uid);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen if (!f)
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen return;
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen if (journal_file_rotate_suggested(f, s->max_file_usec)) {
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->path);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen server_rotate(s);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen server_vacuum(s);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen vacuumed = true;
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen f = find_journal(s, uid);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen if (!f)
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen return;
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen }
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen if (r >= 0) {
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen server_schedule_sync(s, priority);
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen return;
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen }
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen if (vacuumed || !shall_try_append_again(f, r)) {
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen log_error_errno(r, "Failed to write entry (%d items, %zu bytes), ignoring: %m", n, IOVEC_TOTAL_SIZE(iovec, n));
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen return;
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen }
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen server_rotate(s);
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen server_vacuum(s);
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams
76253e73f9c9c24fec755e485516f3b55d0707b4Dan Williams f = find_journal(s, uid);
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen if (!f)
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen return;
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen log_debug("Retrying write.");
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen if (r < 0)
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen log_error_errno(r, "Failed to write entry (%d items, %zu bytes) despite vacuuming, ignoring: %m", n, IOVEC_TOTAL_SIZE(iovec, n));
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen else
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen server_schedule_sync(s, priority);
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen}
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersenstatic void dispatch_message_real(
c15fb62a731f1a457af94e60ac6a4d23f219a8f6Thomas Hindoe Paaboel Andersen Server *s,
c15fb62a731f1a457af94e60ac6a4d23f219a8f6Thomas Hindoe Paaboel Andersen struct iovec *iovec, unsigned n, unsigned m,
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen const struct ucred *ucred,
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen const struct timeval *tv,
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen const char *label, size_t label_len,
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen const char *unit_id,
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen int priority,
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen pid_t object_pid) {
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen char pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)],
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen uid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)],
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen gid[sizeof("_GID=") + DECIMAL_STR_MAX(gid_t)],
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen owner_uid[sizeof("_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)],
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)],
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen o_uid[sizeof("OBJECT_UID=") + DECIMAL_STR_MAX(uid_t)],
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen o_gid[sizeof("OBJECT_GID=") + DECIMAL_STR_MAX(gid_t)],
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen o_owner_uid[sizeof("OBJECT_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)];
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen uid_t object_uid;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen gid_t object_gid;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen char *x;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen int r;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen char *t, *c;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen uid_t realuid = 0, owner = 0, journal_uid;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen bool owner_valid = false;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen#ifdef HAVE_AUDIT
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen char audit_session[sizeof("_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)],
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen audit_loginuid[sizeof("_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)],
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen o_audit_session[sizeof("OBJECT_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)],
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen o_audit_loginuid[sizeof("OBJECT_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)];
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen uint32_t audit;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen uid_t loginuid;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen#endif
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen assert(s);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen assert(iovec);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen assert(n > 0);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen assert(n + N_IOVEC_META_FIELDS + (object_pid ? N_IOVEC_OBJECT_FIELDS : 0) <= m);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen if (ucred) {
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen realuid = ucred->uid;
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen sprintf(pid, "_PID="PID_FMT, ucred->pid);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen IOVEC_SET_STRING(iovec[n++], pid);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen sprintf(uid, "_UID="UID_FMT, ucred->uid);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen IOVEC_SET_STRING(iovec[n++], uid);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen sprintf(gid, "_GID="GID_FMT, ucred->gid);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen IOVEC_SET_STRING(iovec[n++], gid);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen r = get_process_comm(ucred->pid, &t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen if (r >= 0) {
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen x = strjoina("_COMM=", t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen free(t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen IOVEC_SET_STRING(iovec[n++], x);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen }
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen r = get_process_exe(ucred->pid, &t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen if (r >= 0) {
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen x = strjoina("_EXE=", t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen free(t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen IOVEC_SET_STRING(iovec[n++], x);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen }
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen r = get_process_cmdline(ucred->pid, 0, false, &t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen if (r >= 0) {
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen x = strjoina("_CMDLINE=", t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen free(t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen IOVEC_SET_STRING(iovec[n++], x);
e2acdb6b0f68d9b4152708a9f21bf9e11f8b9e7eTorstein Husebø }
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen r = get_process_capeff(ucred->pid, &t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen if (r >= 0) {
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen x = strjoina("_CAP_EFFECTIVE=", t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen free(t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen IOVEC_SET_STRING(iovec[n++], x);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen }
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen#ifdef HAVE_AUDIT
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen r = audit_session_from_pid(ucred->pid, &audit);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen if (r >= 0) {
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen sprintf(audit_session, "_AUDIT_SESSION=%"PRIu32, audit);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen IOVEC_SET_STRING(iovec[n++], audit_session);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen }
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen r = audit_loginuid_from_pid(ucred->pid, &loginuid);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen if (r >= 0) {
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen sprintf(audit_loginuid, "_AUDIT_LOGINUID="UID_FMT, loginuid);
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen IOVEC_SET_STRING(iovec[n++], audit_loginuid);
c7d9ffe6d629cb5b34dd749e4a88b190b11a0f48Tom Gundersen }
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen#endif
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen r = cg_pid_get_path_shifted(ucred->pid, s->cgroup_root, &c);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (r >= 0) {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen char *session = NULL;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen x = strjoina("_SYSTEMD_CGROUP=", c);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen r = cg_path_get_session(c, &t);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (r >= 0) {
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen session = strjoina("_SYSTEMD_SESSION=", t);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen free(t);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen IOVEC_SET_STRING(iovec[n++], session);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (cg_path_get_owner_uid(c, &owner) >= 0) {
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen owner_valid = true;
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen sprintf(owner_uid, "_SYSTEMD_OWNER_UID="UID_FMT, owner);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen IOVEC_SET_STRING(iovec[n++], owner_uid);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen }
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen if (cg_path_get_unit(c, &t) >= 0) {
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen x = strjoina("_SYSTEMD_UNIT=", t);
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen free(t);
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen } else if (unit_id && !session) {
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen x = strjoina("_SYSTEMD_UNIT=", unit_id);
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen }
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen if (cg_path_get_user_unit(c, &t) >= 0) {
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen x = strjoina("_SYSTEMD_USER_UNIT=", t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen free(t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen IOVEC_SET_STRING(iovec[n++], x);
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen } else if (unit_id && session) {
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen x = strjoina("_SYSTEMD_USER_UNIT=", unit_id);
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen }
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen if (cg_path_get_slice(c, &t) >= 0) {
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen x = strjoina("_SYSTEMD_SLICE=", t);
816e2e7af96886e4a43194042ef61ba9fec2c77dTom Gundersen free(t);
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen IOVEC_SET_STRING(iovec[n++], x);
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen free(c);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen } else if (unit_id) {
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen x = strjoina("_SYSTEMD_UNIT=", unit_id);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen }
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen#ifdef HAVE_SELINUX
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (mac_selinux_use()) {
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (label) {
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen x = alloca(strlen("_SELINUX_CONTEXT=") + label_len + 1);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen *((char*) mempcpy(stpcpy(x, "_SELINUX_CONTEXT="), label, label_len)) = 0;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen } else {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen security_context_t con;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (getpidcon(ucred->pid, &con) >= 0) {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen x = strjoina("_SELINUX_CONTEXT=", con);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen freecon(con);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen#endif
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen assert(n <= m);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (object_pid) {
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen r = get_process_uid(object_pid, &object_uid);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (r >= 0) {
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen sprintf(o_uid, "OBJECT_UID="UID_FMT, object_uid);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen IOVEC_SET_STRING(iovec[n++], o_uid);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen }
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen r = get_process_gid(object_pid, &object_gid);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (r >= 0) {
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen sprintf(o_gid, "OBJECT_GID="GID_FMT, object_gid);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen IOVEC_SET_STRING(iovec[n++], o_gid);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen }
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen r = get_process_comm(object_pid, &t);
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (r >= 0) {
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen x = strjoina("OBJECT_COMM=", t);
5b34277c2015e32e51d10cfa076df2c7106b4537Tom Gundersen free(t);
5b34277c2015e32e51d10cfa076df2c7106b4537Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
5b34277c2015e32e51d10cfa076df2c7106b4537Tom Gundersen }
5b34277c2015e32e51d10cfa076df2c7106b4537Tom Gundersen
5b34277c2015e32e51d10cfa076df2c7106b4537Tom Gundersen r = get_process_exe(object_pid, &t);
5b34277c2015e32e51d10cfa076df2c7106b4537Tom Gundersen if (r >= 0) {
5b34277c2015e32e51d10cfa076df2c7106b4537Tom Gundersen x = strjoina("OBJECT_EXE=", t);
5b34277c2015e32e51d10cfa076df2c7106b4537Tom Gundersen free(t);
5b34277c2015e32e51d10cfa076df2c7106b4537Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen }
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen r = get_process_cmdline(object_pid, 0, false, &t);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen if (r >= 0) {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen x = strjoina("OBJECT_CMDLINE=", t);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen free(t);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen }
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#ifdef HAVE_AUDIT
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen r = audit_session_from_pid(object_pid, &audit);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (r >= 0) {
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen sprintf(o_audit_session, "OBJECT_AUDIT_SESSION=%"PRIu32, audit);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen IOVEC_SET_STRING(iovec[n++], o_audit_session);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen }
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen r = audit_loginuid_from_pid(object_pid, &loginuid);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (r >= 0) {
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen sprintf(o_audit_loginuid, "OBJECT_AUDIT_LOGINUID="UID_FMT, loginuid);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen IOVEC_SET_STRING(iovec[n++], o_audit_loginuid);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen }
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen#endif
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen r = cg_pid_get_path_shifted(object_pid, s->cgroup_root, &c);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (r >= 0) {
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen x = strjoina("OBJECT_SYSTEMD_CGROUP=", c);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen r = cg_path_get_session(c, &t);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (r >= 0) {
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen x = strjoina("OBJECT_SYSTEMD_SESSION=", t);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen free(t);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen }
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (cg_path_get_owner_uid(c, &owner) >= 0) {
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen sprintf(o_owner_uid, "OBJECT_SYSTEMD_OWNER_UID="UID_FMT, owner);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen IOVEC_SET_STRING(iovec[n++], o_owner_uid);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen }
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (cg_path_get_unit(c, &t) >= 0) {
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen x = strjoina("OBJECT_SYSTEMD_UNIT=", t);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen free(t);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen }
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen if (cg_path_get_user_unit(c, &t) >= 0) {
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen x = strjoina("OBJECT_SYSTEMD_USER_UNIT=", t);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen free(t);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen IOVEC_SET_STRING(iovec[n++], x);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen free(c);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen assert(n <= m);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen if (tv) {
a7f7d1bde43fc825c49afea3f946f5b4b3d563e0Harald Hoyer sprintf(source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu", (unsigned long long) timeval_load(tv));
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen IOVEC_SET_STRING(iovec[n++], source_time);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen }
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen /* Note that strictly speaking storing the boot id here is
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen * redundant since the entry includes this in-line
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen * anyway. However, we need this indexed, too. */
02557f973aed0fed7154fefe53d67e2935f918dcThomas Hindoe Paaboel Andersen if (!isempty(s->boot_id_field))
02557f973aed0fed7154fefe53d67e2935f918dcThomas Hindoe Paaboel Andersen IOVEC_SET_STRING(iovec[n++], s->boot_id_field);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
02557f973aed0fed7154fefe53d67e2935f918dcThomas Hindoe Paaboel Andersen if (!isempty(s->machine_id_field))
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen IOVEC_SET_STRING(iovec[n++], s->machine_id_field);
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen if (!isempty(s->hostname_field))
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen IOVEC_SET_STRING(iovec[n++], s->hostname_field);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen assert(n <= m);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen if (s->split_mode == SPLIT_UID && realuid > 0)
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen /* Split up strictly by any UID */
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen journal_uid = realuid;
bff92d2c2f913c368d80066ee89855665818edc8Susant Sahani else if (s->split_mode == SPLIT_LOGIN && realuid > 0 && owner_valid && owner > 0)
bff92d2c2f913c368d80066ee89855665818edc8Susant Sahani /* Split up by login UIDs. We do this only if the
bff92d2c2f913c368d80066ee89855665818edc8Susant Sahani * realuid is not root, in order not to accidentally
38a03f06a7393d2721c23f23f0589d2f6d0904afLennart Poettering * leak privileged information to the user that is
bff92d2c2f913c368d80066ee89855665818edc8Susant Sahani * logged by a privileged process that is part of an
bff92d2c2f913c368d80066ee89855665818edc8Susant Sahani * unprivileged session. */
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen journal_uid = owner;
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen else
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen journal_uid = 0;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen write_to_journal(s, journal_uid, iovec, n, priority);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen}
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersenvoid server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) {
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen char mid[11 + 32 + 1];
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen char buffer[16 + LINE_MAX + 1];
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen struct iovec iovec[N_IOVEC_META_FIELDS + 4];
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen int n = 0;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen va_list ap;
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen struct ucred ucred = {};
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen assert(s);
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen assert(format);
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen IOVEC_SET_STRING(iovec[n++], "PRIORITY=6");
87322b3aee0dc649ff1ae7a403dcc9d7305baba2Tom Gundersen IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=driver");
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen memcpy(buffer, "MESSAGE=", 8);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen va_start(ap, format);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen vsnprintf(buffer + 8, sizeof(buffer) - 8, format, ap);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen va_end(ap);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen IOVEC_SET_STRING(iovec[n++], buffer);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen if (!sd_id128_equal(message_id, SD_ID128_NULL)) {
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen snprintf(mid, sizeof(mid), LOG_MESSAGE_ID(message_id));
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen IOVEC_SET_STRING(iovec[n++], mid);
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen }
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen ucred.pid = getpid();
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen ucred.uid = getuid();
bd57b45029ff25067704c9538e79f31e71c10045Tom Gundersen ucred.gid = getgid();
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen}
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersenvoid server_dispatch_message(
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen Server *s,
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen struct iovec *iovec, unsigned n, unsigned m,
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen const struct ucred *ucred,
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen const struct timeval *tv,
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen const char *label, size_t label_len,
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen const char *unit_id,
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen int priority,
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen pid_t object_pid) {
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen int rl, r;
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen _cleanup_free_ char *path = NULL;
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen char *c;
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen assert(s);
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen assert(iovec || n == 0);
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen if (n == 0)
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen return;
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen if (LOG_PRI(priority) > s->max_level_store)
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen return;
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen
500792d8180c9a11d65f107cdc79dea21b2964c4Tom Gundersen /* Stop early in case the information will not be stored
2dead8129f7b6fe644e17e1dc1739bebacfe1364Tom Gundersen * in a journal. */
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen if (s->storage == STORAGE_NONE)
4dc355680460fdc8e0d590d8572dff1b6a257d88Tom Gundersen return;
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen if (!ucred)
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen goto finish;
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen r = cg_pid_get_path_shifted(ucred->pid, s->cgroup_root, &path);
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen if (r < 0)
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen goto finish;
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen /* example: /user/lennart/3/foobar
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen * /system/dbus.service/foobar
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen *
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen * So let's cut of everything past the third /, since that is
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen * where user directories start */
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen c = strchr(path, '/');
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (c) {
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen c = strchr(c+1, '/');
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (c) {
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen c = strchr(c+1, '/');
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (c)
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen *c = 0;
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen }
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen }
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen rl = journal_rate_limit_test(s->rate_limit, path,
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen priority & LOG_PRIMASK, available_space(s, false));
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (rl == 0)
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen return;
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen /* Write a suppression message if we suppressed something */
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (rl > 1)
a38d99451f2bf8026ec51aee91662292e823c6a8Lennart Poettering server_driver_message(s, SD_MESSAGE_JOURNAL_DROPPED,
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen "Suppressed %u messages from %s", rl - 1, path);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
be077570f779664ed87b50f60608df9fbe258821Tom Gundersenfinish:
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, priority, object_pid);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen}
2a1288ff89322a2f49c79f6d1832c8164c14a05cLennart Poettering
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersenstatic int system_journal_open(Server *s, bool flush_requested) {
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen int r;
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen char *fn;
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen sd_id128_t machine;
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen char ids[33];
a6f1e036de8f212f33ead7f5387c297afd8be26eTom Gundersen
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen r = sd_id128_get_machine(&machine);
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen if (r < 0)
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen return log_error_errno(r, "Failed to get machine id: %m");
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen sd_id128_to_string(machine, ids);
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen
3a864fe4a894745ac61f1ecabd7cadf04139a284Tom Gundersen if (!s->system_journal &&
be077570f779664ed87b50f60608df9fbe258821Tom Gundersen (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen (flush_requested
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen || access("/run/systemd/journal/flushed", F_OK) >= 0)) {
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen /* If in auto mode: first try to create the machine
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen * path, but not the prefix.
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen *
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen * If in persistent mode: create /var/log/journal and
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen * the machine path */
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (s->storage == STORAGE_PERSISTENT)
20af7091de0cdf92bf299addfc3f96c3ef805bd8Tom Gundersen (void) mkdir("/var/log/journal/", 0755);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen fn = strjoina("/var/log/journal/", ids);
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen (void) mkdir(fn, 0755);
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen fn = strjoina(fn, "/system.journal");
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal);
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen if (r >= 0)
8de4a226c71ef43e652274b33b5d19211a44ac7bTom Gundersen server_fix_perms(s, s->system_journal, 0);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen else if (r < 0) {
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (r != -ENOENT && r != -EROFS)
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen log_warning_errno(r, "Failed to open system journal: %m");
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen r = 0;
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen }
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen }
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (!s->runtime_journal &&
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen (s->storage != STORAGE_NONE)) {
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen fn = strjoin("/run/log/journal/", ids, "/system.journal", NULL);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (!fn)
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen return -ENOMEM;
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (s->system_journal) {
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen /* Try to open the runtime journal, but only
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen * if it already exists, so that we can flush
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen * it into the system journal */
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen r = journal_file_open(fn, O_RDWR, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen free(fn);
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (r < 0) {
ff734080aa02cd70b13bc0fdeec4a5886166163aTom Gundersen if (r != -ENOENT)
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen log_warning_errno(r, "Failed to open runtime journal: %m");
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen r = 0;
621ac3d2cc8f37169166df9c7f379b0cb6b17e36Thomas Hindoe Paaboel Andersen }
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen } else {
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen /* OK, we really need the runtime journal, so create
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen * it if necessary. */
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen (void) mkdir("/run/log", 0755);
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen (void) mkdir("/run/log/journal", 0755);
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen (void) mkdir_parents(fn, 0750);
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen free(fn);
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen if (r < 0)
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen return log_error_errno(r, "Failed to open runtime journal: %m");
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen }
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen if (s->runtime_journal)
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen server_fix_perms(s, s->runtime_journal, 0);
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen }
527503444ef24ae03c73cf85128c7acbb1146f3cTom Gundersen
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering available_space(s, true);
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering return r;
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering}
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poetteringint server_flush_to_var(Server *s) {
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering sd_id128_t machine;
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering sd_journal *j = NULL;
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering char ts[FORMAT_TIMESPAN_MAX];
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering usec_t start;
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering unsigned n = 0;
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering int r;
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering assert(s);
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering
8eb9058dc1f99a5eb9b8726a978fcc0720837a10Lennart Poettering if (s->storage != STORAGE_AUTO &&
s->storage != STORAGE_PERSISTENT)
return 0;
if (!s->runtime_journal)
return 0;
system_journal_open(s, true);
if (!s->system_journal)
return 0;
log_debug("Flushing to /var...");
start = now(CLOCK_MONOTONIC);
r = sd_id128_get_machine(&machine);
if (r < 0)
return r;
r = sd_journal_open(&j, SD_JOURNAL_RUNTIME_ONLY);
if (r < 0)
return log_error_errno(r, "Failed to read runtime journal: %m");
sd_journal_set_data_threshold(j, 0);
SD_JOURNAL_FOREACH(j) {
Object *o = NULL;
JournalFile *f;
f = j->current_file;
assert(f && f->current_offset > 0);
n++;
r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
if (r < 0) {
log_error_errno(r, "Can't read entry: %m");
goto finish;
}
r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
if (r >= 0)
continue;
if (!shall_try_append_again(s->system_journal, r)) {
log_error_errno(r, "Can't write entry: %m");
goto finish;
}
server_rotate(s);
server_vacuum(s);
if (!s->system_journal) {
log_notice("Didn't flush runtime journal since rotation of system journal wasn't successful.");
r = -EIO;
goto finish;
}
log_debug("Retrying write.");
r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
if (r < 0) {
log_error_errno(r, "Can't write entry: %m");
goto finish;
}
}
finish:
journal_file_post_change(s->system_journal);
journal_file_close(s->runtime_journal);
s->runtime_journal = NULL;
if (r >= 0)
(void) rm_rf("/run/log/journal", REMOVE_ROOT);
sd_journal_close(j);
server_driver_message(s, SD_ID128_NULL, "Time spent on flushing to /var is %s for %u entries.", format_timespan(ts, sizeof(ts), now(CLOCK_MONOTONIC) - start, 0), n);
return r;
}
int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
Server *s = userdata;
struct ucred *ucred = NULL;
struct timeval *tv = NULL;
struct cmsghdr *cmsg;
char *label = NULL;
size_t label_len = 0, m;
struct iovec iovec;
ssize_t n;
int *fds = NULL, v = 0;
unsigned n_fds = 0;
union {
struct cmsghdr cmsghdr;
/* We use NAME_MAX space for the SELinux label
* here. The kernel currently enforces no
* limit, but according to suggestions from
* the SELinux people this will change and it
* will probably be identical to NAME_MAX. For
* now we use that, but this should be updated
* one day when the final limit is known. */
uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
CMSG_SPACE(sizeof(struct timeval)) +
CMSG_SPACE(sizeof(int)) + /* fd */
CMSG_SPACE(NAME_MAX)]; /* selinux label */
} control = {};
union sockaddr_union sa = {};
struct msghdr msghdr = {
.msg_iov = &iovec,
.msg_iovlen = 1,
.msg_control = &control,
.msg_controllen = sizeof(control),
.msg_name = &sa,
.msg_namelen = sizeof(sa),
};
assert(s);
assert(fd == s->native_fd || fd == s->syslog_fd || fd == s->audit_fd);
if (revents != EPOLLIN) {
log_error("Got invalid event from epoll for datagram fd: %"PRIx32, revents);
return -EIO;
}
/* Try to get the right size, if we can. (Not all
* sockets support SIOCINQ, hence we just try, but
* don't rely on it. */
(void) ioctl(fd, SIOCINQ, &v);
/* Fix it up, if it is too small. We use the same fixed value as auditd here. Awful! */
m = PAGE_ALIGN(MAX3((size_t) v + 1,
(size_t) LINE_MAX,
ALIGN(sizeof(struct nlmsghdr)) + ALIGN((size_t) MAX_AUDIT_MESSAGE_LENGTH)) + 1);
if (!GREEDY_REALLOC(s->buffer, s->buffer_size, m))
return log_oom();
iovec.iov_base = s->buffer;
iovec.iov_len = s->buffer_size - 1; /* Leave room for trailing NUL we add later */
n = recvmsg(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
if (n < 0) {
if (errno == EINTR || errno == EAGAIN)
return 0;
return log_error_errno(errno, "recvmsg() failed: %m");
}
CMSG_FOREACH(cmsg, &msghdr) {
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
ucred = (struct ucred*) CMSG_DATA(cmsg);
else if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_SECURITY) {
label = (char*) CMSG_DATA(cmsg);
label_len = cmsg->cmsg_len - CMSG_LEN(0);
} else if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SO_TIMESTAMP &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
tv = (struct timeval*) CMSG_DATA(cmsg);
else if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS) {
fds = (int*) CMSG_DATA(cmsg);
n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
}
}
/* And a trailing NUL, just in case */
s->buffer[n] = 0;
if (fd == s->syslog_fd) {
if (n > 0 && n_fds == 0)
server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len);
else if (n_fds > 0)
log_warning("Got file descriptors via syslog socket. Ignoring.");
} else if (fd == s->native_fd) {
if (n > 0 && n_fds == 0)
server_process_native_message(s, s->buffer, n, ucred, tv, label, label_len);
else if (n == 0 && n_fds == 1)
server_process_native_file(s, fds[0], ucred, tv, label, label_len);
else if (n_fds > 0)
log_warning("Got too many file descriptors via native socket. Ignoring.");
} else {
assert(fd == s->audit_fd);
if (n > 0 && n_fds == 0)
server_process_audit_message(s, s->buffer, n, ucred, &sa, msghdr.msg_namelen);
else if (n_fds > 0)
log_warning("Got file descriptors via audit socket. Ignoring.");
}
close_many(fds, n_fds);
return 0;
}
static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
Server *s = userdata;
assert(s);
log_info("Received request to flush runtime journal from PID %"PRIu32, si->ssi_pid);
server_flush_to_var(s);
server_sync(s);
server_vacuum(s);
touch("/run/systemd/journal/flushed");
return 0;
}
static int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
Server *s = userdata;
assert(s);
log_info("Received request to rotate journal from PID %"PRIu32, si->ssi_pid);
server_rotate(s);
server_vacuum(s);
return 0;
}
static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
Server *s = userdata;
assert(s);
log_received_signal(LOG_INFO, si);
sd_event_exit(s->event, 0);
return 0;
}
static int setup_signals(Server *s) {
sigset_t mask;
int r;
assert(s);
assert_se(sigemptyset(&mask) == 0);
sigset_add_many(&mask, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, -1);
assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
r = sd_event_add_signal(s->event, &s->sigusr1_event_source, SIGUSR1, dispatch_sigusr1, s);
if (r < 0)
return r;
r = sd_event_add_signal(s->event, &s->sigusr2_event_source, SIGUSR2, dispatch_sigusr2, s);
if (r < 0)
return r;
r = sd_event_add_signal(s->event, &s->sigterm_event_source, SIGTERM, dispatch_sigterm, s);
if (r < 0)
return r;
r = sd_event_add_signal(s->event, &s->sigint_event_source, SIGINT, dispatch_sigterm, s);
if (r < 0)
return r;
return 0;
}
static int server_parse_proc_cmdline(Server *s) {
_cleanup_free_ char *line = NULL;
const char *w, *state;
size_t l;
int r;
r = proc_cmdline(&line);
if (r < 0) {
log_warning_errno(r, "Failed to read /proc/cmdline, ignoring: %m");
return 0;
}
FOREACH_WORD_QUOTED(w, l, line, state) {
_cleanup_free_ char *word;
word = strndup(w, l);
if (!word)
return -ENOMEM;
if (startswith(word, "systemd.journald.forward_to_syslog=")) {
r = parse_boolean(word + 35);
if (r < 0)
log_warning("Failed to parse forward to syslog switch %s. Ignoring.", word + 35);
else
s->forward_to_syslog = r;
} else if (startswith(word, "systemd.journald.forward_to_kmsg=")) {
r = parse_boolean(word + 33);
if (r < 0)
log_warning("Failed to parse forward to kmsg switch %s. Ignoring.", word + 33);
else
s->forward_to_kmsg = r;
} else if (startswith(word, "systemd.journald.forward_to_console=")) {
r = parse_boolean(word + 36);
if (r < 0)
log_warning("Failed to parse forward to console switch %s. Ignoring.", word + 36);
else
s->forward_to_console = r;
} else if (startswith(word, "systemd.journald.forward_to_wall=")) {
r = parse_boolean(word + 33);
if (r < 0)
log_warning("Failed to parse forward to wall switch %s. Ignoring.", word + 33);
else
s->forward_to_wall = r;
} else if (startswith(word, "systemd.journald"))
log_warning("Invalid systemd.journald parameter. Ignoring.");
}
/* do not warn about state here, since probably systemd already did */
return 0;
}
static int server_parse_config_file(Server *s) {
assert(s);
return config_parse_many("/etc/systemd/journald.conf",
CONF_DIRS_NULSTR("systemd/journald.conf"),
"Journal\0",
config_item_perf_lookup, journald_gperf_lookup,
false, s);
}
static int server_dispatch_sync(sd_event_source *es, usec_t t, void *userdata) {
Server *s = userdata;
assert(s);
server_sync(s);
return 0;
}
int server_schedule_sync(Server *s, int priority) {
int r;
assert(s);
if (priority <= LOG_CRIT) {
/* Immediately sync to disk when this is of priority CRIT, ALERT, EMERG */
server_sync(s);
return 0;
}
if (s->sync_scheduled)
return 0;
if (s->sync_interval_usec > 0) {
usec_t when;
r = sd_event_now(s->event, CLOCK_MONOTONIC, &when);
if (r < 0)
return r;
when += s->sync_interval_usec;
if (!s->sync_event_source) {
r = sd_event_add_time(
s->event,
&s->sync_event_source,
CLOCK_MONOTONIC,
when, 0,
server_dispatch_sync, s);
if (r < 0)
return r;
r = sd_event_source_set_priority(s->sync_event_source, SD_EVENT_PRIORITY_IMPORTANT);
} else {
r = sd_event_source_set_time(s->sync_event_source, when);
if (r < 0)
return r;
r = sd_event_source_set_enabled(s->sync_event_source, SD_EVENT_ONESHOT);
}
if (r < 0)
return r;
s->sync_scheduled = true;
}
return 0;
}
static int dispatch_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
Server *s = userdata;
assert(s);
server_cache_hostname(s);
return 0;
}
static int server_open_hostname(Server *s) {
int r;
assert(s);
s->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY);
if (s->hostname_fd < 0)
return log_error_errno(errno, "Failed to open /proc/sys/kernel/hostname: %m");
r = sd_event_add_io(s->event, &s->hostname_event_source, s->hostname_fd, 0, dispatch_hostname_change, s);
if (r < 0) {
/* kernels prior to 3.2 don't support polling this file. Ignore
* the failure. */
if (r == -EPERM) {
log_warning("Failed to register hostname fd in event loop: %s. Ignoring.",
strerror(-r));
s->hostname_fd = safe_close(s->hostname_fd);
return 0;
}
return log_error_errno(r, "Failed to register hostname fd in event loop: %m");
}
r = sd_event_source_set_priority(s->hostname_event_source, SD_EVENT_PRIORITY_IMPORTANT-10);
if (r < 0)
return log_error_errno(r, "Failed to adjust priority of host name event source: %m");
return 0;
}
int server_init(Server *s) {
_cleanup_fdset_free_ FDSet *fds = NULL;
int n, r, fd;
assert(s);
zero(*s);
s->syslog_fd = s->native_fd = s->stdout_fd = s->dev_kmsg_fd = s->audit_fd = s->hostname_fd = -1;
s->compress = true;
s->seal = true;
s->sync_interval_usec = DEFAULT_SYNC_INTERVAL_USEC;
s->sync_scheduled = false;
s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL;
s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST;
s->forward_to_wall = true;
s->max_file_usec = DEFAULT_MAX_FILE_USEC;
s->max_level_store = LOG_DEBUG;
s->max_level_syslog = LOG_DEBUG;
s->max_level_kmsg = LOG_NOTICE;
s->max_level_console = LOG_INFO;
s->max_level_wall = LOG_EMERG;
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 "USEC_FMT",%u to 0,0",
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 = ordered_hashmap_new(NULL);
if (!s->user_journals)
return log_oom();
s->mmap = mmap_cache_new();
if (!s->mmap)
return log_oom();
r = sd_event_default(&s->event);
if (r < 0)
return log_error_errno(r, "Failed to create event loop: %m");
sd_event_set_watchdog(s->event, true);
n = sd_listen_fds(true);
if (n < 0)
return log_error_errno(n, "Failed to read listening file descriptors from environment: %m");
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 ||
sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/run/systemd/journal/dev-log", 0) > 0) {
if (s->syslog_fd >= 0) {
log_error("Too many /dev/log sockets passed.");
return -EINVAL;
}
s->syslog_fd = fd;
} else if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
if (s->audit_fd >= 0) {
log_error("Too many audit sockets passed.");
return -EINVAL;
}
s->audit_fd = fd;
} else {
if (!fds) {
fds = fdset_new();
if (!fds)
return log_oom();
}
r = fdset_put(fds, fd);
if (r < 0)
return log_oom();
}
}
r = server_open_stdout_socket(s, fds);
if (r < 0)
return r;
if (fdset_size(fds) > 0) {
log_warning("%u unknown file descriptors passed, closing.", fdset_size(fds));
fds = fdset_free(fds);
}
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_dev_kmsg(s);
if (r < 0)
return r;
r = server_open_audit(s);
if (r < 0)
return r;
r = server_open_kernel_seqnum(s);
if (r < 0)
return r;
r = server_open_hostname(s);
if (r < 0)
return r;
r = setup_signals(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 = cg_get_root_path(&s->cgroup_root);
if (r < 0)
return r;
server_cache_hostname(s);
server_cache_boot_id(s);
server_cache_machine_id(s);
r = system_journal_open(s, false);
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);
ORDERED_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 = ordered_hashmap_steal_first(s->user_journals)))
journal_file_close(f);
ordered_hashmap_free(s->user_journals);
sd_event_source_unref(s->syslog_event_source);
sd_event_source_unref(s->native_event_source);
sd_event_source_unref(s->stdout_event_source);
sd_event_source_unref(s->dev_kmsg_event_source);
sd_event_source_unref(s->audit_event_source);
sd_event_source_unref(s->sync_event_source);
sd_event_source_unref(s->sigusr1_event_source);
sd_event_source_unref(s->sigusr2_event_source);
sd_event_source_unref(s->sigterm_event_source);
sd_event_source_unref(s->sigint_event_source);
sd_event_source_unref(s->hostname_event_source);
sd_event_unref(s->event);
safe_close(s->syslog_fd);
safe_close(s->native_fd);
safe_close(s->stdout_fd);
safe_close(s->dev_kmsg_fd);
safe_close(s->audit_fd);
safe_close(s->hostname_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);
free(s->cgroup_root);
free(s->hostname_field);
if (s->mmap)
mmap_cache_unref(s->mmap);
if (s->udev)
udev_unref(s->udev);
}