X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fjournald.c;h=f56e8224289955f4591798a994899839c901c8db;hb=2fb7a5ce67fd6196416919535fa6a6065e0ea815;hp=871bbb636f981a8194d190f6cb230c3ef52457d7;hpb=b58b344afd1c6dd4ef2b96451c726571f867d130;p=elogind.git diff --git a/src/journal/journald.c b/src/journal/journald.c index 871bbb636..f56e82242 100644 --- a/src/journal/journald.c +++ b/src/journal/journald.c @@ -141,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; @@ -360,6 +361,8 @@ static void server_vacuum(Server *s) { log_debug("Vacuuming..."); + s->oldest_file_usec = 0; + r = sd_id128_get_machine(&machine); if (r < 0) { log_error("Failed to get machine ID: %s", strerror(-r)); @@ -375,7 +378,7 @@ static void server_vacuum(Server *s) { 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); @@ -388,7 +391,7 @@ static void server_vacuum(Server *s) { 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); @@ -439,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; @@ -452,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_debug("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; @@ -463,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_debug("Allocation limit reached, rotating."); - else if (r == -EHOSTDOWN) - log_info("Journal file from other machine, rotating."); - else if (r == -EBUSY) - log_info("Unclean 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_debug("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( @@ -713,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(); @@ -826,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)); @@ -875,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); @@ -917,6 +941,7 @@ static int server_flush_to_var(Server *s) { } SD_JOURNAL_FOREACH(j) { + Object *o = NULL; JournalFile *f; f = j->current_file; @@ -929,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_debug("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; @@ -954,6 +982,9 @@ finish: if (r >= 0) rm_rf("/run/log/journal", false, true, false); + if (j) + sd_journal_close(j); + return r; } @@ -1514,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.system_journal && - journal_file_next_evolve_usec(server.system_journal, &u)) { - usec_t n; + if (server.max_retention_usec > 0 && server.oldest_file_usec > 0) { - n = now(CLOCK_REALTIME); + /* 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; + } - if (n >= u) - t = 0; - else - t = (int) ((u - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC); - } else + /* 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); + } + +#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) { @@ -1553,6 +1598,7 @@ int main(int argc, char *argv[]) { } server_maybe_append_tags(&server); + server_maybe_warn_forward_syslog_missed(&server); } log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid());