X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fsd-journal.c;h=38e58f57328261d91d520f505da07b0aa9dec3c3;hb=8b18eb674ce4d14e4819e102a0d6679a0fd2e6ce;hp=bd510be51cea00202a50bee765a62711d6dd9242;hpb=50f20cfdb0f127e415ab38c024d9ca7a3602f74b;p=elogind.git diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c index bd510be51..38e58f573 100644 --- a/src/journal/sd-journal.c +++ b/src/journal/sd-journal.c @@ -31,58 +31,11 @@ #include "hashmap.h" #include "list.h" #include "lookup3.h" +#include "compress.h" +#include "journal-internal.h" #define JOURNAL_FILES_MAX 1024 -typedef struct Match Match; - -struct Match { - char *data; - size_t size; - uint64_t le_hash; - - LIST_FIELDS(Match, matches); -}; - -typedef enum location_type { - LOCATION_HEAD, - LOCATION_TAIL, - LOCATION_DISCRETE -} location_type_t; - -typedef struct Location { - location_type_t type; - - uint64_t seqnum; - sd_id128_t seqnum_id; - bool seqnum_set; - - uint64_t realtime; - bool realtime_set; - - uint64_t monotonic; - sd_id128_t boot_id; - bool monotonic_set; - - uint64_t xor_hash; - bool xor_hash_set; -} Location; - -struct sd_journal { - Hashmap *files; - - Location current_location; - JournalFile *current_file; - uint64_t current_field; - - int inotify_fd; - Hashmap *inotify_wd_dirs; - Hashmap *inotify_wd_roots; - - LIST_HEAD(Match, matches); - unsigned n_matches; -}; - static void detach_location(sd_journal *j) { Iterator i; JournalFile *f; @@ -436,7 +389,7 @@ static int find_location(sd_journal *j, JournalFile *f, direction_t direction, O (direction == DIRECTION_DOWN && cp < tp) || (direction == DIRECTION_UP && cp > tp)) { to = c; - tp = tp; + tp = cp; } } @@ -525,6 +478,7 @@ static int next_with_matches(sd_journal *j, JournalFile *f, direction_t directio uint64_t np, n; bool found, term_result = false; Match *m, *term_match = NULL; + Object *npo = NULL; n = journal_file_entry_n_items(c); @@ -535,6 +489,7 @@ static int next_with_matches(sd_journal *j, JournalFile *f, direction_t directio np = 0; LIST_FOREACH(matches, m, j->matches) { uint64_t q, k; + Object *qo = NULL; /* Let's check if this is the beginning of a * new term, i.e. has a different field prefix @@ -567,22 +522,26 @@ static int next_with_matches(sd_journal *j, JournalFile *f, direction_t directio * where we'd have to try next, in case the other * matches are not OK */ - r = journal_file_next_entry_for_data(f, c, cp, le64toh(c->entry.items[k].object_offset), direction, NULL, &q); + r = journal_file_next_entry_for_data(f, c, cp, le64toh(c->entry.items[k].object_offset), direction, &qo, &q); if (r > 0) { if (direction == DIRECTION_DOWN) { - if (q > np) + if (q > np) { np = q; + npo = qo; + } } else { - if (np == 0 || q < np) + if (np == 0 || q < np) { np = q; + npo = qo; + } } } } /* Check the last term */ - if (term_match && term_result) - found = true; + if (term_match && !term_result) + found = false; /* Did this entry match against all matches? */ if (found) { @@ -600,6 +559,7 @@ static int next_with_matches(sd_journal *j, JournalFile *f, direction_t directio /* Hmm, ok, this entry only matched partially, so * let's try another one */ cp = np; + c = npo; } } @@ -612,12 +572,12 @@ static int next_beyond_location(sd_journal *j, JournalFile *f, direction_t direc assert(f); if (f->current_offset > 0) { - r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &c); + cp = f->current_offset; + + r = journal_file_move_to_object(f, OBJECT_ENTRY, cp, &c); if (r < 0) return r; - cp = f->current_offset; - r = next_with_matches(j, f, direction, &c, &cp); if (r <= 0) return r; @@ -940,6 +900,10 @@ static int add_file(sd_journal *j, const char *prefix, const char *dir, const ch assert(prefix); assert(filename); + if ((j->flags & SD_JOURNAL_SYSTEM_ONLY) && + !startswith(filename, "system.journal")) + return 0; + if (dir) fn = join(prefix, "/", dir, "/", filename, NULL); else @@ -969,7 +933,7 @@ static int add_file(sd_journal *j, const char *prefix, const char *dir, const ch return r; } - journal_file_dump(f); + /* journal_file_dump(f); */ r = hashmap_put(j->files, f->path, f); if (r < 0) { @@ -1016,11 +980,18 @@ static int add_directory(sd_journal *j, const char *prefix, const char *dir) { int r; DIR *d; int wd; + sd_id128_t id, mid; assert(j); assert(prefix); assert(dir); + if ((j->flags & SD_JOURNAL_LOCAL_ONLY) && + (sd_id128_from_string(dir, &id) < 0 || + sd_id128_get_machine(&mid) < 0 || + !sd_id128_equal(id, mid))) + return 0; + fn = join(prefix, "/", dir, NULL); if (!fn) return -ENOMEM; @@ -1124,7 +1095,7 @@ static void remove_root_wd(sd_journal *j, int wd) { } } -int sd_journal_open(sd_journal **ret) { +int sd_journal_open(sd_journal **ret, int flags) { sd_journal *j; const char *p; const char search_paths[] = @@ -1138,6 +1109,8 @@ int sd_journal_open(sd_journal **ret) { if (!j) return -ENOMEM; + j->flags = flags; + j->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); if (j->inotify_fd < 0) { r = -errno; @@ -1164,6 +1137,10 @@ int sd_journal_open(sd_journal **ret) { NULSTR_FOREACH(p, search_paths) { DIR *d; + if ((flags & SD_JOURNAL_RUNTIME_ONLY) && + !path_startswith(p, "/run")) + continue; + d = opendir(p); if (!d) { if (errno != ENOENT) @@ -1337,7 +1314,7 @@ int sd_journal_get_data(sd_journal *j, const char *field, const void **data, siz size_t t; p = le64toh(o->entry.items[i].object_offset); - le_hash = o->entry.items[j->current_field].hash; + le_hash = o->entry.items[i].hash; r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); if (r < 0) return r; @@ -1347,9 +1324,31 @@ int sd_journal_get_data(sd_journal *j, const char *field, const void **data, siz l = le64toh(o->object.size) - offsetof(Object, data.payload); - if (l >= field_length+1 && - memcmp(o->data.payload, field, field_length) == 0 && - o->data.payload[field_length] == '=') { + if (o->object.flags & OBJECT_COMPRESSED) { + +#ifdef HAVE_XZ + if (uncompress_startswith(o->data.payload, l, + &f->compress_buffer, &f->compress_buffer_size, + field, field_length, '=')) { + + uint64_t rsize; + + if (!uncompress_blob(o->data.payload, l, + &f->compress_buffer, &f->compress_buffer_size, &rsize)) + return -EBADMSG; + + *data = f->compress_buffer; + *size = (size_t) rsize; + + return 0; + } +#else + return -EPROTONOSUPPORT; +#endif + + } else if (l >= field_length+1 && + memcmp(o->data.payload, field, field_length) == 0 && + o->data.payload[field_length] == '=') { t = (size_t) l; @@ -1412,8 +1411,22 @@ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *size) { if ((uint64_t) t != l) return -E2BIG; - *data = o->data.payload; - *size = t; + if (o->object.flags & OBJECT_COMPRESSED) { +#ifdef HAVE_XZ + uint64_t rsize; + + if (!uncompress_blob(o->data.payload, l, &f->compress_buffer, &f->compress_buffer_size, &rsize)) + return -EBADMSG; + + *data = f->compress_buffer; + *size = (size_t) rsize; +#else + return -EPROTONOSUPPORT; +#endif + } else { + *data = o->data.payload; + *size = t; + } j->current_field ++; @@ -1541,3 +1554,20 @@ int sd_journal_process(sd_journal *j) { } } } + +int sd_journal_query_unique(sd_journal *j, const char *field) { + assert(j); + assert(field); + + return -ENOTSUP; +} + +int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l) { + assert(j); + + return -ENOTSUP; +} + +void sd_journal_restart_unique(sd_journal *j) { + assert(j); +}