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 += \
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
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>
#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>
#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)
}
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 (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;
if (s->mmap)
mmap_cache_unref(s->mmap);
+
+ if (s->udev)
+ udev_unref(s->udev);
}
int main(int argc, char *argv[]) {
bool dev_kmsg_readable;
uint64_t *kernel_seqnum;
+
+ struct udev *udev;
} Server;
/* gperf lookup function */