X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fjournal%2Fjournal-file.c;h=1e6d78cfa43606414b4b4d026491d9b1e0bdaf1a;hb=9447a7f1de5e5798cf324ef26579d0dd7e601203;hp=977cfa1010f8a57ae057a4b3412e65c907368d0a;hpb=4bbdcdb301f8ef6f8b9e943210ab61250003c517;p=elogind.git diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c index 977cfa101..1e6d78cfa 100644 --- a/src/journal/journal-file.c +++ b/src/journal/journal-file.c @@ -37,7 +37,7 @@ #define DEFAULT_WINDOW_SIZE (128ULL*1024ULL*1024ULL) -#define COMPRESSION_SIZE_THRESHOLD (64ULL) +#define COMPRESSION_SIZE_THRESHOLD (512ULL) /* This is the minimum journal file size */ #define JOURNAL_FILE_SIZE_MIN (64ULL*1024ULL) @@ -238,7 +238,7 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size) if (fstat(f->fd, &f->last_stat) < 0) return -errno; - f->header->arena_size = new_size - htole64(f->header->arena_offset); + f->header->arena_size = htole64(new_size - le64toh(f->header->arena_offset)); return 0; } @@ -330,18 +330,18 @@ static int journal_file_move_to(JournalFile *f, int wt, uint64_t offset, uint64_ * the window space before and half behind the * requested mapping */ - delta = PAGE_ALIGN((DEFAULT_WINDOW_SIZE - size) / 2); + delta = (DEFAULT_WINDOW_SIZE - size) / 2; - if (offset < delta) + if (delta > offset) delta = offset; offset -= delta; - size += (DEFAULT_WINDOW_SIZE - delta); + size = DEFAULT_WINDOW_SIZE; } else delta = 0; if (offset + size > (uint64_t) f->last_stat.st_size) - size = PAGE_ALIGN((uint64_t) f->last_stat.st_size - offset); + size = (uint64_t) f->last_stat.st_size - offset; if (size <= 0) return -EADDRNOTAVAIL; @@ -581,6 +581,8 @@ static int journal_file_link_data(JournalFile *f, Object *o, uint64_t offset, ui assert(offset > 0); assert(o->object.type == OBJECT_DATA); + /* This might alter the window we are looking at */ + o->data.next_hash_offset = o->data.next_field_offset = 0; o->data.entry_offset = o->data.entry_array_offset = 0; o->data.n_entries = 0; @@ -591,18 +593,14 @@ static int journal_file_link_data(JournalFile *f, Object *o, uint64_t offset, ui /* Only entry in the hash table is easy */ f->data_hash_table[h].head_hash_offset = htole64(offset); } else { - /* Temporarily move back to the previous data object, - * to patch in pointer */ + /* Move back to the previous data object, to patch in + * pointer */ r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); if (r < 0) return r; o->data.next_hash_offset = htole64(offset); - - r = journal_file_move_to_object(f, OBJECT_DATA, offset, &o); - if (r < 0) - return r; } f->data_hash_table[h].tail_hash_offset = htole64(offset); @@ -614,6 +612,7 @@ int journal_file_find_data_object_with_hash( JournalFile *f, const void *data, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset) { + uint64_t p, osize, h; int r; @@ -702,7 +701,11 @@ int journal_file_find_data_object( ret, offset); } -static int journal_file_append_data(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset) { +static int journal_file_append_data( + JournalFile *f, + const void *data, uint64_t size, + Object **ret, uint64_t *offset) { + uint64_t hash, p; uint64_t osize; Object *o; @@ -760,6 +763,12 @@ static int journal_file_append_data(JournalFile *f, const void *data, uint64_t s if (r < 0) return r; + /* The linking might have altered the window, so let's + * refresh our pointer */ + r = journal_file_move_to_object(f, OBJECT_DATA, p, &o); + if (r < 0) + return r; + if (ret) *ret = o; @@ -771,14 +780,14 @@ static int journal_file_append_data(JournalFile *f, const void *data, uint64_t s uint64_t journal_file_entry_n_items(Object *o) { assert(o); - assert(o->object.type == htole64(OBJECT_ENTRY)); + assert(o->object.type == OBJECT_ENTRY); return (le64toh(o->object.size) - offsetof(Object, entry.items)) / sizeof(EntryItem); } static uint64_t journal_file_entry_array_n_items(Object *o) { assert(o); - assert(o->object.type == htole64(OBJECT_ENTRY_ARRAY)); + assert(o->object.type == OBJECT_ENTRY_ARRAY); return (le64toh(o->object.size) - offsetof(Object, entry_array.items)) / sizeof(uint64_t); } @@ -833,7 +842,7 @@ static int link_entry_into_array(JournalFile *f, o->entry_array.items[i] = htole64(p); if (ap == 0) - *first = q; + *first = htole64(q); else { r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, ap, &o); if (r < 0) @@ -866,7 +875,7 @@ static int link_entry_into_array_plus_one(JournalFile *f, else { uint64_t i; - i = le64toh(*idx) - 1; + i = htole64(le64toh(*idx) - 1); r = link_entry_into_array(f, first, &i, p); if (r < 0) return r; @@ -917,7 +926,7 @@ static int journal_file_link_entry(JournalFile *f, Object *o, uint64_t offset) { if (r < 0) return r; - log_error("=> %s seqnr=%lu n_entries=%lu", f->path, (unsigned long) o->entry.seqnum, (unsigned long) f->header->n_entries); + /* log_debug("=> %s seqnr=%lu n_entries=%lu", f->path, (unsigned long) o->entry.seqnum, (unsigned long) f->header->n_entries); */ if (f->header->head_entry_realtime == 0) f->header->head_entry_realtime = o->entry.realtime; @@ -1016,9 +1025,6 @@ int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const st ts->monotonic < le64toh(f->header->tail_entry_monotonic)) return -EINVAL; - if (ts->realtime < le64toh(f->header->tail_entry_realtime)) - return -EINVAL; - items = alloca(sizeof(EntryItem) * n_iovec); for (i = 0; i < n_iovec; i++) { @@ -1721,6 +1727,9 @@ int journal_file_open( (flags & O_ACCMODE) != O_RDWR) return -EINVAL; + if (!endswith(fname, ".journal")) + return -EINVAL; + f = new0(JournalFile, 1); if (!f) return -ENOMEM; @@ -1834,7 +1843,7 @@ int journal_file_rotate(JournalFile **f) { l = strlen(old_file->path); - p = new(char, l + 1 + 16 + 1 + 32 + 1 + 16 + 1); + p = new(char, l + 1 + 32 + 1 + 16 + 1 + 16 + 1); if (!p) return -ENOMEM; @@ -1861,6 +1870,44 @@ int journal_file_rotate(JournalFile **f) { return r; } +int journal_file_open_reliably( + const char *fname, + int flags, + mode_t mode, + JournalFile *template, + JournalFile **ret) { + + int r; + size_t l; + char *p; + + r = journal_file_open(fname, flags, mode, template, ret); + if (r != -EBADMSG) + return r; + + if ((flags & O_ACCMODE) == O_RDONLY) + return r; + + if (!(flags & O_CREAT)) + return r; + + l = strlen(fname); + if (asprintf(&p, "%.*s@%016llx-%016llx.journal~", + (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; + + log_warning("File %s corrupted, renaming and replacing.", fname); + + return journal_file_open(fname, flags, mode, template, ret); +} + struct vacuum_info { off_t usage; char *filename; @@ -2106,7 +2153,7 @@ int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint6 void journal_default_metrics(JournalMetrics *m, int fd) { uint64_t fs_size = 0; struct statvfs ss; - char a[64], b[64], c[64], d[64]; + char a[FORMAT_BYTES_MAX], b[FORMAT_BYTES_MAX], c[FORMAT_BYTES_MAX], d[FORMAT_BYTES_MAX]; assert(m); assert(fd >= 0);