X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fjournal%2Fsd-journal.c;h=41f0c4dfb4bc677ae57df8b50bc2b60b5057bb1f;hp=09b0eb83797474c9fb1e3b5763abdaca3eef0e62;hb=943aad8ca57a6b5c49c4ea60f9e8c13bf9b20e6c;hpb=bdc02927f78180816bcc46e25e72ca0436a2268f diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 09b0eb837..41f0c4dfb 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "sd-journal.h" #include "journal-def.h" @@ -35,9 +37,16 @@ #include "lookup3.h" #include "compress.h" #include "journal-internal.h" +#include "missing.h" +#include "catalog.h" +#include "replace-var.h" #define JOURNAL_FILES_MAX 1024 +#define JOURNAL_FILES_RECHECK_USEC (2 * USEC_PER_SEC) + +#define REPLACE_VAR_MAX 256 + static void detach_location(sd_journal *j) { Iterator i; JournalFile *f; @@ -1184,6 +1193,25 @@ _public_ int sd_journal_seek_tail(sd_journal *j) { return 0; } +static void check_network(sd_journal *j, int fd) { + struct statfs sfs; + + assert(j); + + if (j->on_network) + return; + + if (fstatfs(fd, &sfs) < 0) + return; + + j->on_network = + (long)sfs.f_type == (long)CIFS_MAGIC_NUMBER || + sfs.f_type == CODA_SUPER_MAGIC || + sfs.f_type == NCP_SUPER_MAGIC || + sfs.f_type == NFS_SUPER_MAGIC || + sfs.f_type == SMB_SUPER_MAGIC; +} + static int add_file(sd_journal *j, const char *prefix, const char *filename) { char *path; int r; @@ -1233,6 +1261,8 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) { return r; } + check_network(j, f->fd); + j->current_invalidate_counter ++; log_debug("File %s got added.", f->path); @@ -1366,6 +1396,8 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) } } + check_network(j, dirfd(d)); + closedir(d); return 0; @@ -1453,6 +1485,8 @@ static int add_root_directory(sd_journal *j, const char *p) { } } + check_network(j, dirfd(d)); + closedir(d); return 0; @@ -2079,6 +2113,14 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { return determine_change(j); } + if (j->on_network) { + /* If we are on the network we need to regularly check + * for changes manually */ + + if (timeout_usec == (uint64_t) -1 || timeout_usec > JOURNAL_FILES_RECHECK_USEC) + timeout_usec = JOURNAL_FILES_RECHECK_USEC; + } + do { r = fd_wait_for_event(j->inotify_fd, POLLIN, timeout_usec); } while (r == -EINTR); @@ -2121,7 +2163,7 @@ _public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, if (from) *from = MIN(fr, *from); if (to) - *to = MIN(t, *to); + *to = MAX(t, *to); } } @@ -2160,7 +2202,7 @@ _public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot if (from) *from = MIN(fr, *from); if (to) - *to = MIN(t, *to); + *to = MAX(t, *to); } } @@ -2344,3 +2386,66 @@ _public_ void sd_journal_restart_unique(sd_journal *j) { j->unique_file = NULL; j->unique_offset = 0; } + +_public_ int sd_journal_reliable_fd(sd_journal *j) { + if (!j) + return -EINVAL; + + return !j->on_network; +} + +static char *lookup_field(const char *field, void *userdata) { + sd_journal *j = userdata; + const void *data; + size_t size, d; + int r; + + assert(field); + assert(j); + + r = sd_journal_get_data(j, field, &data, &size); + if (r < 0 || + size > REPLACE_VAR_MAX) + return strdup(field); + + d = strlen(field) + 1; + + return strndup((const char*) data + d, size - d); +} + +_public_ int sd_journal_get_catalog(sd_journal *j, char **ret) { + const void *data; + size_t size; + sd_id128_t id; + _cleanup_free_ char *text = NULL, *cid = NULL; + char *t; + int r; + + if (!j) + return -EINVAL; + if (!ret) + return -EINVAL; + + r = sd_journal_get_data(j, "MESSAGE_ID", &data, &size); + if (r < 0) + return r; + + cid = strndup((const char*) data + 11, size - 11); + if (!cid) + return -ENOMEM; + + r = sd_id128_from_string(cid, &id); + if (r < 0) + return r; + + r = catalog_get(id, &text); + if (r < 0) + return r; + + t = replace_var(text, lookup_field, j); + if (!t) + return -ENOMEM; + + *ret = t; + return 0; +}