journal-verify.c revision f5028bfaf06b58a59d45fcd875dced1413703999
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering/***
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering This file is part of systemd.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Copyright 2012 Lennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering systemd is free software; you can redistribute it and/or modify it
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering under the terms of the GNU Lesser General Public License as published by
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (at your option) any later version.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering systemd is distributed in the hope that it will be useful, but
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Lesser General Public License for more details.
c53158818d8cdaf46b3f1b5299b9bda118a1043fThomas Hindoe Paaboel Andersen
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering You should have received a copy of the GNU Lesser General Public License
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering***/
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <unistd.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <sys/mman.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include <fcntl.h>
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "util.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "macro.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "journal-def.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "journal-file.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "journal-authenticate.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "journal-verify.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "lookup3.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering#include "compress.h"
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering/* FIXME:
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering *
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * - verify FSPRG
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * - Allow building without libgcrypt
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * - check with sparse
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * - 64bit conversions
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering *
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int journal_file_object_verify(JournalFile *f, Object *o) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(f);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering /* This does various superficial tests about the length an
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * possible field values. It does not follow any references to
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * other objects. */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if ((o->object.flags & OBJECT_COMPRESSED) &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering o->object.type != OBJECT_DATA)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering switch (o->object.type) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering case OBJECT_DATA: {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t h1, h2;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(o->data.entry_offset) <= 0 ||
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering le64toh(o->data.n_entries) <= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(o->object.size) - offsetof(DataObject, payload) <= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering h1 = le64toh(o->data.hash);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (o->object.flags & OBJECT_COMPRESSED) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering void *b = NULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t alloc = 0, b_size;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!uncompress_blob(o->data.payload,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering le64toh(o->object.size) - offsetof(Object, data.payload),
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering &b, &alloc, &b_size))
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering h2 = hash64(b, b_size);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering free(b);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering } else
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering h2 = hash64(o->data.payload, le64toh(o->object.size) - offsetof(Object, data.payload));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (h1 != h2)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering break;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering case OBJECT_FIELD:
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(o->object.size) - offsetof(FieldObject, payload) <= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering break;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering case OBJECT_ENTRY:
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if ((le64toh(o->object.size) - offsetof(EntryObject, items)) % sizeof(EntryItem) != 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if ((le64toh(o->object.size) - offsetof(EntryObject, items)) / sizeof(EntryItem) <= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(o->entry.seqnum) <= 0 ||
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering le64toh(o->entry.realtime) <= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering break;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering case OBJECT_DATA_HASH_TABLE:
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering case OBJECT_FIELD_HASH_TABLE:
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) % sizeof(HashItem) != 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) / sizeof(HashItem) <= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering break;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering case OBJECT_ENTRY_ARRAY:
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) % sizeof(le64_t) != 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if ((le64toh(o->object.size) - offsetof(EntryArrayObject, items)) / sizeof(le64_t) <= 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering break;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering case OBJECT_TAG:
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(o->object.size) != sizeof(TagObject))
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering break;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic void draw_progress(uint64_t p, usec_t *last_usec) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering unsigned n, i, j, k;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering usec_t z, x;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!isatty(STDOUT_FILENO))
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering z = now(CLOCK_MONOTONIC);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering x = *last_usec;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (x != 0 && x + 40 * USEC_PER_MSEC > z)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering *last_usec = z;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n = (3 * columns()) / 4;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering j = (n * (unsigned) p) / 65535ULL;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering k = n - j;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering fputs("\r\x1B[?25l" ANSI_HIGHLIGHT_GREEN_ON, stdout);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (i = 0; i < j; i++)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering fputs("\xe2\x96\x88", stdout);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering fputs(ANSI_HIGHLIGHT_OFF, stdout);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (i = 0; i < k; i++)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering fputs("\xe2\x96\x91", stdout);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering printf(" %3lu%%", 100LU * (unsigned long) p / 65535LU);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering fputs("\r\x1B[?25h", stdout);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering fflush(stdout);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic void flush_progress(void) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering unsigned n, i;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!isatty(STDOUT_FILENO))
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n = (3 * columns()) / 4;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering putchar('\r');
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (i = 0; i < n + 5; i++)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering putchar(' ');
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering putchar('\r');
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering fflush(stdout);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int write_uint64(int fd, uint64_t p) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering ssize_t k;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering k = write(fd, &p, sizeof(p));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (k < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -errno;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (k != sizeof(p))
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EIO;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int contains_uint64(MMapCache *m, int fd, uint64_t n, uint64_t p) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t a, b;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(m);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(fd >= 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering /* Bisection ... */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering a = 0; b = n;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering while (a < b) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t c, *z;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering c = (a + b) / 2;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = mmap_cache_get(m, fd, PROT_READ|PROT_WRITE, 0, c * sizeof(uint64_t), sizeof(uint64_t), (void **) &z);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (*z == p)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 1;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (p < *z)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering b = c;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering else
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering a = c;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int entry_points_to_data(
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering JournalFile *f,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int entry_fd,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t n_entries,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t entry_p,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t data_p) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t i, n, a;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Object *o;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering bool found = false;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(f);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(entry_fd >= 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!contains_uint64(f->mmap, entry_fd, n_entries, entry_p)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Data object references invalid entry at %llu", (unsigned long long) data_p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY, entry_p, &o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n = journal_file_entry_n_items(o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (i = 0; i < n; i++)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(o->entry.items[i].object_offset) == data_p) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering found = true;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering break;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!found) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Data object not referenced by linked entry at %llu", (unsigned long long) data_p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering /* Check if this entry is also in main entry array. Since the
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * main entry array has already been verified we can rely on
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * its consistency.*/
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n = le64toh(f->header->n_entries);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering a = le64toh(f->header->entry_array_offset);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering i = 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering while (i < n) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t m, j;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering m = journal_file_entry_array_n_items(o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (j = 0; i < n && j < m; i++, j++)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(o->entry_array.items[j]) == entry_p)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering a = le64toh(o->entry_array.next_entry_array_offset);;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int verify_data(
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering JournalFile *f,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Object *o, uint64_t p,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int entry_fd, uint64_t n_entries,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int entry_array_fd, uint64_t n_entry_arrays) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t i, n, a, last, q;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(f);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(entry_fd >= 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(entry_array_fd >= 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n = le64toh(o->data.n_entries);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering a = le64toh(o->data.entry_array_offset);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering /* We already checked this earlier */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(n > 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering last = q = le64toh(o->data.entry_offset);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = entry_points_to_data(f, entry_fd, n_entries, q, p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
49f43d5f91a99b23f745726aa351d8f159774357Ville Skyttä while (i < n) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t next, m, j;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (a == 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Array chain too short at %llu.", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Invalid array at %llu.", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering next = le64toh(o->entry_array.next_entry_array_offset);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (next != 0 && next <= a) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Array chain has cycle at %llu.", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering m = journal_file_entry_array_n_items(o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (j = 0; i < n && j < m; i++, j++) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering q = le64toh(o->entry_array.items[j]);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (q <= last) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Data object's entry array not sorted at %llu.", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering last = q;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = entry_points_to_data(f, entry_fd, n_entries, q, p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering /* Pointer might have moved, reposition */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering a = next;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int verify_hash_table(
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering JournalFile *f,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int data_fd, uint64_t n_data,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int entry_fd, uint64_t n_entries,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int entry_array_fd, uint64_t n_entry_arrays,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering usec_t *last_usec) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t i, n;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(f);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(data_fd >= 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(entry_fd >= 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(entry_array_fd >= 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(last_usec);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n = le64toh(f->header->data_hash_table_size) / sizeof(HashItem);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (i = 0; i < n; i++) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t last = 0, p;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering draw_progress(0xC000 + (0x3FFF * i / n), last_usec);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering p = le64toh(f->data_hash_table[i].head_hash_offset);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering while (p != 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Object *o;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t next;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!contains_uint64(f->mmap, data_fd, n_data, p)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Invalid data object at hash entry %llu of %llu.",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) i, (unsigned long long) n);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_move_to_object(f, OBJECT_DATA, p, &o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering next = le64toh(o->data.next_hash_offset);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (next != 0 && next <= p) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Hash chain has a cycle in hash entry %llu of %llu.",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) i, (unsigned long long) n);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(o->data.hash) % n != i) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Hash value mismatch in hash entry %llu of %llu.",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) i, (unsigned long long) n);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = verify_data(f, o, p, entry_fd, n_entries, entry_array_fd, n_entry_arrays);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering last = p;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering p = next;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (last != le64toh(f->data_hash_table[i].tail_hash_offset)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Tail hash pointer mismatch in hash table.");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int data_object_in_hash_table(JournalFile *f, uint64_t hash, uint64_t p) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t n, h, q;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(f);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n = le64toh(f->header->data_hash_table_size) / sizeof(HashItem);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering h = hash % n;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering q = le64toh(f->data_hash_table[h].head_hash_offset);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering while (q != 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Object *o;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (p == q)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 1;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_move_to_object(f, OBJECT_DATA, q, &o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering q = le64toh(o->data.next_hash_offset);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int verify_entry(
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering JournalFile *f,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Object *o, uint64_t p,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int data_fd, uint64_t n_data) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t i, n;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(f);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(data_fd >= 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n = journal_file_entry_n_items(o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (i = 0; i < n; i++) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t q, h;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Object *u;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering q = le64toh(o->entry.items[i].object_offset);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering h = le64toh(o->entry.items[i].hash);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!contains_uint64(f->mmap, data_fd, n_data, q)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Invalid data object at entry %llu.",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_move_to_object(f, OBJECT_DATA, q, &u);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(u->data.hash) != h) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Hash mismatch for data object at entry %llu.",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = data_object_in_hash_table(f, h, q);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r == 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Data object missing from hash at entry %llu.",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
49f43d5f91a99b23f745726aa351d8f159774357Ville Skyttä }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringstatic int verify_entry_array(
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering JournalFile *f,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int data_fd, uint64_t n_data,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int entry_fd, uint64_t n_entries,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int entry_array_fd, uint64_t n_entry_arrays,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering usec_t *last_usec) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t i = 0, a, n, last = 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(f);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(data_fd >= 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(entry_fd >= 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(entry_array_fd >= 0);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(last_usec);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n = le64toh(f->header->n_entries);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering a = le64toh(f->header->entry_array_offset);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering while (i < n) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t next, m, j;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Object *o;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering draw_progress(0x8000 + (0x3FFF * i / n), last_usec);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (a == 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Array chain too short at %llu of %llu.",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) i, (unsigned long long) n);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!contains_uint64(f->mmap, entry_array_fd, n_entry_arrays, a)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Invalid array at %llu of %llu.",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) i, (unsigned long long) n);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering next = le64toh(o->entry_array.next_entry_array_offset);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (next != 0 && next <= a) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Array chain has cycle at %llu of %llu.",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) i, (unsigned long long) n);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering m = journal_file_entry_array_n_items(o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering for (j = 0; i < n && j < m; i++, j++) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t p;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering p = le64toh(o->entry_array.items[j]);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (p <= last) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Entry array not sorted at %llu of %llu.",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) i, (unsigned long long) n);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering last = p;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!contains_uint64(f->mmap, entry_fd, n_entries, p)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Invalid array entry at %llu of %llu.",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) i, (unsigned long long) n);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY, p, &o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = verify_entry(f, o, p, data_fd, n_data);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering /* Pointer might have moved, reposition */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_move_to_object(f, OBJECT_ENTRY_ARRAY, a, &o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering a = next;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringint journal_file_verify(JournalFile *f, const char *key) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering Object *o;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t p = 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t tag_seqnum = 0, entry_seqnum = 0, entry_monotonic = 0, entry_realtime = 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering sd_id128_t entry_boot_id;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering bool entry_seqnum_set = false, entry_monotonic_set = false, entry_realtime_set = false, found_main_entry_array = false;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering uint64_t n_weird = 0, n_objects = 0, n_entries = 0, n_data = 0, n_fields = 0, n_data_hash_tables = 0, n_field_hash_tables = 0, n_entry_arrays = 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering usec_t last_usec = 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering int data_fd = -1, entry_fd = -1, entry_array_fd = -1;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering char data_path[] = "/var/tmp/journal-data-XXXXXX",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_path[] = "/var/tmp/journal-entry-XXXXXX",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_array_path[] = "/var/tmp/journal-entry-array-XXXXXX";
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering assert(f);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering data_fd = mkostemp(data_path, O_CLOEXEC);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (data_fd < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Failed to create data file: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering unlink(data_path);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_fd = mkostemp(entry_path, O_CLOEXEC);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (entry_fd < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Failed to create entry file: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering unlink(entry_path);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_array_fd = mkostemp(entry_array_path, O_CLOEXEC);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (entry_array_fd < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Failed to create entry array file: %m");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering unlink(entry_array_path);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering /* First iteration: we go through all objects, verify the
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * superficial structure, headers, hashes. */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_hmac_put_header(f);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Failed to calculate HMAC of header.");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering p = le64toh(f->header->header_size);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering while (p != 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering draw_progress(0x7FFF * p / le64toh(f->header->tail_object_offset), &last_usec);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_move_to_object(f, -1, p, &o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Invalid object at %llu", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(f->header->tail_object_offset) < p) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Invalid tail object pointer.");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n_objects ++;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_object_verify(f, o);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Invalid object contents at %llu", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (o->object.flags & OBJECT_COMPRESSED &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering !(le32toh(f->header->incompatible_flags) & HEADER_INCOMPATIBLE_COMPRESSED)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Compressed object without compression at %llu", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = journal_file_hmac_put_object(f, -1, p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Failed to calculate HMAC at %llu", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (o->object.type == OBJECT_TAG) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
49f43d5f91a99b23f745726aa351d8f159774357Ville Skyttä if (!(le32toh(f->header->compatible_flags) & HEADER_COMPATIBLE_AUTHENTICATED)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Tag object without authentication at %llu", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(o->tag.seqnum) != tag_seqnum) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Tag sequence number out of synchronization at %llu", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering } else if (o->object.type == OBJECT_ENTRY) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = write_uint64(entry_fd, p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!entry_seqnum_set &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering le64toh(o->entry.seqnum) != le64toh(f->header->head_entry_seqnum)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Head entry sequence number incorrect");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (entry_seqnum_set &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_seqnum >= le64toh(o->entry.seqnum)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Entry sequence number out of synchronization at %llu", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_seqnum = le64toh(o->entry.seqnum);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_seqnum_set = true;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (entry_monotonic_set &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering sd_id128_equal(entry_boot_id, o->entry.boot_id) &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_monotonic > le64toh(o->entry.monotonic)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Entry timestamp out of synchronization at %llu", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_monotonic = le64toh(o->entry.monotonic);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_boot_id = o->entry.boot_id;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_monotonic_set = true;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!entry_realtime_set &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering le64toh(o->entry.realtime) != le64toh(f->header->head_entry_realtime)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Head entry realtime timestamp incorrect");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_realtime = le64toh(o->entry.realtime);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_realtime_set = true;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n_entries ++;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering } else if (o->object.type == OBJECT_ENTRY_ARRAY) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = write_uint64(entry_array_fd, p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (p == le64toh(f->header->entry_array_offset)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (found_main_entry_array) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("More than one main entry array at %llu", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering found_main_entry_array = true;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n_entry_arrays++;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering } else if (o->object.type == OBJECT_DATA) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = write_uint64(data_fd, p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n_data++;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering } else if (o->object.type == OBJECT_FIELD)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n_fields++;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering else if (o->object.type == OBJECT_DATA_HASH_TABLE) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n_data_hash_tables++;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (n_data_hash_tables > 1) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("More than one data hash table at %llu", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(f->header->data_hash_table_offset) != p + offsetof(HashTableObject, items) ||
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering le64toh(f->header->data_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Header fields for data hash table invalid.");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering } else if (o->object.type == OBJECT_FIELD_HASH_TABLE) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n_field_hash_tables++;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (n_field_hash_tables > 1) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("More than one field hash table at %llu", (unsigned long long) p);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (le64toh(f->header->field_hash_table_offset) != p + offsetof(HashTableObject, items) ||
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering le64toh(f->header->field_hash_table_size) != le64toh(o->object.size) - offsetof(HashTableObject, items)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Header fields for field hash table invalid.");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering } else if (o->object.type >= _OBJECT_TYPE_MAX)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n_weird ++;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (p == le64toh(f->header->tail_object_offset))
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering p = 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering else
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering p = p + ALIGN64(le64toh(o->object.size));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (n_objects != le64toh(f->header->n_objects)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Object number mismatch");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (n_entries != le64toh(f->header->n_entries)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Entry number mismatch");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (JOURNAL_HEADER_CONTAINS(f->header, n_data) &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n_data != le64toh(f->header->n_data)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Data number mismatch");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (JOURNAL_HEADER_CONTAINS(f->header, n_fields) &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering n_fields != le64toh(f->header->n_fields)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Field number mismatch");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (JOURNAL_HEADER_CONTAINS(f->header, n_tags) &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering tag_seqnum != le64toh(f->header->n_tags)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Tag number mismatch");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (n_data_hash_tables != 1) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Missing data hash table");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (n_field_hash_tables != 1) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Missing field hash table");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (!found_main_entry_array) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Missing entry array");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (entry_seqnum_set &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_seqnum != le64toh(f->header->tail_entry_seqnum)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Invalid tail seqnum");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (entry_monotonic_set &&
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (!sd_id128_equal(entry_boot_id, f->header->boot_id) ||
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_monotonic != le64toh(f->header->tail_entry_monotonic))) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Invalid tail monotonic timestamp");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (entry_realtime_set && entry_realtime != le64toh(f->header->tail_entry_realtime)) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("Invalid tail realtime timestamp");
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = -EBADMSG;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering /* Second iteration: we follow all objects referenced from the
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * two entry points: the object hash table and the entry
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * array. We also check that everything referenced (directly
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * or indirectly) in the data hash table also exists in the
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * entry array, and vice versa. Note that we do not care for
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * unreferenced objects. We only care that everything that is
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering * referenced is consistent. */
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = verify_entry_array(f,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering data_fd, n_data,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_fd, n_entries,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_array_fd, n_entry_arrays,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering &last_usec);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering r = verify_hash_table(f,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering data_fd, n_data,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_fd, n_entries,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering entry_array_fd, n_entry_arrays,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering &last_usec);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (r < 0)
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering goto fail;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering flush_progress();
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering mmap_cache_close_fd(f->mmap, data_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering mmap_cache_close_fd(f->mmap, entry_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering mmap_cache_close_fd(f->mmap, entry_array_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering close_nointr_nofail(data_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering close_nointr_nofail(entry_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering close_nointr_nofail(entry_array_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return 0;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poetteringfail:
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering flush_progress();
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering log_error("File corruption detected at %s:%llu (of %llu, %llu%%).",
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering f->path,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) p,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) f->last_stat.st_size,
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering (unsigned long long) (100 * p / f->last_stat.st_size));
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (data_fd >= 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering mmap_cache_close_fd(f->mmap, data_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering close_nointr_nofail(data_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (entry_fd >= 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering mmap_cache_close_fd(f->mmap, entry_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering close_nointr_nofail(entry_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering if (entry_array_fd >= 0) {
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering mmap_cache_close_fd(f->mmap, entry_array_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering close_nointr_nofail(entry_array_fd);
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering }
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering return r;
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering}
87d2c1ff6a7375f03476767e6f59454bcc5cd04bLennart Poettering