From 47c8ae43bf83b73d16257784e8afc957175489c0 Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Wed, 30 Nov 2016 16:46:37 +0100 Subject: Recover from extra data at end of index file --- c_src/filebuffer.c | 6 ++++++ c_src/filebuffer.h | 2 ++ c_src/permdb.c | 41 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) (limited to 'c_src') diff --git a/c_src/filebuffer.c b/c_src/filebuffer.c index 40b79ad..d35bfa7 100644 --- a/c_src/filebuffer.c +++ b/c_src/filebuffer.c @@ -63,6 +63,12 @@ bf_lastcommit(buffered_file *file) return file->lastcommit; } +void +bf_setlastcommit(buffered_file *file, uint64_t lastcommit) +{ + file->lastcommit = lastcommit; +} + const char * bf_name(buffered_file *file) { diff --git a/c_src/filebuffer.h b/c_src/filebuffer.h index b2fb7ef..f98d20d 100644 --- a/c_src/filebuffer.h +++ b/c_src/filebuffer.h @@ -27,6 +27,8 @@ uint64_t bf_total_length(buffered_file *file); uint64_t bf_lastcommit(buffered_file *file); +void +bf_setlastcommit(buffered_file *file, uint64_t lastcommit); const char * bf_name(buffered_file *file); diff --git a/c_src/permdb.c b/c_src/permdb.c index f92958d..0ce74b6 100644 --- a/c_src/permdb.c +++ b/c_src/permdb.c @@ -272,6 +272,27 @@ verify_index_commit(buffered_file *file, node_offset offset) return validate_checksum(&commit, file); } +node_offset +search_index_commit(buffered_file *file, node_offset startoffset) +{ + node_offset offset = startoffset; + + offset -= INDEX_COMMIT_TRAILER_SIZE; + + while (offset > 0) { + unsigned char *data = + bf_read(file, offset, INDEX_COMMIT_TRAILER_SIZE, NULL); + uint64_t cookie = + read_be64(data + sizeof(uint64_t) + SHA256_DIGEST_SIZE); + if (cookie == index_commit_cookie) { + return offset + INDEX_COMMIT_TRAILER_SIZE; + } + offset -= 8; + } + + return 0; +} + int indexfile_verify_file(buffered_file *file) { @@ -283,7 +304,23 @@ indexfile_verify_file(buffered_file *file) return -1; } free(header); - if (verify_index_commit(file, bf_total_length(file)) < 0) { + + node_offset offset = bf_total_length(file); + while (offset) { + offset = search_index_commit(file, offset); + if (offset) { + fprintf(stderr, + "verifying index file: found potential commit at %lld\n", (unsigned long long) offset); + } + if (offset && verify_index_commit(file, offset) == 0) { + bf_setlastcommit(file, offset); + break; + } + } + fprintf(stderr, + "verifying index file: found commit at %lld\n", (unsigned long long) bf_lastcommit(file)); + + if (offset == 0) { fprintf(stderr, "verifying index file: commit verification failed\n"); return -1; @@ -468,9 +505,11 @@ try_reload_database(permdb_object *state) { if (bf_total_length(state->indexfile) == oldindexsize) { return 0; } else { +#if 0 if (datafile_verify_file(state->datafile) < 0) { warnx("data file verification failed"); } +#endif if (indexfile_verify_file(state->indexfile) < 0) { warnx("cannot rebuild in readonly mode"); } -- cgit v1.1