#include <sys/statvfs.h>
#include <sys/mman.h>
+#include <libudev.h>
#include <systemd/sd-journal.h>
#include <systemd/sd-messages.h>
#include <systemd/sd-daemon.h>
#include "list.h"
#include "journal-rate-limit.h"
#include "journal-internal.h"
+#include "journal-vacuum.h"
+#include "journal-authenticate.h"
#include "conf-parser.h"
#include "journald.h"
#include "virt.h"
#define N_IOVEC_META_FIELDS 17
#define N_IOVEC_KERNEL_FIELDS 64
+#define N_IOVEC_UDEV_FIELDS 32
#define ENTRY_SIZE_MAX (1024*1024*32)
char *p;
int r;
JournalFile *f;
- char ids[33];
sd_id128_t machine;
assert(s);
if (f)
return f;
- if (asprintf(&p, "/var/log/journal/%s/user-%lu.journal", sd_id128_to_string(machine, ids), (unsigned long) uid) < 0)
+ if (asprintf(&p, "/var/log/journal/" SD_ID128_FORMAT_STR "/user-%lu.journal",
+ SD_ID128_FORMAT_VAL(machine), (unsigned long) uid) < 0)
return s->system_journal;
while (hashmap_size(s->user_journals) >= USER_JOURNALS_MAX) {
journal_file_close(f);
}
- r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, &s->system_metrics, s->system_journal, &f);
+ r = journal_file_open_reliably(p, O_RDWR|O_CREAT, 0640, s->compress, s->seal, &s->system_metrics, s->mmap, s->system_journal, &f);
free(p);
if (r < 0)
log_info("Rotating...");
if (s->runtime_journal) {
- r = journal_file_rotate(&s->runtime_journal);
+ r = journal_file_rotate(&s->runtime_journal, s->compress, false);
if (r < 0)
if (s->runtime_journal)
log_error("Failed to rotate %s: %s", s->runtime_journal->path, strerror(-r));
}
if (s->system_journal) {
- r = journal_file_rotate(&s->system_journal);
+ r = journal_file_rotate(&s->system_journal, s->compress, s->seal);
if (r < 0)
if (s->system_journal)
log_error("Failed to rotate %s: %s", s->system_journal->path, strerror(-r));
}
HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
- r = journal_file_rotate(&f);
+ r = journal_file_rotate(&f, s->compress, s->seal);
if (r < 0)
if (f->path)
log_error("Failed to rotate %s: %s", f->path, strerror(-r));
}
static void dev_kmsg_record(Server *s, char *p, size_t l) {
- struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS];
+ struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS];
char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL;
int priority, r;
unsigned n = 0, z = 0, j;
char *identifier = NULL, *pid = NULL, *e, *f, *k;
uint64_t serial;
size_t pl;
+ char *kernel_device = NULL;
assert(s);
assert(p);
if (!m)
break;
+ if (startswith(m, "_KERNEL_DEVICE="))
+ kernel_device = m + 15;
+
IOVEC_SET_STRING(iovec[n++], m);
z++;
k = e + 1;
}
+ if (kernel_device) {
+ struct udev_device *ud;
+
+ ud = udev_device_new_from_device_id(s->udev, kernel_device);
+ if (ud) {
+ const char *g;
+ struct udev_list_entry *ll;
+ char *b;
+
+ g = udev_device_get_devnode(ud);
+ if (g) {
+ b = strappend("_UDEV_DEVNODE=", g);
+ if (b) {
+ IOVEC_SET_STRING(iovec[n++], b);
+ z++;
+ }
+ }
+
+ g = udev_device_get_sysname(ud);
+ if (g) {
+ b = strappend("_UDEV_SYSNAME=", g);
+ if (b) {
+ IOVEC_SET_STRING(iovec[n++], b);
+ z++;
+ }
+ }
+
+ j = 0;
+ ll = udev_device_get_devlinks_list_entry(ud);
+ udev_list_entry_foreach(ll, ll) {
+
+ if (j > N_IOVEC_UDEV_FIELDS)
+ break;
+
+ g = udev_list_entry_get_name(ll);
+ b = strappend("_UDEV_DEVLINK=", g);
+ if (g) {
+ IOVEC_SET_STRING(iovec[n++], b);
+ z++;
+ }
+
+ j++;
+ }
+
+ udev_device_unref(ud);
+ }
+ }
+
if (asprintf(&source_time, "_SOURCE_MONOTONIC_TIMESTAMP=%llu",
(unsigned long long) usec) >= 0)
IOVEC_SET_STRING(iovec[n++], source_time);
if (!fn)
return -ENOMEM;
- r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, &s->system_metrics, NULL, &s->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);
free(fn);
- if (r >= 0) {
- s->system_journal->compress = s->compress;
-
+ if (r >= 0)
server_fix_perms(s, s->system_journal, 0);
- } else if (r < 0) {
+ else if (r < 0) {
if (r != -ENOENT && r != -EROFS)
log_warning("Failed to open system journal: %s", strerror(-r));
* if it already exists, so that we can flush
* it into the system journal */
- r = journal_file_open(fn, O_RDWR, 0640, &s->runtime_metrics, NULL, &s->runtime_journal);
+ r = journal_file_open(fn, O_RDWR, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
free(fn);
if (r < 0) {
* it if necessary. */
(void) mkdir_parents(fn, 0755);
- r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, &s->runtime_metrics, NULL, &s->runtime_journal);
+ r = journal_file_open_reliably(fn, O_RDWR|O_CREAT, 0640, s->compress, false, &s->runtime_metrics, s->mmap, NULL, &s->runtime_journal);
free(fn);
if (r < 0) {
}
}
- if (s->runtime_journal) {
- s->runtime_journal->compress = s->compress;
-
+ if (s->runtime_journal)
server_fix_perms(s, s->runtime_journal, 0);
- }
}
return r;
return 0;
}
- if (errno == EAGAIN || errno == EINTR)
+ if (errno == EAGAIN || errno == EINTR || errno == EPIPE)
return 0;
log_error("Failed to read from kernel: %m");
zero(*s);
s->syslog_fd = s->native_fd = s->stdout_fd = s->signal_fd = s->epoll_fd = s->dev_kmsg_fd = -1;
s->compress = true;
+ s->seal = true;
s->rate_limit_interval = DEFAULT_RATE_LIMIT_INTERVAL;
s->rate_limit_burst = DEFAULT_RATE_LIMIT_BURST;
if (!s->user_journals)
return log_oom();
+ s->mmap = mmap_cache_new();
+ if (!s->mmap)
+ return log_oom();
+
s->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (s->epoll_fd < 0) {
log_error("Failed to create epoll object: %m");
if (r < 0)
return r;
+ s->udev = udev_new();
+ if (!s->udev)
+ return -ENOMEM;
+
s->rate_limit = journal_rate_limit_new(s->rate_limit_interval, s->rate_limit_burst);
if (!s->rate_limit)
return -ENOMEM;
free(s->buffer);
free(s->tty_path);
+
+ if (s->mmap)
+ mmap_cache_unref(s->mmap);
+
+ if (s->udev)
+ udev_unref(s->udev);
}
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();
for (;;) {
struct epoll_event event;
+ int t;
- r = epoll_wait(server.epoll_fd, &event, 1, -1);
+#ifdef HAVE_GCRYPT
+ usec_t u;
+
+ if (server.system_journal &&
+ journal_file_next_evolve_usec(server.system_journal, &u)) {
+ usec_t n;
+
+ n = now(CLOCK_MONOTONIC);
+
+ if (n >= u)
+ t = 0;
+ else
+ t = (int) ((u - n + USEC_PER_MSEC - 1) / USEC_PER_MSEC);
+ } else
+#endif
+ t = -1;
+
+ r = epoll_wait(server.epoll_fd, &event, 1, t);
if (r < 0) {
if (errno == EINTR)
log_error("epoll_wait() failed: %m");
r = -errno;
goto finish;
- } else if (r == 0)
- break;
+ }
- r = process_event(&server, &event);
- if (r < 0)
- goto finish;
- else if (r == 0)
- break;
+ if (r > 0) {
+ r = process_event(&server, &event);
+ if (r < 0)
+ goto finish;
+ else if (r == 0)
+ break;
+ }
+
+#ifdef HAVE_GCRYPT
+ if (server.system_journal)
+ journal_file_maybe_append_tag(server.system_journal, 0);
+#endif
}
log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid());