Commit 8321967a authored by Rusty Russell's avatar Rusty Russell

tdb: fix recovery reuse after crash (from SAMBA)

commit b37b452cb8c1f56b37b04abe7bffdede371ca361
Author: Rusty Russell <rusty@rustcorp.com.au>
Date:   Thu Feb 4 23:59:54 2010 +1030

    tdb: fix recovery reuse after crash
    
    If a process (or the machine) dies after just after writing the
    recovery head (pointing at the end of file), the recovery record will filled
    with 0x42.  This will not invoke a recovery on open, since rec.magic
    != TDB_RECOVERY_MAGIC.
    
    Unfortunately, the first transaction commit will happily reuse that
    area: tdb_recovery_allocate() doesn't check the magic.  The recovery
    record has length 0x42424242, and it writes that back into the
    now-valid-looking transaction header) for the next comer (which
    happens to be tdb_wipe_all in my tests).
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 6ad04b02
......@@ -683,10 +683,16 @@ static int tdb_recovery_allocate(struct tdb_context *tdb,
rec.rec_len = 0;
if (recovery_head != 0 &&
methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) {
TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery record\n"));
return -1;
if (recovery_head != 0) {
if (methods->tdb_read(tdb, recovery_head, &rec, sizeof(rec), DOCONV()) == -1) {
TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to read recovery record\n"));
return -1;
}
/* ignore invalid recovery regions: can happen in crash */
if (rec.magic != TDB_RECOVERY_MAGIC &&
rec.magic != TDB_RECOVERY_INVALID_MAGIC) {
recovery_head = 0;
}
}
*recovery_size = tdb_recovery_size(tdb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment