X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=man%2Fsd_journal_get_fd.xml;h=764f716a17efb3aa0c282a4f6f2e00b193b8e5f9;hp=f4db2a392aed5b329ad6cfd29ae335b70173af37;hb=accdd018ede77ef1c057775396c18c73406cbcb4;hpb=91a031725396faebf51ea7b5475532453b8d6df3 diff --git a/man/sd_journal_get_fd.xml b/man/sd_journal_get_fd.xml index f4db2a392..764f716a1 100644 --- a/man/sd_journal_get_fd.xml +++ b/man/sd_journal_get_fd.xml @@ -44,8 +44,14 @@ sd_journal_get_fd - sd_journal_get_process - sd_journal_get_wait + 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 @@ -59,6 +65,17 @@ sd_journal* j + + int sd_journal_get_events + sd_journal* j + + + + int sd_journal_get_timeout + sd_journal* j + uint64_t* timeout_usec + + int sd_journal_process sd_journal* j @@ -70,6 +87,11 @@ uint64_t timeout_usec + + int sd_journal_reliable_fd + sd_journal* j + + @@ -78,57 +100,147 @@ sd_journal_get_fd() returns a file descriptor that may be asynchronously polled in - an external event loop and is signalled readable as - soon as the journal changes, for example because new - entries were added. The file descriptor is suitable + 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 - poll2 - where it will yield POLLIN on all changes. The call - takes one argument: the journal context object. + poll2. Use + sd_journal_get_events() 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 + sd_journal_reliable_fd(), + below. sd_journal_get_timeout() + will ensure in these cases that wake-ups happen + frequently enough for changes to be noticed, although + with a certain latency. + + sd_journal_get_events() + will return the poll() mask to + wait for. This function will return a combination of + POLLIN and + POLLOUT and similar to fill into + the .events field of + struct pollfd. + + sd_journal_get_timeout() + will return a timeout value for usage in + poll(). This returns a value in + microseconds since the epoch of + CLOCK_MONOTONIC for timing out + poll() in + timeout_usec. See + clock_gettime2 + for details about + CLOCK_MONOTONIC. If there is no + timeout to wait for, this will fill in + (uint64_t) -1 instead. Note that + poll() 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: + + 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; +} - After each POLLIN wake-up + The code above does not do any error checking + for brevity's sake. The calculated msec + integer can be passed directly as + poll()'s timeout + parameter. + + After each poll() wake-up sd_journal_process() needs to be - called to process events and reset the readable state - of the file descriptor. This call will also indicate + 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). A synchronous alternative for using - sd_journal_get_fd() and + sd_journal_get_fd(), + sd_journal_get_events(), + sd_journal_get_timeout() and sd_journal_process() is sd_journal_wait(). It will - synchronously wait until the journal gets changed up - to a certain time-out as specified in its second - argument. Pass (uint64_t) -1 to + synchronously wait until the journal gets changed. The + maximum time this call sleeps may be controlled with + the timeout_usec + parameter. Pass (uint64_t) -1 to wait indefinitely. Internally this call simply combines sd_journal_get_fd(), + sd_journal_get_events(), + sd_journal_get_timeout(), poll() and sd_journal_process() into one. + sd_journal_reliable_fd() + may be used to check whether the wakeup events from + the file descriptor returned by + sd_journal_get_fd() 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 + sd_journal_get_timeout() on these + file systems will ask for timeouts explicitly + anyway. Return Value - sd_journal_get_fd() returns a valid file descriptor on success or a negative errno-style error - code. + sd_journal_get_fd() returns + a valid file descriptor on success or a negative + errno-style error code. + + sd_journal_get_events() + returns a combination of POLLIN, + POLLOUT and suchlike on success or + a negative errno-style error code. + + sd_journal_reliable_fd() + returns a positive integer if the file descriptor + returned by sd_journal_get_fd() + will generate wake-ups immediately for all journal + changes. Returns 0 if there might be a latency + involved. sd_journal_process() and sd_journal_wait() return one of - SD_JOURNAL_NOP, - SD_JOURNAL_APPEND or - SD_JOURNAL_INVALIDATE on success or + SD_JOURNAL_NOP, + SD_JOURNAL_APPEND or + SD_JOURNAL_INVALIDATE on success or a negative errno-style error code. If - SD_JOURNAL_NOP is returned the - journal didn't change since the last invocation. If - SD_JOURNAL_APPEND is returned new + SD_JOURNAL_NOP is returned, the + journal did not change since the last invocation. If + SD_JOURNAL_APPEND is returned, new entries have been appended to the end of the - journal. If SD_JOURNAL_INVALIDATE + journal. If SD_JOURNAL_INVALIDATE, 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 SD_JOURNAL_APPEND it is + rotation). In the latter event, live-view UIs should + probably refresh their entire display, while in the + case of SD_JOURNAL_APPEND, it is sufficient to simply continue reading at the previous end of the journal. @@ -137,15 +249,91 @@ Notes The sd_journal_get_fd(), + sd_journal_get_events(), + sd_journal_reliable_fd(), sd_journal_process() and sd_journal_wait() interfaces are available as shared library, which can be compiled and linked to with the - libsystemd-journal - pkg-config1 + libsystemd-journal pkg-config1 file. + + Examples + + Iterating through the journal, in a live view tracking all changes: + + #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; +} + + Waiting with poll() (this + example lacks all error checking for the sake of + simplicity): + + #include <sys/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); +} + + + See Also @@ -153,7 +341,9 @@ systemd1, sd-journal3, sd_journal_open3, - sd_journal_next3 + sd_journal_next3, + poll2, + clock_gettime2