X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fsd-journal.c;h=149dc10bdf60dd6767a7e9ab8adc9b3eb9ce82a4;hb=e02d1cf72d115d1d61defdca5b551672d876c6bd;hp=5e1fd4773e835d1534e54765bbeedab06df41940;hpb=19a2bd80c18d2845f0e37699c8d8df8c8cb4ed78;p=elogind.git diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index 5e1fd4773..149dc10bd 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -6,16 +6,16 @@ Copyright 2011 Lennart Poettering systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. systemd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Lesser General Public License along with systemd; If not, see . ***/ @@ -24,12 +24,14 @@ #include #include #include +#include #include "sd-journal.h" #include "journal-def.h" #include "journal-file.h" #include "hashmap.h" #include "list.h" +#include "path-util.h" #include "lookup3.h" #include "compress.h" #include "journal-internal.h" @@ -66,7 +68,7 @@ static void init_location(Location *l, JournalFile *f, Object *o) { l->seqnum_id = f->header->seqnum_id; l->realtime = le64toh(o->entry.realtime); l->monotonic = le64toh(o->entry.monotonic); - l->boot_id = le64toh(o->entry.boot_id); + l->boot_id = o->entry.boot_id; l->xor_hash = le64toh(o->entry.xor_hash); l->seqnum_set = l->realtime_set = l->monotonic_set = l->xor_hash_set = true; @@ -108,15 +110,24 @@ static int same_field(const void *_a, size_t s, const void *_b, size_t t) { _public_ int sd_journal_add_match(sd_journal *j, const void *data, size_t size) { Match *m, *after = NULL; - uint64_t le_hash; + le64_t le_hash; if (!j) return -EINVAL; if (!data) return -EINVAL; - if (size <= 0) + if (size <= 1) + return -EINVAL; + if (!memchr(data, '=', size)) + return -EINVAL; + if (*(char*) data == '=') return -EINVAL; + /* FIXME: iterating with multiple matches is currently + * broken */ + if (j->matches) + return -ENOTSUP; + le_hash = htole64(hash64(data, size)); LIST_FOREACH(matches, m, j->matches) { @@ -325,9 +336,17 @@ static int find_location(sd_journal *j, JournalFile *f, direction_t direction, O else if (j->current_location.seqnum_set && sd_id128_equal(j->current_location.seqnum_id, f->header->seqnum_id)) r = journal_file_move_to_entry_by_seqnum(f, j->current_location.seqnum, direction, &o, &p); - else if (j->current_location.monotonic_set) + else if (j->current_location.monotonic_set) { r = journal_file_move_to_entry_by_monotonic(f, j->current_location.boot_id, j->current_location.monotonic, direction, &o, &p); - else if (j->current_location.realtime_set) + + if (r == -ENOENT) { + /* boot id unknown in this file */ + if (j->current_location.realtime_set) + r = journal_file_move_to_entry_by_realtime(f, j->current_location.realtime, direction, &o, &p); + else + r = journal_file_next_entry(f, NULL, 0, direction, &o, &p); + } + } else if (j->current_location.realtime_set) r = journal_file_move_to_entry_by_realtime(f, j->current_location.realtime, direction, &o, &p); else r = journal_file_next_entry(f, NULL, 0, direction, &o, &p); @@ -356,7 +375,7 @@ static int find_location(sd_journal *j, JournalFile *f, direction_t direction, O Object *c, *d; uint64_t cp, dp; - r = journal_file_find_data_object_with_hash(f, m->data, m->size, m->le_hash, &d, &dp); + r = journal_file_find_data_object_with_hash(f, m->data, m->size, le64toh(m->le_hash), &d, &dp); if (r <= 0) return r; @@ -527,6 +546,9 @@ static int next_with_matches(sd_journal *j, JournalFile *f, direction_t directio * matches are not OK */ r = journal_file_next_entry_for_data(f, c, cp, le64toh(c->entry.items[k].object_offset), direction, &qo, &q); + /* This pointer is invalidated if the window was + * remapped. May need to re-fetch it later */ + c = NULL; if (r < 0) return r; @@ -552,8 +574,15 @@ static int next_with_matches(sd_journal *j, JournalFile *f, direction_t directio /* Did this entry match against all matches? */ if (found) { - if (ret) + if (ret) { + if (c == NULL) { + /* Re-fetch the entry */ + r = journal_file_move_to_object(f, OBJECT_ENTRY, cp, &c); + if (r < 0) + return r; + } *ret = c; + } if (offset) *offset = cp; return 1; @@ -642,9 +671,10 @@ static int real_journal_next(sd_journal *j, direction_t direction) { bool found; r = next_beyond_location(j, f, direction, &o, &p); - if (r < 0) - return r; - else if (r == 0) + if (r < 0) { + log_debug("Can't iterate through %s, ignoring: %s", f->path, strerror(-r)); + continue; + } else if (r == 0) continue; if (!new_current) @@ -747,7 +777,7 @@ _public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) { bid, (unsigned long long) le64toh(o->entry.monotonic), (unsigned long long) le64toh(o->entry.realtime), (unsigned long long) le64toh(o->entry.xor_hash), - file_name_from_path(j->current_file->path)) < 0) + path_get_file_name(j->current_file->path)) < 0) return -ENOMEM; return 1; @@ -915,7 +945,8 @@ static int add_file(sd_journal *j, const char *prefix, const char *dir, const ch assert(filename); if ((j->flags & SD_JOURNAL_SYSTEM_ONLY) && - !startswith(filename, "system.journal")) + !(streq(filename, "system.journal") || + (startswith(filename, "system@") && endswith(filename, ".journal")))) return 0; if (dir) @@ -1339,7 +1370,8 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void ** n = journal_file_entry_n_items(o); for (i = 0; i < n; i++) { - uint64_t p, l, le_hash; + uint64_t p, l; + le64_t le_hash; size_t t; p = le64toh(o->entry.items[i].object_offset); @@ -1400,7 +1432,8 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void ** _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *size) { JournalFile *f; - uint64_t p, l, n, le_hash; + uint64_t p, l, n; + le64_t le_hash; int r; Object *o; size_t t; @@ -1590,6 +1623,95 @@ _public_ int sd_journal_process(sd_journal *j) { } } +_public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) { + int r, k; + + assert(j); + + r = fd_wait_for_event(j->inotify_fd, POLLIN, timeout_usec); + k = sd_journal_process(j); + + if (r < 0) + return r; + + return k; +} + +_public_ int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, uint64_t *to) { + Iterator i; + JournalFile *f; + bool first = true; + int r; + + if (!j) + return -EINVAL; + if (!from && !to) + return -EINVAL; + + HASHMAP_FOREACH(f, j->files, i) { + usec_t fr, t; + + r = journal_file_get_cutoff_realtime_usec(f, &fr, &t); + if (r < 0) + return r; + if (r == 0) + continue; + + if (first) { + if (from) + *from = fr; + if (to) + *to = t; + first = false; + } else { + if (from) + *from = MIN(fr, *from); + if (to) + *to = MIN(t, *to); + } + } + + return first ? 0 : 1; +} + +_public_ int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t *from, uint64_t *to) { + Iterator i; + JournalFile *f; + bool first = true; + int r; + + if (!j) + return -EINVAL; + if (!from && !to) + return -EINVAL; + + HASHMAP_FOREACH(f, j->files, i) { + usec_t fr, t; + + r = journal_file_get_cutoff_monotonic_usec(f, boot_id, &fr, &t); + if (r < 0) + return r; + if (r == 0) + continue; + + if (first) { + if (from) + *from = fr; + if (to) + *to = t; + first = false; + } else { + if (from) + *from = MIN(fr, *from); + if (to) + *to = MIN(t, *to); + } + } + + return first ? 0 : 1; +} + + /* _public_ int sd_journal_query_unique(sd_journal *j, const char *field) { */ /* if (!j) */ /* return -EINVAL; */