#define RECHECK_AVAILABLE_SPACE_USEC (30*USEC_PER_SEC)
-#define RECHECK_VAR_AVAILABLE_USEC (30*USEC_PER_SEC)
-
#define N_IOVEC_META_FIELDS 17
#define ENTRY_SIZE_MAX (1024*1024*32)
static const char* const storage_table[] = {
[STORAGE_AUTO] = "auto",
[STORAGE_VOLATILE] = "volatile",
- [STORAGE_PERMANENT] = "permanent",
+ [STORAGE_PERSISTENT] = "persistent",
[STORAGE_NONE] = "none"
};
DEFINE_STRING_TABLE_LOOKUP(storage, Storage);
DEFINE_CONFIG_PARSE_ENUM(config_parse_storage, storage, Storage, "Failed to parse storage setting");
-static int server_flush_to_var(Server *s);
-
static uint64_t available_space(Server *s) {
char ids[33], *p;
const char *f;
journal_file_close(f);
}
- r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->system_journal, &f);
+ r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, &s->system_metrics, s->system_journal, &f);
free(p);
if (r < 0)
return path;
}
+static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, unsigned n) {
+ JournalFile *f;
+ bool vacuumed = false;
+ int r;
+
+ assert(s);
+ assert(iovec);
+ assert(n > 0);
+
+ f = find_journal(s, uid);
+ if (!f)
+ return;
+
+ if (journal_file_rotate_suggested(f)) {
+ log_info("Journal header limits reached or header out-of-date, rotating.");
+ server_rotate(s);
+ server_vacuum(s);
+ vacuumed = true;
+ }
+
+ 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;
+ }
+
+ 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.");
+
+ server_rotate(s);
+ server_vacuum(s);
+ vacuumed = true;
+
+ log_info("Retrying write.");
+ }
+}
+
static void dispatch_message_real(
Server *s,
struct iovec *iovec, unsigned n, unsigned m,
int r;
char *t;
uid_t loginuid = 0, realuid = 0;
- JournalFile *f;
- bool vacuumed = false;
assert(s);
assert(iovec);
assert(n <= m);
- server_flush_to_var(s);
-
-retry:
- f = find_journal(s, realuid == 0 ? 0 : loginuid);
- if (f) {
- r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
-
- if ((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 */
- !vacuumed) {
-
- if (r == -E2BIG)
- log_info("Allocation limit reached, rotating.");
- else
- log_warning("Journal file corrupted, rotating.");
-
- server_rotate(s);
- server_vacuum(s);
- vacuumed = true;
-
- log_info("Retrying write.");
- goto retry;
- }
-
- if (r < 0)
- log_error("Failed to write entry, ignoring: %s", strerror(-r));
- }
+ write_to_journal(s, realuid == 0 ? 0 : loginuid, iovec, n);
free(pid);
free(uid);
sd_id128_to_string(machine, ids);
if (!s->system_journal &&
- (s->storage == STORAGE_PERMANENT ||
- s->storage == STORAGE_AUTO)) {
+ (s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
+ access("/run/systemd/journal/flushed", F_OK) >= 0) {
/* If in auto mode: first try to create the machine
* path, but not the prefix.
*
- * If in permanent mode: create /var/log/journal and
+ * If in persistent mode: create /var/log/journal and
* the machine path */
- if (s->storage & STORAGE_PERMANENT)
+ if (s->storage == STORAGE_PERSISTENT)
(void) mkdir("/var/log/journal/", 0755);
fn = strappend("/var/log/journal/", ids);
(void) mkdir(fn, 0755);
free(fn);
- /* The create the system journal file */
- fn = join("/var/log/journal/", ids, "/system.journal", NULL);
+ fn = strjoin("/var/log/journal/", ids, "/system.journal", NULL);
if (!fn)
return -ENOMEM;
- r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, NULL, &s->system_journal);
+ r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, &s->system_metrics, NULL, &s->system_journal);
free(fn);
if (r >= 0) {
- journal_default_metrics(&s->system_metrics, s->system_journal->fd);
-
- s->system_journal->metrics = s->system_metrics;
s->system_journal->compress = s->compress;
server_fix_perms(s, s->system_journal, 0);
if (!s->runtime_journal &&
(s->storage != STORAGE_NONE)) {
- fn = join("/run/log/journal/", ids, "/system.journal", NULL);
+ fn = strjoin("/run/log/journal/", ids, "/system.journal", NULL);
if (!fn)
return -ENOMEM;
* if it already exists, so that we can flush
* it into the system journal */
- r = journal_file_open(fn, O_RDWR, 0640, NULL, &s->runtime_journal);
+ r = journal_file_open(fn, O_RDWR, 0640, &s->runtime_metrics, NULL, &s->runtime_journal);
free(fn);
if (r < 0) {
/* OK, we really need the runtime journal, so create
* it if necessary. */
- (void) mkdir_parents_label(fn, 0755);
- r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, NULL, &s->runtime_journal);
+ (void) mkdir_parents(fn, 0755);
+ r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, &s->runtime_metrics, NULL, &s->runtime_journal);
free(fn);
if (r < 0) {
}
if (s->runtime_journal) {
- journal_default_metrics(&s->runtime_metrics, s->runtime_journal->fd);
-
- s->runtime_journal->metrics = s->runtime_metrics;
s->runtime_journal->compress = s->compress;
server_fix_perms(s, s->runtime_journal, 0);
int r;
sd_id128_t machine;
sd_journal *j;
- usec_t ts;
assert(s);
if (s->storage != STORAGE_AUTO &&
- s->storage != STORAGE_PERMANENT)
+ s->storage != STORAGE_PERSISTENT)
return 0;
if (!s->runtime_journal)
return 0;
- ts = now(CLOCK_MONOTONIC);
- if (s->var_available_timestamp + RECHECK_VAR_AVAILABLE_USEC > ts)
- return 0;
-
- s->var_available_timestamp = ts;
-
system_journal_open(s);
if (!s->system_journal)
}
if (sfsi.ssi_signo == SIGUSR1) {
+ touch("/run/systemd/journal/flushed");
server_flush_to_var(s);
return 1;
}