X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fjournal%2Fsd-journal.c;h=3ccb14a242832fa2b4d0e0c903313d40004bed16;hp=7e06a70344ac55eb5e70bfd4e0e311badb605f8f;hb=68313d3dfa2082dae8a06643d639e0200afc19fc;hpb=23e97f7d9274b90fb0e1664945dc6259fdae6d39 diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 7e06a7034..3ccb14a24 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -33,6 +33,7 @@ #include "journal-file.h" #include "hashmap.h" #include "list.h" +#include "strv.h" #include "path-util.h" #include "lookup3.h" #include "compress.h" @@ -49,6 +50,15 @@ #define DEFAULT_DATA_THRESHOLD (64*1024) +static bool journal_pid_changed(sd_journal *j) { + assert(j); + + /* We don't support people creating a journal object and + * keeping it around over a fork(). Let's complain. */ + + return j->original_pid != getpid(); +} + /* We return an error here only if we didn't manage to memorize the real error. */ static int set_put_error(sd_journal *j, int r) { @@ -101,7 +111,8 @@ static void init_location(Location *l, LocationType type, JournalFile *f, Object l->seqnum_set = l->realtime_set = l->monotonic_set = l->xor_hash_set = true; } -static void set_location(sd_journal *j, LocationType type, JournalFile *f, Object *o, uint64_t offset) { +static void set_location(sd_journal *j, LocationType type, JournalFile *f, Object *o, + direction_t direction, uint64_t offset) { assert(j); assert(type == LOCATION_DISCRETE || type == LOCATION_SEEK); assert(f); @@ -112,6 +123,7 @@ static void set_location(sd_journal *j, LocationType type, JournalFile *f, Objec j->current_file = f; j->current_field = 0; + f->last_direction = direction; f->current_offset = offset; } @@ -160,7 +172,7 @@ static bool same_field(const void *_a, size_t s, const void *_b, size_t t) { return true; } - return true; + assert_not_reached("\"=\" not found"); } static Match *match_new(Match *p, MatchType t) { @@ -174,7 +186,7 @@ static Match *match_new(Match *p, MatchType t) { if (p) { m->parent = p; - LIST_PREPEND(Match, matches, p->matches, m); + LIST_PREPEND(matches, p->matches, m); } return m; @@ -187,27 +199,27 @@ static void match_free(Match *m) { match_free(m->matches); if (m->parent) - LIST_REMOVE(Match, matches, m->parent->matches, m); + LIST_REMOVE(matches, m->parent->matches, m); free(m->data); free(m); } static void match_free_if_empty(Match *m) { - assert(m); - - if (m->matches) + if (!m || m->matches) return; match_free(m); } _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) { - Match *l2, *l3, *add_here = NULL, *m; + Match *l3, *l4, *add_here = NULL, *m; le64_t le_hash; if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!data) return -EINVAL; @@ -218,44 +230,52 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) if (!match_is_valid(data, size)) return -EINVAL; - /* level 0: OR term - * level 1: AND terms - * level 2: OR terms - * level 3: concrete matches */ + /* level 0: AND term + * level 1: OR terms + * level 2: AND terms + * level 3: OR terms + * level 4: concrete matches */ if (!j->level0) { - j->level0 = match_new(NULL, MATCH_OR_TERM); + j->level0 = match_new(NULL, MATCH_AND_TERM); if (!j->level0) return -ENOMEM; } if (!j->level1) { - j->level1 = match_new(j->level0, MATCH_AND_TERM); + j->level1 = match_new(j->level0, MATCH_OR_TERM); if (!j->level1) return -ENOMEM; } - assert(j->level0->type == MATCH_OR_TERM); - assert(j->level1->type == MATCH_AND_TERM); + if (!j->level2) { + j->level2 = match_new(j->level1, MATCH_AND_TERM); + if (!j->level2) + return -ENOMEM; + } + + assert(j->level0->type == MATCH_AND_TERM); + assert(j->level1->type == MATCH_OR_TERM); + assert(j->level2->type == MATCH_AND_TERM); le_hash = htole64(hash64(data, size)); - LIST_FOREACH(matches, l2, j->level1->matches) { - assert(l2->type == MATCH_OR_TERM); + LIST_FOREACH(matches, l3, j->level2->matches) { + assert(l3->type == MATCH_OR_TERM); - LIST_FOREACH(matches, l3, l2->matches) { - assert(l3->type == MATCH_DISCRETE); + LIST_FOREACH(matches, l4, l3->matches) { + assert(l4->type == MATCH_DISCRETE); /* Exactly the same match already? Then ignore * this addition */ - if (l3->le_hash == le_hash && - l3->size == size && - memcmp(l3->data, data, size) == 0) + if (l4->le_hash == le_hash && + l4->size == size && + memcmp(l4->data, data, size) == 0) return 0; /* Same field? Then let's add this to this OR term */ - if (same_field(data, size, l3->data, l3->size)) { - add_here = l2; + if (same_field(data, size, l4->data, l4->size)) { + add_here = l3; break; } } @@ -265,7 +285,7 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) } if (!add_here) { - add_here = match_new(j->level1, MATCH_OR_TERM); + add_here = match_new(j->level2, MATCH_OR_TERM); if (!add_here) goto fail; } @@ -285,22 +305,40 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) return 0; fail: - if (add_here) - match_free_if_empty(add_here); + match_free_if_empty(add_here); + match_free_if_empty(j->level2); + match_free_if_empty(j->level1); + match_free_if_empty(j->level0); - if (j->level1) - match_free_if_empty(j->level1); + return -ENOMEM; +} - if (j->level0) - match_free_if_empty(j->level0); +_public_ int sd_journal_add_conjunction(sd_journal *j) { + if (!j) + return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; - return -ENOMEM; + if (!j->level0) + return 0; + + if (!j->level1) + return 0; + + if (!j->level1->matches) + return 0; + + j->level1 = NULL; + j->level2 = NULL; + + return 0; } _public_ int sd_journal_add_disjunction(sd_journal *j) { - Match *m; - - assert(j); + if (!j) + return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!j->level0) return 0; @@ -308,14 +346,13 @@ _public_ int sd_journal_add_disjunction(sd_journal *j) { if (!j->level1) return 0; - if (!j->level1->matches) + if (!j->level2) return 0; - m = match_new(j->level0, MATCH_AND_TERM); - if (!m) - return -ENOMEM; + if (!j->level2->matches) + return 0; - j->level1 = m; + j->level2 = NULL; return 0; } @@ -325,7 +362,7 @@ static char *match_make_string(Match *m) { bool enclose = false; if (!m) - return strdup(""); + return strdup("none"); if (m->type == MATCH_DISCRETE) return strndup(m->data, m->size); @@ -351,10 +388,8 @@ static char *match_make_string(Match *m) { p = k; enclose = true; - } else { - free(p); + } else p = t; - } } if (enclose) { @@ -373,20 +408,19 @@ char *journal_make_match_string(sd_journal *j) { } _public_ void sd_journal_flush_matches(sd_journal *j) { - if (!j) return; if (j->level0) match_free(j->level0); - j->level0 = j->level1 = NULL; + j->level0 = j->level1 = j->level2 = NULL; detach_location(j); } static int compare_entry_order(JournalFile *af, Object *_ao, - JournalFile *bf, uint64_t bp) { + JournalFile *bf, uint64_t bp) { uint64_t a, b; Object *ao, *bo; @@ -469,7 +503,7 @@ static int compare_entry_order(JournalFile *af, Object *_ao, return 0; } -static int compare_with_location(JournalFile *af, Object *ao, Location *l) { +_pure_ static int compare_with_location(JournalFile *af, Object *ao, Location *l) { uint64_t a; assert(af); @@ -567,52 +601,47 @@ static int next_for_match( if (r < 0) return r; else if (r > 0) { - if (np == 0 || (direction == DIRECTION_DOWN ? np > cp : np < cp)) + if (np == 0 || (direction == DIRECTION_DOWN ? cp < np : cp > np)) np = cp; } } + if (np == 0) + return 0; + } else if (m->type == MATCH_AND_TERM) { - Match *i; - bool continue_looking; + Match *i, *last_moved; /* Always jump to the next matching entry and repeat - * this until we fine and offset that matches for all + * this until we find an offset that matches for all * matches. */ if (!m->matches) return 0; - np = 0; - do { - continue_looking = false; + r = next_for_match(j, m->matches, f, after_offset, direction, NULL, &np); + if (r <= 0) + return r; - LIST_FOREACH(matches, i, m->matches) { - uint64_t cp, limit; + assert(direction == DIRECTION_DOWN ? np >= after_offset : np <= after_offset); + last_moved = m->matches; - if (np == 0) - limit = after_offset; - else if (direction == DIRECTION_DOWN) - limit = MAX(np, after_offset); - else - limit = MIN(np, after_offset); + LIST_LOOP_BUT_ONE(matches, i, m->matches, last_moved) { + uint64_t cp; - r = next_for_match(j, i, f, limit, direction, NULL, &cp); - if (r <= 0) - return r; + r = next_for_match(j, i, f, np, direction, NULL, &cp); + if (r <= 0) + return r; - if ((direction == DIRECTION_DOWN ? cp >= after_offset : cp <= after_offset) && - (np == 0 || (direction == DIRECTION_DOWN ? cp > np : cp < np))) { - np = cp; - continue_looking = true; - } + assert(direction == DIRECTION_DOWN ? cp >= np : cp <= np); + if (direction == DIRECTION_DOWN ? cp > np : cp < np) { + np = cp; + last_moved = i; } - - } while (continue_looking); + } } - if (np == 0) - return 0; + assert(np > 0); r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n); if (r < 0) @@ -717,7 +746,7 @@ static int find_location_for_match( if (r <= 0) return r; - if (np == 0 || (direction == DIRECTION_DOWN ? np < cp : np > cp)) + if (np == 0 || (direction == DIRECTION_DOWN ? cp > np : cp < np)) np = cp; } @@ -797,7 +826,7 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc assert(j); assert(f); - if (f->current_offset > 0) { + if (f->last_direction == direction && f->current_offset > 0) { cp = f->current_offset; r = journal_file_move_to_object(f, OBJECT_ENTRY, cp, &c); @@ -813,7 +842,7 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc return r; } - /* OK, we found the spot, now let's advance until to an entry + /* OK, we found the spot, now let's advance until an entry * that is actually different from what we were previously * looking at. This is necessary to handle entries which exist * in two (or more) journal files, and which shall all be @@ -857,6 +886,8 @@ static int real_journal_next(sd_journal *j, direction_t direction) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; HASHMAP_FOREACH(f, j->files, i) { bool found; @@ -875,10 +906,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) { k = compare_entry_order(f, o, new_file, new_offset); - if (direction == DIRECTION_DOWN) - found = k < 0; - else - found = k > 0; + found = direction == DIRECTION_DOWN ? k < 0 : k > 0; } if (found) { @@ -894,7 +922,7 @@ static int real_journal_next(sd_journal *j, direction_t direction) { if (r < 0) return r; - set_location(j, LOCATION_DISCRETE, new_file, o, new_offset); + set_location(j, LOCATION_DISCRETE, new_file, o, direction, new_offset); return 1; } @@ -912,6 +940,8 @@ static int real_journal_next_skip(sd_journal *j, direction_t direction, uint64_t if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (skip == 0) { /* If this is not a discrete skip, then at least @@ -952,6 +982,8 @@ _public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!cursor) return -EINVAL; @@ -966,11 +998,11 @@ _public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) { sd_id128_to_string(o->entry.boot_id, bid); if (asprintf(cursor, - "s=%s;i=%llx;b=%s;m=%llx;t=%llx;x=%llx", - sid, (unsigned long long) le64toh(o->entry.seqnum), - bid, (unsigned long long) le64toh(o->entry.monotonic), - (unsigned long long) le64toh(o->entry.realtime), - (unsigned long long) le64toh(o->entry.xor_hash)) < 0) + "s=%s;i=%"PRIx64";b=%s;m=%"PRIx64";t=%"PRIx64";x=%"PRIx64, + sid, le64toh(o->entry.seqnum), + bid, le64toh(o->entry.monotonic), + le64toh(o->entry.realtime), + le64toh(o->entry.xor_hash)) < 0) return -ENOMEM; return 0; @@ -991,6 +1023,8 @@ _public_ int sd_journal_seek_cursor(sd_journal *j, const char *cursor) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (isempty(cursor)) return -EINVAL; @@ -1090,6 +1124,8 @@ _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (isempty(cursor)) return -EINVAL; @@ -1168,6 +1204,8 @@ _public_ int sd_journal_test_cursor(sd_journal *j, const char *cursor) { _public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; reset_location(j); j->current_location.type = LOCATION_SEEK; @@ -1181,6 +1219,8 @@ _public_ int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, u _public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; reset_location(j); j->current_location.type = LOCATION_SEEK; @@ -1193,6 +1233,8 @@ _public_ int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec) { _public_ int sd_journal_seek_head(sd_journal *j) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; reset_location(j); j->current_location.type = LOCATION_HEAD; @@ -1203,6 +1245,8 @@ _public_ int sd_journal_seek_head(sd_journal *j) { _public_ int sd_journal_seek_tail(sd_journal *j) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; reset_location(j); j->current_location.type = LOCATION_TAIL; @@ -1222,48 +1266,67 @@ static void check_network(sd_journal *j, int fd) { 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; + F_TYPE_EQUAL(sfs.f_type, CIFS_MAGIC_NUMBER) || + F_TYPE_EQUAL(sfs.f_type, CODA_SUPER_MAGIC) || + F_TYPE_EQUAL(sfs.f_type, NCP_SUPER_MAGIC) || + F_TYPE_EQUAL(sfs.f_type, NFS_SUPER_MAGIC) || + F_TYPE_EQUAL(sfs.f_type, SMB_SUPER_MAGIC); } -static int add_file(sd_journal *j, const char *prefix, const char *filename) { - char _cleanup_free_ *path = NULL; - int r; - JournalFile *f; +static bool file_has_type_prefix(const char *prefix, const char *filename) { + const char *full, *tilded, *atted; - assert(j); - assert(prefix); - assert(filename); + full = strappend(prefix, ".journal"); + tilded = strappenda(full, "~"); + atted = strappenda(prefix, "@"); - if ((j->flags & SD_JOURNAL_SYSTEM_ONLY) && - !(streq(filename, "system.journal") || - streq(filename, "system.journal~") || - (startswith(filename, "system@") && - (endswith(filename, ".journal") || endswith(filename, ".journal~"))))) - return 0; + return streq(filename, full) || + streq(filename, tilded) || + startswith(filename, atted); +} - path = strjoin(prefix, "/", filename, NULL); - if (!path) - return -ENOMEM; +static bool file_type_wanted(int flags, const char *filename) { + if (!endswith(filename, ".journal") && !endswith(filename, ".journal~")) + return false; + + /* no flags set → every type is OK */ + if (!(flags & (SD_JOURNAL_SYSTEM | SD_JOURNAL_CURRENT_USER))) + return true; + + if (flags & SD_JOURNAL_SYSTEM && file_has_type_prefix("system", filename)) + return true; + + if (flags & SD_JOURNAL_CURRENT_USER) { + char prefix[5 + DECIMAL_STR_MAX(uid_t) + 1]; + + assert_se(snprintf(prefix, sizeof(prefix), "user-%lu", (unsigned long) getuid()) + < (int) sizeof(prefix)); + + if (file_has_type_prefix(prefix, filename)) + return true; + } + + return false; +} + +static int add_any_file(sd_journal *j, const char *path) { + JournalFile *f; + int r; + + assert(j); + assert(path); if (hashmap_get(j->files, path)) return 0; if (hashmap_size(j->files) >= JOURNAL_FILES_MAX) { - log_debug("Too many open journal files, not adding %s, ignoring.", path); + log_warning("Too many open journal files, not adding %s.", path); return set_put_error(j, -ETOOMANYREFS); } r = journal_file_open(path, O_RDONLY, 0, false, false, NULL, j->mmap, NULL, &f); - if (r < 0) { - if (errno == ENOENT) - return 0; - + if (r < 0) return r; - } /* journal_file_dump(f); */ @@ -1273,7 +1336,7 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) { return r; } - log_debug("File %s got added.", f->path); + log_debug("File %s added.", f->path); check_network(j, f->fd); @@ -1282,6 +1345,28 @@ static int add_file(sd_journal *j, const char *prefix, const char *filename) { return 0; } +static int add_file(sd_journal *j, const char *prefix, const char *filename) { + _cleanup_free_ char *path = NULL; + int r; + + assert(j); + assert(prefix); + assert(filename); + + if (j->no_new_files || + !file_type_wanted(j->flags, filename)) + return 0; + + path = strjoin(prefix, "/", filename, NULL); + if (!path) + return -ENOMEM; + + r = add_any_file(j, path); + if (r == -ENOENT) + return 0; + return 0; +} + static int remove_file(sd_journal *j, const char *prefix, const char *filename) { char *path; JournalFile *f; @@ -1301,7 +1386,7 @@ static int remove_file(sd_journal *j, const char *prefix, const char *filename) hashmap_remove(j->files, f->path); - log_debug("File %s got removed.", f->path); + log_debug("File %s removed.", f->path); if (j->current_file == f) { j->current_file = NULL; @@ -1321,9 +1406,9 @@ static int remove_file(sd_journal *j, const char *prefix, const char *filename) } static int add_directory(sd_journal *j, const char *prefix, const char *dirname) { - char _cleanup_free_ *path = NULL; + _cleanup_free_ char *path = NULL; int r; - DIR _cleanup_closedir_ *d = NULL; + _cleanup_closedir_ DIR *d = NULL; sd_id128_t id, mid; Directory *m; @@ -1368,7 +1453,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) path = NULL; /* avoid freeing in cleanup */ j->current_invalidate_counter ++; - log_debug("Directory %s got added.", m->path); + log_debug("Directory %s added.", m->path); } else if (m->is_root) return 0; @@ -1411,7 +1496,7 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dirname) } static int add_root_directory(sd_journal *j, const char *p) { - DIR _cleanup_closedir_ *d = NULL; + _cleanup_closedir_ DIR *d = NULL; Directory *m; int r; @@ -1447,7 +1532,7 @@ static int add_root_directory(sd_journal *j, const char *p) { j->current_invalidate_counter ++; - log_debug("Root directory %s got added.", m->path); + log_debug("Root directory %s added.", m->path); } else if (!m->is_root) return 0; @@ -1462,6 +1547,9 @@ static int add_root_directory(sd_journal *j, const char *p) { inotify_rm_watch(j->inotify_fd, m->wd); } + if (j->no_new_files) + return 0; + for (;;) { struct dirent *de; union dirent_storage buf; @@ -1508,9 +1596,9 @@ static int remove_directory(sd_journal *j, Directory *d) { hashmap_remove(j->directories_by_path, d->path); if (d->is_root) - log_debug("Root directory %s got removed.", d->path); + log_debug("Root directory %s removed.", d->path); else - log_debug("Directory %s got removed.", d->path); + log_debug("Directory %s removed.", d->path); free(d->path); free(d); @@ -1542,6 +1630,36 @@ static int add_search_paths(sd_journal *j) { return 0; } +static int add_current_paths(sd_journal *j) { + Iterator i; + JournalFile *f; + + assert(j); + assert(j->no_new_files); + + /* Simply adds all directories for files we have open as + * "root" directories. We don't expect errors here, so we + * treat them as fatal. */ + + HASHMAP_FOREACH(f, j->files, i) { + int r; + _cleanup_free_ char *dir; + + dir = dirname_malloc(f->path); + if (!dir) + return -ENOMEM; + + r = add_root_directory(j, dir); + if (r < 0) { + set_put_error(j, r); + return r; + } + } + + return 0; +} + + static int allocate_inotify(sd_journal *j) { assert(j); @@ -1567,6 +1685,7 @@ static sd_journal *journal_new(int flags, const char *path) { if (!j) return NULL; + j->original_pid = getpid(); j->inotify_fd = -1; j->flags = flags; j->data_threshold = DEFAULT_DATA_THRESHOLD; @@ -1599,7 +1718,8 @@ _public_ int sd_journal_open(sd_journal **ret, int flags) { if (flags & ~(SD_JOURNAL_LOCAL_ONLY| SD_JOURNAL_RUNTIME_ONLY| - SD_JOURNAL_SYSTEM_ONLY)) + SD_JOURNAL_SYSTEM| + SD_JOURNAL_CURRENT_USER)) return -EINVAL; j = journal_new(flags, NULL); @@ -1651,6 +1771,40 @@ fail: return r; } +_public_ int sd_journal_open_files(sd_journal **ret, const char **paths, int flags) { + sd_journal *j; + const char **path; + int r; + + if (!ret) + return -EINVAL; + + if (flags != 0) + return -EINVAL; + + j = journal_new(flags, NULL); + if (!j) + return -ENOMEM; + + STRV_FOREACH(path, paths) { + r = add_any_file(j, *path); + if (r < 0) { + log_error("Failed to open %s: %s", *path, strerror(-r)); + goto fail; + } + } + + j->no_new_files = true; + + *ret = j; + return 0; + +fail: + sd_journal_close(j); + + return r; +} + _public_ void sd_journal_close(sd_journal *j) { Directory *d; JournalFile *f; @@ -1693,6 +1847,8 @@ _public_ int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!ret) return -EINVAL; @@ -1719,6 +1875,8 @@ _public_ int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id12 if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; f = j->current_file; if (!f) @@ -1785,6 +1943,8 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void ** if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!field) return -EINVAL; if (!data) @@ -1911,6 +2071,8 @@ _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!data) return -EINVAL; if (!size) @@ -1961,6 +2123,8 @@ _public_ int sd_journal_get_fd(sd_journal *j) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (j->inotify_fd >= 0) return j->inotify_fd; @@ -1971,7 +2135,9 @@ _public_ int sd_journal_get_fd(sd_journal *j) { /* Iterate through all dirs again, to add them to the * inotify */ - if (j->path) + if (j->no_new_files) + r = add_current_paths(j); + else if (j->path) r = add_root_directory(j, j->path); else r = add_search_paths(j); @@ -1986,6 +2152,8 @@ _public_ int sd_journal_get_events(sd_journal *j) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; fd = sd_journal_get_fd(j); if (fd < 0) @@ -1999,6 +2167,8 @@ _public_ int sd_journal_get_timeout(sd_journal *j, uint64_t *timeout_usec) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!timeout_usec) return -EINVAL; @@ -2099,6 +2269,8 @@ _public_ int sd_journal_process(sd_journal *j) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; j->last_process_usec = now(CLOCK_MONOTONIC); @@ -2137,7 +2309,10 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { int r; uint64_t t; - assert(j); + if (!j) + return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (j->inotify_fd < 0) { @@ -2186,8 +2361,12 @@ _public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!from && !to) return -EINVAL; + if (from == to) + return -EINVAL; HASHMAP_FOREACH(f, j->files, i) { usec_t fr, t; @@ -2225,8 +2404,12 @@ _public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!from && !to) return -EINVAL; + if (from == to) + return -EINVAL; HASHMAP_FOREACH(f, j->files, i) { usec_t fr, t; @@ -2280,6 +2463,8 @@ _public_ int sd_journal_get_usage(sd_journal *j, uint64_t *bytes) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!bytes) return -EINVAL; @@ -2301,6 +2486,8 @@ _public_ int sd_journal_query_unique(sd_journal *j, const char *field) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (isempty(field)) return -EINVAL; if (!field_is_valid(field)) @@ -2325,6 +2512,8 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_ if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!data) return -EINVAL; if (!l) @@ -2437,6 +2626,8 @@ _public_ void sd_journal_restart_unique(sd_journal *j) { _public_ int sd_journal_reliable_fd(sd_journal *j) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; return !j->on_network; } @@ -2470,6 +2661,8 @@ _public_ int sd_journal_get_catalog(sd_journal *j, char **ret) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!ret) return -EINVAL; @@ -2507,6 +2700,8 @@ _public_ int sd_journal_get_catalog_for_message_id(sd_id128_t id, char **ret) { _public_ int sd_journal_set_data_threshold(sd_journal *j, size_t sz) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; j->data_threshold = sz; return 0; @@ -2515,6 +2710,8 @@ _public_ int sd_journal_set_data_threshold(sd_journal *j, size_t sz) { _public_ int sd_journal_get_data_threshold(sd_journal *j, size_t *sz) { if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!sz) return -EINVAL;