chiark / gitweb /
journald: augment journal entries from the kernel with data from udev
authorLennart Poettering <lennart@poettering.net>
Wed, 22 Aug 2012 00:49:17 +0000 (02:49 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 22 Aug 2012 00:49:17 +0000 (02:49 +0200)
Makefile.am
man/sd_journal_print.xml
man/systemd.journal-fields.xml
src/journal/journald.c
src/journal/journald.h

index e6bfc1f..22445fb 100644 (file)
@@ -2322,7 +2322,8 @@ systemd_journald_LDADD = \
        libsystemd-audit.la \
        libsystemd-daemon.la \
        libsystemd-id128-internal.la \
-       libsystemd-journal-internal.la
+       libsystemd-journal-internal.la \
+       libudev.la
 
 if ENABLE_LOGIND
 systemd_journald_LDADD += \
index 7eac6c8..c03762a 100644 (file)
                 immediately followed by their associated parameters,
                 terminated by NULL. The strings passed should be of
                 the format <literal>VARIABLE=value</literal>. The
-                variable name must be in uppercase and consist only
-                of characters, numbers and underscores, and may not
-                begin with an underscore. The value can be of any size
-                and format. It is highly recommended to submit
-                text strings formatted in the UTF-8 character encoding
-                only, and submit binary fields only when formatting in
-                UTf-8 strings is not sensible. A number of well known
-                fields are defined, see
+                variable name must be in uppercase and consist only of
+                characters, numbers and underscores, and may not begin
+                with an underscore. (All assignments that do not
+                follow this syntax will be ignored.) The value can be
+                of any size and format. It is highly recommended to
+                submit text strings formatted in the UTF-8 character
+                encoding only, and submit binary fields only when
+                formatting in UTf-8 strings is not sensible. A number
+                of well known fields are defined, see
                 <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry>
                 for details, but additional application defined fields
-                may be used.</para>
+                may be used. A variable may be assigned more than one
+                value per entry.</para>
 
                 <para><function>sd_journal_sendv()</function> is
                 similar to <function>sd_journal_send()</function> but
index d790c35..b555c0e 100644 (file)
@@ -58,7 +58,8 @@
                 sense. New fields may freely be defined by
                 applications, but a few fields have special
                 meaning. All fields with special meanings are
-                optional.</para>
+                optional. In some cases fields may appear more than
+                once per entry.</para>
         </refsect1>
 
         <refsect1>
                                         <para>The kernel subsystem name.</para>
                                 </listitem>
                         </varlistentry>
+                        <varlistentry>
+                                <term>_UDEV_SYSNAME=</term>
+                                <listitem>
+                                        <para>The kernel device name
+                                        as it shows up in the device
+                                        tree below
+                                        <filename>/sys</filename>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term>_UDEV_DEVNODE=</term>
+                                <listitem>
+                                        <para>The device node path of
+                                        this device in
+                                        <filename>/dev</filename>.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
+                                <term>_UDEV_DEVLINK=</term>
+                                <listitem>
+                                        <para>Additional symlink names
+                                        pointing to the device node in
+                                        <filename>/dev</filename>. This
+                                        field is frequently set more
+                                        than once per entry.</para>
+                                </listitem>
+                        </varlistentry>
                 </variablelist>
         </refsect1>
 
index a5025f5..2429dd3 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>
@@ -74,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)
 
@@ -1811,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;
@@ -1819,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);
@@ -1910,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++;
 
@@ -1917,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);
@@ -2871,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;
@@ -2929,6 +2987,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[]) {
index 13f2f1f..da2c312 100644 (file)
@@ -99,6 +99,8 @@ typedef struct Server {
         bool dev_kmsg_readable;
 
         uint64_t *kernel_seqnum;
+
+        struct udev *udev;
 } Server;
 
 /* gperf lookup function */