journald: augment journal entries from the kernel with data from udev

This commit is contained in:
Lennart Poettering 2012-08-22 02:49:17 +02:00
parent c0d6e764d1
commit bdfb9e7f7c
5 changed files with 106 additions and 12 deletions

View 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 += \

View file

@ -131,17 +131,19 @@
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

View 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>
@ -338,6 +339,33 @@
<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>

View 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[]) {

View file

@ -99,6 +99,8 @@ typedef struct Server {
bool dev_kmsg_readable;
uint64_t *kernel_seqnum;
struct udev *udev;
} Server;
/* gperf lookup function */