chiark / gitweb /
journald: write tags also to user journal files
[elogind.git] / src / journal / journald.c
index 7b3b6471de79c4cf4e22d29512186aa898de278d..5dc5c95cfa9b59e7591e4a1d56a7810c83f21441 100644 (file)
@@ -31,6 +31,7 @@
 #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>
@@ -48,6 +49,7 @@
 #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"
@@ -73,6 +75,7 @@
 
 #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)
 
@@ -1810,7 +1813,7 @@ static bool is_us(const char *pid) {
 }
 
 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;
@@ -1818,6 +1821,7 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) {
         char *identifier = NULL, *pid = NULL, *e, *f, *k;
         uint64_t serial;
         size_t pl;
+        char *kernel_device = NULL;
 
         assert(s);
         assert(p);
@@ -1909,6 +1913,9 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) {
                 if (!m)
                         break;
 
+                if (startswith(m, "_KERNEL_DEVICE="))
+                        kernel_device = m + 15;
+
                 IOVEC_SET_STRING(iovec[n++], m);
                 z++;
 
@@ -1916,6 +1923,54 @@ static void dev_kmsg_record(Server *s, char *p, size_t l) {
                 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);
@@ -2160,7 +2215,7 @@ static int server_read_dev_kmsg(Server *s) {
                         return 0;
                 }
 
-                if (errno == EAGAIN || errno == EINTR)
+                if (errno == EAGAIN || errno == EINTR || errno == EPIPE)
                         return 0;
 
                 log_error("Failed to read from kernel: %m");
@@ -2870,6 +2925,10 @@ static int server_init(Server *s) {
         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;
@@ -2881,6 +2940,22 @@ static int server_init(Server *s) {
         return 0;
 }
 
+static void maybe_append_tags(Server *s) {
+#ifdef HAVE_GCRYPT
+        JournalFile *f;
+        Iterator i;
+        usec_t n;
+
+        n = now(CLOCK_REALTIME);
+
+        if (s->system_journal)
+                journal_file_maybe_append_tag(s->system_journal, n);
+
+        HASHMAP_FOREACH(f, s->user_journals, i)
+                journal_file_maybe_append_tag(f, n);
+#endif
+}
+
 static void server_done(Server *s) {
         JournalFile *f;
         assert(s);
@@ -2928,6 +3003,9 @@ static void server_done(Server *s) {
 
         if (s->mmap)
                 mmap_cache_unref(s->mmap);
+
+        if (s->udev)
+                udev_unref(s->udev);
 }
 
 int main(int argc, char *argv[]) {
@@ -2969,8 +3047,26 @@ int main(int argc, char *argv[]) {
 
         for (;;) {
                 struct epoll_event event;
+                int t;
+
+#ifdef HAVE_GCRYPT
+                usec_t u;
+
+                if (server.system_journal &&
+                    journal_file_next_evolve_usec(server.system_journal, &u)) {
+                        usec_t n;
 
-                r = epoll_wait(server.epoll_fd, &event, 1, -1);
+                        n = now(CLOCK_REALTIME);
+
+                        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)
@@ -2979,14 +3075,17 @@ int main(int argc, char *argv[]) {
                         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;
+                }
+
+                maybe_append_tags(&server);
         }
 
         log_debug("systemd-journald stopped as pid %lu", (unsigned long) getpid());