d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek This file is part of systemd.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Copyright 2011 Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (at your option) any later version.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk#define DEFAULT_SYNC_INTERVAL_USEC (5*USEC_PER_MINUTE)
7f1ad696a273703789b624fe0b209fb63e953016Lennart Poettering#define DEFAULT_RATE_LIMIT_INTERVAL (30*USEC_PER_SEC)
e150e82097211f09b911c7784a89ef9efed713caMichał Bartoszkiewicz#define DEFAULT_MAX_FILE_USEC USEC_PER_MONTH
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering#define RECHECK_SPACE_USEC (30*USEC_PER_SEC)
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo/* The period to insert between posting changes for coalescing */
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo#define POST_CHANGE_TIMER_INTERVAL_USEC (250*USEC_PER_MSEC)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering const char *p;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (!verbose && s->cached_space_timestamp + RECHECK_SPACE_USEC > ts) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering p = strjoina(path, SERVER_MACHINE_ID(s));
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to open %s: %m", p);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (fstatvfs(dirfd(d), &ss) < 0)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return log_error_errno(errno, "Failed to fstatvfs(%s): %m", p);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!endswith(de->d_name, ".journal") &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek !endswith(de->d_name, ".journal~"))
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering log_debug_errno(errno, "Failed to stat %s/%s, ignoring: %m", p, de->d_name);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek sum += (uint64_t) st.st_blocks * 512UL;
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek /* If requested, then let's bump the min_use limit to the
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering * current usage on disk. We do this when starting up and
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering * first opening the journal files. This way sudden spikes in
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering * disk usage will not cause journald to vacuum files without
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering * bounds. Note that this means that only a restart of
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering * journald will make it reset this value. */
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering metrics->min_use = MAX(metrics->min_use, sum);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering avail = LESS_BY(ss_avail, metrics->keep_free);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering s->cached_space_limit = MIN(MAX(sum + avail, metrics->min_use), metrics->max_use);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering s->cached_space_available = LESS_BY(s->cached_space_limit, sum);
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek char fb1[FORMAT_BYTES_MAX], fb2[FORMAT_BYTES_MAX], fb3[FORMAT_BYTES_MAX],
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering fb4[FORMAT_BYTES_MAX], fb5[FORMAT_BYTES_MAX], fb6[FORMAT_BYTES_MAX];
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek format_bytes(fb1, sizeof(fb1), sum);
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek format_bytes(fb2, sizeof(fb2), metrics->max_use);
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek format_bytes(fb3, sizeof(fb3), metrics->keep_free);
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek format_bytes(fb4, sizeof(fb4), ss_avail);
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek format_bytes(fb5, sizeof(fb5), s->cached_space_limit);
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek format_bytes(fb6, sizeof(fb6), s->cached_space_available);
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek server_driver_message(s, SD_MESSAGE_JOURNAL_USAGE,
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek LOG_MESSAGE("%s (%s) is %s, max %s, %s free.",
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek "MAX_USE=%"PRIu64, metrics->max_use,
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek "DISK_KEEP_FREE=%"PRIu64, metrics->keep_free,
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek "DISK_KEEP_FREE_PRETTY=%s", fb3,
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek "DISK_AVAILABLE=%"PRIu64, ss_avail,
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek "DISK_AVAILABLE_PRETTY=%s", fb4,
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek "LIMIT=%"PRIu64, s->cached_space_limit,
282c5c4e422cb6e6685c870946d8b9bdf0879ad1Zbigniew Jędrzejewski-Szmek "AVAILABLE=%"PRIu64, s->cached_space_available,
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poetteringstatic int determine_space(Server *s, bool verbose, bool patch_min_use, uint64_t *available, uint64_t *limit) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering return determine_space_for(s, metrics, path, name, verbose, patch_min_use, available, limit);
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmekstatic void server_add_acls(JournalFile *f, uid_t uid) {
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek r = add_acls_for_user(f->fd, uid);
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek log_warning_errno(r, "Failed to set ACL on %s, ignoring: %m", f->path);
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo const char *fname,
089ed40bf4b1df0408c9123f7dfcaa23768668f5Vito Caputo r = journal_file_open_reliably(fname, flags, 0640, s->compress, seal, metrics, s->mmap, NULL, &f);
089ed40bf4b1df0408c9123f7dfcaa23768668f5Vito Caputo r = journal_file_open(fname, flags, 0640, s->compress, seal, metrics, s->mmap, NULL, &f);
e167d7fd8d5fe918b6d675e16aeca2c43398a5b2Lennart Poettering r = journal_file_enable_post_change_timer(f, s->event, POST_CHANGE_TIMER_INTERVAL_USEC);
7a24f3bf2fb181243a1957a0cdd54cd919396793Vito Caputo if (r < 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic JournalFile* find_journal(Server *s, uid_t uid) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* We split up user logs only on /var, not on /run. If the
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * runtime file is open, we write to it exclusively, in order
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * to guarantee proper order as soon as we flush /run to
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * /var and close the runtime file. */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_id128_get_machine(&machine);
4a0b58c4a30ecaa61202f845ed86f75b36370cd0Lennart Poettering f = ordered_hashmap_get(s->user_journals, UID_TO_PTR(uid));
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/user-"UID_FMT".journal",
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek SD_ID128_FORMAT_VAL(machine), uid) < 0)
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt while (ordered_hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Too many open? Then let's close one */
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt f = ordered_hashmap_steal_first(s->user_journals);
089ed40bf4b1df0408c9123f7dfcaa23768668f5Vito Caputo r = open_journal(s, true, p, O_RDWR|O_CREAT, s->seal, &s->system_metrics, &f);
4a0b58c4a30ecaa61202f845ed86f75b36370cd0Lennart Poettering r = ordered_hashmap_put(s->user_journals, UID_TO_PTR(uid), f);
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek r = journal_file_rotate(f, s->compress, seal);
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering log_error_errno(r, "Failed to rotate %s: %m", (*f)->path);
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering log_error_errno(r, "Failed to create new %s journal: %m", name);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering (void) do_rotate(s, &s->runtime_journal, "runtime", false, 0);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering (void) do_rotate(s, &s->system_journal, "system", s->seal, 0);
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt ORDERED_HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
4a0b58c4a30ecaa61202f845ed86f75b36370cd0Lennart Poettering r = do_rotate(s, &f, "user", s->seal, PTR_TO_UID(k));
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt ordered_hashmap_replace(s->user_journals, k, f);
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek /* Old file has been closed and deallocated */
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk r = journal_file_set_offline(s->system_journal);
65089b82401cd395786a7987c470056ff3f01151Lennart Poettering log_warning_errno(r, "Failed to sync system journal, ignoring: %m");
65c1d46b0923771955519329160a1e4c7cd027b0Lennart Poettering ORDERED_HASHMAP_FOREACH(f, s->user_journals, i) {
65089b82401cd395786a7987c470056ff3f01151Lennart Poettering log_warning_errno(r, "Failed to sync user journal, ignoring: %m");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = sd_event_source_set_enabled(s->sync_event_source, SD_EVENT_OFF);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to disable sync timer source: %m");
ea69bd41c5923f4f278a09bb7d8cb1abcfa122e1Lennart Poettering const char *p;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering p = strjoina(path, SERVER_MACHINE_ID(s));
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering (void) determine_space_for(s, metrics, path, name, verbose, patch_min_use, NULL, &limit);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering r = journal_directory_vacuum(p, limit, metrics->n_max_files, s->max_retention_usec, &s->oldest_file_usec, verbose);
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek if (r < 0 && r != -ENOENT)
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering log_warning_errno(r, "Failed to vacuum %s, ignoring: %m", p);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poetteringint server_vacuum(Server *s, bool verbose, bool patch_min_use) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering do_vacuum(s, s->system_journal, &s->system_metrics, "/var/log/journal/", "System journal", verbose, patch_min_use);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering do_vacuum(s, s->runtime_journal, &s->runtime_metrics, "/run/log/journal/", "Runtime journal", verbose, patch_min_use);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poetteringstatic void server_cache_machine_id(Server *s) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering sd_id128_to_string(id, stpcpy(s->machine_id_field, "_MACHINE_ID="));
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poetteringstatic void server_cache_boot_id(Server *s) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering sd_id128_to_string(id, stpcpy(s->boot_id_field, "_BOOT_ID="));
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poetteringstatic void server_cache_hostname(Server *s) {
8531ae707d4d0203e83304d4af948b8169a5fce1Lennart Poetteringstatic bool shall_try_append_again(JournalFile *f, int r) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* -E2BIG Hit configured limit
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek -EFBIG Hit fs limit
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek -EDQUOT Quota limit hit
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek -ENOSPC Disk full
fa6ac76083b8ffc1309876459f54f9f0e2843731Lennart Poettering -EIO I/O error of some kind (mmap)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek -EHOSTDOWN Other machine
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek -EBUSY Unclean shutdown
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek -EPROTONOSUPPORT Unsupported feature
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek -EBADMSG Corrupted
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek -ENODATA Truncated
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering -ESHUTDOWN Already archived
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering -EIDRM Journal file has been deleted */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_debug("%s: Allocation limit reached, rotating.", f->path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_info("%s: Journal file from other machine, rotating.", f->path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_info("%s: Unclean shutdown, rotating.", f->path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_info("%s: Unsupported feature, rotating.", f->path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_warning("%s: Journal file corrupted, rotating.", f->path);
fa6ac76083b8ffc1309876459f54f9f0e2843731Lennart Poettering else if (r == -EIO)
fa6ac76083b8ffc1309876459f54f9f0e2843731Lennart Poettering log_warning("%s: IO error, rotating.", f->path);
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering else if (r == -EIDRM)
2678031a179a9b91fc799f8ef951a548c66c4b49Lennart Poettering log_warning("%s: Journal file has been deleted, rotating.", f->path);
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poetteringstatic void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n, int priority) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (journal_file_rotate_suggested(f, s->max_file_usec)) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->path);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering server_vacuum(s, false, false);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk if (r >= 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (vacuumed || !shall_try_append_again(f, r)) {
8266e1c04db8cabe3c68510a0c1f07c09ecdb2e8Lennart Poettering log_error_errno(r, "Failed to write entry (%d items, %zu bytes), ignoring: %m", n, IOVEC_TOTAL_SIZE(iovec, n));
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering server_vacuum(s, false, false);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
8266e1c04db8cabe3c68510a0c1f07c09ecdb2e8Lennart Poettering log_error_errno(r, "Failed to write entry (%d items, %zu bytes) despite vacuuming, ignoring: %m", n, IOVEC_TOTAL_SIZE(iovec, n));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic void dispatch_message_real(
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek struct iovec *iovec, unsigned n, unsigned m,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const char *label, size_t label_len,
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek char pid[sizeof("_PID=") + DECIMAL_STR_MAX(pid_t)],
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering uid[sizeof("_UID=") + DECIMAL_STR_MAX(uid_t)],
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering gid[sizeof("_GID=") + DECIMAL_STR_MAX(gid_t)],
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering owner_uid[sizeof("_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)],
d378991747d67fff1d4dc39e7fb2bc8f49f1b561Mirco Tischler source_time[sizeof("_SOURCE_REALTIME_TIMESTAMP=") + DECIMAL_STR_MAX(usec_t)],
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek o_uid[sizeof("OBJECT_UID=") + DECIMAL_STR_MAX(uid_t)],
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek o_gid[sizeof("OBJECT_GID=") + DECIMAL_STR_MAX(gid_t)],
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek o_owner_uid[sizeof("OBJECT_SYSTEMD_OWNER_UID=") + DECIMAL_STR_MAX(uid_t)];
82499507b369fea3033a74c22813bf423301aef4Lennart Poettering uid_t realuid = 0, owner = 0, journal_uid;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek char audit_session[sizeof("_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)],
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek audit_loginuid[sizeof("_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)],
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek o_audit_session[sizeof("OBJECT_AUDIT_SESSION=") + DECIMAL_STR_MAX(uint32_t)],
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek o_audit_loginuid[sizeof("OBJECT_AUDIT_LOGINUID=") + DECIMAL_STR_MAX(uid_t)];
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek assert(n + N_IOVEC_META_FIELDS + (object_pid ? N_IOVEC_OBJECT_FIELDS : 0) <= m);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek sprintf(pid, "_PID="PID_FMT, ucred->pid);
c2457105d76e3daf159f554a9bafb9751b23d756Holger Hans Peter Freyther IOVEC_SET_STRING(iovec[n++], pid);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek sprintf(uid, "_UID="UID_FMT, ucred->uid);
c2457105d76e3daf159f554a9bafb9751b23d756Holger Hans Peter Freyther IOVEC_SET_STRING(iovec[n++], uid);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek sprintf(gid, "_GID="GID_FMT, ucred->gid);
c2457105d76e3daf159f554a9bafb9751b23d756Holger Hans Peter Freyther IOVEC_SET_STRING(iovec[n++], gid);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = get_process_comm(ucred->pid, &t);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = get_process_exe(ucred->pid, &t);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
9bdbc2e2ec523dbefe1c1c7e164b5544aff0b185Lukas Nykryn r = get_process_cmdline(ucred->pid, 0, false, &t);
3a83211689bdf4ab617a4fb79e11980c50918123Shawn Landden if (r >= 0) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = audit_session_from_pid(ucred->pid, &audit);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek sprintf(audit_session, "_AUDIT_SESSION=%"PRIu32, audit);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering IOVEC_SET_STRING(iovec[n++], audit_session);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = audit_loginuid_from_pid(ucred->pid, &loginuid);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek sprintf(audit_loginuid, "_AUDIT_LOGINUID="UID_FMT, loginuid);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering IOVEC_SET_STRING(iovec[n++], audit_loginuid);
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering r = cg_pid_get_path_shifted(ucred->pid, s->cgroup_root, &c);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering session = strjoina("_SYSTEMD_SESSION=", t);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], session);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering if (cg_path_get_owner_uid(c, &owner) >= 0) {
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek sprintf(owner_uid, "_SYSTEMD_OWNER_UID="UID_FMT, owner);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], owner_uid);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering if (cg_path_get_unit(c, &t) >= 0) {
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering if (cg_path_get_user_unit(c, &t) >= 0) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering x = strjoina("_SYSTEMD_USER_UNIT=", unit_id);
0a244b8ecb6dfcb381fe831dc2aa9bacb2c12975Lennart Poettering if (cg_path_get_slice(c, &t) >= 0) {
2d43b190901902dbd98ccea77c1d1ddc9e2a9955Dan McGee } else if (unit_id) {
f8294e4175918117ca6c131720bcf287eadcd029Josh Triplett x = alloca(strlen("_SELINUX_CONTEXT=") + label_len + 1);
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering *((char*) mempcpy(stpcpy(x, "_SELINUX_CONTEXT="), label, label_len)) = 0;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = get_process_uid(object_pid, &object_uid);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek sprintf(o_uid, "OBJECT_UID="UID_FMT, object_uid);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], o_uid);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = get_process_gid(object_pid, &object_gid);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek sprintf(o_gid, "OBJECT_GID="GID_FMT, object_gid);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], o_gid);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = get_process_comm(object_pid, &t);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = get_process_exe(object_pid, &t);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = get_process_cmdline(object_pid, 0, false, &t);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = audit_session_from_pid(object_pid, &audit);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek sprintf(o_audit_session, "OBJECT_AUDIT_SESSION=%"PRIu32, audit);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], o_audit_session);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = audit_loginuid_from_pid(object_pid, &loginuid);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek sprintf(o_audit_loginuid, "OBJECT_AUDIT_LOGINUID="UID_FMT, loginuid);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], o_audit_loginuid);
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering r = cg_pid_get_path_shifted(object_pid, s->cgroup_root, &c);
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering x = strjoina("OBJECT_SYSTEMD_CGROUP=", c);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering x = strjoina("OBJECT_SYSTEMD_SESSION=", t);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (cg_path_get_owner_uid(c, &owner) >= 0) {
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek sprintf(o_owner_uid, "OBJECT_SYSTEMD_OWNER_UID="UID_FMT, owner);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], o_owner_uid);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (cg_path_get_unit(c, &t) >= 0) {
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering if (cg_path_get_user_unit(c, &t) >= 0) {
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering x = strjoina("OBJECT_SYSTEMD_USER_UNIT=", t);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], x);
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering sprintf(source_time, "_SOURCE_REALTIME_TIMESTAMP=%llu", (unsigned long long) timeval_load(tv));
a569398925430de1f8479262e8ab39502054f2e9Lennart Poettering IOVEC_SET_STRING(iovec[n++], source_time);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Note that strictly speaking storing the boot id here is
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * redundant since the entry includes this in-line
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * anyway. However, we need this indexed, too. */
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering IOVEC_SET_STRING(iovec[n++], s->boot_id_field);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering IOVEC_SET_STRING(iovec[n++], s->machine_id_field);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering IOVEC_SET_STRING(iovec[n++], s->hostname_field);
40adcda869bda55f44b57fd3a2bd71d006dfb51bLennart Poettering /* Split up strictly by any UID */
82499507b369fea3033a74c22813bf423301aef4Lennart Poettering else if (s->split_mode == SPLIT_LOGIN && realuid > 0 && owner_valid && owner > 0)
edc3797f7cd9e37c24e5241cac3263e7c918f732Lennart Poettering /* Split up by login UIDs. We do this only if the
edc3797f7cd9e37c24e5241cac3263e7c918f732Lennart Poettering * realuid is not root, in order not to accidentally
edc3797f7cd9e37c24e5241cac3263e7c918f732Lennart Poettering * leak privileged information to the user that is
edc3797f7cd9e37c24e5241cac3263e7c918f732Lennart Poettering * logged by a privileged process that is part of an
7517e17443225fafea86b21e42a36af69feb1dbcTorstein Husebø * unprivileged session. */
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering write_to_journal(s, journal_uid, iovec, n, priority);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekvoid server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) {
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek struct iovec iovec[N_IOVEC_META_FIELDS + 5 + N_IOVEC_PAYLOAD_FIELDS];
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek unsigned n = 0, m;
b6fa25552e538eca207072e12d223e3523b21a19Evgeny Vereshchagin IOVEC_SET_STRING(iovec[n++], "SYSLOG_FACILITY=3");
b6fa25552e538eca207072e12d223e3523b21a19Evgeny Vereshchagin IOVEC_SET_STRING(iovec[n++], "SYSLOG_IDENTIFIER=systemd-journald");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=driver");
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], "PRIORITY=6");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!sd_id128_equal(message_id, SD_ID128_NULL)) {
e2cc6eca73cd1df8be552d7c23f9ff3d69c06f1eLennart Poettering snprintf(mid, sizeof(mid), LOG_MESSAGE_ID(message_id));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], mid);
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, false, 0, format, ap);
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek /* Error handling below */
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek /* We failed to format the message. Emit a warning instead. */
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek xsprintf(buf, "MESSAGE=Entry printing failed: %s", strerror(-r));
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], "PRIORITY=4");
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], buf);
32917e33882778cf2ec6dd54b1e1082266fb072eZbigniew Jędrzejewski-Szmek dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek struct iovec *iovec, unsigned n, unsigned m,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const char *label, size_t label_len,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (LOG_PRI(priority) > s->max_level_store)
2f5df74a5ec135ab2baebf26af6f088e5b4b8205Holger Hans Peter Freyther /* Stop early in case the information will not be stored
2f5df74a5ec135ab2baebf26af6f088e5b4b8205Holger Hans Peter Freyther * in a journal. */
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering r = cg_pid_get_path_shifted(ucred->pid, s->cgroup_root, &path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* example: /user/lennart/3/foobar
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * So let's cut of everything past the third /, since that is
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * where user directories start */
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering (void) determine_space(s, false, false, &available, NULL);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering rl = journal_rate_limit_test(s->rate_limit, path, priority & LOG_PRIMASK, available);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Write a suppression message if we suppressed something */
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek server_driver_message(s, SD_MESSAGE_JOURNAL_DROPPED,
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek LOG_MESSAGE("Suppressed %u messages from %s", rl - 1, path),
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, priority, object_pid);
caa2f4c0c9613b2e02aafa308c8fb092576014a9Zbigniew Jędrzejewski-Szmekstatic int system_journal_open(Server *s, bool flush_requested) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
caa2f4c0c9613b2e02aafa308c8fb092576014a9Zbigniew Jędrzejewski-Szmek || access("/run/systemd/journal/flushed", F_OK) >= 0)) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* If in auto mode: first try to create the machine
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * path, but not the prefix.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * If in persistent mode: create /var/log/journal and
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * the machine path */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->storage == STORAGE_PERSISTENT)
ac892057c2ddd8f06323c73ebd80423cc3ec7190Dimitri John Ledkov (void) mkdir_p("/var/log/journal/", 0755);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering fn = strjoina("/var/log/journal/", SERVER_MACHINE_ID(s));
089ed40bf4b1df0408c9123f7dfcaa23768668f5Vito Caputo r = open_journal(s, true, fn, O_RDWR|O_CREAT, s->seal, &s->system_metrics, &s->system_journal);
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek server_add_acls(s->system_journal, 0);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering (void) determine_space_for(s, &s->system_metrics, "/var/log/journal/", "System journal", true, true, NULL, NULL);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering } else if (r < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to open system journal: %m");
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering fn = strjoina("/run/log/journal/", SERVER_MACHINE_ID(s), "/system.journal");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Try to open the runtime journal, but only
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * if it already exists, so that we can flush
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * it into the system journal */
089ed40bf4b1df0408c9123f7dfcaa23768668f5Vito Caputo r = open_journal(s, false, fn, O_RDWR, false, &s->runtime_metrics, &s->runtime_journal);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to open runtime journal: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* OK, we really need the runtime journal, so create
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * it if necessary. */
089ed40bf4b1df0408c9123f7dfcaa23768668f5Vito Caputo r = open_journal(s, true, fn, O_RDWR|O_CREAT, false, &s->runtime_metrics, &s->runtime_journal);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return log_error_errno(r, "Failed to open runtime journal: %m");
5c3bde3fa8613e09e694198862ea9038566af422Zbigniew Jędrzejewski-Szmek server_add_acls(s->runtime_journal, 0);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering (void) determine_space_for(s, &s->runtime_metrics, "/run/log/journal/", "Runtime journal", true, true, NULL, NULL);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint server_flush_to_var(Server *s) {
fbb634117d0b0ebd5b105e65b141e75ae9af7f8fLennart Poettering unsigned n = 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (s->storage != STORAGE_AUTO &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->storage != STORAGE_PERSISTENT)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_debug("Flushing to /var...");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_id128_get_machine(&machine);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_journal_open(&j, SD_JOURNAL_RUNTIME_ONLY);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return log_error_errno(r, "Failed to read runtime journal: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert(f && f->current_offset > 0);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!shall_try_append_again(s->system_journal, r)) {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering server_vacuum(s, false, false);
253f59dff9c93ee1d2c33444b5715e42bc1c6889Lennart Poettering log_notice("Didn't flush runtime journal since rotation of system journal wasn't successful.");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek journal_file_post_change(s->system_journal);
804ae586d475d77946debb22c1bc9ee049d4750cLennart Poettering s->runtime_journal = journal_file_close(s->runtime_journal);
c6878637502b1717a110a9a7e8bba32a8583fcdfLennart Poettering (void) rm_rf("/run/log/journal", REMOVE_ROOT);
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek server_driver_message(s, SD_ID128_NULL,
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek LOG_MESSAGE("Time spent on flushing to /var is %s for %u entries.",
8a03c9ef744e13dc700a7e7ca6cae8afdcf0d71cZbigniew Jędrzejewski-Szmek format_timespan(ts, sizeof(ts), now(CLOCK_MONOTONIC) - start, 0),
8531ae707d4d0203e83304d4af948b8169a5fce1Lennart Poetteringint server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering /* We use NAME_MAX space for the SELinux label
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering * here. The kernel currently enforces no
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering * limit, but according to suggestions from
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering * the SELinux people this will change and it
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering * will probably be identical to NAME_MAX. For
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering * now we use that, but this should be updated
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering * one day when the final limit is known. */
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering CMSG_SPACE(NAME_MAX)]; /* selinux label */
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering assert(fd == s->native_fd || fd == s->syslog_fd || fd == s->audit_fd);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_error("Got invalid event from epoll for datagram fd: %"PRIx32, revents);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering /* Try to get the right size, if we can. (Not all
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering * sockets support SIOCINQ, hence we just try, but
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering * don't rely on it. */
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering /* Fix it up, if it is too small. We use the same fixed value as auditd here. Awful! */
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering ALIGN(sizeof(struct nlmsghdr)) + ALIGN((size_t) MAX_AUDIT_MESSAGE_LENGTH)) + 1);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (!GREEDY_REALLOC(s->buffer, s->buffer_size, m))
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering iovec.iov_len = s->buffer_size - 1; /* Leave room for trailing NUL we add later */
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering n = recvmsg(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering return log_error_errno(errno, "recvmsg() failed: %m");
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering else if (cmsg->cmsg_level == SOL_SOCKET &&
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering label_len = cmsg->cmsg_len - CMSG_LEN(0);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering } else if (cmsg->cmsg_level == SOL_SOCKET &&
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering else if (cmsg->cmsg_level == SOL_SOCKET &&
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering /* And a trailing NUL, just in case */
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (n > 0 && n_fds == 0)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering server_process_syslog_message(s, strstrip(s->buffer), ucred, tv, label, label_len);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering log_warning("Got file descriptors via syslog socket. Ignoring.");
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (n > 0 && n_fds == 0)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering server_process_native_message(s, s->buffer, n, ucred, tv, label, label_len);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering server_process_native_file(s, fds[0], ucred, tv, label, label_len);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering log_warning("Got too many file descriptors via native socket. Ignoring.");
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering if (n > 0 && n_fds == 0)
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering server_process_audit_message(s, s->buffer, n, ucred, &sa, msghdr.msg_namelen);
a315ac4e076c4ce7ce3e5c95792cf916d5e918c5Lennart Poettering log_warning("Got file descriptors via audit socket. Ignoring.");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringstatic int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering log_info("Received request to flush runtime journal from PID " PID_FMT, si->ssi_pid);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering server_vacuum(s, false, false);
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering r = touch("/run/systemd/journal/flushed");
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering log_warning_errno(r, "Failed to touch /run/systemd/journal/flushed, ignoring: %m");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringstatic int dispatch_sigusr2(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering log_info("Received request to rotate journal from PID " PID_FMT, si->ssi_pid);
dbd6e31cf91ab86a4a2fffeb50ccef211da3126dLennart Poettering /* Let clients know when the most recent rotation happened. */
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering r = write_timestamp_file_atomic("/run/systemd/journal/rotated", now(CLOCK_MONOTONIC));
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering log_warning_errno(r, "Failed to write /run/systemd/journal/rotated, ignoring: %m");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringstatic int dispatch_sigterm(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
4daf54a851e4fb7ed1a13c3117bba12528fd2c7fZbigniew Jędrzejewski-Szmek log_received_signal(LOG_INFO, si);
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poetteringstatic int dispatch_sigrtmin1(sd_event_source *es, const struct signalfd_siginfo *si, void *userdata) {
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering log_debug("Received request to sync from PID " PID_FMT, si->ssi_pid);
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering /* Let clients know when the most recent sync happened. */
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering r = write_timestamp_file_atomic("/run/systemd/journal/synced", now(CLOCK_MONOTONIC));
33d52ab92f2f0bfd706e6f343d172618d1e03f3dLennart Poettering log_warning_errno(r, "Failed to write /run/systemd/journal/synced, ignoring: %m");
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering assert(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGRTMIN+1, -1) >= 0);
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering r = sd_event_add_signal(s->event, &s->sigusr1_event_source, SIGUSR1, dispatch_sigusr1, s);
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering r = sd_event_add_signal(s->event, &s->sigusr2_event_source, SIGUSR2, dispatch_sigusr2, s);
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering r = sd_event_add_signal(s->event, &s->sigterm_event_source, SIGTERM, dispatch_sigterm, s);
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering /* Let's process SIGTERM late, so that we flush all queued
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering * messages to disk before we exit */
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering r = sd_event_source_set_priority(s->sigterm_event_source, SD_EVENT_PRIORITY_NORMAL+20);
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering /* When journald is invoked on the terminal (when debugging),
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering * it's useful if C-c is handled equivalent to SIGTERM. */
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering r = sd_event_add_signal(s->event, &s->sigint_event_source, SIGINT, dispatch_sigterm, s);
b374689c02c681671a3c3c0b0fd3add32386b442Lennart Poettering r = sd_event_source_set_priority(s->sigint_event_source, SD_EVENT_PRIORITY_NORMAL+20);
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering /* SIGRTMIN+1 causes an immediate sync. We process this very
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering * late, so that everything else queued at this point is
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering * really written to disk. Clients can watch
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering * /run/systemd/journal/synced with inotify until its mtime
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering * changes to see when a sync happened. */
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering r = sd_event_add_signal(s->event, &s->sigrtmin1_event_source, SIGRTMIN+1, dispatch_sigrtmin1, s);
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering r = sd_event_source_set_priority(s->sigrtmin1_event_source, SD_EVENT_PRIORITY_NORMAL+15);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int server_parse_proc_cmdline(Server *s) {
d581d9d91fa5c42ce7828a7d0b1334d370cf1670Susant Sahani const char *p;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to read /proc/cmdline, ignoring: %m");
ff82c36c792a23a03994af2ae40cbd441e128bb4Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *word = NULL;
d581d9d91fa5c42ce7828a7d0b1334d370cf1670Susant Sahani return log_error_errno(r, "Failed to parse journald syntax \"%s\": %m", line);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (startswith(word, "systemd.journald.forward_to_syslog=")) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_warning("Failed to parse forward to syslog switch %s. Ignoring.", word + 35);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (startswith(word, "systemd.journald.forward_to_kmsg=")) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_warning("Failed to parse forward to kmsg switch %s. Ignoring.", word + 33);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (startswith(word, "systemd.journald.forward_to_console=")) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_warning("Failed to parse forward to console switch %s. Ignoring.", word + 36);
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen } else if (startswith(word, "systemd.journald.forward_to_wall=")) {
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen log_warning("Failed to parse forward to wall switch %s. Ignoring.", word + 33);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (startswith(word, "systemd.journald"))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_warning("Invalid systemd.journald parameter. Ignoring.");
804ae586d475d77946debb22c1bc9ee049d4750cLennart Poettering /* do not warn about state here, since probably systemd already did */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int server_parse_config_file(Server *s) {
75eb615480afd787fa412f0a529523f568f79b26Lennart Poettering return config_parse_many(PKGSYSCONFDIR "/journald.conf",
75eb615480afd787fa412f0a529523f568f79b26Lennart Poettering CONF_PATHS_NULSTR("systemd/journald.conf.d"),
a9edaeff8481573764288ccf7e433a95b6dc7c03Josh Triplett config_item_perf_lookup, journald_gperf_lookup,
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringstatic int server_dispatch_sync(sd_event_source *es, usec_t t, void *userdata) {
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poetteringint server_schedule_sync(Server *s, int priority) {
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering /* Immediately sync to disk when this is of priority CRIT, ALERT, EMERG */
6a0f1f6d5af7c7300d3db7a0ba2b068f8abd222bLennart Poettering r = sd_event_now(s->event, CLOCK_MONOTONIC, &when);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = sd_event_source_set_priority(s->sync_event_source, SD_EVENT_PRIORITY_IMPORTANT);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = sd_event_source_set_time(s->sync_event_source, when);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = sd_event_source_set_enabled(s->sync_event_source, SD_EVENT_ONESHOT);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poetteringstatic int dispatch_hostname_change(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poetteringstatic int server_open_hostname(Server *s) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering s->hostname_fd = open("/proc/sys/kernel/hostname", O_RDONLY|O_CLOEXEC|O_NDELAY|O_NOCTTY);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "Failed to open /proc/sys/kernel/hostname: %m");
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering r = sd_event_add_io(s->event, &s->hostname_event_source, s->hostname_fd, 0, dispatch_hostname_change, s);
28def94cc8fd4394b20e2155d7130166662343c4Dave Reisner /* kernels prior to 3.2 don't support polling this file. Ignore
28def94cc8fd4394b20e2155d7130166662343c4Dave Reisner * the failure. */
e53fc357a9bb9d0a5362ccc4246d598cb0febd5eLennart Poettering log_warning_errno(r, "Failed to register hostname fd in event loop, ignoring: %m");
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering s->hostname_fd = safe_close(s->hostname_fd);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return log_error_errno(r, "Failed to register hostname fd in event loop: %m");
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering r = sd_event_source_set_priority(s->hostname_event_source, SD_EVENT_PRIORITY_IMPORTANT-10);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return log_error_errno(r, "Failed to adjust priority of host name event source: %m");
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringstatic int dispatch_notify_event(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering /* The $NOTIFY_SOCKET is writable again, now send exactly one
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering * message on it. Either it's the wtachdog event, the initial
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering * READY=1 event or an stdout stream event. If there's nothing
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering * to write anymore, turn our event source off. The next time
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering * there's something to send it will be turned on again. */
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering static const char p[] =
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering "STATUS=Processing requests...";
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering l = send(s->notify_fd, p, strlen(p), MSG_DONTWAIT);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return log_error_errno(errno, "Failed to send READY=1 notification message: %m");
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering } else if (s->send_watchdog) {
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering static const char p[] =
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering l = send(s->notify_fd, p, strlen(p), MSG_DONTWAIT);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering return log_error_errno(errno, "Failed to send WATCHDOG=1 notification message: %m");
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering log_debug("Sent WATCHDOG=1 notification.");
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering } else if (s->stdout_streams_notify_queue)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering /* Dispatch one stream notification event */
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering stdout_stream_send_notify(s->stdout_streams_notify_queue);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering /* Leave us enabled if there's still more to to do. */
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering if (s->send_watchdog || s->stdout_streams_notify_queue)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering /* There was nothing to do anymore, let's turn ourselves off. */
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering r = sd_event_source_set_enabled(es, SD_EVENT_OFF);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return log_error_errno(r, "Failed to turn off notify event source: %m");
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poetteringstatic int dispatch_watchdog(sd_event_source *es, uint64_t usec, void *userdata) {
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering r = sd_event_source_set_enabled(s->notify_event_source, SD_EVENT_ON);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering log_warning_errno(r, "Failed to turn on notify event source: %m");
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering r = sd_event_source_set_time(s->watchdog_event_source, usec + s->watchdog_usec / 2);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering return log_error_errno(r, "Failed to restart watchdog event source: %m");
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering r = sd_event_source_set_enabled(s->watchdog_event_source, SD_EVENT_ON);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering return log_error_errno(r, "Failed to enable watchdog event source: %m");
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringstatic int server_connect_notify(Server *s) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering const char *e;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering So here's the problem: we'd like to send notification
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering messages to PID 1, but we cannot do that via sd_notify(),
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering since that's synchronous, and we might end up blocking on
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering it. Specifically: given that PID 1 might block on
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering dbus-daemon during IPC, and dbus-daemon is logging to us,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering and might hence block on us, we might end up in a deadlock
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if we block on sending PID 1 notification messages -- by
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering generating a full blocking circle. To avoid this, let's
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering create a non-blocking socket, and connect it to the
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering notification socket, and then wait for POLLOUT before we
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering send anything. This should efficiently avoid any deadlocks,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering as we'll never block on PID 1, hence PID 1 can safely block
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering on dbus-daemon which can safely block on us again.
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering Don't think that this issue is real? It is, see:
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering https://github.com/systemd/systemd/issues/1505
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if ((e[0] != '@' && e[0] != '/') || e[1] == 0) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering log_error("NOTIFY_SOCKET set to an invalid value: %s", e);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (strlen(e) > sizeof(sa.un.sun_path)) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering log_error("NOTIFY_SOCKET path too long: %s", e);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->notify_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return log_error_errno(errno, "Failed to create notify socket: %m");
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering (void) fd_inc_sndbuf(s->notify_fd, NOTIFY_SNDBUF_SIZE);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering strncpy(sa.un.sun_path, e, sizeof(sa.un.sun_path));
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering r = connect(s->notify_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(e));
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return log_error_errno(errno, "Failed to connect to notify socket: %m");
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering r = sd_event_add_io(s->event, &s->notify_event_source, s->notify_fd, EPOLLOUT, dispatch_notify_event, s);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return log_error_errno(r, "Failed to watch notification socket: %m");
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering if (sd_watchdog_enabled(false, &s->watchdog_usec) > 0) {
4de2402b603ea2f518f451d06f09e15aeae54fabLennart Poettering 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);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering return log_error_errno(r, "Failed to add watchdog time event: %m");
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering /* This should fire pretty soon, which we'll use to send the
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering * READY=1 event. */
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->syslog_fd = s->native_fd = s->stdout_fd = s->dev_kmsg_fd = s->audit_fd = s->hostname_fd = s->notify_fd = -1;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk s->sync_interval_usec = DEFAULT_SYNC_INTERVAL_USEC;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST;
e150e82097211f09b911c7784a89ef9efed713caMichał Bartoszkiewicz s->max_file_usec = DEFAULT_MAX_FILE_USEC;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->max_level_syslog = LOG_DEBUG;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s->max_level_console = LOG_INFO;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering journal_reset_metrics(&s->system_metrics);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering journal_reset_metrics(&s->runtime_metrics);
d288f79fb4a2fe4a93cf99f74dacd2cebd3f2440Zbigniew Jędrzejewski-Szmek if (!!s->rate_limit_interval ^ !!s->rate_limit_burst) {
b1389b0d0805392570085acc7cb10eafcf885405Zbigniew Jędrzejewski-Szmek log_debug("Setting both rate limit interval and burst from "USEC_FMT",%u to 0,0",
b1389b0d0805392570085acc7cb10eafcf885405Zbigniew Jędrzejewski-Szmek s->rate_limit_interval, s->rate_limit_burst);
d288f79fb4a2fe4a93cf99f74dacd2cebd3f2440Zbigniew Jędrzejewski-Szmek s->rate_limit_interval = s->rate_limit_burst = 0;
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poettering (void) mkdir_p("/run/systemd/journal", 0755);
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt s->user_journals = ordered_hashmap_new(NULL);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return log_error_errno(r, "Failed to create event loop: %m");
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return log_error_errno(n, "Failed to read listening file descriptors from environment: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/run/systemd/journal/socket", 0) > 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Too many native sockets passed.");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek } else if (sd_is_socket_unix(fd, SOCK_STREAM, 1, "/run/systemd/journal/stdout", 0) > 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Too many stdout sockets passed.");
03ee5c38cb0da193dd08733fb4c0c2809cee6a99Lennart Poettering } else if (sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/dev/log", 0) > 0 ||
03ee5c38cb0da193dd08733fb4c0c2809cee6a99Lennart Poettering sd_is_socket_unix(fd, SOCK_DGRAM, -1, "/run/systemd/journal/dev-log", 0) > 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Too many /dev/log sockets passed.");
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering } else if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering log_error("Too many audit sockets passed.");
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmek /* Try to restore streams, but don't bother if this fails */
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmek (void) server_restore_streams(s, fds);
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_warning("%u unknown file descriptors passed, closing.", fdset_size(fds));
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek no_sockets = s->native_fd < 0 && s->stdout_fd < 0 && s->syslog_fd < 0 && s->audit_fd < 0;
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek /* always open stdout, syslog, native, and kmsg sockets */
37b7affefde5443680d73642a990ce86776e28afZbigniew Jędrzejewski-Szmek /* systemd-journald.socket: /run/systemd/journal/stdout */
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmek r = server_open_stdout_socket(s);
37b7affefde5443680d73642a990ce86776e28afZbigniew Jędrzejewski-Szmek /* systemd-journald-dev-log.socket: /run/systemd/journal/dev-log */
37b7affefde5443680d73642a990ce86776e28afZbigniew Jędrzejewski-Szmek /* systemd-journald.socket: /run/systemd/journal/socket */
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek /* Unless we got *some* sockets and not audit, open audit socket */
7d18d348da26fdbb392c76b0f5edb7f06282afbbZbigniew Jędrzejewski-Szmek if (s->audit_fd >= 0 || no_sockets) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = server_open_kernel_seqnum(s);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering s->rate_limit = journal_rate_limit_new(s->rate_limit_interval, s->rate_limit_burst);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekvoid server_maybe_append_tags(Server *s) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek journal_file_maybe_append_tag(s->system_journal, n);
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt ORDERED_HASHMAP_FOREACH(f, s->user_journals, i)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek journal_file_maybe_append_tag(f, n);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek stdout_stream_free(s->stdout_streams);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek journal_file_close(s->system_journal);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek journal_file_close(s->runtime_journal);
43cf8388ea4ffed1801468d4b650d6e48eefce9eMichal Schmidt while ((f = ordered_hashmap_steal_first(s->user_journals)))
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_source_unref(s->syslog_event_source);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_source_unref(s->native_event_source);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_source_unref(s->stdout_event_source);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_source_unref(s->dev_kmsg_event_source);
875c2e220e2611165e09051c4747971811f1de58Lennart Poettering sd_event_source_unref(s->audit_event_source);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_source_unref(s->sync_event_source);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_source_unref(s->sigusr1_event_source);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_source_unref(s->sigusr2_event_source);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_source_unref(s->sigterm_event_source);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_source_unref(s->sigint_event_source);
94b6551662e0db8eb09768ed70f77759f322b4c6Lennart Poettering sd_event_source_unref(s->sigrtmin1_event_source);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering sd_event_source_unref(s->hostname_event_source);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering sd_event_source_unref(s->notify_event_source);
119e9655dc36f18ed74f9a256d5c693b5aeb43abLennart Poettering sd_event_source_unref(s->watchdog_event_source);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek journal_rate_limit_free(s->rate_limit);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek munmap(s->kernel_seqnum, sizeof(uint64_t));
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poetteringstatic const char* const storage_table[_STORAGE_MAX] = {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart PoetteringDEFINE_STRING_TABLE_LOOKUP(storage, Storage);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart PoetteringDEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart Poetteringstatic const char* const split_mode_table[_SPLIT_MAX] = {
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart PoetteringDEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode);
8580d1f73db36e9383e674e388b4fb55828c0c66Lennart PoetteringDEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting");