journald-server.c revision 65c1d46b0923771955519329160a1e4c7cd027b0
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering This file is part of systemd.
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering Copyright 2011 Lennart Poettering
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering systemd is free software; you can redistribute it and/or modify it
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering under the terms of the GNU Lesser General Public License as published by
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering (at your option) any later version.
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering systemd is distributed in the hope that it will be useful, but
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering Lesser General Public License for more details.
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering You should have received a copy of the GNU Lesser General Public License
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#define DEFAULT_RATE_LIMIT_INTERVAL (30*USEC_PER_SEC)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#define DEFAULT_MAX_FILE_USEC USEC_PER_MONTH
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#define RECHECK_SPACE_USEC (30*USEC_PER_SEC)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const char *p;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (!verbose && s->cached_space_timestamp + RECHECK_SPACE_USEC > ts) {
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek p = strjoina(path, SERVER_MACHINE_ID(s));
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to open %s: %m", p);
e3b9d9c8027a7c4c55cf1614e0fe9423fad69e8fZbigniew Jędrzejewski-Szmek return log_error_errno(errno, "Failed to fstatvfs(%s): %m", p);
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek FOREACH_DIRENT_ALL(de, d, break) {
e3b9d9c8027a7c4c55cf1614e0fe9423fad69e8fZbigniew Jędrzejewski-Szmek if (!endswith(de->d_name, ".journal") &&
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_debug_errno(errno, "Failed to stat %s/%s, ignoring: %m", p, de->d_name);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek sum += (uint64_t) st.st_blocks * 512UL;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek /* If request, then let's bump the min_use limit to the
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek * current usage on disk. We do this when starting up and
4b8268f843b0da1cfe1995d93a0b1f95faccc454Zbigniew Jędrzejewski-Szmek * first opening the journal files. This way sudden spikes in
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek * disk usage will not cause journald to vacuum files without
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek * bounds. Note that this means that only a restart of
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek * journald will make it reset this value. */
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek metrics->min_use = MAX(metrics->min_use, sum);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek ss_avail = ss.f_bsize * ss.f_bavail;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek avail = LESS_BY(ss_avail, metrics->keep_free);
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek s->cached_space_limit = MIN(MAX(sum + avail, metrics->min_use), metrics->max_use);
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek s->cached_space_available = LESS_BY(s->cached_space_limit, sum);
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek s->cached_space_timestamp = ts;
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek char fb1[FORMAT_BYTES_MAX], fb2[FORMAT_BYTES_MAX], fb3[FORMAT_BYTES_MAX],
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek fb4[FORMAT_BYTES_MAX], fb5[FORMAT_BYTES_MAX], fb6[FORMAT_BYTES_MAX];
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek server_driver_message(s, SD_MESSAGE_JOURNAL_USAGE,
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek "%s (%s) is currently using %s.\n"
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek "Maximum allowed usage is set to %s.\n"
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek "Leaving at least %s free (of currently available %s of space).\n"
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek "Enforced usage limit is thus %s, of which %s are still available.",
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek format_bytes(fb1, sizeof(fb1), sum),
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek format_bytes(fb2, sizeof(fb2), metrics->max_use),
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek format_bytes(fb3, sizeof(fb3), metrics->keep_free),
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek format_bytes(fb4, sizeof(fb4), ss_avail),
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek format_bytes(fb5, sizeof(fb5), s->cached_space_limit),
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek format_bytes(fb6, sizeof(fb6), s->cached_space_available));
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek *available = s->cached_space_available;
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmek *limit = s->cached_space_limit;
baf167ee0a2953f98e4e7d4c35752ef737832674Zbigniew Jędrzejewski-Szmekstatic int determine_space(Server *s, bool verbose, bool patch_min_use, uint64_t *available, uint64_t *limit) {
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return determine_space_for(s, metrics, path, name, verbose, patch_min_use, available, limit);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmekvoid server_fix_perms(Server *s, JournalFile *f, uid_t uid) {
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek _cleanup_(acl_freep) acl_t acl = NULL;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_warning_errno(errno, "Failed to fix access mode on %s, ignoring: %m", f->path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_warning_errno(errno, "Failed to read ACL on %s, ignoring: %m", f->path);
d3b6d0c21ea5a0d15ec6dbd8b8d179138b7463bcZbigniew Jędrzejewski-Szmek if (acl_create_entry(&acl, &entry) < 0 ||
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_warning_errno(errno, "Failed to patch ACL on %s, ignoring: %m", f->path);
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek /* We do not recalculate the mask unconditionally here,
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering * so that the fchmod() mask above stays intact. */
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (acl_get_permset(entry, &permset) < 0 ||
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_warning_errno(errno, "Failed to patch ACL on %s, ignoring: %m", f->path);
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek r = calc_acl_mask_if_needed(&acl);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_warning_errno(r, "Failed to patch ACL on %s, ignoring: %m", f->path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_warning_errno(errno, "Failed to set ACL on %s, ignoring: %m", f->path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringstatic JournalFile* find_journal(Server *s, uid_t uid) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering /* We split up user logs only on /var, not on /run. If the
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering * runtime file is open, we write to it exclusively, in order
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering * to guarantee proper order as soon as we flush /run to
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering * /var and close the runtime file. */
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering f = ordered_hashmap_get(s->user_journals, UID_TO_PTR(uid));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/user-"UID_FMT".journal",
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering while (ordered_hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering /* Too many open? Then let's close one */
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering f = ordered_hashmap_steal_first(s->user_journals);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &f);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = ordered_hashmap_put(s->user_journals, UID_TO_PTR(uid), f);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = journal_file_rotate(f, s->compress, seal);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_error_errno(r, "Failed to rotate %s: %m", (*f)->path);
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt log_error_errno(r, "Failed to create new %s journal: %m", name);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek (void) do_rotate(s, &s->runtime_journal, "runtime", false, 0);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek (void) do_rotate(s, &s->system_journal, "system", s->seal, 0);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek ORDERED_HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = do_rotate(s, &f, "user", s->seal, PTR_TO_UID(k));
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek ordered_hashmap_replace(s->user_journals, k, f);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek /* Old file has been closed and deallocated */
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek ordered_hashmap_remove(s->user_journals, k);
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering r = journal_file_set_offline(s->system_journal);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_warning_errno(r, "Failed to sync system journal, ignoring: %m");
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek ORDERED_HASHMAP_FOREACH(f, s->user_journals, i) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = journal_file_set_offline(f);
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering log_warning_errno(r, "Failed to sync user journal, ignoring: %m");
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = sd_event_source_set_enabled(s->sync_event_source, SD_EVENT_OFF);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_error_errno(r, "Failed to disable sync timer source: %m");
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering const char *p;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering p = strjoina(path, SERVER_MACHINE_ID(s));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering (void) determine_space_for(s, metrics, path, name, verbose, patch_min_use, NULL, &limit);
e3b9d9c8027a7c4c55cf1614e0fe9423fad69e8fZbigniew Jędrzejewski-Szmek r = journal_directory_vacuum(p, limit, metrics->n_max_files, s->max_retention_usec, &s->oldest_file_usec, verbose);
e3b9d9c8027a7c4c55cf1614e0fe9423fad69e8fZbigniew Jędrzejewski-Szmek if (r < 0 && r != -ENOENT)
e53fc357a9bb9d0a5362ccc4246d598cb0febd5eLennart Poettering log_warning_errno(r, "Failed to vacuum %s, ignoring: %m", p);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringint server_vacuum(Server *s, bool verbose, bool patch_min_use) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering do_vacuum(s, s->system_journal, &s->system_metrics, "/var/log/journal/", "System journal", verbose, patch_min_use);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering do_vacuum(s, s->runtime_journal, &s->runtime_metrics, "/run/log/journal/", "Runtime journal", verbose, patch_min_use);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringstatic void server_cache_machine_id(Server *s) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek sd_id128_to_string(id, stpcpy(s->machine_id_field, "_MACHINE_ID="));
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekstatic void server_cache_boot_id(Server *s) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sd_id128_to_string(id, stpcpy(s->boot_id_field, "_BOOT_ID="));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringstatic void server_cache_hostname(Server *s) {
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poetteringstatic bool shall_try_append_again(JournalFile *f, int r) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering /* -E2BIG Hit configured limit
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -EFBIG Hit fs limit
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -EDQUOT Quota limit hit
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -ENOSPC Disk full
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering -EIO I/O error of some kind (mmap)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -EHOSTDOWN Other machine
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -EBUSY Unclean shutdown
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -EPROTONOSUPPORT Unsupported feature
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -EBADMSG Corrupted
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -ENODATA Truncated
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering -ESHUTDOWN Already archived
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering -EIDRM Journal file has been deleted */
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering log_debug("%s: Allocation limit reached, rotating.", f->path);
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering else if (r == -EHOSTDOWN)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_info("%s: Journal file from other machine, rotating.", f->path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering else if (r == -EBUSY)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_info("%s: Unclean shutdown, rotating.", f->path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_info("%s: Unsupported feature, rotating.", f->path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_warning("%s: Journal file corrupted, rotating.", f->path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering else if (r == -EIO)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_warning("%s: IO error, rotating.", f->path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering else if (r == -EIDRM)
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_warning("%s: Journal file has been deleted, rotating.", f->path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringstatic void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n, int priority) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (journal_file_rotate_suggested(f, s->max_file_usec)) {
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering server_vacuum(s, false, false);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering if (vacuumed || !shall_try_append_again(f, r)) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_error_errno(r, "Failed to write entry (%d items, %zu bytes), ignoring: %m", n, IOVEC_TOTAL_SIZE(iovec, n));
a7f7d1bde43fc825c49afea3f946f5b4b3d563e0Harald Hoyer server_vacuum(s, false, false);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_error_errno(r, "Failed to write entry (%d items, %zu bytes) despite vacuuming, ignoring: %m", n, IOVEC_TOTAL_SIZE(iovec, n));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering struct iovec *iovec, unsigned n, unsigned m,
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering char pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)],
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering uid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)],
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering gid[sizeof("_GID=") + DECIMAL_STR_MAX(gid_t)],
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering owner_uid[sizeof("_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)],
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)],
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering o_uid[sizeof("OBJECT_UID=") + DECIMAL_STR_MAX(uid_t)],
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering o_gid[sizeof("OBJECT_GID=") + DECIMAL_STR_MAX(gid_t)],
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering o_owner_uid[sizeof("OBJECT_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)];
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering uid_t realuid = 0, owner = 0, journal_uid;
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering char audit_session[sizeof("_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)],
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering audit_loginuid[sizeof("_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)],
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering o_audit_session[sizeof("OBJECT_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)],
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering o_audit_loginuid[sizeof("OBJECT_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)];
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering assert(n + N_IOVEC_META_FIELDS + (object_pid ? N_IOVEC_OBJECT_FIELDS : 0) <= m);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek sprintf(pid, "_PID="PID_FMT, ucred->pid);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], pid);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek sprintf(uid, "_UID="UID_FMT, ucred->uid);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], uid);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek sprintf(gid, "_GID="GID_FMT, ucred->gid);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], gid);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek r = get_process_comm(ucred->pid, &t);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek r = get_process_exe(ucred->pid, &t);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = get_process_cmdline(ucred->pid, 0, false, &t);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = audit_session_from_pid(ucred->pid, &audit);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sprintf(audit_session, "_AUDIT_SESSION=%"PRIu32, audit);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering IOVEC_SET_STRING(iovec[n++], audit_session);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = audit_loginuid_from_pid(ucred->pid, &loginuid);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sprintf(audit_loginuid, "_AUDIT_LOGINUID="UID_FMT, loginuid);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering IOVEC_SET_STRING(iovec[n++], audit_loginuid);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = cg_pid_get_path_shifted(ucred->pid, s->cgroup_root, &c);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek x = strjoina("_SYSTEMD_CGROUP=", c);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek r = cg_path_get_session(c, &t);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], session);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek sprintf(owner_uid, "_SYSTEMD_OWNER_UID="UID_FMT, owner);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], owner_uid);
e53fc357a9bb9d0a5362ccc4246d598cb0febd5eLennart Poettering if (cg_path_get_unit(c, &t) >= 0) {
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek } else if (unit_id && !session) {
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek x = strjoina("_SYSTEMD_UNIT=", unit_id);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek if (cg_path_get_user_unit(c, &t) >= 0) {
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek x = strjoina("_SYSTEMD_USER_UNIT=", t);
if (cg_path_get_slice(c, &t) >= 0) {
free(t);
free(c);
} else if (unit_id) {
#ifdef HAVE_SELINUX
if (mac_selinux_use()) {
if (label) {
assert(n <= m);
if (object_pid) {
free(t);
free(t);
free(t);
#ifdef HAVE_AUDIT
r = cg_path_get_session(c, &t);
free(t);
if (cg_path_get_unit(c, &t) >= 0) {
free(t);
if (cg_path_get_user_unit(c, &t) >= 0) {
free(t);
free(c);
assert(n <= m);
if (tv) {
assert(n <= m);
journal_uid = 0;
assert(s);
void server_dispatch_message(
Server *s,
const char *unit_id,
int priority,
int rl, r;
assert(s);
if (!ucred)
goto finish;
goto finish;
if (rl == 0)
const char *fn;
if (!s->system_journal &&
r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal);
(void) determine_space_for(s, &s->system_metrics, "/var/log/journal/", "System journal", true, true, NULL, NULL);
if (!s->runtime_journal &&
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) {
(void) determine_space_for(s, &s->runtime_metrics, "/run/log/journal/", "Runtime journal", true, true, NULL, NULL);
assert(s);
if (!s->runtime_journal)
(void) system_journal_open(s, true);
if (!s->system_journal)
SD_JOURNAL_FOREACH(j) {
JournalFile *f;
f = j->current_file;
goto finish;
goto finish;
server_rotate(s);
server_vacuum(s, false, false);
if (!s->system_journal) {
r = -EIO;
goto finish;
goto finish;
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);
ssize_t n;
unsigned n_fds = 0;
} control = {};
assert(s);
return -EIO;
return log_oom();
s->buffer[n] = 0;
if (n > 0 && n_fds == 0)
else if (n_fds > 0)
if (n > 0 && n_fds == 0)
else if (n_fds > 0)
if (n > 0 && n_fds == 0)
else if (n_fds > 0)
static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
assert(s);
server_sync(s);
server_vacuum(s, false, false);
static int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
assert(s);
server_rotate(s);
server_vacuum(s, true, true);
static int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
assert(s);
static int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
assert(s);
server_sync(s);
assert(s);
assert(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGRTMIN+1, -1) >= 0);
p = line;
s->forward_to_syslog = r;
s->forward_to_kmsg = r;
s->forward_to_console = r;
s->forward_to_wall = r;
assert(s);
assert(s);
server_sync(s);
assert(s);
server_sync(s);
if (s->sync_scheduled)
if (s->sync_interval_usec > 0) {
if (!s->sync_event_source) {
r = sd_event_add_time(
s->event,
&s->sync_event_source,
when, 0,
server_dispatch_sync, s);
s->sync_scheduled = true;
static int dispatch_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
assert(s);
assert(s);
if (s->hostname_fd < 0)
r = sd_event_add_io(s->event, &s->hostname_event_source, s->hostname_fd, 0, dispatch_hostname_change, s);
if (r == -EPERM) {
assert(s);
if (!s->sent_notify_ready) {
ssize_t l;
s->sent_notify_ready = true;
} else if (s->send_watchdog) {
ssize_t l;
s->send_watchdog = false;
} else if (s->stdout_streams_notify_queue)
assert(s);
s->send_watchdog = true;
assert(s);
return -EINVAL;
return -EINVAL;
if (s->notify_fd < 0)
r = sd_event_add_io(s->event, &s->notify_event_source, s->notify_fd, EPOLLOUT, dispatch_notify_event, s);
s->send_watchdog = true;
r = sd_event_add_time(s->event, &s->watchdog_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + s->watchdog_usec/2, s->watchdog_usec/4, dispatch_watchdog, s);
int n, r, fd;
bool no_sockets;
assert(s);
zero(*s);
s->syslog_fd = s->native_fd = s->stdout_fd = s->dev_kmsg_fd = s->audit_fd = s->hostname_fd = s->notify_fd = -1;
s->compress = true;
s->seal = true;
s->sync_scheduled = false;
s->forward_to_wall = true;
if (!s->user_journals)
return log_oom();
if (!s->mmap)
return log_oom();
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;
if (s->audit_fd >= 0) {
return -EINVAL;
if (!fds) {
if (!fds)
return log_oom();
return log_oom();
/* systemd-journald.socket: /run/systemd/journal/stdout */
r = server_open_stdout_socket(s);
/* systemd-journald-dev-log.socket: /run/systemd/journal/dev-log */
r = server_open_syslog_socket(s);
/* systemd-journald.socket: /run/systemd/journal/socket */
r = server_open_native_socket(s);
r = server_open_dev_kmsg(s);
r = server_open_audit(s);
r = server_open_kernel_seqnum(s);
r = server_open_hostname(s);
r = setup_signals(s);
if (!s->udev)
return -ENOMEM;
if (!s->rate_limit)
return -ENOMEM;
(void) server_connect_notify(s);
return system_journal_open(s, false);
#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->rate_limit)
if (s->kernel_seqnum)
if (s->mmap)
DEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
DEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting");