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;
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;
Iterator i;
int r;
- log_info("Rotating...");
+ log_debug("Rotating...");
if (s->runtime_journal) {
r = journal_file_rotate(&s->runtime_journal, s->compress, false);
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));
}
}
}
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) {
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);
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);
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;
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;
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(
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);
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();
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));
}
}
- 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);
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) {
}
SD_JOURNAL_FOREACH(j) {
+ Object *o = NULL;
JournalFile *f;
f = j->current_file;
}
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;
if (r >= 0)
rm_rf("/run/log/journal", false, true, false);
+ if (j)
+ sd_journal_close(j);
+
return r;
}
ssize_t n;
if (ev->events != EPOLLIN) {
- log_info("Got invalid event from epoll.");
+ log_error("Got invalid event from epoll.");
return -EIO;
}
int r;
if (ev->events != EPOLLIN) {
- log_info("Got invalid event from epoll.");
+ log_error("Got invalid event from epoll.");
return -EIO;
}
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;
}
} 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;
}
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;
}
log_set_target(LOG_TARGET_SAFE);
log_set_facility(LOG_SYSLOG);
- log_set_max_level(LOG_DEBUG);
log_parse_environment();
log_open();
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) {
}
server_maybe_append_tags(&server);
+ server_maybe_warn_forward_syslog_missed(&server);
}
log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid());