journald-server.c revision 23ad4dd8844c582929115a11ed2830a1371568d6
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering This file is part of systemd.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Copyright 2011 Lennart Poettering
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering systemd is free software; you can redistribute it and/or modify it
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering under the terms of the GNU Lesser General Public License as published by
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering (at your option) any later version.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering systemd is distributed in the hope that it will be useful, but
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering Lesser General Public License for more details.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering You should have received a copy of the GNU Lesser General Public License
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering#define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE)
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering#define DEFAULT_RATE_LIMIT_INTERVAL (10*USEC_PER_SEC)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering#define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic const char* const storage_table[] = {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_STRING_TABLE_LOOKUP(storage, Storage);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic const char* const split_mode_table[] = {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart PoetteringDEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic uint64_t available_space(Server *s) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *f;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering uint64_t sum = 0, avail = 0, ss_avail = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (s->cached_available_space_timestamp + RECHECK_AVAILABLE_SPACE_USEC > ts)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering p = strappend(f, sd_id128_to_string(machine, ids));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers avail = sum >= m->max_use ? 0 : m->max_use - sum;
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers ss_avail = ss_avail < m->keep_free ? 0 : ss_avail - m->keep_free;
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering s->cached_available_space_timestamp = ts;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic void server_read_file_gid(Server *s) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering const char *g = "systemd-journal";
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to resolve '%s' group: %s", g, strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* if we couldn't read the gid, then it will be 0, but that's
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * fine and we shouldn't try to resolve the group again, so
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * let's just pretend it worked right-away. */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringvoid server_fix_perms(Server *s, JournalFile *f, uid_t uid) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = fchmod_and_fchown(f->fd, 0640, 0, s->file_gid);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to fix access mode/rights on %s, ignoring: %s", f->path, strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to read ACL on %s, ignoring: %m", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* We do not recalculate the mask unconditionally here,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * so that the fchmod() mask above stays intact. */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (acl_get_permset(entry, &permset) < 0 ||
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to patch ACL on %s, ignoring: %m", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("Failed to set ACL on %s, ignoring: %m", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic JournalFile* find_journal(Server *s, uid_t uid) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* We split up user logs only on /var, not on /run. If the
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * runtime file is open, we write to it exclusively, in order
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * to guarantee proper order as soon as we flush /run to
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * /var and close the runtime file. */
0affed79d2e30013f07cb94e6f07e3fcb81c02faLennart Poettering f = hashmap_get(s->user_journals, UINT32_TO_PTR(uid));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/user-%lu.journal",
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering SD_ID128_FORMAT_VAL(machine), (unsigned long) uid) < 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering while (hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek /* Too many open? Then let's close one */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering f = hashmap_steal_first(s->user_journals);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, s->system_journal, &f);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna r = hashmap_put(s->user_journals, UINT32_TO_PTR(uid), f);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna r = journal_file_rotate(&s->runtime_journal, s->compress, false);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("Failed to rotate %s: %s", s->runtime_journal->path, strerror(-r));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("Failed to create new runtime journal: %s", strerror(-r));
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek server_fix_perms(s, s->runtime_journal, 0);
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek r = journal_file_rotate(&s->system_journal, s->compress, s->seal);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("Failed to rotate %s: %s", s->system_journal->path, strerror(-r));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("Failed to create new system journal: %s", strerror(-r));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna server_fix_perms(s, s->system_journal, 0);
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek r = journal_file_rotate(&f, s->compress, s->seal);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers log_error("Failed to rotate %s: %s", f->path, strerror(-r));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna log_error("Failed to create user journal: %s", strerror(-r));
17d33cecaa762f7e43200307328af5e9135e2091Giovanni Campagna static const struct itimerspec sync_timer_disable = {};
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek r = journal_file_set_offline(s->system_journal);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to sync system journal: %s", strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
7c2d80944afb4196f2eff614e8da1450dffcbeaaThomas Hindoe Paaboel Andersen r = journal_file_set_offline(f);
bac3c8eefe23a820caac930d41629cebafbfc7b2Zbigniew Jędrzejewski-Szmek log_error("Failed to sync user journal: %s", strerror(-r));
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers r = timerfd_settime(s->sync_timer_fd, 0, &sync_timer_disable, NULL);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to disable max timer: %m");
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering log_error("Failed to get machine ID: %s", strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0 && r != -ENOENT)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to vacuum %s: %s", p, strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r < 0 && r != -ENOENT)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to vacuum %s: %s", p, strerror(-r));
2b6bf07dd23bb467099d213c97b3875c5e453491Zbigniew Jędrzejewski-Szmek s->cached_available_space_timestamp = 0;
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringbool shall_try_append_again(JournalFile *f, int r) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* -E2BIG Hit configured limit
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -EFBIG Hit fs limit
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -EDQUOT Quota limit hit
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -ENOSPC Disk full
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -EHOSTDOWN Other machine
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -EBUSY Unclean shutdown
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -EPROTONOSUPPORT Unsupported feature
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek -EBADMSG Corrupted
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek -ENODATA Truncated
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering -ESHUTDOWN Already archived */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("%s: Allocation limit reached, rotating.", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else if (r == -EHOSTDOWN)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_info("%s: Journal file from other machine, rotating.", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else if (r == -EBUSY)
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers log_info("%s: Unclean shutdown, rotating.", f->path);
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer else if (r == -EPROTONOSUPPORT)
0732ef7acf37473847992888bcb6446726d9d877Zbigniew Jędrzejewski-Szmek log_info("%s: Unsupported feature, rotating.", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_warning("%s: Journal file corrupted, rotating.", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (journal_file_rotate_suggested(f, s->max_file_usec)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (vacuumed || !shall_try_append_again(f, r)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to write entry, ignoring: %s", strerror(-r));
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering log_error("Failed to write entry, ignoring: %s", strerror(-r));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)],
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering uid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)],
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering owner_uid[sizeof("_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)],
7fd1b19bc9e9f5574f2877936b8ac267c7706947Harald Hoyer source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)],
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering boot_id[sizeof("_BOOT_ID=") + 32] = "_BOOT_ID=",
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering machine_id[sizeof("_MACHINE_ID=") + 32] = "_MACHINE_ID=";
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering char *comm, *exe, *cmdline, *cgroup, *session, *unit, *hostname;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering uid_t realuid = 0, owner = 0, journal_uid;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering char audit_session[sizeof("_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)],
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering audit_loginuid[sizeof("_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)];
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sprintf(pid, "_PID=%lu", (unsigned long) ucred->pid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sprintf(uid, "_UID=%lu", (unsigned long) ucred->uid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sprintf(gid, "_GID=%lu", (unsigned long) ucred->gid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = get_process_cmdline(ucred->pid, 0, false, &t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = audit_session_from_pid(ucred->pid, &audit);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sprintf(audit_session, "_AUDIT_SESSION=%lu", (unsigned long) audit);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], audit_session);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = audit_loginuid_from_pid(ucred->pid, &loginuid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sprintf(audit_loginuid, "_AUDIT_LOGINUID=%lu", (unsigned long) loginuid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], audit_loginuid);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering r = cg_pid_get_path_shifted(ucred->pid, NULL, &c);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering cgroup = strappenda("_SYSTEMD_CGROUP=", c);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering session = strappenda("_SYSTEMD_SESSION=", t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (cg_path_get_owner_uid(c, &owner) >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering sprintf(owner_uid, "_SYSTEMD_OWNER_UID=%lu", (unsigned long) owner);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering if (cg_path_get_unit(c, &t) >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering } else if (cg_path_get_user_unit(c, &t) >= 0) {
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering unit = strappenda("_SYSTEMD_USER_UNIT=", t);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering unit = strappenda("_SYSTEMD_USER_UNIT=", unit_id);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering unit = strappenda("_SYSTEMD_UNIT=", unit_id);
a86a47ce1f63476631635fbcbc10af8877172114Lennart Poettering char *selinux_context = alloca(sizeof("_SELINUX_CONTEXT=") + label_len);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering *((char*) mempcpy(stpcpy(selinux_context, "_SELINUX_CONTEXT="), label, label_len)) = 0;
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], selinux_context);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering char *selinux_context = strappenda("_SELINUX_CONTEXT=", con);
50cfc579280fb42569488079bd2e249e32a27df2Lennart Poettering IOVEC_SET_STRING(iovec[n++], selinux_context);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering sprintf(source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu", (unsigned long long) timeval_load(tv));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering IOVEC_SET_STRING(iovec[n++], source_time);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Note that strictly speaking storing the boot id here is
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * redundant since the entry includes this in-line
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * anyway. However, we need this indexed, too. */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering sd_id128_to_string(id, boot_id + sizeof("_BOOT_ID=") - 1);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers if (r >= 0) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers sd_id128_to_string(id, machine_id + sizeof("_MACHINE_ID=") - 1);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (s->split_mode == SPLIT_UID && realuid > 0)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Split up strictly by any UID */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering else if (s->split_mode == SPLIT_LOGIN && realuid > 0 && owner_valid && owner > 0)
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering /* Split up by login UIDs, this avoids creation of
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * individual journals for system UIDs. We do this
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * only if the realuid is not root, in order not to
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * accidentally leak privileged information to the
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * user that is logged by a privileged process that is
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * part of an unprivileged session.*/
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering write_to_journal(s, journal_uid, iovec, n);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringvoid server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=driver");
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering vsnprintf(buffer + 8, sizeof(buffer) - 8, format, ap);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (!sd_id128_equal(message_id, SD_ID128_NULL)) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering snprintf(mid, sizeof(mid), MESSAGE_ID(message_id));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering struct iovec *iovec, unsigned n, unsigned m,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering if (LOG_PRI(priority) > s->max_level_store)
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering r = cg_pid_get_path_shifted(ucred->pid, NULL, &path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* example: /user/lennart/3/foobar
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * So let's cut of everything past the third /, since that is
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * where user directories start */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering rl = journal_rate_limit_test(s->rate_limit, path,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering priority & LOG_PRIMASK, available_space(s));
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering /* Write a suppression message if we suppressed something */
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering server_driver_message(s, SD_MESSAGE_JOURNAL_DROPPED,
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering "Suppressed %u messages from %s", rl - 1, path);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poetteringstatic int system_journal_open(Server *s) {
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering access("/run/systemd/journal/flushed", F_OK) >= 0) {
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers /* If in auto mode: first try to create the machine
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers * path, but not the prefix.
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering * If in persistent mode: create /var/log/journal and
a9cdc94f7ff40f22a3cf9472f612a80730a1b010Dave Reisner * the machine path */
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering fn = strappend("/var/log/journal/", ids);
2087a7aff26ea5d1bc2c7c29add3275328f36baaLennart Poettering fn = strjoin("/var/log/journal/", ids, "/system.journal", NULL);
4d7859d173282e16bb75254c2b4ec14a915ef30bKay Sievers r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal);
if (!s->runtime_journal &&
if (!fn)
return -ENOMEM;
if (s->system_journal) {
r = journal_file_open(fn, O_RDWR, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
if (r != -ENOENT)
r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
if (s->runtime_journal) {
assert(s);
if (!s->runtime_journal)
if (!s->system_journal)
SD_JOURNAL_FOREACH(j) {
JournalFile *f;
f = j->current_file;
goto finish;
goto finish;
server_rotate(s);
server_vacuum(s);
if (!s->system_journal) {
r = -EIO;
goto finish;
goto finish;
sd_journal_close(j);
assert(s);
ssize_t n;
return -EIO;
if (n != sizeof(sfsi)) {
return -EIO;
return -errno;
server_sync(s);
server_rotate(s);
server_vacuum(s);
uint64_t t;
server_sync(s);
return -EIO;
r = server_read_dev_kmsg(s);
return -EIO;
} control;
ssize_t n;
unsigned n_fds = 0;
return -errno;
size_t l;
return -ENOMEM;
s->buffer_size = l;
s->buffer = b;
return -errno;
if (n > 0 && n_fds == 0) {
s->buffer[n] = 0;
} else if (n_fds > 0)
if (n > 0 && n_fds == 0)
else if (n_fds > 0)
return -EIO;
return -EIO;
assert(s);
if (s->signal_fd < 0) {
return -errno;
return -errno;
char *w, *state;
size_t l;
if (!word)
return -ENOMEM;
s->forward_to_syslog = r;
s->forward_to_kmsg = r;
s->forward_to_console = r;
assert(s);
return -errno;
(void*) journald_gperf_lookup, false, false, s);
assert(s);
if (s->sync_timer_fd < 0)
return -errno;
return -errno;
assert(s);
if (s->sync_scheduled)
if (s->sync_interval_usec) {
return -errno;
s->sync_scheduled = true;
int n, r, fd;
assert(s);
zero(*s);
s->compress = true;
s->seal = true;
s->sync_scheduled = false;
s->forward_to_syslog = true;
(long long unsigned) s->rate_limit_interval,
s->rate_limit_burst);
if (!s->user_journals)
return log_oom();
if (!s->mmap)
return log_oom();
if (s->epoll_fd < 0) {
return -errno;
n = sd_listen_fds(true);
if (s->native_fd >= 0) {
return -EINVAL;
if (s->stdout_fd >= 0) {
return -EINVAL;
if (s->syslog_fd >= 0) {
return -EINVAL;
return -EINVAL;
r = server_open_syslog_socket(s);
r = server_open_native_socket(s);
r = server_open_stdout_socket(s);
r = server_open_dev_kmsg(s);
r = server_open_kernel_seqnum(s);
r = server_open_sync_timer(s);
r = open_signalfd(s);
if (!s->udev)
return -ENOMEM;
s->rate_limit_burst);
if (!s->rate_limit)
return -ENOMEM;
r = system_journal_open(s);
#ifdef HAVE_GCRYPT
JournalFile *f;
Iterator i;
usec_t n;
if (s->system_journal)
JournalFile *f;
assert(s);
while (s->stdout_streams)
if (s->system_journal)
if (s->runtime_journal)
if (s->epoll_fd >= 0)
if (s->signal_fd >= 0)
if (s->syslog_fd >= 0)
if (s->native_fd >= 0)
if (s->stdout_fd >= 0)
if (s->dev_kmsg_fd >= 0)
if (s->sync_timer_fd >= 0)
if (s->rate_limit)
if (s->kernel_seqnum)
if (s->mmap)
if (s->udev)