X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fjournald.c;h=f56e8224289955f4591798a994899839c901c8db;hb=915bf0f60fa77ffc2e7e229fff8fdc262912f912;hp=5836119bede27ddf963370ac11a04a8368550801;hpb=3b7124a8db56ed57525b9ecfd19cfdc8c9facba0;p=elogind.git diff --git a/src/journal/journald.c b/src/journal/journald.c index 5836119be..f56e82242 100644 --- a/src/journal/journald.c +++ b/src/journal/journald.c @@ -49,15 +49,16 @@ #include "virt.h" #include "missing.h" #include "conf-parser.h" -#include "journal-rate-limit.h" #include "journal-internal.h" #include "journal-vacuum.h" #include "journal-authenticate.h" #include "journald.h" +#include "journald-rate-limit.h" #include "journald-kmsg.h" #include "journald-syslog.h" #include "journald-stream.h" #include "journald-console.h" +#include "journald-native.h" #ifdef HAVE_ACL #include @@ -76,8 +77,6 @@ #define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC) -#define ENTRY_SIZE_MAX (1024*1024*32) - static const char* const storage_table[] = { [STORAGE_AUTO] = "auto", [STORAGE_VOLATILE] = "volatile", @@ -88,6 +87,15 @@ static const char* const storage_table[] = { DEFINE_STRING_TABLE_LOOKUP(storage, Storage); DEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting"); +static const char* const split_mode_table[] = { + [SPLIT_NONE] = "none", + [SPLIT_UID] = "uid", + [SPLIT_LOGIN] = "login" +}; + +DEFINE_STRING_TABLE_LOOKUP(split_mode, SplitMode); +DEFINE_CONFIG_PARSE_ENUM(config_parse_split_mode, split_mode, SplitMode, "Failed to parse split mode setting"); + static uint64_t available_space(Server *s) { char ids[33], *p; const char *f; @@ -133,9 +141,10 @@ static uint64_t available_space(Server *s) { for (;;) { struct stat st; - struct dirent buf, *de; + struct dirent *de; + union dirent_storage buf; - r = readdir_r(d, &buf, &de); + r = readdir_r(d, &buf.de, &de); if (r != 0) break; @@ -305,7 +314,7 @@ static void server_rotate(Server *s) { Iterator i; int r; - log_info("Rotating..."); + log_debug("Rotating..."); if (s->runtime_journal) { r = journal_file_rotate(&s->runtime_journal, s->compress, false); @@ -339,7 +348,7 @@ static void server_rotate(Server *s) { log_error("Failed to create user journal: %s", strerror(-r)); else { hashmap_replace(s->user_journals, k, f); - server_fix_perms(s, s->system_journal, PTR_TO_UINT32(k)); + server_fix_perms(s, f, PTR_TO_UINT32(k)); } } } @@ -350,7 +359,9 @@ static void server_vacuum(Server *s) { sd_id128_t machine; int r; - log_info("Vacuuming..."); + log_debug("Vacuuming..."); + + s->oldest_file_usec = 0; r = sd_id128_get_machine(&machine); if (r < 0) { @@ -361,24 +372,26 @@ static void server_vacuum(Server *s) { sd_id128_to_string(machine, ids); if (s->system_journal) { - if (asprintf(&p, "/var/log/journal/%s", ids) < 0) { + p = strappend("/var/log/journal/", ids); + if (!p) { log_oom(); return; } - r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free); + r = journal_directory_vacuum(p, s->system_metrics.max_use, s->system_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec); if (r < 0 && r != -ENOENT) log_error("Failed to vacuum %s: %s", p, strerror(-r)); free(p); } if (s->runtime_journal) { - if (asprintf(&p, "/run/log/journal/%s", ids) < 0) { + p = strappend("/run/log/journal/", ids); + if (!p) { log_oom(); return; } - r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free); + r = journal_directory_vacuum(p, s->runtime_metrics.max_use, s->runtime_metrics.keep_free, s->max_retention_usec, &s->oldest_file_usec); if (r < 0 && r != -ENOENT) log_error("Failed to vacuum %s: %s", p, strerror(-r)); free(p); @@ -429,6 +442,35 @@ static char *shortened_cgroup_path(pid_t pid) { return path; } +static bool shall_try_append_again(JournalFile *f, int r) { + + /* -E2BIG Hit configured limit + -EFBIG Hit fs limit + -EDQUOT Quota limit hit + -ENOSPC Disk full + -EHOSTDOWN Other machine + -EBUSY Unclean shutdown + -EPROTONOSUPPORT Unsupported feature + -EBADMSG Corrupted + -ENODATA Truncated + -ESHUTDOWN Already archived */ + + if (r == -E2BIG || r == -EFBIG || r == -EDQUOT || r == -ENOSPC) + log_debug("%s: Allocation limit reached, rotating.", f->path); + else if (r == -EHOSTDOWN) + log_info("%s: Journal file from other machine, rotating.", f->path); + else if (r == -EBUSY) + log_info("%s: Unclean shutdown, rotating.", f->path); + else if (r == -EPROTONOSUPPORT) + log_info("%s: Unsupported feature, rotating.", f->path); + else if (r == -EBADMSG || r == -ENODATA || r == ESHUTDOWN) + log_warning("%s: Journal file corrupted, rotating.", f->path); + else + return false; + + return true; +} + static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n) { JournalFile *f; bool vacuumed = false; @@ -442,8 +484,8 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned if (!f) return; - if (journal_file_rotate_suggested(f)) { - log_info("Journal header limits reached or header out-of-date, rotating."); + if (journal_file_rotate_suggested(f, s->max_file_usec)) { + log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->path); server_rotate(s); server_vacuum(s); vacuumed = true; @@ -453,45 +495,26 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned return; } - for (;;) { - r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL); - if (r >= 0) - return; - - if (vacuumed || - (r != -E2BIG && /* hit limit */ - r != -EFBIG && /* hit fs limit */ - r != -EDQUOT && /* quota hit */ - r != -ENOSPC && /* disk full */ - r != -EBADMSG && /* corrupted */ - r != -ENODATA && /* truncated */ - r != -EHOSTDOWN && /* other machine */ - r != -EPROTONOSUPPORT && /* unsupported feature */ - r != -EBUSY && /* unclean shutdown */ - r != -ESHUTDOWN /* already archived */)) { - log_error("Failed to write entry, ignoring: %s", strerror(-r)); - return; - } + r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL); + if (r >= 0) + return; - if (r == -E2BIG || r == -EFBIG || r == EDQUOT || r == ENOSPC) - log_info("Allocation limit reached, rotating."); - else if (r == -EHOSTDOWN) - log_info("Journal file from other machine, rotating."); - else if (r == -EBUSY) - log_info("Unlcean shutdown, rotating."); - else - log_warning("Journal file corrupted, rotating."); + if (vacuumed || !shall_try_append_again(f, r)) { + log_error("Failed to write entry, ignoring: %s", strerror(-r)); + return; + } - server_rotate(s); - server_vacuum(s); - vacuumed = true; + server_rotate(s); + server_vacuum(s); - f = find_journal(s, uid); - if (!f) - return; + f = find_journal(s, uid); + if (!f) + return; - log_info("Retrying write."); - } + log_debug("Retrying write."); + r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL); + if (r < 0) + log_error("Failed to write entry, ignoring: %s", strerror(-r)); } static void dispatch_message_real( @@ -658,7 +681,10 @@ static void dispatch_message_real( assert(n <= m); - write_to_journal(s, realuid == 0 ? 0 : loginuid, iovec, n); + write_to_journal(s, + s->split_mode == SPLIT_NONE ? 0 : + (s->split_mode == SPLIT_UID ? realuid : + (realuid == 0 ? 0 : loginuid)), iovec, n); free(pid); free(uid); @@ -700,9 +726,11 @@ void server_driver_message(Server *s, sd_id128_t message_id, const char *format, char_array_0(buffer); IOVEC_SET_STRING(iovec[n++], buffer); - snprintf(mid, sizeof(mid), "MESSAGE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(message_id)); - char_array_0(mid); - IOVEC_SET_STRING(iovec[n++], mid); + if (!sd_id128_equal(message_id, SD_ID128_NULL)) { + snprintf(mid, sizeof(mid), MESSAGE_ID(message_id)); + char_array_0(mid); + IOVEC_SET_STRING(iovec[n++], mid); + } zero(ucred); ucred.pid = getpid(); @@ -773,292 +801,6 @@ finish: dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id); } -static bool valid_user_field(const char *p, size_t l) { - const char *a; - - /* We kinda enforce POSIX syntax recommendations for - environment variables here, but make a couple of additional - requirements. - - http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */ - - /* No empty field names */ - if (l <= 0) - return false; - - /* Don't allow names longer than 64 chars */ - if (l > 64) - return false; - - /* Variables starting with an underscore are protected */ - if (p[0] == '_') - return false; - - /* Don't allow digits as first character */ - if (p[0] >= '0' && p[0] <= '9') - return false; - - /* Only allow A-Z0-9 and '_' */ - for (a = p; a < p + l; a++) - if (!((*a >= 'A' && *a <= 'Z') || - (*a >= '0' && *a <= '9') || - *a == '_')) - return false; - - return true; -} - -static void process_native_message( - Server *s, - const void *buffer, size_t buffer_size, - struct ucred *ucred, - struct timeval *tv, - const char *label, size_t label_len) { - - struct iovec *iovec = NULL; - unsigned n = 0, m = 0, j, tn = (unsigned) -1; - const char *p; - size_t remaining; - int priority = LOG_INFO; - char *identifier = NULL, *message = NULL; - - assert(s); - assert(buffer || buffer_size == 0); - - p = buffer; - remaining = buffer_size; - - while (remaining > 0) { - const char *e, *q; - - e = memchr(p, '\n', remaining); - - if (!e) { - /* Trailing noise, let's ignore it, and flush what we collected */ - log_debug("Received message with trailing noise, ignoring."); - break; - } - - if (e == p) { - /* Entry separator */ - server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority); - n = 0; - priority = LOG_INFO; - - p++; - remaining--; - continue; - } - - if (*p == '.' || *p == '#') { - /* Ignore control commands for now, and - * comments too. */ - remaining -= (e - p) + 1; - p = e + 1; - continue; - } - - /* A property follows */ - - if (n+N_IOVEC_META_FIELDS >= m) { - struct iovec *c; - unsigned u; - - u = MAX((n+N_IOVEC_META_FIELDS+1) * 2U, 4U); - c = realloc(iovec, u * sizeof(struct iovec)); - if (!c) { - log_oom(); - break; - } - - iovec = c; - m = u; - } - - q = memchr(p, '=', e - p); - if (q) { - if (valid_user_field(p, q - p)) { - size_t l; - - l = e - p; - - /* If the field name starts with an - * underscore, skip the variable, - * since that indidates a trusted - * field */ - iovec[n].iov_base = (char*) p; - iovec[n].iov_len = l; - n++; - - /* We need to determine the priority - * of this entry for the rate limiting - * logic */ - if (l == 10 && - memcmp(p, "PRIORITY=", 9) == 0 && - p[9] >= '0' && p[9] <= '9') - priority = (priority & LOG_FACMASK) | (p[9] - '0'); - - else if (l == 17 && - memcmp(p, "SYSLOG_FACILITY=", 16) == 0 && - p[16] >= '0' && p[16] <= '9') - priority = (priority & LOG_PRIMASK) | ((p[16] - '0') << 3); - - else if (l == 18 && - memcmp(p, "SYSLOG_FACILITY=", 16) == 0 && - p[16] >= '0' && p[16] <= '9' && - p[17] >= '0' && p[17] <= '9') - priority = (priority & LOG_PRIMASK) | (((p[16] - '0')*10 + (p[17] - '0')) << 3); - - else if (l >= 19 && - memcmp(p, "SYSLOG_IDENTIFIER=", 18) == 0) { - char *t; - - t = strndup(p + 18, l - 18); - if (t) { - free(identifier); - identifier = t; - } - } else if (l >= 8 && - memcmp(p, "MESSAGE=", 8) == 0) { - char *t; - - t = strndup(p + 8, l - 8); - if (t) { - free(message); - message = t; - } - } - } - - remaining -= (e - p) + 1; - p = e + 1; - continue; - } else { - le64_t l_le; - uint64_t l; - char *k; - - if (remaining < e - p + 1 + sizeof(uint64_t) + 1) { - log_debug("Failed to parse message, ignoring."); - break; - } - - memcpy(&l_le, e + 1, sizeof(uint64_t)); - l = le64toh(l_le); - - if (remaining < e - p + 1 + sizeof(uint64_t) + l + 1 || - e[1+sizeof(uint64_t)+l] != '\n') { - log_debug("Failed to parse message, ignoring."); - break; - } - - k = malloc((e - p) + 1 + l); - if (!k) { - log_oom(); - break; - } - - memcpy(k, p, e - p); - k[e - p] = '='; - memcpy(k + (e - p) + 1, e + 1 + sizeof(uint64_t), l); - - if (valid_user_field(p, e - p)) { - iovec[n].iov_base = k; - iovec[n].iov_len = (e - p) + 1 + l; - n++; - } else - free(k); - - remaining -= (e - p) + 1 + sizeof(uint64_t) + l + 1; - p = e + 1 + sizeof(uint64_t) + l + 1; - } - } - - if (n <= 0) - goto finish; - - tn = n++; - IOVEC_SET_STRING(iovec[tn], "_TRANSPORT=journal"); - - if (message) { - if (s->forward_to_syslog) - server_forward_syslog(s, priority, identifier, message, ucred, tv); - - if (s->forward_to_kmsg) - server_forward_kmsg(s, priority, identifier, message, ucred); - - if (s->forward_to_console) - server_forward_console(s, priority, identifier, message, ucred); - } - - server_dispatch_message(s, iovec, n, m, ucred, tv, label, label_len, NULL, priority); - -finish: - for (j = 0; j < n; j++) { - if (j == tn) - continue; - - if (iovec[j].iov_base < buffer || - (const uint8_t*) iovec[j].iov_base >= (const uint8_t*) buffer + buffer_size) - free(iovec[j].iov_base); - } - - free(iovec); - free(identifier); - free(message); -} - -static void process_native_file( - Server *s, - int fd, - struct ucred *ucred, - struct timeval *tv, - const char *label, size_t label_len) { - - struct stat st; - void *p; - ssize_t n; - - assert(s); - assert(fd >= 0); - - /* Data is in the passed file, since it didn't fit in a - * datagram. We can't map the file here, since clients might - * then truncate it and trigger a SIGBUS for us. So let's - * stupidly read it */ - - if (fstat(fd, &st) < 0) { - log_error("Failed to stat passed file, ignoring: %m"); - return; - } - - if (!S_ISREG(st.st_mode)) { - log_error("File passed is not regular. Ignoring."); - return; - } - - if (st.st_size <= 0) - return; - - if (st.st_size > ENTRY_SIZE_MAX) { - log_error("File passed too large. Ignoring."); - return; - } - - p = malloc(st.st_size); - if (!p) { - log_oom(); - return; - } - - n = pread(fd, p, st.st_size, 0); - if (n < 0) - log_error("Failed to read file, ignoring: %s", strerror(-n)); - else if (n > 0) - process_native_message(s, p, n, ucred, tv, label, label_len); - - free(p); -} static int system_journal_open(Server *s) { int r; @@ -1099,9 +841,14 @@ static int system_journal_open(Server *s) { r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal); free(fn); - if (r >= 0) + if (r >= 0) { + char fb[FORMAT_BYTES_MAX]; + server_fix_perms(s, s->system_journal, 0); - else if (r < 0) { + server_driver_message(s, SD_ID128_NULL, "Allowing system journal files to grow to %s.", + format_bytes(fb, sizeof(fb), s->system_metrics.max_use)); + + } else if (r < 0) { if (r != -ENOENT && r != -EROFS) log_warning("Failed to open system journal: %s", strerror(-r)); @@ -1148,18 +895,22 @@ static int system_journal_open(Server *s) { } } - if (s->runtime_journal) + if (s->runtime_journal) { + char fb[FORMAT_BYTES_MAX]; + server_fix_perms(s, s->runtime_journal, 0); + server_driver_message(s, SD_ID128_NULL, "Allowing runtime journal files to grow to %s.", + format_bytes(fb, sizeof(fb), s->runtime_metrics.max_use)); + } } return r; } static int server_flush_to_var(Server *s) { - Object *o = NULL; int r; sd_id128_t machine; - sd_journal *j; + sd_journal *j = NULL; assert(s); @@ -1175,7 +926,7 @@ static int server_flush_to_var(Server *s) { if (!s->system_journal) return 0; - log_info("Flushing to /var..."); + log_debug("Flushing to /var..."); r = sd_id128_get_machine(&machine); if (r < 0) { @@ -1190,6 +941,7 @@ static int server_flush_to_var(Server *s) { } SD_JOURNAL_FOREACH(j) { + Object *o = NULL; JournalFile *f; f = j->current_file; @@ -1202,16 +954,19 @@ static int server_flush_to_var(Server *s) { } r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL); - if (r == -E2BIG) { - log_info("Allocation limit reached."); - - journal_file_post_change(s->system_journal); - server_rotate(s); - server_vacuum(s); + if (r >= 0) + continue; - r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL); + if (!shall_try_append_again(s->system_journal, r)) { + log_error("Can't write entry: %s", strerror(-r)); + goto finish; } + server_rotate(s); + server_vacuum(s); + + log_debug("Retrying write."); + r = journal_file_copy_entry(f, s->system_journal, o, f->current_offset, NULL, NULL, NULL); if (r < 0) { log_error("Can't write entry: %s", strerror(-r)); goto finish; @@ -1227,6 +982,9 @@ finish: if (r >= 0) rm_rf("/run/log/journal", false, true, false); + if (j) + sd_journal_close(j); + return r; } @@ -1239,7 +997,7 @@ static int process_event(Server *s, struct epoll_event *ev) { ssize_t n; if (ev->events != EPOLLIN) { - log_info("Got invalid event from epoll."); + log_error("Got invalid event from epoll."); return -EIO; } @@ -1275,7 +1033,7 @@ static int process_event(Server *s, struct epoll_event *ev) { int r; if (ev->events != EPOLLIN) { - log_info("Got invalid event from epoll."); + log_error("Got invalid event from epoll."); return -EIO; } @@ -1289,7 +1047,7 @@ static int process_event(Server *s, struct epoll_event *ev) { ev->data.fd == s->syslog_fd) { if (ev->events != EPOLLIN) { - log_info("Got invalid event from epoll."); + log_error("Got invalid event from epoll."); return -EIO; } @@ -1402,9 +1160,9 @@ static int process_event(Server *s, struct epoll_event *ev) { } else { if (n > 0 && n_fds == 0) - process_native_message(s, s->buffer, n, ucred, tv, label, label_len); + server_process_native_message(s, s->buffer, n, ucred, tv, label, label_len); else if (n == 0 && n_fds == 1) - process_native_file(s, fds[0], ucred, tv, label, label_len); + server_process_native_file(s, fds[0], ucred, tv, label, label_len); else if (n_fds > 0) log_warning("Got too many file descriptors via native socket. Ignoring."); } @@ -1417,7 +1175,7 @@ static int process_event(Server *s, struct epoll_event *ev) { } else if (ev->data.fd == s->stdout_fd) { if (ev->events != EPOLLIN) { - log_info("Got invalid event from epoll."); + log_error("Got invalid event from epoll."); return -EIO; } @@ -1428,7 +1186,7 @@ static int process_event(Server *s, struct epoll_event *ev) { StdoutStream *stream; if ((ev->events|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) { - log_info("Got invalid event from epoll."); + log_error("Got invalid event from epoll."); return -EIO; } @@ -1451,71 +1209,6 @@ static int process_event(Server *s, struct epoll_event *ev) { return 0; } - -static int open_native_socket(Server*s) { - union sockaddr_union sa; - int one, r; - struct epoll_event ev; - - assert(s); - - if (s->native_fd < 0) { - - s->native_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); - if (s->native_fd < 0) { - log_error("socket() failed: %m"); - return -errno; - } - - zero(sa); - sa.un.sun_family = AF_UNIX; - strncpy(sa.un.sun_path, "/run/systemd/journal/socket", sizeof(sa.un.sun_path)); - - unlink(sa.un.sun_path); - - r = bind(s->native_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); - if (r < 0) { - log_error("bind() failed: %m"); - return -errno; - } - - chmod(sa.un.sun_path, 0666); - } else - fd_nonblock(s->native_fd, 1); - - one = 1; - r = setsockopt(s->native_fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)); - if (r < 0) { - log_error("SO_PASSCRED failed: %m"); - return -errno; - } - -#ifdef HAVE_SELINUX - one = 1; - r = setsockopt(s->syslog_fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)); - if (r < 0) - log_warning("SO_PASSSEC failed: %m"); -#endif - - one = 1; - r = setsockopt(s->native_fd, SOL_SOCKET, SO_TIMESTAMP, &one, sizeof(one)); - if (r < 0) { - log_error("SO_TIMESTAMP failed: %m"); - return -errno; - } - - zero(ev); - ev.events = EPOLLIN; - ev.data.fd = s->native_fd; - if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, s->native_fd, &ev) < 0) { - log_error("Failed to add native server fd to epoll object: %m"); - return -errno; - } - - return 0; -} - - static int open_signalfd(Server *s) { sigset_t mask; struct epoll_event ev; @@ -1711,7 +1404,7 @@ static int server_init(Server *s) { if (r < 0) return r; - r = open_native_socket(s); + r = server_open_native_socket(s); if (r < 0) return r; @@ -1746,7 +1439,7 @@ static int server_init(Server *s) { return 0; } -static void maybe_append_tags(Server *s) { +static void server_maybe_append_tags(Server *s) { #ifdef HAVE_GCRYPT JournalFile *f; Iterator i; @@ -1830,7 +1523,6 @@ int main(int argc, char *argv[]) { log_set_target(LOG_TARGET_SAFE); log_set_facility(LOG_SYSLOG); - log_set_max_level(LOG_DEBUG); log_parse_environment(); log_open(); @@ -1853,24 +1545,38 @@ int main(int argc, char *argv[]) { for (;;) { struct epoll_event event; - int t; + int t = -1; + usec_t n; -#ifdef HAVE_GCRYPT - usec_t u; + n = now(CLOCK_REALTIME); + + if (server.max_retention_usec > 0 && server.oldest_file_usec > 0) { - if (server.system_journal && - journal_file_next_evolve_usec(server.system_journal, &u)) { - usec_t n; + /* The retention time is reached, so let's vacuum! */ + if (server.oldest_file_usec + server.max_retention_usec < n) { + log_info("Retention time reached."); + server_rotate(&server); + server_vacuum(&server); + continue; + } - n = now(CLOCK_REALTIME); + /* Calculate when to rotate the next time */ + t = (int) ((server.oldest_file_usec + server.max_retention_usec - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC); + log_info("Sleeping for %i ms", t); + } - if (n >= u) - t = 0; - else - t = (int) ((u - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC); - } else +#ifdef HAVE_GCRYPT + if (server.system_journal) { + usec_t u; + + if (journal_file_next_evolve_usec(server.system_journal, &u)) { + if (n >= u) + t = 0; + else + t = MIN(t, (int) ((u - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC)); + } + } #endif - t = -1; r = epoll_wait(server.epoll_fd, &event, 1, t); if (r < 0) { @@ -1891,7 +1597,8 @@ int main(int argc, char *argv[]) { break; } - maybe_append_tags(&server); + server_maybe_append_tags(&server); + server_maybe_warn_forward_syslog_missed(&server); } log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid());