mirror of
https://github.com/systemd/systemd.git
synced 2024-10-30 14:55:37 +03:00
Merge pull request #24974 from yuwata/sd-journal
sd-journal: several cleanups and follow-ups for compact mode PR
This commit is contained in:
commit
31b5f92016
@ -58,8 +58,7 @@ static void test_journal_flush(int argc, char *argv[]) {
|
||||
assert_se(r >= 0 ||
|
||||
IN_SET(r, -EBADMSG, /* corrupted file */
|
||||
-EPROTONOSUPPORT, /* unsupported compression */
|
||||
-EIO, /* file rotated */
|
||||
-EADDRNOTAVAIL)); /* corrupted file */
|
||||
-EIO)); /* file rotated */
|
||||
|
||||
if (++n >= 10000)
|
||||
break;
|
||||
|
@ -395,6 +395,9 @@ static bool warn_wrong_flags(const JournalFile *f, bool compatible) {
|
||||
const char *type = compatible ? "compatible" : "incompatible";
|
||||
uint32_t flags;
|
||||
|
||||
assert(f);
|
||||
assert(f->header);
|
||||
|
||||
flags = le32toh(compatible ? f->header->compatible_flags : f->header->incompatible_flags);
|
||||
|
||||
if (flags & ~supported) {
|
||||
@ -640,6 +643,10 @@ static int journal_file_move_to(
|
||||
assert(f);
|
||||
assert(ret);
|
||||
|
||||
/* This function may clear, overwrite, or alter previously cached entries. After this function has
|
||||
* been called, all objects except for one obtained by this function are invalidated and must be
|
||||
* re-read before use. */
|
||||
|
||||
if (size <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
@ -724,6 +731,7 @@ static int check_object_header(JournalFile *f, Object *o, ObjectType type, uint6
|
||||
/* Lightweight object checks. We want this to be fast, so that we won't
|
||||
* slowdown every journal_file_move_to_object() call too much. */
|
||||
static int check_object(JournalFile *f, Object *o, uint64_t offset) {
|
||||
assert(f);
|
||||
assert(o);
|
||||
|
||||
switch (o->object.type) {
|
||||
@ -874,6 +882,10 @@ int journal_file_move_to_object(JournalFile *f, ObjectType type, uint64_t offset
|
||||
|
||||
assert(f);
|
||||
|
||||
/* Even if this function fails, it may clear, overwrite, or alter previously cached entries. After
|
||||
* this function has been called, all objects except for one obtained by this function are
|
||||
* invalidated and must be re-read before use.. */
|
||||
|
||||
/* Objects may only be located at multiple of 64 bit */
|
||||
if (!VALID64(offset))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG),
|
||||
@ -996,7 +1008,7 @@ int journal_file_append_object(
|
||||
JournalFile *f,
|
||||
ObjectType type,
|
||||
uint64_t size,
|
||||
Object **ret,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
int r;
|
||||
@ -1032,8 +1044,8 @@ int journal_file_append_object(
|
||||
f->header->tail_object_offset = htole64(p);
|
||||
f->header->n_objects = htole64(le64toh(f->header->n_objects) + 1);
|
||||
|
||||
if (ret)
|
||||
*ret = o;
|
||||
if (ret_object)
|
||||
*ret_object = o;
|
||||
|
||||
if (ret_offset)
|
||||
*ret_offset = p;
|
||||
@ -1252,7 +1264,7 @@ static int journal_file_link_data(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int next_hash_offset(
|
||||
static int get_next_hash_offset(
|
||||
JournalFile *f,
|
||||
uint64_t *p,
|
||||
le64_t *next_hash_offset,
|
||||
@ -1261,6 +1273,11 @@ static int next_hash_offset(
|
||||
|
||||
uint64_t nextp;
|
||||
|
||||
assert(f);
|
||||
assert(p);
|
||||
assert(next_hash_offset);
|
||||
assert(depth);
|
||||
|
||||
nextp = le64toh(READ_NOW(*next_hash_offset));
|
||||
if (nextp > 0) {
|
||||
if (nextp <= *p) /* Refuse going in loops */
|
||||
@ -1280,15 +1297,19 @@ static int next_hash_offset(
|
||||
|
||||
int journal_file_find_field_object_with_hash(
|
||||
JournalFile *f,
|
||||
const void *field, uint64_t size, uint64_t hash,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
const void *field,
|
||||
uint64_t size,
|
||||
uint64_t hash,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
uint64_t p, osize, h, m, depth = 0;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
assert(f->header);
|
||||
assert(field && size > 0);
|
||||
assert(field);
|
||||
assert(size > 0);
|
||||
|
||||
/* If the field hash table is empty, we can't find anything */
|
||||
if (le64toh(f->header->field_hash_table_size) <= 0)
|
||||
@ -1318,15 +1339,15 @@ int journal_file_find_field_object_with_hash(
|
||||
le64toh(o->object.size) == osize &&
|
||||
memcmp(o->field.payload, field, size) == 0) {
|
||||
|
||||
if (ret)
|
||||
*ret = o;
|
||||
if (ret_object)
|
||||
*ret_object = o;
|
||||
if (ret_offset)
|
||||
*ret_offset = p;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = next_hash_offset(
|
||||
r = get_next_hash_offset(
|
||||
f,
|
||||
&p,
|
||||
&o->field.next_hash_offset,
|
||||
@ -1345,6 +1366,7 @@ uint64_t journal_file_hash_data(
|
||||
size_t sz) {
|
||||
|
||||
assert(f);
|
||||
assert(f->header);
|
||||
assert(data || sz == 0);
|
||||
|
||||
/* We try to unify our codebase on siphash, hence new-styled journal files utilizing the keyed hash
|
||||
@ -1358,23 +1380,29 @@ uint64_t journal_file_hash_data(
|
||||
|
||||
int journal_file_find_field_object(
|
||||
JournalFile *f,
|
||||
const void *field, uint64_t size,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
const void *field,
|
||||
uint64_t size,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
assert(f);
|
||||
assert(field && size > 0);
|
||||
assert(field);
|
||||
assert(size > 0);
|
||||
|
||||
return journal_file_find_field_object_with_hash(
|
||||
f,
|
||||
field, size,
|
||||
journal_file_hash_data(f, field, size),
|
||||
ret, ret_offset);
|
||||
ret_object, ret_offset);
|
||||
}
|
||||
|
||||
int journal_file_find_data_object_with_hash(
|
||||
JournalFile *f,
|
||||
const void *data, uint64_t size, uint64_t hash,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
const void *data,
|
||||
uint64_t size,
|
||||
uint64_t hash,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
uint64_t p, h, m, depth = 0;
|
||||
int r;
|
||||
@ -1417,8 +1445,8 @@ int journal_file_find_data_object_with_hash(
|
||||
assert(r > 0); /* journal_file_data_payload() always returns > 0 if no field is provided. */
|
||||
|
||||
if (memcmp_nn(data, size, d, rsize) == 0) {
|
||||
if (ret)
|
||||
*ret = o;
|
||||
if (ret_object)
|
||||
*ret_object = o;
|
||||
|
||||
if (ret_offset)
|
||||
*ret_offset = p;
|
||||
@ -1427,7 +1455,7 @@ int journal_file_find_data_object_with_hash(
|
||||
}
|
||||
|
||||
next:
|
||||
r = next_hash_offset(
|
||||
r = get_next_hash_offset(
|
||||
f,
|
||||
&p,
|
||||
&o->data.next_hash_offset,
|
||||
@ -1442,8 +1470,10 @@ int journal_file_find_data_object_with_hash(
|
||||
|
||||
int journal_file_find_data_object(
|
||||
JournalFile *f,
|
||||
const void *data, uint64_t size,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
const void *data,
|
||||
uint64_t size,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
assert(f);
|
||||
assert(data || size == 0);
|
||||
@ -1452,7 +1482,7 @@ int journal_file_find_data_object(
|
||||
f,
|
||||
data, size,
|
||||
journal_file_hash_data(f, data, size),
|
||||
ret, ret_offset);
|
||||
ret_object, ret_offset);
|
||||
}
|
||||
|
||||
bool journal_field_valid(const char *p, size_t l, bool allow_protected) {
|
||||
@ -1462,6 +1492,8 @@ bool journal_field_valid(const char *p, size_t l, bool allow_protected) {
|
||||
|
||||
http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html */
|
||||
|
||||
assert(p);
|
||||
|
||||
if (l == SIZE_MAX)
|
||||
l = strlen(p);
|
||||
|
||||
@ -1493,8 +1525,10 @@ bool journal_field_valid(const char *p, size_t l, bool allow_protected) {
|
||||
|
||||
static int journal_file_append_field(
|
||||
JournalFile *f,
|
||||
const void *field, uint64_t size,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
const void *field,
|
||||
uint64_t size,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
uint64_t hash, p;
|
||||
uint64_t osize;
|
||||
@ -1502,14 +1536,15 @@ static int journal_file_append_field(
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
assert(field && size > 0);
|
||||
assert(field);
|
||||
assert(size > 0);
|
||||
|
||||
if (!journal_field_valid(field, size, true))
|
||||
return -EBADMSG;
|
||||
|
||||
hash = journal_file_hash_data(f, field, size);
|
||||
|
||||
r = journal_file_find_field_object_with_hash(f, field, size, hash, ret, ret_offset);
|
||||
r = journal_file_find_field_object_with_hash(f, field, size, hash, ret_object, ret_offset);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
@ -1536,8 +1571,8 @@ static int journal_file_append_field(
|
||||
return r;
|
||||
#endif
|
||||
|
||||
if (ret) {
|
||||
r = journal_file_move_to_object(f, OBJECT_FIELD, p, ret);
|
||||
if (ret_object) {
|
||||
r = journal_file_move_to_object(f, OBJECT_FIELD, p, ret_object);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -1551,13 +1586,16 @@ static int journal_file_append_field(
|
||||
static Compression maybe_compress_payload(JournalFile *f, uint8_t *dst, const uint8_t *src, uint64_t size, size_t *rsize) {
|
||||
Compression compression = COMPRESSION_NONE;
|
||||
|
||||
assert(f);
|
||||
assert(f->header);
|
||||
|
||||
#if HAVE_COMPRESSION
|
||||
if (JOURNAL_FILE_COMPRESS(f) && size >= f->compress_threshold_bytes) {
|
||||
compression = compress_blob(src, size, dst, size - 1, rsize);
|
||||
if (compression > 0) {
|
||||
if (compression > 0)
|
||||
log_debug("Compressed data object %"PRIu64" -> %zu using %s",
|
||||
size, *rsize, compression_to_string(compression));
|
||||
} else
|
||||
else
|
||||
/* Compression didn't work, we don't really care why, let's continue without compression */
|
||||
compression = COMPRESSION_NONE;
|
||||
}
|
||||
@ -1568,8 +1606,10 @@ static Compression maybe_compress_payload(JournalFile *f, uint8_t *dst, const ui
|
||||
|
||||
static int journal_file_append_data(
|
||||
JournalFile *f,
|
||||
const void *data, uint64_t size,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
const void *data,
|
||||
uint64_t size,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
uint64_t hash, p, osize;
|
||||
Object *o, *fo;
|
||||
@ -1585,7 +1625,7 @@ static int journal_file_append_data(
|
||||
|
||||
hash = journal_file_hash_data(f, data, size);
|
||||
|
||||
r = journal_file_find_data_object_with_hash(f, data, size, hash, ret, ret_offset);
|
||||
r = journal_file_find_data_object_with_hash(f, data, size, hash, ret_object, ret_offset);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
@ -1634,8 +1674,8 @@ static int journal_file_append_data(
|
||||
o->data.next_field_offset = fo->field.head_data_offset;
|
||||
fo->field.head_data_offset = le64toh(p);
|
||||
|
||||
if (ret)
|
||||
*ret = o;
|
||||
if (ret_object)
|
||||
*ret_object = o;
|
||||
|
||||
if (ret_offset)
|
||||
*ret_offset = p;
|
||||
@ -1654,6 +1694,8 @@ static int maybe_decompress_payload(
|
||||
void **ret_data,
|
||||
size_t *ret_size) {
|
||||
|
||||
assert(f);
|
||||
|
||||
/* We can't read objects larger than 4G on a 32bit machine */
|
||||
if ((uint64_t) (size_t) size != size)
|
||||
return -E2BIG;
|
||||
@ -1672,8 +1714,10 @@ static int maybe_decompress_payload(
|
||||
compression_to_string(compression),
|
||||
size);
|
||||
if (r == 0) {
|
||||
*ret_data = NULL;
|
||||
*ret_size = 0;
|
||||
if (ret_data)
|
||||
*ret_data = NULL;
|
||||
if (ret_size)
|
||||
*ret_size = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1691,8 +1735,10 @@ static int maybe_decompress_payload(
|
||||
#endif
|
||||
} else {
|
||||
if (field && (size < field_length + 1 || memcmp(payload, field, field_length) != 0 || payload[field_length] != '=')) {
|
||||
*ret_data = NULL;
|
||||
*ret_size = 0;
|
||||
if (ret_data)
|
||||
*ret_data = NULL;
|
||||
if (ret_size)
|
||||
*ret_size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1719,9 +1765,8 @@ int journal_file_data_payload(
|
||||
Compression c;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
assert(!field == (field_length == 0)); /* These must be specified together. */
|
||||
assert(ret_data);
|
||||
assert(ret_size);
|
||||
|
||||
if (!o) {
|
||||
r = journal_file_move_to_object(f, OBJECT_DATA, offset, &o);
|
||||
@ -1762,6 +1807,7 @@ uint64_t journal_file_entry_n_items(JournalFile *f, Object *o) {
|
||||
uint64_t journal_file_entry_array_n_items(JournalFile *f, Object *o) {
|
||||
uint64_t sz;
|
||||
|
||||
assert(f);
|
||||
assert(o);
|
||||
|
||||
if (o->object.type != OBJECT_ENTRY_ARRAY)
|
||||
@ -1800,15 +1846,17 @@ static void write_entry_array_item(JournalFile *f, Object *o, uint64_t i, uint64
|
||||
o->entry_array.items.regular[i] = htole64(p);
|
||||
}
|
||||
|
||||
static int link_entry_into_array(JournalFile *f,
|
||||
le64_t *first,
|
||||
le64_t *idx,
|
||||
le32_t *tail,
|
||||
le32_t *tidx,
|
||||
uint64_t p) {
|
||||
int r;
|
||||
static int link_entry_into_array(
|
||||
JournalFile *f,
|
||||
le64_t *first,
|
||||
le64_t *idx,
|
||||
le32_t *tail,
|
||||
le32_t *tidx,
|
||||
uint64_t p) {
|
||||
|
||||
uint64_t n = 0, ap = 0, q, i, a, hidx;
|
||||
Object *o;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
assert(f->header);
|
||||
@ -1819,8 +1867,8 @@ static int link_entry_into_array(JournalFile *f,
|
||||
a = tail ? le32toh(*tail) : le64toh(*first);
|
||||
hidx = le64toh(READ_NOW(*idx));
|
||||
i = tidx ? le32toh(READ_NOW(*tidx)) : hidx;
|
||||
while (a > 0) {
|
||||
|
||||
while (a > 0) {
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -1884,13 +1932,14 @@ static int link_entry_into_array(JournalFile *f,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_entry_into_array_plus_one(JournalFile *f,
|
||||
le64_t *extra,
|
||||
le64_t *first,
|
||||
le64_t *idx,
|
||||
le32_t *tail,
|
||||
le32_t *tidx,
|
||||
uint64_t p) {
|
||||
static int link_entry_into_array_plus_one(
|
||||
JournalFile *f,
|
||||
le64_t *extra,
|
||||
le64_t *first,
|
||||
le64_t *idx,
|
||||
le32_t *tail,
|
||||
le32_t *tidx,
|
||||
uint64_t p) {
|
||||
|
||||
uint64_t hidx;
|
||||
int r;
|
||||
@ -1919,11 +1968,11 @@ static int link_entry_into_array_plus_one(JournalFile *f,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int journal_file_link_entry_item(JournalFile *f, Object *o, uint64_t offset, uint64_t p) {
|
||||
static int journal_file_link_entry_item(JournalFile *f, uint64_t offset, uint64_t p) {
|
||||
Object *o;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
assert(o);
|
||||
assert(offset > 0);
|
||||
|
||||
r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
|
||||
@ -1984,7 +2033,7 @@ static int journal_file_link_entry(
|
||||
* immediately but try to link the other entry items since it might still be possible to link
|
||||
* those if they don't require a new entry array to be allocated. */
|
||||
|
||||
k = journal_file_link_entry_item(f, o, offset, items[i].object_offset);
|
||||
k = journal_file_link_entry_item(f, offset, items[i].object_offset);
|
||||
if (k == -E2BIG)
|
||||
r = k;
|
||||
else if (k < 0)
|
||||
@ -2013,9 +2062,12 @@ static int journal_file_append_entry_internal(
|
||||
const dual_timestamp *ts,
|
||||
const sd_id128_t *boot_id,
|
||||
uint64_t xor_hash,
|
||||
const EntryItem items[], size_t n_items,
|
||||
const EntryItem items[],
|
||||
size_t n_items,
|
||||
uint64_t *seqnum,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
uint64_t np;
|
||||
uint64_t osize;
|
||||
Object *o;
|
||||
@ -2023,8 +2075,8 @@ static int journal_file_append_entry_internal(
|
||||
|
||||
assert(f);
|
||||
assert(f->header);
|
||||
assert(items || n_items == 0);
|
||||
assert(ts);
|
||||
assert(items || n_items == 0);
|
||||
|
||||
osize = offsetof(Object, entry.items) + (n_items * journal_file_entry_item_size(f));
|
||||
|
||||
@ -2053,8 +2105,8 @@ static int journal_file_append_entry_internal(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (ret)
|
||||
*ret = o;
|
||||
if (ret_object)
|
||||
*ret_object = o;
|
||||
|
||||
if (ret_offset)
|
||||
*ret_offset = np;
|
||||
@ -2152,12 +2204,14 @@ int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t)
|
||||
}
|
||||
|
||||
static int entry_item_cmp(const EntryItem *a, const EntryItem *b) {
|
||||
return CMP(a->object_offset, b->object_offset);
|
||||
return CMP(ASSERT_PTR(a)->object_offset, ASSERT_PTR(b)->object_offset);
|
||||
}
|
||||
|
||||
static size_t remove_duplicate_entry_items(EntryItem items[], size_t n) {
|
||||
size_t j = 1;
|
||||
|
||||
assert(items || n == 0);
|
||||
|
||||
if (n <= 1)
|
||||
return n;
|
||||
|
||||
@ -2172,9 +2226,11 @@ int journal_file_append_entry(
|
||||
JournalFile *f,
|
||||
const dual_timestamp *ts,
|
||||
const sd_id128_t *boot_id,
|
||||
const struct iovec iovec[], unsigned n_iovec,
|
||||
const struct iovec iovec[],
|
||||
unsigned n_iovec,
|
||||
uint64_t *seqnum,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
EntryItem *items;
|
||||
int r;
|
||||
@ -2183,7 +2239,8 @@ int journal_file_append_entry(
|
||||
|
||||
assert(f);
|
||||
assert(f->header);
|
||||
assert(iovec && n_iovec > 0);
|
||||
assert(iovec);
|
||||
assert(n_iovec > 0);
|
||||
|
||||
if (ts) {
|
||||
if (!VALID_REALTIME(ts->realtime))
|
||||
@ -2240,7 +2297,7 @@ int journal_file_append_entry(
|
||||
typesafe_qsort(items, n_iovec, entry_item_cmp);
|
||||
n_iovec = remove_duplicate_entry_items(items, n_iovec);
|
||||
|
||||
r = journal_file_append_entry_internal(f, ts, boot_id, xor_hash, items, n_iovec, seqnum, ret, ret_offset);
|
||||
r = journal_file_append_entry_internal(f, ts, boot_id, xor_hash, items, n_iovec, seqnum, ret_object, ret_offset);
|
||||
|
||||
/* If the memory mapping triggered a SIGBUS then we return an
|
||||
* IO error and ignore the error code passed down to us, since
|
||||
@ -2275,6 +2332,8 @@ static void chain_cache_put(
|
||||
uint64_t total,
|
||||
uint64_t last_index) {
|
||||
|
||||
assert(h);
|
||||
|
||||
if (!ci) {
|
||||
/* If the chain item to cache for this chain is the
|
||||
* first one it's not worth caching anything */
|
||||
@ -2325,7 +2384,14 @@ static int bump_array_index(uint64_t *i, direction_t direction, uint64_t n) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bump_entry_array(JournalFile *f, Object *o, uint64_t offset, uint64_t first, direction_t direction, uint64_t *ret) {
|
||||
static int bump_entry_array(
|
||||
JournalFile *f,
|
||||
Object *o,
|
||||
uint64_t offset,
|
||||
uint64_t first,
|
||||
direction_t direction,
|
||||
uint64_t *ret) {
|
||||
|
||||
uint64_t p, q = 0;
|
||||
int r;
|
||||
|
||||
@ -2333,8 +2399,10 @@ static int bump_entry_array(JournalFile *f, Object *o, uint64_t offset, uint64_t
|
||||
assert(offset);
|
||||
assert(ret);
|
||||
|
||||
if (direction == DIRECTION_DOWN)
|
||||
if (direction == DIRECTION_DOWN) {
|
||||
assert(o);
|
||||
return le64toh(o->entry_array.next_entry_array_offset);
|
||||
}
|
||||
|
||||
/* Entry array chains are a singly linked list, so to find the previous array in the chain, we have
|
||||
* to start iterating from the top. */
|
||||
@ -2365,15 +2433,18 @@ static int generic_array_get(
|
||||
uint64_t first,
|
||||
uint64_t i,
|
||||
direction_t direction,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
Object *o;
|
||||
uint64_t p = 0, a, t = 0, k;
|
||||
int r;
|
||||
ChainCacheItem *ci;
|
||||
Object *o;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
|
||||
/* FIXME: fix return value assignment on success. */
|
||||
|
||||
a = first;
|
||||
|
||||
/* Try the chain cache first */
|
||||
@ -2437,7 +2508,7 @@ static int generic_array_get(
|
||||
do {
|
||||
p = journal_file_entry_array_item(f, o, i);
|
||||
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, p, ret);
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, p, ret_object);
|
||||
if (r >= 0) {
|
||||
/* Let's cache this item for the next invocation */
|
||||
chain_cache_put(f->chain_cache, ci, first, a, journal_file_entry_array_item(f, o, 0), t, i);
|
||||
@ -2472,16 +2543,19 @@ static int generic_array_get_plus_one(
|
||||
uint64_t first,
|
||||
uint64_t i,
|
||||
direction_t direction,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
|
||||
/* FIXME: fix return value assignment on success. */
|
||||
|
||||
if (i == 0) {
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, ret);
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, ret_object);
|
||||
if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG))
|
||||
return generic_array_get(f, first, 0, direction, ret, ret_offset);
|
||||
return generic_array_get(f, first, 0, direction, ret_object, ret_offset);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2491,7 +2565,7 @@ static int generic_array_get_plus_one(
|
||||
return 1;
|
||||
}
|
||||
|
||||
return generic_array_get(f, first, i - 1, direction, ret, ret_offset);
|
||||
return generic_array_get(f, first, i - 1, direction, ret_object, ret_offset);
|
||||
}
|
||||
|
||||
enum {
|
||||
@ -2507,7 +2581,7 @@ static int generic_array_bisect(
|
||||
uint64_t needle,
|
||||
int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle),
|
||||
direction_t direction,
|
||||
Object **ret,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset,
|
||||
uint64_t *ret_idx) {
|
||||
|
||||
@ -2527,8 +2601,8 @@ static int generic_array_bisect(
|
||||
uint64_t a, p, t = 0, i = 0, last_p = 0, last_index = UINT64_MAX;
|
||||
bool subtract_one = false;
|
||||
Object *array = NULL;
|
||||
int r;
|
||||
ChainCacheItem *ci;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
assert(test_object);
|
||||
@ -2714,8 +2788,8 @@ found:
|
||||
else
|
||||
p = journal_file_entry_array_item(f, array, i);
|
||||
|
||||
if (ret) {
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, p, ret);
|
||||
if (ret_object) {
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, p, ret_object);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -2737,7 +2811,7 @@ static int generic_array_bisect_plus_one(
|
||||
uint64_t needle,
|
||||
int (*test_object)(JournalFile *f, uint64_t p, uint64_t needle),
|
||||
direction_t direction,
|
||||
Object **ret,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset,
|
||||
uint64_t *ret_idx) {
|
||||
|
||||
@ -2774,7 +2848,7 @@ static int generic_array_bisect_plus_one(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = generic_array_bisect(f, first, n-1, needle, test_object, direction, ret, ret_offset, ret_idx);
|
||||
r = generic_array_bisect(f, first, n-1, needle, test_object, direction, ret_object, ret_offset, ret_idx);
|
||||
|
||||
if (r == 0 && step_back)
|
||||
goto found;
|
||||
@ -2785,8 +2859,8 @@ static int generic_array_bisect_plus_one(
|
||||
return r;
|
||||
|
||||
found:
|
||||
if (ret) {
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, ret);
|
||||
if (ret_object) {
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, extra, ret_object);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -2816,7 +2890,7 @@ int journal_file_move_to_entry_by_offset(
|
||||
JournalFile *f,
|
||||
uint64_t p,
|
||||
direction_t direction,
|
||||
Object **ret,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
assert(f);
|
||||
@ -2829,7 +2903,7 @@ int journal_file_move_to_entry_by_offset(
|
||||
p,
|
||||
test_object_offset,
|
||||
direction,
|
||||
ret, ret_offset, NULL);
|
||||
ret_object, ret_offset, NULL);
|
||||
}
|
||||
|
||||
static int test_object_seqnum(JournalFile *f, uint64_t p, uint64_t needle) {
|
||||
@ -2857,8 +2931,9 @@ int journal_file_move_to_entry_by_seqnum(
|
||||
JournalFile *f,
|
||||
uint64_t seqnum,
|
||||
direction_t direction,
|
||||
Object **ret,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
assert(f);
|
||||
assert(f->header);
|
||||
|
||||
@ -2869,7 +2944,7 @@ int journal_file_move_to_entry_by_seqnum(
|
||||
seqnum,
|
||||
test_object_seqnum,
|
||||
direction,
|
||||
ret, ret_offset, NULL);
|
||||
ret_object, ret_offset, NULL);
|
||||
}
|
||||
|
||||
static int test_object_realtime(JournalFile *f, uint64_t p, uint64_t needle) {
|
||||
@ -2897,8 +2972,9 @@ int journal_file_move_to_entry_by_realtime(
|
||||
JournalFile *f,
|
||||
uint64_t realtime,
|
||||
direction_t direction,
|
||||
Object **ret,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
assert(f);
|
||||
assert(f->header);
|
||||
|
||||
@ -2909,7 +2985,7 @@ int journal_file_move_to_entry_by_realtime(
|
||||
realtime,
|
||||
test_object_realtime,
|
||||
direction,
|
||||
ret, ret_offset, NULL);
|
||||
ret_object, ret_offset, NULL);
|
||||
}
|
||||
|
||||
static int test_object_monotonic(JournalFile *f, uint64_t p, uint64_t needle) {
|
||||
@ -2936,13 +3012,15 @@ static int test_object_monotonic(JournalFile *f, uint64_t p, uint64_t needle) {
|
||||
static int find_data_object_by_boot_id(
|
||||
JournalFile *f,
|
||||
sd_id128_t boot_id,
|
||||
Object **o,
|
||||
uint64_t *b) {
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
char t[STRLEN("_BOOT_ID=") + 32 + 1] = "_BOOT_ID=";
|
||||
|
||||
assert(f);
|
||||
|
||||
sd_id128_to_string(boot_id, t + 9);
|
||||
return journal_file_find_data_object(f, t, sizeof(t) - 1, o, b);
|
||||
return journal_file_find_data_object(f, t, sizeof(t) - 1, ret_object, ret_offset);
|
||||
}
|
||||
|
||||
int journal_file_move_to_entry_by_monotonic(
|
||||
@ -2950,7 +3028,7 @@ int journal_file_move_to_entry_by_monotonic(
|
||||
sd_id128_t boot_id,
|
||||
uint64_t monotonic,
|
||||
direction_t direction,
|
||||
Object **ret,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
Object *o;
|
||||
@ -2972,10 +3050,12 @@ int journal_file_move_to_entry_by_monotonic(
|
||||
monotonic,
|
||||
test_object_monotonic,
|
||||
direction,
|
||||
ret, ret_offset, NULL);
|
||||
ret_object, ret_offset, NULL);
|
||||
}
|
||||
|
||||
void journal_file_reset_location(JournalFile *f) {
|
||||
assert(f);
|
||||
|
||||
f->location_type = LOCATION_HEAD;
|
||||
f->current_offset = 0;
|
||||
f->current_seqnum = 0;
|
||||
@ -2986,6 +3066,9 @@ void journal_file_reset_location(JournalFile *f) {
|
||||
}
|
||||
|
||||
void journal_file_save_location(JournalFile *f, Object *o, uint64_t offset) {
|
||||
assert(f);
|
||||
assert(o);
|
||||
|
||||
f->location_type = LOCATION_SEEK;
|
||||
f->current_offset = offset;
|
||||
f->current_seqnum = le64toh(o->entry.seqnum);
|
||||
@ -3061,7 +3144,8 @@ int journal_file_next_entry(
|
||||
JournalFile *f,
|
||||
uint64_t p,
|
||||
direction_t direction,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
uint64_t i, n, ofs;
|
||||
int r;
|
||||
@ -3069,6 +3153,8 @@ int journal_file_next_entry(
|
||||
assert(f);
|
||||
assert(f->header);
|
||||
|
||||
/* FIXME: fix return value assignment. */
|
||||
|
||||
n = le64toh(READ_NOW(f->header->n_entries));
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
@ -3093,7 +3179,7 @@ int journal_file_next_entry(
|
||||
}
|
||||
|
||||
/* And jump to it */
|
||||
r = generic_array_get(f, le64toh(f->header->entry_array_offset), i, direction, ret, &ofs);
|
||||
r = generic_array_get(f, le64toh(f->header->entry_array_offset), i, direction, ret_object, &ofs);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -3113,7 +3199,8 @@ int journal_file_next_entry_for_data(
|
||||
JournalFile *f,
|
||||
Object *d,
|
||||
direction_t direction,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
uint64_t i, n, ofs;
|
||||
int r;
|
||||
@ -3122,6 +3209,8 @@ int journal_file_next_entry_for_data(
|
||||
assert(d);
|
||||
assert(d->object.type == OBJECT_DATA);
|
||||
|
||||
/* FIXME: fix return value assignment. */
|
||||
|
||||
n = le64toh(READ_NOW(d->data.n_entries));
|
||||
if (n <= 0)
|
||||
return n;
|
||||
@ -3133,7 +3222,7 @@ int journal_file_next_entry_for_data(
|
||||
le64toh(d->data.entry_array_offset),
|
||||
i,
|
||||
direction,
|
||||
ret, &ofs);
|
||||
ret_object, &ofs);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -3171,11 +3260,12 @@ int journal_file_move_to_entry_by_monotonic_for_data(
|
||||
sd_id128_t boot_id,
|
||||
uint64_t monotonic,
|
||||
direction_t direction,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
uint64_t b, z, entry_offset, entry_array_offset, n_entries;
|
||||
Object *o;
|
||||
int r;
|
||||
uint64_t b, z, entry_offset, entry_array_offset, n_entries;
|
||||
|
||||
assert(f);
|
||||
assert(d);
|
||||
@ -3238,8 +3328,8 @@ int journal_file_move_to_entry_by_monotonic_for_data(
|
||||
return r;
|
||||
|
||||
if (p == q) {
|
||||
if (ret) {
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, q, ret);
|
||||
if (ret_object) {
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, q, ret_object);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -3259,7 +3349,8 @@ int journal_file_move_to_entry_by_seqnum_for_data(
|
||||
Object *d,
|
||||
uint64_t seqnum,
|
||||
direction_t direction,
|
||||
Object **ret, uint64_t *ret_offset) {
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset) {
|
||||
|
||||
assert(f);
|
||||
assert(d);
|
||||
@ -3273,7 +3364,7 @@ int journal_file_move_to_entry_by_seqnum_for_data(
|
||||
seqnum,
|
||||
test_object_seqnum,
|
||||
direction,
|
||||
ret, ret_offset, NULL);
|
||||
ret_object, ret_offset, NULL);
|
||||
}
|
||||
|
||||
int journal_file_move_to_entry_by_realtime_for_data(
|
||||
@ -3300,8 +3391,8 @@ int journal_file_move_to_entry_by_realtime_for_data(
|
||||
|
||||
void journal_file_dump(JournalFile *f) {
|
||||
Object *o;
|
||||
int r;
|
||||
uint64_t p;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
assert(f->header);
|
||||
@ -3587,9 +3678,9 @@ int journal_file_open(
|
||||
void *h;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
assert(fd >= 0 || fname);
|
||||
assert(mmap_cache);
|
||||
assert(ret);
|
||||
|
||||
if (!IN_SET((open_flags & O_ACCMODE), O_RDONLY, O_RDWR))
|
||||
return -EINVAL;
|
||||
@ -3893,7 +3984,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
|
||||
assert(from);
|
||||
assert(to);
|
||||
assert(o);
|
||||
assert(p);
|
||||
assert(p > 0);
|
||||
|
||||
if (!journal_file_writable(to))
|
||||
return -EPERM;
|
||||
@ -3917,7 +4008,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
|
||||
r = journal_file_data_payload(from, NULL, q, NULL, 0, 0, &data, &l);
|
||||
if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) {
|
||||
log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", i);
|
||||
continue;
|
||||
goto next;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -3939,6 +4030,13 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6
|
||||
.object_offset = h,
|
||||
.hash = le64toh(u->data.hash),
|
||||
};
|
||||
|
||||
next:
|
||||
/* The above journal_file_data_payload() may clear or overwrite cached object. Hence, we need
|
||||
* to re-read the object from the cache. */
|
||||
r = journal_file_move_to_object(from, OBJECT_ENTRY, p, &o);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = journal_file_append_entry_internal(to, &ts, boot_id, xor_hash, items, n, NULL, NULL, NULL);
|
||||
@ -3964,35 +4062,37 @@ void journal_reset_metrics(JournalMetrics *m) {
|
||||
};
|
||||
}
|
||||
|
||||
int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to) {
|
||||
int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *ret_from, usec_t *ret_to) {
|
||||
assert(f);
|
||||
assert(f->header);
|
||||
assert(from || to);
|
||||
assert(ret_from || ret_to);
|
||||
|
||||
if (from) {
|
||||
if (ret_from) {
|
||||
if (f->header->head_entry_realtime == 0)
|
||||
return -ENOENT;
|
||||
|
||||
*from = le64toh(f->header->head_entry_realtime);
|
||||
*ret_from = le64toh(f->header->head_entry_realtime);
|
||||
}
|
||||
|
||||
if (to) {
|
||||
if (ret_to) {
|
||||
if (f->header->tail_entry_realtime == 0)
|
||||
return -ENOENT;
|
||||
|
||||
*to = le64toh(f->header->tail_entry_realtime);
|
||||
*ret_to = le64toh(f->header->tail_entry_realtime);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot_id, usec_t *from, usec_t *to) {
|
||||
int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot_id, usec_t *ret_from, usec_t *ret_to) {
|
||||
Object *o;
|
||||
uint64_t p;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
assert(from || to);
|
||||
assert(ret_from || ret_to);
|
||||
|
||||
/* FIXME: fix return value assignment on success with 0. */
|
||||
|
||||
r = find_data_object_by_boot_id(f, boot_id, &o, &p);
|
||||
if (r <= 0)
|
||||
@ -4001,15 +4101,15 @@ int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot_id, u
|
||||
if (le64toh(o->data.n_entries) <= 0)
|
||||
return 0;
|
||||
|
||||
if (from) {
|
||||
if (ret_from) {
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, le64toh(o->data.entry_offset), &o);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*from = le64toh(o->entry.monotonic);
|
||||
*ret_from = le64toh(o->entry.monotonic);
|
||||
}
|
||||
|
||||
if (to) {
|
||||
if (ret_to) {
|
||||
r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -4023,7 +4123,7 @@ int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot_id, u
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
*to = le64toh(o->entry.monotonic);
|
||||
*ret_to = le64toh(o->entry.monotonic);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -249,38 +249,38 @@ static inline size_t journal_file_entry_array_item_size(JournalFile *f) {
|
||||
|
||||
uint64_t journal_file_hash_table_n_items(Object *o) _pure_;
|
||||
|
||||
int journal_file_append_object(JournalFile *f, ObjectType type, uint64_t size, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_append_object(JournalFile *f, ObjectType type, uint64_t size, Object **ret_object, uint64_t *ret_offset);
|
||||
int journal_file_append_entry(
|
||||
JournalFile *f,
|
||||
const dual_timestamp *ts,
|
||||
const sd_id128_t *boot_id,
|
||||
const struct iovec iovec[], unsigned n_iovec,
|
||||
uint64_t *seqno,
|
||||
Object **ret,
|
||||
Object **ret_object,
|
||||
uint64_t *ret_offset);
|
||||
|
||||
int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, uint64_t size, uint64_t hash, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret_object, uint64_t *ret_offset);
|
||||
int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, uint64_t size, uint64_t hash, Object **ret_object, uint64_t *ret_offset);
|
||||
|
||||
int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t size, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_find_field_object(JournalFile *f, const void *field, uint64_t size, Object **ret_object, uint64_t *ret_offset);
|
||||
int journal_file_find_field_object_with_hash(JournalFile *f, const void *field, uint64_t size, uint64_t hash, Object **ret_object, uint64_t *ret_offset);
|
||||
|
||||
void journal_file_reset_location(JournalFile *f);
|
||||
void journal_file_save_location(JournalFile *f, Object *o, uint64_t offset);
|
||||
int journal_file_compare_locations(JournalFile *af, JournalFile *bf);
|
||||
int journal_file_next_entry(JournalFile *f, uint64_t p, direction_t direction, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_next_entry(JournalFile *f, uint64_t p, direction_t direction, Object **ret_object, uint64_t *ret_offset);
|
||||
|
||||
int journal_file_next_entry_for_data(JournalFile *f, Object *d, direction_t direction, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_next_entry_for_data(JournalFile *f, Object *d, direction_t direction, Object **ret_object, uint64_t *ret_offset);
|
||||
|
||||
int journal_file_move_to_entry_by_offset(JournalFile *f, uint64_t p, direction_t direction, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_monotonic(JournalFile *f, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_offset(JournalFile *f, uint64_t p, direction_t direction, Object **ret_object, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret_object, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret_object, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_monotonic(JournalFile *f, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret_object, uint64_t *ret_offset);
|
||||
|
||||
int journal_file_move_to_entry_by_offset_for_data(JournalFile *f, Object *d, uint64_t p, direction_t direction, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_seqnum_for_data(JournalFile *f, Object *d, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_realtime_for_data(JournalFile *f, Object *d, uint64_t realtime, direction_t direction, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_monotonic_for_data(JournalFile *f, Object *d, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_offset_for_data(JournalFile *f, Object *d, uint64_t p, direction_t direction, Object **ret_object, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_seqnum_for_data(JournalFile *f, Object *d, uint64_t seqnum, direction_t direction, Object **ret_object, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_realtime_for_data(JournalFile *f, Object *d, uint64_t realtime, direction_t direction, Object **ret_object, uint64_t *ret_offset);
|
||||
int journal_file_move_to_entry_by_monotonic_for_data(JournalFile *f, Object *d, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret_object, uint64_t *ret_offset);
|
||||
|
||||
int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p);
|
||||
|
||||
@ -297,8 +297,8 @@ int journal_file_enable_post_change_timer(JournalFile *f, sd_event *e, usec_t t)
|
||||
|
||||
void journal_reset_metrics(JournalMetrics *m);
|
||||
|
||||
int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *to);
|
||||
int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot, usec_t *from, usec_t *to);
|
||||
int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *ret_from, usec_t *ret_to);
|
||||
int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot, usec_t *ret_from, usec_t *ret_to);
|
||||
|
||||
bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec, int log_level);
|
||||
|
||||
|
@ -2264,8 +2264,8 @@ static bool field_is_valid(const char *field) {
|
||||
_public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *size) {
|
||||
JournalFile *f;
|
||||
size_t field_length;
|
||||
int r;
|
||||
Object *o;
|
||||
int r;
|
||||
|
||||
assert_return(j, -EINVAL);
|
||||
assert_return(!journal_pid_changed(j), -ECHILD);
|
||||
@ -2296,10 +2296,10 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
|
||||
p = journal_file_entry_item_object_offset(f, o, i);
|
||||
r = journal_file_data_payload(f, NULL, p, field, field_length, j->data_threshold, &d, &l);
|
||||
if (r == 0)
|
||||
continue;
|
||||
goto next;
|
||||
if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) {
|
||||
log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", i);
|
||||
continue;
|
||||
goto next;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -2308,6 +2308,12 @@ _public_ int sd_journal_get_data(sd_journal *j, const char *field, const void **
|
||||
*size = l;
|
||||
|
||||
return 0;
|
||||
|
||||
next:
|
||||
/* journal_file_data_payload() may clear or overwrite cached object. */
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
@ -2343,7 +2349,7 @@ _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t
|
||||
r = journal_file_data_payload(f, NULL, p, NULL, 0, j->data_threshold, &d, &l);
|
||||
if (IN_SET(r, -EADDRNOTAVAIL, -EBADMSG)) {
|
||||
log_debug_errno(r, "Entry item %"PRIu64" data object is bad, skipping over it: %m", j->current_field);
|
||||
continue;
|
||||
goto next;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -2355,6 +2361,12 @@ _public_ int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t
|
||||
j->current_field++;
|
||||
|
||||
return 1;
|
||||
|
||||
next:
|
||||
/* journal_file_data_payload() may clear or overwrite cached object. */
|
||||
r = journal_file_move_to_object(f, OBJECT_ENTRY, f->current_offset, &o);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user