#define COMPRESSION_SIZE_THRESHOLD (512ULL)
/* This is the minimum journal file size */
-#define JOURNAL_FILE_SIZE_MIN (64ULL*1024ULL) /* 64 KiB */
+#define JOURNAL_FILE_SIZE_MIN (4ULL*1024ULL*1024ULL) /* 4 MiB */
/* These are the lower and upper bounds if we deduce the max_use value
* from the file system size */
/* How many entries to keep in the entry array chain cache at max */
#define CHAIN_CACHE_MAX 20
-int journal_file_set_online(JournalFile *f) {
+static int journal_file_set_online(JournalFile *f) {
assert(f);
if (!f->writable)
if (s < DEFAULT_DATA_HASH_TABLE_SIZE)
s = DEFAULT_DATA_HASH_TABLE_SIZE;
- log_debug("Reserving %llu entries in hash table.", (unsigned long long) (s / sizeof(HashItem)));
+ log_debug("Reserving %"PRIu64" entries in hash table.", s / sizeof(HashItem));
r = journal_file_append_object(f,
OBJECT_DATA_HASH_TABLE,
osize = offsetof(Object, field.payload) + size;
r = journal_file_append_object(f, OBJECT_FIELD, osize, &o, &p);
+ if (r < 0)
+ return r;
o->field.hash = htole64(hash);
memcpy(o->field.payload, field, size);
o->object.size = htole64(offsetof(Object, data.payload) + rsize);
o->object.flags |= OBJECT_COMPRESSED;
- log_debug("Compressed data object %lu -> %lu", (unsigned long) size, (unsigned long) rsize);
+ log_debug("Compressed data object %"PRIu64" -> %"PRIu64, size, rsize);
}
}
#endif
if (r < 0)
return r;
- /* log_debug("=> %s seqnr=%lu n_entries=%lu", f->path, (unsigned long) o->entry.seqnum, (unsigned long) f->header->n_entries); */
+ /* log_debug("=> %s seqnr=%"PRIu64" n_entries=%"PRIu64, f->path, o->entry.seqnum, f->header->n_entries); */
if (f->header->head_entry_realtime == 0)
f->header->head_entry_realtime = o->entry.realtime;
/* Order by the position on disk, in order to improve seek
* times for rotating media. */
- qsort(items, n_iovec, sizeof(EntryItem), entry_item_cmp);
+ qsort_safe(items, n_iovec, sizeof(EntryItem), entry_item_cmp);
r = journal_file_append_entry_internal(f, ts, xor_hash, items, n_iovec, seqnum, ret, offset);
return 1;
}
-static int test_object_offset(JournalFile *f, uint64_t p, uint64_t needle) {
+_pure_ static int test_object_offset(JournalFile *f, uint64_t p, uint64_t needle) {
assert(f);
assert(p > 0);
return TEST_RIGHT;
}
+static inline int find_data_object_by_boot_id(
+ JournalFile *f,
+ sd_id128_t boot_id,
+ Object **o,
+ uint64_t *b) {
+ char t[sizeof("_BOOT_ID=")-1 + 32 + 1] = "_BOOT_ID=";
+
+ sd_id128_to_string(boot_id, t + 9);
+ return journal_file_find_data_object(f, t, sizeof(t) - 1, o, b);
+}
+
int journal_file_move_to_entry_by_monotonic(
JournalFile *f,
sd_id128_t boot_id,
Object **ret,
uint64_t *offset) {
- char t[9+32+1] = "_BOOT_ID=";
Object *o;
int r;
assert(f);
- sd_id128_to_string(boot_id, t + 9);
- r = journal_file_find_data_object(f, t, strlen(t), &o, NULL);
+ r = find_data_object_by_boot_id(f, boot_id, &o, NULL);
if (r < 0)
return r;
if (r == 0)
direction_t direction,
Object **ret, uint64_t *offset) {
- char t[9+32+1] = "_BOOT_ID=";
Object *o, *d;
int r;
uint64_t b, z;
assert(f);
/* First, seek by time */
- sd_id128_to_string(boot_id, t + 9);
- r = journal_file_find_data_object(f, t, strlen(t), &o, &b);
+ r = find_data_object_by_boot_id(f, boot_id, &o, &b);
if (r < 0)
return r;
if (r == 0)
break;
case OBJECT_ENTRY:
- printf("Type: OBJECT_ENTRY seqnum=%llu monotonic=%llu realtime=%llu\n",
- (unsigned long long) le64toh(o->entry.seqnum),
- (unsigned long long) le64toh(o->entry.monotonic),
- (unsigned long long) le64toh(o->entry.realtime));
+ printf("Type: OBJECT_ENTRY seqnum=%"PRIu64" monotonic=%"PRIu64" realtime=%"PRIu64"\n",
+ le64toh(o->entry.seqnum),
+ le64toh(o->entry.monotonic),
+ le64toh(o->entry.realtime));
break;
case OBJECT_FIELD_HASH_TABLE:
break;
case OBJECT_TAG:
- printf("Type: OBJECT_TAG seqnum=%llu epoch=%llu\n",
- (unsigned long long) le64toh(o->tag.seqnum),
- (unsigned long long) le64toh(o->tag.epoch));
+ printf("Type: OBJECT_TAG seqnum=%"PRIu64" epoch=%"PRIu64"\n",
+ le64toh(o->tag.seqnum),
+ le64toh(o->tag.epoch));
break;
default:
log_error("File corrupt");
}
+static const char* format_timestamp_safe(char *buf, size_t l, usec_t t) {
+ const char *x;
+
+ x = format_timestamp(buf, l, t);
+ if (x)
+ return x;
+ return " --- ";
+}
+
void journal_file_print_header(JournalFile *f) {
- char a[33], b[33], c[33];
- char x[FORMAT_TIMESTAMP_MAX], y[FORMAT_TIMESTAMP_MAX];
+ char a[33], b[33], c[33], d[33];
+ char x[FORMAT_TIMESTAMP_MAX], y[FORMAT_TIMESTAMP_MAX], z[FORMAT_TIMESTAMP_MAX];
struct stat st;
char bytes[FORMAT_BYTES_MAX];
"State: %s\n"
"Compatible Flags:%s%s\n"
"Incompatible Flags:%s%s\n"
- "Header size: %llu\n"
- "Arena size: %llu\n"
- "Data Hash Table Size: %llu\n"
- "Field Hash Table Size: %llu\n"
+ "Header size: %"PRIu64"\n"
+ "Arena size: %"PRIu64"\n"
+ "Data Hash Table Size: %"PRIu64"\n"
+ "Field Hash Table Size: %"PRIu64"\n"
"Rotate Suggested: %s\n"
- "Head Sequential Number: %llu\n"
- "Tail Sequential Number: %llu\n"
+ "Head Sequential Number: %"PRIu64"\n"
+ "Tail Sequential Number: %"PRIu64"\n"
"Head Realtime Timestamp: %s\n"
"Tail Realtime Timestamp: %s\n"
- "Objects: %llu\n"
- "Entry Objects: %llu\n",
+ "Tail Monotonic Timestamp: %s\n"
+ "Objects: %"PRIu64"\n"
+ "Entry Objects: %"PRIu64"\n",
f->path,
sd_id128_to_string(f->header->file_id, a),
sd_id128_to_string(f->header->machine_id, b),
sd_id128_to_string(f->header->boot_id, c),
- sd_id128_to_string(f->header->seqnum_id, c),
+ sd_id128_to_string(f->header->seqnum_id, d),
f->header->state == STATE_OFFLINE ? "OFFLINE" :
f->header->state == STATE_ONLINE ? "ONLINE" :
f->header->state == STATE_ARCHIVED ? "ARCHIVED" : "UNKNOWN",
(le32toh(f->header->compatible_flags) & ~HEADER_COMPATIBLE_SEALED) ? " ???" : "",
JOURNAL_HEADER_COMPRESSED(f->header) ? " COMPRESSED" : "",
(le32toh(f->header->incompatible_flags) & ~HEADER_INCOMPATIBLE_COMPRESSED) ? " ???" : "",
- (unsigned long long) le64toh(f->header->header_size),
- (unsigned long long) le64toh(f->header->arena_size),
- (unsigned long long) le64toh(f->header->data_hash_table_size) / sizeof(HashItem),
- (unsigned long long) le64toh(f->header->field_hash_table_size) / sizeof(HashItem),
+ le64toh(f->header->header_size),
+ le64toh(f->header->arena_size),
+ le64toh(f->header->data_hash_table_size) / sizeof(HashItem),
+ le64toh(f->header->field_hash_table_size) / sizeof(HashItem),
yes_no(journal_file_rotate_suggested(f, 0)),
- (unsigned long long) le64toh(f->header->head_entry_seqnum),
- (unsigned long long) le64toh(f->header->tail_entry_seqnum),
- format_timestamp(x, sizeof(x), le64toh(f->header->head_entry_realtime)),
- format_timestamp(y, sizeof(y), le64toh(f->header->tail_entry_realtime)),
- (unsigned long long) le64toh(f->header->n_objects),
- (unsigned long long) le64toh(f->header->n_entries));
+ le64toh(f->header->head_entry_seqnum),
+ le64toh(f->header->tail_entry_seqnum),
+ format_timestamp_safe(x, sizeof(x), le64toh(f->header->head_entry_realtime)),
+ format_timestamp_safe(y, sizeof(y), le64toh(f->header->tail_entry_realtime)),
+ format_timespan(z, sizeof(z), le64toh(f->header->tail_entry_monotonic), USEC_PER_MSEC),
+ le64toh(f->header->n_objects),
+ le64toh(f->header->n_entries));
if (JOURNAL_HEADER_CONTAINS(f->header, n_data))
- printf("Data Objects: %llu\n"
+ printf("Data Objects: %"PRIu64"\n"
"Data Hash Table Fill: %.1f%%\n",
- (unsigned long long) le64toh(f->header->n_data),
+ le64toh(f->header->n_data),
100.0 * (double) le64toh(f->header->n_data) / ((double) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem))));
if (JOURNAL_HEADER_CONTAINS(f->header, n_fields))
- printf("Field Objects: %llu\n"
+ printf("Field Objects: %"PRIu64"\n"
"Field Hash Table Fill: %.1f%%\n",
- (unsigned long long) le64toh(f->header->n_fields),
+ le64toh(f->header->n_fields),
100.0 * (double) le64toh(f->header->n_fields) / ((double) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem))));
if (JOURNAL_HEADER_CONTAINS(f->header, n_tags))
- printf("Tag Objects: %llu\n",
- (unsigned long long) le64toh(f->header->n_tags));
+ printf("Tag Objects: %"PRIu64"\n",
+ le64toh(f->header->n_tags));
if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays))
- printf("Entry Array Objects: %llu\n",
- (unsigned long long) le64toh(f->header->n_entry_arrays));
+ printf("Entry Array Objects: %"PRIu64"\n",
+ le64toh(f->header->n_entry_arrays));
if (fstat(f->fd, &st) >= 0)
printf("Disk usage: %s\n", format_bytes(bytes, sizeof(bytes), (off_t) st.st_blocks * 512ULL));
}
int journal_file_rotate(JournalFile **f, bool compress, bool seal) {
- char *p;
+ _cleanup_free_ char *p = NULL;
size_t l;
JournalFile *old_file, *new_file = NULL;
int r;
return -EINVAL;
l = strlen(old_file->path);
-
- p = new(char, l + 1 + 32 + 1 + 16 + 1 + 16 + 1);
- if (!p)
+ r = asprintf(&p, "%.*s@" SD_ID128_FORMAT_STR "-%016"PRIx64"-%016"PRIx64".journal",
+ (int) l - 8, old_file->path,
+ SD_ID128_FORMAT_VAL(old_file->header->seqnum_id),
+ le64toh((*f)->header->head_entry_seqnum),
+ le64toh((*f)->header->head_entry_realtime));
+ if (r < 0)
return -ENOMEM;
- memcpy(p, old_file->path, l - 8);
- p[l-8] = '@';
- sd_id128_to_string(old_file->header->seqnum_id, p + l - 8 + 1);
- snprintf(p + l - 8 + 1 + 32, 1 + 16 + 1 + 16 + 8 + 1,
- "-%016llx-%016llx.journal",
- (unsigned long long) le64toh((*f)->header->head_entry_seqnum),
- (unsigned long long) le64toh((*f)->header->head_entry_realtime));
-
r = rename(old_file->path, p);
- free(p);
-
if (r < 0)
return -errno;
int r;
size_t l;
- char *p;
+ _cleanup_free_ char *p = NULL;
r = journal_file_open(fname, flags, mode, compress, seal,
metrics, mmap_cache, template, ret);
l = strlen(fname);
if (asprintf(&p, "%.*s@%016llx-%016llx.journal~",
- (int) (l-8), fname,
+ (int) l - 8, fname,
(unsigned long long) now(CLOCK_REALTIME),
random_ull()) < 0)
return -ENOMEM;
r = rename(fname, p);
- free(p);
if (r < 0)
return -errno;
if (m->keep_free == (uint64_t) -1) {
if (fs_size > 0) {
- m->keep_free = PAGE_ALIGN(fs_size / 20); /* 5% of file system size */
+ m->keep_free = PAGE_ALIGN(fs_size * 3 / 20); /* 15% of file system size */
if (m->keep_free > DEFAULT_KEEP_FREE_UPPER)
m->keep_free = DEFAULT_KEEP_FREE_UPPER;
}
int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot_id, usec_t *from, usec_t *to) {
- char t[9+32+1] = "_BOOT_ID=";
Object *o;
uint64_t p;
int r;
assert(f);
assert(from || to);
- sd_id128_to_string(boot_id, t + 9);
-
- r = journal_file_find_data_object(f, t, strlen(t), &o, &p);
+ r = find_data_object_by_boot_id(f, boot_id, &o, &p);
if (r <= 0)
return r;
if (JOURNAL_HEADER_CONTAINS(f->header, n_data))
if (le64toh(f->header->n_data) * 4ULL > (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)) * 3ULL) {
- log_debug("Data hash table of %s has a fill level at %.1f (%llu of %llu items, %llu file size, %llu bytes per hash table item), suggesting rotation.",
+ log_debug("Data hash table of %s has a fill level at %.1f (%"PRIu64" of %"PRIu64" items, %llu file size, %"PRIu64" bytes per hash table item), suggesting rotation.",
f->path,
100.0 * (double) le64toh(f->header->n_data) / ((double) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem))),
- (unsigned long long) le64toh(f->header->n_data),
- (unsigned long long) (le64toh(f->header->data_hash_table_size) / sizeof(HashItem)),
- (unsigned long long) (f->last_stat.st_size),
- (unsigned long long) (f->last_stat.st_size / le64toh(f->header->n_data)));
+ le64toh(f->header->n_data),
+ le64toh(f->header->data_hash_table_size) / sizeof(HashItem),
+ (unsigned long long) f->last_stat.st_size,
+ f->last_stat.st_size / le64toh(f->header->n_data));
return true;
}
if (JOURNAL_HEADER_CONTAINS(f->header, n_fields))
if (le64toh(f->header->n_fields) * 4ULL > (le64toh(f->header->field_hash_table_size) / sizeof(HashItem)) * 3ULL) {
- log_debug("Field hash table of %s has a fill level at %.1f (%llu of %llu items), suggesting rotation.",
+ log_debug("Field hash table of %s has a fill level at %.1f (%"PRIu64" of %"PRIu64" items), suggesting rotation.",
f->path,
100.0 * (double) le64toh(f->header->n_fields) / ((double) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem))),
- (unsigned long long) le64toh(f->header->n_fields),
- (unsigned long long) (le64toh(f->header->field_hash_table_size) / sizeof(HashItem)));
+ le64toh(f->header->n_fields),
+ le64toh(f->header->field_hash_table_size) / sizeof(HashItem));
return true;
}