journald-server.c revision ff82c36c792a23a03994af2ae40cbd441e128bb4
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/>.
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering#define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE)
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering#define DEFAULT_RATE_LIMIT_INTERVAL (30*USEC_PER_SEC)
9bf3b53533cdc9b95c921b71da755401f223f765Lennart Poettering#define DEFAULT_MAX_FILE_USEC USEC_PER_MONTH
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering#define RECHECK_SPACE_USEC (30*USEC_PER_SEC)
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt const char *p;
e3b9d9c8027a7c4c55cf1614e0fe9423fad69e8fZbigniew Jędrzejewski-Szmek if (!verbose && s->cached_space_timestamp + RECHECK_SPACE_USEC > ts) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering p = strjoina(path, SERVER_MACHINE_ID(s));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to open %s: %m", p);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek return log_error_errno(errno, "Failed to fstatvfs(%s): %m", p);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek FOREACH_DIRENT_ALL(de, d, break) {
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek 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 /* 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
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew 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);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek s->cached_space_limit = MIN(MAX(sum + avail, metrics->min_use), metrics->max_use);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek s->cached_space_available = LESS_BY(s->cached_space_limit, sum);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek s->cached_space_timestamp = ts;
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek char fb1[FORMAT_BYTES_MAX], fb2[FORMAT_BYTES_MAX], fb3[FORMAT_BYTES_MAX],
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew 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) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering return determine_space_for(s, metrics, path, name, verbose, patch_min_use, available, limit);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringstatic void server_add_acls(JournalFile *f, uid_t uid) {
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek r = add_acls_for_user(f->fd, uid);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_warning_errno(r, "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 */
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek 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);
c7332b0844e28d9b70c3c763b929f105c1056fe8Zbigniew Jędrzejewski-Szmek r = ordered_hashmap_put(s->user_journals, UID_TO_PTR(uid), f);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = journal_file_rotate(f, s->compress, seal);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_error_errno(r, "Failed to rotate %s: %m", (*f)->path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering log_error_errno(r, "Failed to create new %s journal: %m", name);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering (void) do_rotate(s, &s->runtime_journal, "runtime", false, 0);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering (void) do_rotate(s, &s->system_journal, "system", s->seal, 0);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ORDERED_HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = do_rotate(s, &f, "user", s->seal, PTR_TO_UID(k));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ordered_hashmap_replace(s->user_journals, k, f);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering /* Old file has been closed and deallocated */
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering ordered_hashmap_remove(s->user_journals, k);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek 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);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_warning_errno(r, "Failed to sync user journal, ignoring: %m");
eb56eb9b40950f1edcffdb7313f8de4f8572a6d5Michal Schmidt 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");
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek p = strjoina(path, SERVER_MACHINE_ID(s));
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek (void) determine_space_for(s, metrics, path, name, verbose, patch_min_use, NULL, &limit);
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering r = journal_directory_vacuum(p, limit, metrics->n_max_files, s->max_retention_usec, &s->oldest_file_usec, verbose);
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering if (r < 0 && r != -ENOENT)
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering log_warning_errno(r, "Failed to vacuum %s, ignoring: %m", p);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmekint server_vacuum(Server *s, bool verbose, bool patch_min_use) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek do_vacuum(s, s->system_journal, &s->system_metrics, "/var/log/journal/", "System journal", verbose, patch_min_use);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek 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) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sd_id128_to_string(id, stpcpy(s->machine_id_field, "_MACHINE_ID="));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poetteringstatic void server_cache_boot_id(Server *s) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sd_id128_to_string(id, stpcpy(s->boot_id_field, "_BOOT_ID="));
e3b9d9c8027a7c4c55cf1614e0fe9423fad69e8fZbigniew Jędrzejewski-Szmekstatic void server_cache_hostname(Server *s) {
80343dc19a9bcd703275ad2ad88f43e5310559d6Zbigniew Jędrzejewski-Szmek x = strappend("_HOSTNAME=", t);
d4205751d4643c272059a3728045929dd0e5e800Lennart 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
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek -ENOSPC Disk full
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek -EIO I/O error of some kind (mmap)
18cd5fe99f70a55a2d6f2303d6ee0624942695b1Zbigniew Jędrzejewski-Szmek -EHOSTDOWN Other machine
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -EBUSY Unclean shutdown
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -EPROTONOSUPPORT Unsupported feature
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -EBADMSG Corrupted
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -ENODATA Truncated
7ff7394d9e4e9189c30fd018235e6b1728c6f2d0Zbigniew Jędrzejewski-Szmek -ESHUTDOWN Already archived
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering -EIDRM Journal file has been deleted */
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_debug("%s: Allocation limit reached, rotating.", f->path);
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek log_info("%s: Journal file from other machine, rotating.", f->path);
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 log_warning("%s: IO error, rotating.", f->path);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering else if (r == -EIDRM)
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek 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) {
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering if (journal_file_rotate_suggested(f, s->max_file_usec)) {
d4205751d4643c272059a3728045929dd0e5e800Lennart 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);
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart 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));
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering server_vacuum(s, false, false);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering 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)],
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart 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;
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering char audit_session[sizeof("_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)],
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart Poettering audit_loginuid[sizeof("_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)],
83f6936a018b08880670838756e0f4e9ea98b4a7Lennart 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);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sprintf(pid, "_PID="PID_FMT, ucred->pid);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sprintf(uid, "_UID="UID_FMT, ucred->uid);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sprintf(gid, "_GID="GID_FMT, ucred->gid);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering r = get_process_cmdline(ucred->pid, 0, false, &t);
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);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek 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 session = strjoina("_SYSTEMD_SESSION=", t);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], session);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (cg_path_get_owner_uid(c, &owner) >= 0) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering sprintf(owner_uid, "_SYSTEMD_OWNER_UID="UID_FMT, owner);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (cg_path_get_unit(c, &t) >= 0) {
844ec79b3c2f246114ea316ebe1f36044bdb688eZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering if (cg_path_get_user_unit(c, &t) >= 0) {
d4205751d4643c272059a3728045929dd0e5e800Lennart Poettering x = strjoina("_SYSTEMD_USER_UNIT=", unit_id);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek if (cg_path_get_slice(c, &t) >= 0) {
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek x = alloca(strlen("_SELINUX_CONTEXT=") + label_len + 1);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek *((char*) mempcpy(stpcpy(x, "_SELINUX_CONTEXT="), label, label_len)) = 0;
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek r = get_process_uid(object_pid, &object_uid);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek sprintf(o_uid, "OBJECT_UID="UID_FMT, object_uid);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], o_uid);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek r = get_process_gid(object_pid, &object_gid);
54b7254c1fa629937f92fd6fa34bdf127b696a00Zbigniew Jędrzejewski-Szmek sprintf(o_gid, "OBJECT_GID="GID_FMT, object_gid);
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");