mirror of
https://git.proxmox.com/git/systemd
synced 2025-06-04 18:52:29 +00:00
202 lines
14 KiB
HTML
202 lines
14 KiB
HTML
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>sd_journal_get_fd</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><style>
|
||
a.headerlink {
|
||
color: #c60f0f;
|
||
font-size: 0.8em;
|
||
padding: 0 4px 0 4px;
|
||
text-decoration: none;
|
||
visibility: hidden;
|
||
}
|
||
|
||
a.headerlink:hover {
|
||
background-color: #c60f0f;
|
||
color: white;
|
||
}
|
||
|
||
h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, dt:hover > a.headerlink {
|
||
visibility: visible;
|
||
}
|
||
</style><a href="index.html">Index </a>·
|
||
<a href="systemd.directives.html">Directives </a>·
|
||
<a href="../python-systemd/index.html">Python </a>·
|
||
<a href="../libudev/index.html">libudev </a>·
|
||
<a href="../libudev/index.html">gudev </a><span style="float:right">systemd 219</span><hr><div class="refentry"><a name="sd_journal_get_fd"></a><div class="titlepage"></div><div class="refnamediv"><h2>Name</h2><p>sd_journal_get_fd, sd_journal_get_events, sd_journal_get_timeout, sd_journal_process, sd_journal_wait, sd_journal_reliable_fd, SD_JOURNAL_NOP, SD_JOURNAL_APPEND, SD_JOURNAL_INVALIDATE — Journal change notification
|
||
interface</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><div class="funcsynopsis"><pre class="funcsynopsisinfo">#include <systemd/sd-journal.h></pre><table border="0" class="funcprototype-table" summary="Function synopsis" style="cellspacing: 0; cellpadding: 0;"><tr><td><code class="funcdef">int <b class="fsfunc">sd_journal_get_fd</b>(</code></td><td>sd_journal *<var class="pdparam">j</var><code>)</code>;</td></tr></table><div class="funcprototype-spacer"> </div><table border="0" class="funcprototype-table" summary="Function synopsis" style="cellspacing: 0; cellpadding: 0;"><tr><td><code class="funcdef">int <b class="fsfunc">sd_journal_get_events</b>(</code></td><td>sd_journal *<var class="pdparam">j</var><code>)</code>;</td></tr></table><div class="funcprototype-spacer"> </div><table border="0" class="funcprototype-table" summary="Function synopsis" style="cellspacing: 0; cellpadding: 0;"><tr><td><code class="funcdef">int <b class="fsfunc">sd_journal_get_timeout</b>(</code></td><td>sd_journal *<var class="pdparam">j</var>, </td></tr><tr><td> </td><td>uint64_t *<var class="pdparam">timeout_usec</var><code>)</code>;</td></tr></table><div class="funcprototype-spacer"> </div><table border="0" class="funcprototype-table" summary="Function synopsis" style="cellspacing: 0; cellpadding: 0;"><tr><td><code class="funcdef">int <b class="fsfunc">sd_journal_process</b>(</code></td><td>sd_journal *<var class="pdparam">j</var><code>)</code>;</td></tr></table><div class="funcprototype-spacer"> </div><table border="0" class="funcprototype-table" summary="Function synopsis" style="cellspacing: 0; cellpadding: 0;"><tr><td><code class="funcdef">int <b class="fsfunc">sd_journal_wait</b>(</code></td><td>sd_journal *<var class="pdparam">j</var>, </td></tr><tr><td> </td><td>uint64_t <var class="pdparam">timeout_usec</var><code>)</code>;</td></tr></table><div class="funcprototype-spacer"> </div><table border="0" class="funcprototype-table" summary="Function synopsis" style="cellspacing: 0; cellpadding: 0;"><tr><td><code class="funcdef">int <b class="fsfunc">sd_journal_reliable_fd</b>(</code></td><td>sd_journal *<var class="pdparam">j</var><code>)</code>;</td></tr></table><div class="funcprototype-spacer"> </div></div></div><div class="refsect1"><a name="idm140121381493808"></a><h2 id="Description">Description<a class="headerlink" title="Permalink to this headline" href="#Description">¶</a></h2><p><code class="function">sd_journal_get_fd()</code> returns a file
|
||
descriptor that may be asynchronously polled in an external event
|
||
loop and is signaled as soon as the journal changes, because new
|
||
entries or files were added, rotation took place, or files have
|
||
been deleted, and similar. The file descriptor is suitable for
|
||
usage in
|
||
<a href="http://man7.org/linux/man-pages/man2/poll.2.html"><span class="citerefentry"><span class="refentrytitle">poll</span>(2)</span></a>.
|
||
Use <code class="function">sd_journal_get_events()</code> for an events
|
||
mask to watch for. The call takes one argument: the journal
|
||
context object. Note that not all file systems are capable of
|
||
generating the necessary events for wakeups from this file
|
||
descriptor for changes to be noticed immediately. In particular
|
||
network files systems do not generate suitable file change events
|
||
in all cases. Cases like this can be detected with
|
||
<code class="function">sd_journal_reliable_fd()</code>, below.
|
||
<code class="function">sd_journal_get_timeout()</code> will ensure in these
|
||
cases that wake-ups happen frequently enough for changes to be
|
||
noticed, although with a certain latency.</p><p><code class="function">sd_journal_get_events()</code> will return the
|
||
<code class="function">poll()</code> mask to wait for. This function will
|
||
return a combination of <code class="constant">POLLIN</code> and
|
||
<code class="constant">POLLOUT</code> and similar to fill into the
|
||
"<code class="literal">.events</code>" field of <code class="varname">struct
|
||
pollfd</code>.</p><p><code class="function">sd_journal_get_timeout()</code> will return a
|
||
timeout value for usage in <code class="function">poll()</code>. This
|
||
returns a value in microseconds since the epoch of
|
||
<code class="constant">CLOCK_MONOTONIC</code> for timing out
|
||
<code class="function">poll()</code> in <code class="varname">timeout_usec</code>.
|
||
See
|
||
<a href="http://man7.org/linux/man-pages/man2/clock_gettime.2.html"><span class="citerefentry"><span class="refentrytitle">clock_gettime</span>(2)</span></a>
|
||
for details about <code class="constant">CLOCK_MONOTONIC</code>. If there
|
||
is no timeout to wait for, this will fill in <code class="constant">(uint64_t)
|
||
-1</code> instead. Note that <code class="function">poll()</code> takes
|
||
a relative timeout in milliseconds rather than an absolute timeout
|
||
in microseconds. To convert the absolute 'us' timeout into
|
||
relative 'ms', use code like the following:</p><pre class="programlisting">uint64_t t;
|
||
int msec;
|
||
sd_journal_get_timeout(m, &t);
|
||
if (t == (uint64_t) -1)
|
||
msec = -1;
|
||
else {
|
||
struct timespec ts;
|
||
uint64_t n;
|
||
clock_getttime(CLOCK_MONOTONIC, &ts);
|
||
n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
|
||
msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
|
||
}</pre><p>The code above does not do any error checking for brevity's
|
||
sake. The calculated <code class="varname">msec</code> integer can be passed
|
||
directly as <code class="function">poll()</code>'s timeout
|
||
parameter.</p><p>After each <code class="function">poll()</code> wake-up
|
||
<code class="function">sd_journal_process()</code> needs to be called to
|
||
process events. This call will also indicate what kind of change
|
||
has been detected (see below; note that spurious wake-ups are
|
||
possible).</p><p>A synchronous alternative for using
|
||
<code class="function">sd_journal_get_fd()</code>,
|
||
<code class="function">sd_journal_get_events()</code>,
|
||
<code class="function">sd_journal_get_timeout()</code> and
|
||
<code class="function">sd_journal_process()</code> is
|
||
<code class="function">sd_journal_wait()</code>. It will synchronously wait
|
||
until the journal gets changed. The maximum time this call sleeps
|
||
may be controlled with the <em class="parameter"><code>timeout_usec</code></em>
|
||
parameter. Pass <code class="constant">(uint64_t) -1</code> to wait
|
||
indefinitely. Internally this call simply combines
|
||
<code class="function">sd_journal_get_fd()</code>,
|
||
<code class="function">sd_journal_get_events()</code>,
|
||
<code class="function">sd_journal_get_timeout()</code>,
|
||
<code class="function">poll()</code> and
|
||
<code class="function">sd_journal_process()</code> into one.</p><p><code class="function">sd_journal_reliable_fd()</code> may be used to
|
||
check whether the wakeup events from the file descriptor returned
|
||
by <code class="function">sd_journal_get_fd()</code> are known to be
|
||
immediately triggered. On certain file systems where file change
|
||
events from the OS are not available (such as NFS) changes need to
|
||
be polled for repeatedly, and hence are detected only with a
|
||
certain latency. This call will return a positive value if the
|
||
journal changes are detected immediately and zero when they need
|
||
to be polled for and hence might be noticed only with a certain
|
||
latency. Note that there's usually no need to invoke this function
|
||
directly as <code class="function">sd_journal_get_timeout()</code> on these
|
||
file systems will ask for timeouts explicitly anyway.</p></div><div class="refsect1"><a name="idm140121381454848"></a><h2 id="Return Value">Return Value<a class="headerlink" title="Permalink to this headline" href="#Return%20Value">¶</a></h2><p><code class="function">sd_journal_get_fd()</code> returns a valid
|
||
file descriptor on success or a negative errno-style error
|
||
code.</p><p><code class="function">sd_journal_get_events()</code> returns a
|
||
combination of <code class="constant">POLLIN</code>,
|
||
<code class="constant">POLLOUT</code> and suchlike on success or a negative
|
||
errno-style error code.</p><p><code class="function">sd_journal_reliable_fd()</code> returns a
|
||
positive integer if the file descriptor returned by
|
||
<code class="function">sd_journal_get_fd()</code> will generate wake-ups
|
||
immediately for all journal changes. Returns 0 if there might be a
|
||
latency involved.</p><p><code class="function">sd_journal_process()</code> and
|
||
<code class="function">sd_journal_wait()</code> return one of
|
||
<code class="constant">SD_JOURNAL_NOP</code>,
|
||
<code class="constant">SD_JOURNAL_APPEND</code> or
|
||
<code class="constant">SD_JOURNAL_INVALIDATE</code> on success or a
|
||
negative errno-style error code. If
|
||
<code class="constant">SD_JOURNAL_NOP</code> is returned, the journal did
|
||
not change since the last invocation. If
|
||
<code class="constant">SD_JOURNAL_APPEND</code> is returned, new entries
|
||
have been appended to the end of the journal. If
|
||
<code class="constant">SD_JOURNAL_INVALIDATE</code>, journal files were
|
||
added or removed (possibly due to rotation). In the latter event,
|
||
live-view UIs should probably refresh their entire display, while
|
||
in the case of <code class="constant">SD_JOURNAL_APPEND</code>, it is
|
||
sufficient to simply continue reading at the previous end of the
|
||
journal.</p></div><div class="refsect1"><a name="idm140121381556448"></a><h2 id="Notes">Notes<a class="headerlink" title="Permalink to this headline" href="#Notes">¶</a></h2><p>The <code class="function">sd_journal_get_fd()</code>,
|
||
<code class="function">sd_journal_get_events()</code>,
|
||
<code class="function">sd_journal_reliable_fd()</code>,
|
||
<code class="function">sd_journal_process()</code> and
|
||
<code class="function">sd_journal_wait()</code> interfaces are available as
|
||
a shared library, which can be compiled and linked to with the
|
||
<code class="constant">libsystemd</code> <a href="http://linux.die.net/man/1/pkg-config"><span class="citerefentry"><span class="refentrytitle">pkg-config</span>(1)</span></a>
|
||
file.</p></div><div class="refsect1"><a name="idm140121376465504"></a><h2 id="Examples">Examples<a class="headerlink" title="Permalink to this headline" href="#Examples">¶</a></h2><p>Iterating through the journal, in a live view tracking all
|
||
changes:</p><pre class="programlisting">#include <stdio.h>
|
||
#include <string.h>
|
||
#include <systemd/sd-journal.h>
|
||
|
||
int main(int argc, char *argv[]) {
|
||
int r;
|
||
sd_journal *j;
|
||
r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
|
||
if (r < 0) {
|
||
fprintf(stderr, "Failed to open journal: %s\n", strerror(-r));
|
||
return 1;
|
||
}
|
||
for (;;) {
|
||
const void *d;
|
||
size_t l;
|
||
r = sd_journal_next(j);
|
||
if (r < 0) {
|
||
fprintf(stderr, "Failed to iterate to next entry: %s\n", strerror(-r));
|
||
break;
|
||
}
|
||
if (r == 0) {
|
||
/* Reached the end, let's wait for changes, and try again */
|
||
r = sd_journal_wait(j, (uint64_t) -1);
|
||
if (r < 0) {
|
||
fprintf(stderr, "Failed to wait for changes: %s\n", strerror(-r));
|
||
break;
|
||
}
|
||
continue;
|
||
}
|
||
r = sd_journal_get_data(j, "MESSAGE", &d, &l);
|
||
if (r < 0) {
|
||
fprintf(stderr, "Failed to read message field: %s\n", strerror(-r));
|
||
continue;
|
||
}
|
||
printf("%.*s\n", (int) l, (const char*) d);
|
||
}
|
||
sd_journal_close(j);
|
||
return 0;
|
||
}</pre><p>Waiting with <code class="function">poll()</code> (this
|
||
example lacks all error checking for the sake of
|
||
simplicity):</p><pre class="programlisting">#include <poll.h>
|
||
#include <systemd/sd-journal.h>
|
||
|
||
int wait_for_changes(sd_journal *j) {
|
||
struct pollfd pollfd;
|
||
int msec;
|
||
|
||
sd_journal_get_timeout(m, &t);
|
||
if (t == (uint64_t) -1)
|
||
msec = -1;
|
||
else {
|
||
struct timespec ts;
|
||
uint64_t n;
|
||
clock_getttime(CLOCK_MONOTONIC, &ts);
|
||
n = (uint64_t) ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
|
||
msec = t > n ? (int) ((t - n + 999) / 1000) : 0;
|
||
}
|
||
|
||
pollfd.fd = sd_journal_get_fd(j);
|
||
pollfd.events = sd_journal_get_events(j);
|
||
poll(&pollfd, 1, msec);
|
||
return sd_journal_process(j);
|
||
}</pre></div><div class="refsect1"><a name="idm140121376459680"></a><h2 id="See Also">See Also<a class="headerlink" title="Permalink to this headline" href="#See%20Also">¶</a></h2><p>
|
||
<a href="systemd.html"><span class="citerefentry"><span class="refentrytitle">systemd</span>(1)</span></a>,
|
||
<a href="sd-journal.html"><span class="citerefentry"><span class="refentrytitle">sd-journal</span>(3)</span></a>,
|
||
<a href="sd_journal_open.html"><span class="citerefentry"><span class="refentrytitle">sd_journal_open</span>(3)</span></a>,
|
||
<a href="sd_journal_next.html"><span class="citerefentry"><span class="refentrytitle">sd_journal_next</span>(3)</span></a>,
|
||
<a href="http://man7.org/linux/man-pages/man2/poll.2.html"><span class="citerefentry"><span class="refentrytitle">poll</span>(2)</span></a>,
|
||
<a href="http://man7.org/linux/man-pages/man2/clock_gettime.2.html"><span class="citerefentry"><span class="refentrytitle">clock_gettime</span>(2)</span></a>
|
||
</p></div></div></body></html>
|