summaryrefslogtreecommitdiff
path: root/src/journal
diff options
context:
space:
mode:
Diffstat (limited to 'src/journal')
-rw-r--r--src/journal/compress.c85
-rw-r--r--src/journal/coredump.c27
-rw-r--r--src/journal/journal-file.c106
-rw-r--r--src/journal/journal-file.h5
-rw-r--r--src/journal/journal-send.c1
-rw-r--r--src/journal/journalctl.c2
-rw-r--r--src/journal/journald-audit.c4
-rw-r--r--src/journal/journald-kmsg.c6
-rw-r--r--src/journal/journald-server.c134
-rw-r--r--src/journal/journald-server.h3
-rw-r--r--src/journal/journald-syslog.c11
-rw-r--r--src/journal/journald.c8
12 files changed, 254 insertions, 138 deletions
diff --git a/src/journal/compress.c b/src/journal/compress.c
index 1828165894..78935fee74 100644
--- a/src/journal/compress.c
+++ b/src/journal/compress.c
@@ -612,80 +612,8 @@ int decompress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
#endif
}
+int decompress_stream_lz4(int in, int out, uint64_t max_bytes) {
#ifdef HAVE_LZ4
-static int decompress_stream_lz4_v1(int fdf, int fdt, uint64_t max_bytes) {
-
- _cleanup_free_ char *buf = NULL, *out = NULL;
- size_t buf_size = 0;
- LZ4_streamDecode_t lz4_data = {};
- le32_t header;
- size_t total_in = sizeof(header), total_out = 0;
-
- assert(fdf >= 0);
- assert(fdt >= 0);
-
- out = malloc(4*LZ4_BUFSIZE);
- if (!out)
- return -ENOMEM;
-
- for (;;) {
- ssize_t m;
- int r;
-
- r = loop_read_exact(fdf, &header, sizeof(header), false);
- if (r < 0)
- return r;
-
- m = le32toh(header);
- if (m == 0)
- break;
-
- /* We refuse to use a bigger decompression buffer than
- * the one used for compression by 4 times. This means
- * that compression buffer size can be enlarged 4
- * times. This can be changed, but old binaries might
- * not accept buffers compressed by newer binaries then.
- */
- if (m > LZ4_COMPRESSBOUND(LZ4_BUFSIZE * 4)) {
- log_debug("Compressed stream block too big: %zd bytes", m);
- return -ENOBUFS;
- }
-
- total_in += sizeof(header) + m;
-
- if (!GREEDY_REALLOC(buf, buf_size, m))
- return -ENOMEM;
-
- r = loop_read_exact(fdf, buf, m, false);
- if (r < 0)
- return r;
-
- r = LZ4_decompress_safe_continue(&lz4_data, buf, out, m, 4*LZ4_BUFSIZE);
- if (r <= 0) {
- log_debug("LZ4 decompression failed (legacy format).");
- return -EBADMSG;
- }
-
- total_out += r;
-
- if (max_bytes != (uint64_t) -1 && (uint64_t) total_out > max_bytes) {
- log_debug("Decompressed stream longer than %" PRIu64 " bytes", max_bytes);
- return -EFBIG;
- }
-
- r = loop_write(fdt, out, r, false);
- if (r < 0)
- return r;
- }
-
- log_debug("LZ4 decompression finished (legacy format, %zu -> %zu bytes, %.1f%%)",
- total_in, total_out,
- (double) total_out / total_in * 100);
-
- return 0;
-}
-
-static int decompress_stream_lz4_v2(int in, int out, uint64_t max_bytes) {
size_t c;
_cleanup_(LZ4F_freeDecompressionContextp) LZ4F_decompressionContext_t ctx = NULL;
_cleanup_free_ char *buf = NULL;
@@ -739,17 +667,6 @@ static int decompress_stream_lz4_v2(int in, int out, uint64_t max_bytes) {
cleanup:
munmap(src, st.st_size);
return r;
-}
-#endif
-
-int decompress_stream_lz4(int fdf, int fdt, uint64_t max_bytes) {
-#ifdef HAVE_LZ4
- int r;
-
- r = decompress_stream_lz4_v2(fdf, fdt, max_bytes);
- if (r == -EBADMSG)
- r = decompress_stream_lz4_v1(fdf, fdt, max_bytes);
- return r;
#else
log_debug("Cannot decompress file. Compiled without LZ4 support.");
return -EPROTONOSUPPORT;
diff --git a/src/journal/coredump.c b/src/journal/coredump.c
index f750ddfcbd..8298b02439 100644
--- a/src/journal/coredump.c
+++ b/src/journal/coredump.c
@@ -297,7 +297,8 @@ static int save_external_coredump(
const char *info[_INFO_LEN],
uid_t uid,
char **ret_filename,
- int *ret_fd,
+ int *ret_node_fd,
+ int *ret_data_fd,
uint64_t *ret_size) {
_cleanup_free_ char *fn = NULL, *tmp = NULL;
@@ -307,7 +308,8 @@ static int save_external_coredump(
assert(info);
assert(ret_filename);
- assert(ret_fd);
+ assert(ret_node_fd);
+ assert(ret_data_fd);
assert(ret_size);
r = make_filename(info, &fn);
@@ -386,11 +388,12 @@ static int save_external_coredump(
unlink_noerrno(tmp);
*ret_filename = fn_compressed; /* compressed */
- *ret_fd = fd; /* uncompressed */
+ *ret_node_fd = fd_compressed; /* compressed */
+ *ret_data_fd = fd; /* uncompressed */
*ret_size = (uint64_t) st.st_size; /* uncompressed */
fn_compressed = NULL;
- fd = -1;
+ fd = fd_compressed = -1;
return 0;
@@ -400,12 +403,14 @@ static int save_external_coredump(
uncompressed:
#endif
+
r = fix_permissions(fd, tmp, fn, info, uid);
if (r < 0)
goto fail;
*ret_filename = fn;
- *ret_fd = fd;
+ *ret_data_fd = fd;
+ *ret_node_fd = -1;
*ret_size = (uint64_t) st.st_size;
fn = NULL;
@@ -527,7 +532,7 @@ static int compose_open_fds(pid_t pid, char **open_fds) {
errno = 0;
stream = safe_fclose(stream);
- if (errno != 0)
+ if (errno > 0)
return -errno;
*open_fds = buffer;
@@ -554,7 +559,7 @@ int main(int argc, char* argv[]) {
_cleanup_free_ char *exe = NULL, *comm = NULL, *filename = NULL;
const char *info[_INFO_LEN];
- _cleanup_close_ int coredump_fd = -1;
+ _cleanup_close_ int coredump_fd = -1, coredump_node_fd = -1;
struct iovec iovec[26];
uint64_t coredump_size;
@@ -633,7 +638,7 @@ int main(int argc, char* argv[]) {
if (arg_storage != COREDUMP_STORAGE_NONE)
arg_storage = COREDUMP_STORAGE_EXTERNAL;
- r = save_external_coredump(info, uid, &filename, &coredump_fd, &coredump_size);
+ r = save_external_coredump(info, uid, &filename, &coredump_node_fd, &coredump_fd, &coredump_size);
if (r < 0)
goto finish;
@@ -789,13 +794,15 @@ int main(int argc, char* argv[]) {
IOVEC_SET_STRING(iovec[j++], core_timestamp);
IOVEC_SET_STRING(iovec[j++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1");
+
+ assert_cc(2 == LOG_CRIT);
IOVEC_SET_STRING(iovec[j++], "PRIORITY=2");
/* Vacuum before we write anything again */
coredump_vacuum(-1, arg_keep_free, arg_max_use);
/* Always stream the coredump to disk, if that's possible */
- r = save_external_coredump(info, uid, &filename, &coredump_fd, &coredump_size);
+ r = save_external_coredump(info, uid, &filename, &coredump_node_fd, &coredump_fd, &coredump_size);
if (r < 0)
/* skip whole core dumping part */
goto log;
@@ -815,7 +822,7 @@ int main(int argc, char* argv[]) {
}
/* Vacuum again, but exclude the coredump we just created */
- coredump_vacuum(coredump_fd, arg_keep_free, arg_max_use);
+ coredump_vacuum(coredump_node_fd >= 0 ? coredump_node_fd : coredump_fd, arg_keep_free, arg_max_use);
/* Now, let's drop privileges to become the user who owns the
* segfaulted process and allocate the coredump memory under
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 9e362bacae..2973176c8d 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -39,6 +39,7 @@
#include "lookup3.h"
#include "parse-util.h"
#include "random-util.h"
+#include "sd-event.h"
#include "string-util.h"
#include "xattr-util.h"
@@ -149,6 +150,17 @@ JournalFile* journal_file_close(JournalFile *f) {
journal_file_append_tag(f);
#endif
+ if (f->post_change_timer) {
+ int enabled;
+
+ if (sd_event_source_get_enabled(f->post_change_timer, &enabled) >= 0)
+ if (enabled == SD_EVENT_ONESHOT)
+ journal_file_post_change(f);
+
+ (void) sd_event_source_set_enabled(f->post_change_timer, SD_EVENT_OFF);
+ sd_event_source_unref(f->post_change_timer);
+ }
+
journal_file_set_offline(f);
if (f->mmap && f->fd >= 0)
@@ -1397,7 +1409,84 @@ void journal_file_post_change(JournalFile *f) {
__sync_synchronize();
if (ftruncate(f->fd, f->last_stat.st_size) < 0)
- log_error_errno(errno, "Failed to truncate file to its own size: %m");
+ log_debug_errno(errno, "Failed to truncate file to its own size: %m");
+}
+
+static int post_change_thunk(sd_event_source *timer, uint64_t usec, void *userdata) {
+ assert(userdata);
+
+ journal_file_post_change(userdata);
+
+ return 1;
+}
+
+static void schedule_post_change(JournalFile *f) {
+ sd_event_source *timer;
+ int enabled, r;
+ uint64_t now;
+
+ assert(f);
+ assert(f->post_change_timer);
+
+ timer = f->post_change_timer;
+
+ r = sd_event_source_get_enabled(timer, &enabled);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to get ftruncate timer state: %m");
+ goto fail;
+ }
+
+ if (enabled == SD_EVENT_ONESHOT)
+ return;
+
+ r = sd_event_now(sd_event_source_get_event(timer), CLOCK_MONOTONIC, &now);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to get clock's now for scheduling ftruncate: %m");
+ goto fail;
+ }
+
+ r = sd_event_source_set_time(timer, now+f->post_change_timer_period);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to set time for scheduling ftruncate: %m");
+ goto fail;
+ }
+
+ r = sd_event_source_set_enabled(timer, SD_EVENT_ONESHOT);
+ if (r < 0) {
+ log_debug_errno(r, "Failed to enable scheduled ftruncate: %m");
+ goto fail;
+ }
+
+ return;
+
+fail:
+ /* On failure, let's simply post the change immediately. */
+ journal_file_post_change(f);
+}
+
+/* Enable coalesced change posting in a timer on the provided sd_event instance */
+int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t) {
+ _cleanup_(sd_event_source_unrefp) sd_event_source *timer = NULL;
+ int r;
+
+ assert(f);
+ assert_return(!f->post_change_timer, -EINVAL);
+ assert(e);
+ assert(t);
+
+ r = sd_event_add_time(e, &timer, CLOCK_MONOTONIC, 0, 0, post_change_thunk, f);
+ if (r < 0)
+ return r;
+
+ r = sd_event_source_set_enabled(timer, SD_EVENT_OFF);
+ if (r < 0)
+ return r;
+
+ f->post_change_timer = timer;
+ timer = NULL;
+ f->post_change_timer_period = t;
+
+ return r;
}
static int entry_item_cmp(const void *_a, const void *_b) {
@@ -1465,7 +1554,10 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st
if (mmap_cache_got_sigbus(f->mmap, f->fd))
r = -EIO;
- journal_file_post_change(f);
+ if (f->post_change_timer)
+ schedule_post_change(f);
+ else
+ journal_file_post_change(f);
return r;
}
@@ -2767,6 +2859,16 @@ int journal_file_open(
goto fail;
}
+ if (template && template->post_change_timer) {
+ r = journal_file_enable_post_change_timer(
+ f,
+ sd_event_source_get_event(template->post_change_timer),
+ template->post_change_timer_period);
+
+ if (r < 0)
+ goto fail;
+ }
+
*ret = f;
return 0;
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
index 46c1f3278e..7970ebe738 100644
--- a/src/journal/journal-file.h
+++ b/src/journal/journal-file.h
@@ -33,6 +33,7 @@
#include "journal-def.h"
#include "macro.h"
#include "mmap-cache.h"
+#include "sd-event.h"
#include "sparse-endian.h"
typedef struct JournalMetrics {
@@ -101,6 +102,9 @@ typedef struct JournalFile {
JournalMetrics metrics;
MMapCache *mmap;
+ sd_event_source *post_change_timer;
+ usec_t post_change_timer_period;
+
OrderedHashmap *chain_cache;
#if defined(HAVE_XZ) || defined(HAVE_LZ4)
@@ -224,6 +228,7 @@ void journal_file_print_header(JournalFile *f);
int journal_file_rotate(JournalFile **f, bool compress, bool seal);
void journal_file_post_change(JournalFile *f);
+int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t);
void journal_reset_metrics(JournalMetrics *m);
void journal_default_metrics(JournalMetrics *m, int fd);
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c
index 44fa11a00e..def4caab92 100644
--- a/src/journal/journal-send.c
+++ b/src/journal/journal-send.c
@@ -372,6 +372,7 @@ static int fill_iovec_perror_and_send(const char *message, int skip, struct iove
xsprintf(error, "ERRNO=%i", _saved_errno_);
+ assert_cc(3 == LOG_ERR);
IOVEC_SET_STRING(iov[skip+0], "PRIORITY=3");
IOVEC_SET_STRING(iov[skip+1], buffer);
IOVEC_SET_STRING(iov[skip+2], error);
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index d009b2e93b..db11421e7a 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -2336,7 +2336,7 @@ int main(int argc, char *argv[]) {
flags =
arg_all * OUTPUT_SHOW_ALL |
arg_full * OUTPUT_FULL_WIDTH |
- on_tty() * OUTPUT_COLOR |
+ colors_enabled() * OUTPUT_COLOR |
arg_catalog * OUTPUT_CATALOG |
arg_utc * OUTPUT_UTC;
diff --git a/src/journal/journald-audit.c b/src/journal/journald-audit.c
index 3c13fe0d67..28970131e7 100644
--- a/src/journal/journald-audit.c
+++ b/src/journal/journald-audit.c
@@ -397,8 +397,8 @@ static void process_audit_string(Server *s, int type, const char *data, size_t s
sprintf(id_field, "_AUDIT_ID=%" PRIu64, id);
IOVEC_SET_STRING(iov[n_iov++], id_field);
- assert_cc(32 == LOG_AUTH);
- IOVEC_SET_STRING(iov[n_iov++], "SYSLOG_FACILITY=32");
+ assert_cc(4 == LOG_FAC(LOG_AUTH));
+ IOVEC_SET_STRING(iov[n_iov++], "SYSLOG_FACILITY=4");
IOVEC_SET_STRING(iov[n_iov++], "SYSLOG_IDENTIFIER=audit");
type_name = audit_type_name_alloca(type);
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
index e048e04716..1306ad6974 100644
--- a/src/journal/journald-kmsg.c
+++ b/src/journal/journald-kmsg.c
@@ -158,8 +158,10 @@ static void dev_kmsg_record(Server *s, const char *p, size_t l) {
/* Did we lose any? */
if (serial > *s->kernel_seqnum)
- server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED, "Missed %"PRIu64" kernel messages",
- serial - *s->kernel_seqnum);
+ server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED,
+ LOG_MESSAGE("Missed %"PRIu64" kernel messages",
+ serial - *s->kernel_seqnum),
+ NULL);
/* Make sure we never read this one again. Note that
* we always store the next message serial we expect
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index a8a9b72080..8ff7ef943b 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -67,9 +67,11 @@
#include "selinux-util.h"
#include "signal-util.h"
#include "socket-util.h"
+#include "stdio-util.h"
#include "string-table.h"
#include "string-util.h"
#include "user-util.h"
+#include "log.h"
#define USER_JOURNALS_MAX 1024
@@ -82,6 +84,9 @@
#define NOTIFY_SNDBUF_SIZE (8*1024*1024)
+/* The period to insert between posting changes for coalescing */
+#define POST_CHANGE_TIMER_INTERVAL_USEC (250*USEC_PER_MSEC)
+
static int determine_space_for(
Server *s,
JournalMetrics *metrics,
@@ -142,7 +147,7 @@ static int determine_space_for(
sum += (uint64_t) st.st_blocks * 512UL;
}
- /* If request, then let's bump the min_use limit to the
+ /* If requested, then let's bump the min_use limit to the
* current usage on disk. We do this when starting up and
* first opening the journal files. This way sudden spikes in
* disk usage will not cause journald to vacuum files without
@@ -162,19 +167,31 @@ static int determine_space_for(
if (verbose) {
char fb1[FORMAT_BYTES_MAX], fb2[FORMAT_BYTES_MAX], fb3[FORMAT_BYTES_MAX],
fb4[FORMAT_BYTES_MAX], fb5[FORMAT_BYTES_MAX], fb6[FORMAT_BYTES_MAX];
+ format_bytes(fb1, sizeof(fb1), sum);
+ format_bytes(fb2, sizeof(fb2), metrics->max_use);
+ format_bytes(fb3, sizeof(fb3), metrics->keep_free);
+ format_bytes(fb4, sizeof(fb4), ss_avail);
+ format_bytes(fb5, sizeof(fb5), s->cached_space_limit);
+ format_bytes(fb6, sizeof(fb6), s->cached_space_available);
server_driver_message(s, SD_MESSAGE_JOURNAL_USAGE,
- "%s (%s) is currently using %s.\n"
- "Maximum allowed usage is set to %s.\n"
- "Leaving at least %s free (of currently available %s of space).\n"
- "Enforced usage limit is thus %s, of which %s are still available.",
- name, path,
- format_bytes(fb1, sizeof(fb1), sum),
- format_bytes(fb2, sizeof(fb2), metrics->max_use),
- format_bytes(fb3, sizeof(fb3), metrics->keep_free),
- format_bytes(fb4, sizeof(fb4), ss_avail),
- format_bytes(fb5, sizeof(fb5), s->cached_space_limit),
- format_bytes(fb6, sizeof(fb6), s->cached_space_available));
+ LOG_MESSAGE("%s (%s) is %s, max %s, %s free.",
+ name, path, fb1, fb5, fb6),
+ "JOURNAL_NAME=%s", name,
+ "JOURNAL_PATH=%s", path,
+ "CURRENT_USE=%"PRIu64, sum,
+ "CURRENT_USE_PRETTY=%s", fb1,
+ "MAX_USE=%"PRIu64, metrics->max_use,
+ "MAX_USE_PRETTY=%s", fb2,
+ "DISK_KEEP_FREE=%"PRIu64, metrics->keep_free,
+ "DISK_KEEP_FREE_PRETTY=%s", fb3,
+ "DISK_AVAILABLE=%"PRIu64, ss_avail,
+ "DISK_AVAILABLE_PRETTY=%s", fb4,
+ "LIMIT=%"PRIu64, s->cached_space_limit,
+ "LIMIT_PRETTY=%s", fb5,
+ "AVAILABLE=%"PRIu64, s->cached_space_available,
+ "AVAILABLE_PRETTY=%s", fb6,
+ NULL);
}
if (available)
@@ -220,6 +237,39 @@ static void server_add_acls(JournalFile *f, uid_t uid) {
#endif
}
+static int open_journal(
+ Server *s,
+ bool reliably,
+ const char *fname,
+ int flags,
+ bool seal,
+ JournalMetrics *metrics,
+ JournalFile *template,
+ JournalFile **ret) {
+ int r;
+ JournalFile *f;
+
+ assert(s);
+ assert(fname);
+ assert(ret);
+
+ if (reliably)
+ r = journal_file_open_reliably(fname, flags, 0640, s->compress, seal, metrics, s->mmap, template, &f);
+ else
+ r = journal_file_open(fname, flags, 0640, s->compress, seal, metrics, s->mmap, template, &f);
+ if (r < 0)
+ return r;
+
+ r = journal_file_enable_post_change_timer(f, s->event, POST_CHANGE_TIMER_INTERVAL_USEC);
+ if (r < 0) {
+ journal_file_close(f);
+ return r;
+ }
+
+ *ret = f;
+ return r;
+}
+
static JournalFile* find_journal(Server *s, uid_t uid) {
_cleanup_free_ char *p = NULL;
int r;
@@ -258,7 +308,7 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
journal_file_close(f);
}
- r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &f);
+ r = open_journal(s, true, p, O_RDWR|O_CREAT, s->seal, &s->system_metrics, NULL, &f);
if (r < 0)
return s->system_journal;
@@ -808,37 +858,56 @@ static void dispatch_message_real(
void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) {
char mid[11 + 32 + 1];
- char buffer[16 + LINE_MAX + 1];
- struct iovec iovec[N_IOVEC_META_FIELDS + 6];
- int n = 0;
+ struct iovec iovec[N_IOVEC_META_FIELDS + 5 + N_IOVEC_PAYLOAD_FIELDS];
+ unsigned n = 0, m;
+ int r;
va_list ap;
struct ucred ucred = {};
assert(s);
assert(format);
+ assert_cc(3 == LOG_FAC(LOG_DAEMON));
IOVEC_SET_STRING(iovec[n++], "SYSLOG_FACILITY=3");
IOVEC_SET_STRING(iovec[n++], "SYSLOG_IDENTIFIER=systemd-journald");
- IOVEC_SET_STRING(iovec[n++], "PRIORITY=6");
IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=driver");
-
- memcpy(buffer, "MESSAGE=", 8);
- va_start(ap, format);
- vsnprintf(buffer + 8, sizeof(buffer) - 8, format, ap);
- va_end(ap);
- IOVEC_SET_STRING(iovec[n++], buffer);
+ assert_cc(6 == LOG_INFO);
+ IOVEC_SET_STRING(iovec[n++], "PRIORITY=6");
if (!sd_id128_equal(message_id, SD_ID128_NULL)) {
snprintf(mid, sizeof(mid), LOG_MESSAGE_ID(message_id));
IOVEC_SET_STRING(iovec[n++], mid);
}
+ m = n;
+
+ va_start(ap, format);
+ r = log_format_iovec(iovec, ELEMENTSOF(iovec), &n, false, 0, format, ap);
+ /* Error handling below */
+ va_end(ap);
+
ucred.pid = getpid();
ucred.uid = getuid();
ucred.gid = getgid();
- dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
+ if (r >= 0)
+ dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
+
+ while (m < n)
+ free(iovec[m++].iov_base);
+
+ if (r < 0) {
+ /* We failed to format the message. Emit a warning instead. */
+ char buf[LINE_MAX];
+
+ xsprintf(buf, "MESSAGE=Entry printing failed: %s", strerror(-r));
+
+ n = 3;
+ IOVEC_SET_STRING(iovec[n++], "PRIORITY=4");
+ IOVEC_SET_STRING(iovec[n++], buf);
+ dispatch_message_real(s, iovec, n, ELEMENTSOF(iovec), &ucred, NULL, NULL, 0, NULL, LOG_INFO, 0);
+ }
}
void server_dispatch_message(
@@ -901,7 +970,8 @@ void server_dispatch_message(
/* Write a suppression message if we suppressed something */
if (rl > 1)
server_driver_message(s, SD_MESSAGE_JOURNAL_DROPPED,
- "Suppressed %u messages from %s", rl - 1, path);
+ LOG_MESSAGE("Suppressed %u messages from %s", rl - 1, path),
+ NULL);
finish:
dispatch_message_real(s, iovec, n, m, ucred, tv, label, label_len, unit_id, priority, object_pid);
@@ -930,7 +1000,7 @@ static int system_journal_open(Server *s, bool flush_requested) {
(void) mkdir(fn, 0755);
fn = strjoina(fn, "/system.journal");
- r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, NULL, &s->system_journal);
+ r = open_journal(s, true, fn, O_RDWR|O_CREAT, s->seal, &s->system_metrics, NULL, &s->system_journal);
if (r >= 0) {
server_add_acls(s->system_journal, 0);
(void) determine_space_for(s, &s->system_metrics, "/var/log/journal/", "System journal", true, true, NULL, NULL);
@@ -953,7 +1023,7 @@ static int system_journal_open(Server *s, bool flush_requested) {
* if it already exists, so that we can flush
* it into the system journal */
- r = journal_file_open(fn, O_RDWR, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
+ r = open_journal(s, false, fn, O_RDWR, false, &s->runtime_metrics, NULL, &s->runtime_journal);
if (r < 0) {
if (r != -ENOENT)
log_warning_errno(r, "Failed to open runtime journal: %m");
@@ -970,7 +1040,7 @@ static int system_journal_open(Server *s, bool flush_requested) {
(void) mkdir("/run/log/journal", 0755);
(void) mkdir_parents(fn, 0750);
- r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
+ r = open_journal(s, true, fn, O_RDWR|O_CREAT, false, &s->runtime_metrics, NULL, &s->runtime_journal);
if (r < 0)
return log_error_errno(r, "Failed to open runtime journal: %m");
}
@@ -1073,7 +1143,11 @@ finish:
sd_journal_close(j);
- server_driver_message(s, SD_ID128_NULL, "Time spent on flushing to /var is %s for %u entries.", format_timespan(ts, sizeof(ts), now(CLOCK_MONOTONIC) - start, 0), n);
+ server_driver_message(s, SD_ID128_NULL,
+ LOG_MESSAGE("Time spent on flushing to /var is %s for %u entries.",
+ format_timespan(ts, sizeof(ts), now(CLOCK_MONOTONIC) - start, 0),
+ n),
+ NULL);
return r;
}
@@ -1330,7 +1404,7 @@ static int server_parse_proc_cmdline(Server *s) {
p = line;
for(;;) {
- _cleanup_free_ char *word;
+ _cleanup_free_ char *word = NULL;
r = extract_first_word(&p, &word, NULL, 0);
if (r < 0)
diff --git a/src/journal/journald-server.h b/src/journal/journald-server.h
index 1822765228..49bbee0646 100644
--- a/src/journal/journald-server.h
+++ b/src/journal/journald-server.h
@@ -157,9 +157,10 @@ struct Server {
#define N_IOVEC_KERNEL_FIELDS 64
#define N_IOVEC_UDEV_FIELDS 32
#define N_IOVEC_OBJECT_FIELDS 12
+#define N_IOVEC_PAYLOAD_FIELDS 15
void server_dispatch_message(Server *s, struct iovec *iovec, unsigned n, unsigned m, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len, const char *unit_id, int priority, pid_t object_pid);
-void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) _printf_(3,4);
+void server_driver_message(Server *s, sd_id128_t message_id, const char *format, ...) _printf_(3,0) _sentinel_;
/* gperf lookup function */
const struct ConfigPerfItem* journald_gperf_lookup(const char *key, unsigned length);
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
index 2f7a805f14..9f2ccdcc77 100644
--- a/src/journal/journald-syslog.c
+++ b/src/journal/journald-syslog.c
@@ -326,7 +326,7 @@ void server_process_syslog_message(
size_t label_len) {
char syslog_priority[sizeof("PRIORITY=") + DECIMAL_STR_MAX(int)],
- syslog_facility[sizeof("SYSLOG_FACILITY") + DECIMAL_STR_MAX(int)];
+ syslog_facility[sizeof("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(int)];
const char *message = NULL, *syslog_identifier = NULL, *syslog_pid = NULL;
struct iovec iovec[N_IOVEC_META_FIELDS + 6];
unsigned n = 0;
@@ -357,11 +357,11 @@ void server_process_syslog_message(
IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=syslog");
- sprintf(syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK);
+ xsprintf(syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK);
IOVEC_SET_STRING(iovec[n++], syslog_priority);
if (priority & LOG_FACMASK) {
- sprintf(syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority));
+ xsprintf(syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority));
IOVEC_SET_STRING(iovec[n++], syslog_facility);
}
@@ -448,7 +448,10 @@ void server_maybe_warn_forward_syslog_missed(Server *s) {
if (s->last_warn_forward_syslog_missed + WARN_FORWARD_SYSLOG_MISSED_USEC > n)
return;
- server_driver_message(s, SD_MESSAGE_FORWARD_SYSLOG_MISSED, "Forwarding to syslog missed %u messages.", s->n_forward_syslog_missed);
+ server_driver_message(s, SD_MESSAGE_FORWARD_SYSLOG_MISSED,
+ LOG_MESSAGE("Forwarding to syslog missed %u messages.",
+ s->n_forward_syslog_missed),
+ NULL);
s->n_forward_syslog_missed = 0;
s->last_warn_forward_syslog_missed = n;
diff --git a/src/journal/journald.c b/src/journal/journald.c
index b9f5c099e1..293b788d03 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -58,7 +58,9 @@ int main(int argc, char *argv[]) {
server_flush_dev_kmsg(&server);
log_debug("systemd-journald running as pid "PID_FMT, getpid());
- server_driver_message(&server, SD_MESSAGE_JOURNAL_START, "Journal started");
+ server_driver_message(&server, SD_MESSAGE_JOURNAL_START,
+ LOG_MESSAGE("Journal started"),
+ NULL);
for (;;) {
usec_t t = USEC_INFINITY, n;
@@ -109,7 +111,9 @@ int main(int argc, char *argv[]) {
}
log_debug("systemd-journald stopped as pid "PID_FMT, getpid());
- server_driver_message(&server, SD_MESSAGE_JOURNAL_STOP, "Journal stopped");
+ server_driver_message(&server, SD_MESSAGE_JOURNAL_STOP,
+ LOG_MESSAGE("Journal stopped"),
+ NULL);
finish:
server_done(&server);