journald-server.c revision fbb634117d0b0ebd5b105e65b141e75ae9af7f8f
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen This file is part of systemd.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Copyright 2011 Lennart Poettering
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen systemd is free software; you can redistribute it and/or modify it
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen under the terms of the GNU Lesser General Public License as published by
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (at your option) any later version.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen systemd is distributed in the hope that it will be useful, but
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Lesser General Public License for more details.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen You should have received a copy of the GNU Lesser General Public License
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#define DEFAULT_RATE_LIMIT_INTERVAL (30*USEC_PER_SEC)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic const char* const storage_table[] = {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom GundersenDEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic const char* const split_mode_table[] = {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom GundersenDEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom GundersenDEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic uint64_t available_space(Server *s, bool verbose) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen const char *f;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen p = strappend(f, sd_id128_to_string(machine, ids));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen avail = ss_avail > m->keep_free ? ss_avail - m->keep_free : 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->cached_available_space = MIN(m->max_use, avail) > sum ? MIN(m->max_use, avail) - sum : 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char fb1[FORMAT_BYTES_MAX], fb2[FORMAT_BYTES_MAX], fb3[FORMAT_BYTES_MAX],
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen server_driver_message(s, SD_MESSAGE_JOURNAL_USAGE,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "%s journal is using %s (max %s, leaving %s of free %s, current limit %s).",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen format_bytes(fb5, sizeof(fb5), MIN(m->max_use, avail)));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenvoid server_fix_perms(Server *s, JournalFile *f, uid_t uid) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to fix access mode on %s, ignoring: %s", f->path, strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to read ACL on %s, ignoring: %m", f->path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r <= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* We do not recalculate the mask unconditionally here,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * so that the fchmod() mask above stays intact. */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to set ACL on %s, ignoring: %m", f->path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic JournalFile* find_journal(Server *s, uid_t uid) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* We split up user logs only on /var, not on /run. If the
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * runtime file is open, we write to it exclusively, in order
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * to guarantee proper order as soon as we flush /run to
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * /var and close the runtime file. */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen f = hashmap_get(s->user_journals, UINT32_TO_PTR(uid));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/user-%lu.journal",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen SD_ID128_FORMAT_VAL(machine), (unsigned long) uid) < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen while (hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Too many open? Then let's close one */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &f);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_rotate(&s->runtime_journal, s->compress, false);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to rotate %s: %s", s->runtime_journal->path, strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to create new runtime journal: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_rotate(&s->system_journal, s->compress, s->seal);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to rotate %s: %s", s->system_journal->path, strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to create new system journal: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_rotate(&f, s->compress, s->seal);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to rotate %s: %s", f->path, strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to create user journal: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen static const struct itimerspec sync_timer_disable = {};
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_set_offline(s->system_journal);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to sync system journal: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to sync user journal: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = timerfd_settime(s->sync_timer_fd, 0, &sync_timer_disable, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to get machine ID: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *p = strappenda("/var/log/journal/", ids);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0 && r != -ENOENT)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to vacuum %s: %s", p, strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *p = strappenda("/run/log/journal/", ids);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0 && r != -ENOENT)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to vacuum %s: %s", p, strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenbool shall_try_append_again(JournalFile *f, int r) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* -E2BIG Hit configured limit
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen -EFBIG Hit fs limit
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen -EDQUOT Quota limit hit
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen -ENOSPC Disk full
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen -EHOSTDOWN Other machine
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen -EBUSY Unclean shutdown
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen -EPROTONOSUPPORT Unsupported feature
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen -EBADMSG Corrupted
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen -ENODATA Truncated
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen -ESHUTDOWN Already archived */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_debug("%s: Allocation limit reached, rotating.", f->path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (r == -EHOSTDOWN)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_info("%s: Journal file from other machine, rotating.", f->path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (r == -EBUSY)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_info("%s: Unclean shutdown, rotating.", f->path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (r == -EPROTONOSUPPORT)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_info("%s: Unsupported feature, rotating.", f->path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("%s: Journal file corrupted, rotating.", f->path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return false;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n, int priority) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (journal_file_rotate_suggested(f, s->max_file_usec)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (vacuumed || !shall_try_append_again(f, r)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen for (i = 0; i < n; i++)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to write entry (%d items, %zu bytes), ignoring: %s", n, size, strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen for (i = 0; i < n; i++)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to write entry (%d items, %zu bytes) despite vacuuming, ignoring: %s", n, size, strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)],
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)],
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen gid[sizeof("_GID=") + DECIMAL_STR_MAX(gid_t)],
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen owner_uid[sizeof("_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)],
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)],
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen boot_id[sizeof("_BOOT_ID=") + 32] = "_BOOT_ID=",
bba061662b0f759abb43bad60c9733305c191045Tom Gundersen machine_id[sizeof("_MACHINE_ID=") + 32] = "_MACHINE_ID=",
bba061662b0f759abb43bad60c9733305c191045Tom Gundersen o_uid[sizeof("OBJECT_UID=") + DECIMAL_STR_MAX(uid_t)],
bba061662b0f759abb43bad60c9733305c191045Tom Gundersen o_gid[sizeof("OBJECT_GID=") + DECIMAL_STR_MAX(gid_t)],
bba061662b0f759abb43bad60c9733305c191045Tom Gundersen o_owner_uid[sizeof("OBJECT_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)];
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char audit_session[sizeof("_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)],
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen audit_loginuid[sizeof("_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)],
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen o_audit_session[sizeof("OBJECT_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)],
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen o_audit_loginuid[sizeof("OBJECT_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)];
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(n + N_IOVEC_META_FIELDS + (object_pid ? N_IOVEC_OBJECT_FIELDS : 0) <= m);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sprintf(pid, "_PID=%lu", (unsigned long) ucred->pid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sprintf(uid, "_UID=%lu", (unsigned long) ucred->uid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sprintf(gid, "_GID=%lu", (unsigned long) ucred->gid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = get_process_cmdline(ucred->pid, 0, false, &t);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = audit_session_from_pid(ucred->pid, &audit);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sprintf(audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = audit_loginuid_from_pid(ucred->pid, &loginuid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sprintf(audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = cg_pid_get_path_shifted(ucred->pid, NULL, &c);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sprintf(owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (cg_path_get_unit(c, &t) >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (cg_path_get_user_unit(c, &t) >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen x = strappenda("_SYSTEMD_USER_UNIT=", unit_id);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (cg_path_get_slice(c, &t) >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen x = alloca(sizeof("_SELINUX_CONTEXT=") + label_len);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen *((char*) mempcpy(stpcpy(x, "_SELINUX_CONTEXT="), label, label_len)) = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sprintf(o_uid, "OBJECT_UID=%lu", (unsigned long) object_uid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sprintf(o_gid, "OBJECT_GID=%lu", (unsigned long) object_gid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = get_process_cmdline(object_pid, 0, false, &t);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = audit_session_from_pid(object_pid, &audit);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sprintf(o_audit_session, "OBJECT_AUDIT_SESSION=%lu", (unsigned long) audit);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen IOVEC_SET_STRING(iovec[n++], o_audit_session);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = audit_loginuid_from_pid(object_pid, &loginuid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sprintf(o_audit_loginuid, "OBJECT_AUDIT_LOGINUID=%lu", (unsigned long) loginuid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen IOVEC_SET_STRING(iovec[n++], o_audit_loginuid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = cg_pid_get_path_shifted(object_pid, NULL, &c);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sprintf(o_owner_uid, "OBJECT_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (cg_path_get_unit(c, &t) >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (cg_path_get_user_unit(c, &t) >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen x = strappenda("OBJECT_SYSTEMD_USER_UNIT=", t);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sprintf(source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu", (unsigned long long) timeval_load(tv));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Note that strictly speaking storing the boot id here is
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * redundant since the entry includes this in-line
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * anyway. However, we need this indexed, too. */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_id128_to_string(id, boot_id + strlen("_BOOT_ID="));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_id128_to_string(id, machine_id + strlen("_MACHINE_ID="));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->split_mode == SPLIT_UID && realuid > 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Split up strictly by any UID */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (s->split_mode == SPLIT_LOGIN && realuid > 0 && owner_valid && owner > 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Split up by login UIDs, this avoids creation of
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * individual journals for system UIDs. We do this
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * only if the realuid is not root, in order not to
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * accidentally leak privileged information to the
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * user that is logged by a privileged process that is
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * part of an unprivileged session.*/
85091685af65831f379580c75b40776c20e245eeTom Gundersen write_to_journal(s, journal_uid, iovec, n, priority);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenvoid server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=driver");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen vsnprintf(buffer + 8, sizeof(buffer) - 8, format, ap);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!sd_id128_equal(message_id, SD_ID128_NULL)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen snprintf(mid, sizeof(mid), MESSAGE_ID(message_id));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Stop early in case the information will not be stored
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * in a journal. */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = cg_pid_get_path_shifted(ucred->pid, NULL, &path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* example: /user/lennart/3/foobar
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * So let's cut of everything past the third /, since that is
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * where user directories start */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen rl = journal_rate_limit_test(s->rate_limit, path,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen priority & LOG_PRIMASK, available_space(s, false));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Write a suppression message if we suppressed something */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen server_driver_message(s, SD_MESSAGE_JOURNAL_DROPPED,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen "Suppressed %u messages from %s", rl - 1, path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, priority, object_pid);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to get machine id: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen access("/run/systemd/journal/flushed", F_OK) >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* If in auto mode: first try to create the machine
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * path, but not the prefix.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * If in persistent mode: create /var/log/journal and
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * the machine path */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to open system journal: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen fn = strjoin("/run/log/journal/", ids, "/system.journal", NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Try to open the runtime journal, but only
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * if it already exists, so that we can flush
afcac065c0f649ebcf0f450475a8d7c3bc776d14Tom Gundersen * it into the system journal */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_open(fn, O_RDWR, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to open runtime journal: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* OK, we really need the runtime journal, so create
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * it if necessary. */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to open runtime journal: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen unsigned n = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_journal_open(&j, SD_JOURNAL_RUNTIME_ONLY);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to read runtime journal: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Can't read entry: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!shall_try_append_again(s->system_journal, r)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Can't write entry: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_notice("Didn't flush runtime journal since rotation of system journal wasn't successful.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Can't write entry: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen rm_rf("/run/log/journal", false, true, false);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen server_driver_message(s, SD_ID128_NULL, "Time spent on flushing to /var is %s for %u entries.", format_timespan(ts, sizeof(ts), now(CLOCK_MONOTONIC) - start, 0), n);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenint process_event(Server *s, struct epoll_event *ev) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Got invalid event from epoll for %s: %"PRIx32,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (n != sizeof(sfsi)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_info("Received request to flush runtime journal from PID %"PRIu32,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_info("Received request to rotate journal from PID %"PRIu32,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_info("Received SIG%s", signal_to_string(sfsi.ssi_signo));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("/dev/kmsg buffer overrun, some messages lost.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Got invalid event from epoll for %s: %"PRIx32,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Got invalid event from epoll for %s: %"PRIx32,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen ev->data.fd == s->native_fd ? "native fd" : "syslog fd",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* We use NAME_MAX space for the
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * SELinux label here. The kernel
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * currently enforces no limit, but
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * according to suggestions from the
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * SELinux people this will change and
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * it will probably be identical to
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * NAME_MAX. For now we use that, but
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * this should be updated one day when
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * the final limit is known.*/
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen unsigned n_fds = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!GREEDY_REALLOC(s->buffer, s->buffer_size, LINE_MAX + (size_t) v))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen n = recvmsg(ev->data.fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (n > 0 && n_fds == 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (n_fds > 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Got file descriptors via syslog socket. Ignoring.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (n > 0 && n_fds == 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen server_process_native_message(s, s->buffer, n, ucred, tv, label, label_len);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen server_process_native_file(s, fds[0], ucred, tv, label, label_len);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (n_fds > 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Got too many file descriptors via native socket. Ignoring.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Got invalid event from epoll for %s: %"PRIx32,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if ((ev->events|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Got invalid event from epoll for %s: %"PRIx32,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* If it is none of the well-known fds, it must be an
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * stdout stream fd. Note that this is a bit ugly here
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * (since we rely that none of the well-known fds
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * could be interpreted as pointer), but nonetheless
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * safe, since the well-known fds would never get an
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen * fd > 4096, i.e. beyond the first memory page */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sigset_add_many(&mask, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, -1);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->signal_fd, &ev) < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int server_parse_proc_cmdline(Server *s) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (startswith(word, "systemd.journald.forward_to_syslog=")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to parse forward to syslog switch %s. Ignoring.", word + 35);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (startswith(word, "systemd.journald.forward_to_kmsg=")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to parse forward to kmsg switch %s. Ignoring.", word + 33);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (startswith(word, "systemd.journald.forward_to_console=")) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to parse forward to console switch %s. Ignoring.", word + 36);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (startswith(word, "systemd.journald"))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Invalid systemd.journald parameter. Ignoring.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int server_parse_config_file(Server *s) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen static const char fn[] = "/etc/systemd/journald.conf";
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to open configuration file %s: %m", fn);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = config_parse(NULL, fn, f, "Journal\0", config_item_perf_lookup,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (void*) journald_gperf_lookup, false, false, s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to parse configuration file: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->sync_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->sync_timer_fd, &ev);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to add idle timer fd to epoll object: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenint server_schedule_sync(Server *s, int priority) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen /* Immediately sync to disk when this is of priority CRIT, ALERT, EMERG */
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen timespec_store(&sync_timer_enable.it_value, s->sync_interval_usec);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = timerfd_settime(s->sync_timer_fd, 0, &sync_timer_enable, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->sync_timer_fd = s->syslog_fd = s->native_fd = s->stdout_fd =
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->sync_interval_usec = DEFAULT_SYNC_INTERVAL_USEC;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen memset(&s->system_metrics, 0xFF, sizeof(s->system_metrics));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen memset(&s->runtime_metrics, 0xFF, sizeof(s->runtime_metrics));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!!s->rate_limit_interval ^ !!s->rate_limit_burst) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_debug("Setting both rate limit interval and burst from %llu,%u to 0,0",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (long long unsigned) s->rate_limit_interval,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->rate_limit_interval = s->rate_limit_burst = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->user_journals = hashmap_new(trivial_hash_func, trivial_compare_func);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to create epoll object: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to read listening file descriptors from environment: %s", strerror(-n));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/run/systemd/journal/socket", 0) > 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->native_fd >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_is_socket_unix(fd, SOCK_STREAM, 1, "/run/systemd/journal/stdout", 0) > 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->stdout_fd >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/dev/log", 0) > 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->syslog_fd >= 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Too many /dev/log sockets passed.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->rate_limit = journal_rate_limit_new(s->rate_limit_interval,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen journal_file_maybe_append_tag(s->system_journal, n);