X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fsd-journal.c;h=4579e9ee2dedcf532d34b0e382717e79f784eed5;hb=26fefda707e6511733f48da03b281a004dba6abf;hp=3aa9ed4b3275df6e9e2a82442f3e1125f6931a0e;hpb=5302ebe15ff3a11eceb75e095e5a09d2a676de2b;p=elogind.git diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 3aa9ed4b3..4579e9ee2 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -50,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) { @@ -102,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); @@ -110,12 +120,10 @@ static void set_location(sd_journal *j, LocationType type, JournalFile *f, Objec init_location(&j->current_location, type, f, o); - if (j->current_file) - j->current_file->current_offset = 0; - j->current_file = f; j->current_field = 0; + f->last_direction = direction; f->current_offset = offset; } @@ -164,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) { @@ -178,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; @@ -191,7 +199,7 @@ 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); @@ -210,6 +218,8 @@ _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) if (!j) return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!data) return -EINVAL; @@ -304,7 +314,10 @@ fail: } _public_ int sd_journal_add_conjunction(sd_journal *j) { - assert(j); + if (!j) + return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!j->level0) return 0; @@ -322,7 +335,10 @@ _public_ int sd_journal_add_conjunction(sd_journal *j) { } _public_ int sd_journal_add_disjunction(sd_journal *j) { - assert(j); + if (!j) + return -EINVAL; + if (journal_pid_changed(j)) + return -ECHILD; if (!j->level0) return 0; @@ -346,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); @@ -372,10 +388,8 @@ static char *match_make_string(Match *m) { p = k; enclose = true; - } else { - free(p); + } else p = t; - } } if (enclose) { @@ -394,7 +408,6 @@ char *journal_make_match_string(sd_journal *j) { } _public_ void sd_journal_flush_matches(sd_journal *j) { - if (!j) return; @@ -588,11 +601,14 @@ 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, *last_moved; @@ -625,8 +641,7 @@ static int next_for_match( } } - if (np == 0) - return 0; + assert(np > 0); r = journal_file_move_to_object(f, OBJECT_ENTRY, np, &n); if (r < 0) @@ -731,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; } @@ -811,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); @@ -827,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 @@ -871,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; @@ -889,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) { @@ -908,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; } @@ -926,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 @@ -966,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; @@ -1005,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; @@ -1104,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; @@ -1182,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; @@ -1195,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; @@ -1207,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; @@ -1217,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; @@ -1236,17 +1266,17 @@ static void check_network(sd_journal *j, int fd) { return; j->on_network = - F_TYPE_CMP(sfs.f_type, CIFS_MAGIC_NUMBER) || - F_TYPE_CMP(sfs.f_type, CODA_SUPER_MAGIC) || - F_TYPE_CMP(sfs.f_type, NCP_SUPER_MAGIC) || - F_TYPE_CMP(sfs.f_type, NFS_SUPER_MAGIC) || - F_TYPE_CMP(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 bool file_has_type_prefix(const char *prefix, const char *filename) { const char *full, *tilded, *atted; - full = strappend(prefix, ".journal"); + full = strappenda(prefix, ".journal"); tilded = strappenda(full, "~"); atted = strappenda(prefix, "@"); @@ -1655,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; @@ -1816,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; @@ -1842,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) @@ -1908,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) @@ -2034,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) @@ -2084,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; @@ -2111,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) @@ -2124,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; @@ -2224,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); @@ -2262,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) { @@ -2311,6 +2361,8 @@ _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) @@ -2352,6 +2404,8 @@ _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) @@ -2409,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; @@ -2430,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)) @@ -2454,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) @@ -2566,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; } @@ -2599,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; @@ -2636,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; @@ -2644,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;