FIXED Re: New bogofilter TXN snapshot available.
Matthias Andree
matthias.andree at gmx.de
Sun Oct 31 23:05:29 CET 2004
David Relson <relson at osagesoftware.com> writes:
> In any case, the 0.93 release is on hold. Either we'll have a software
> fix or have to add a warning. With Matthias' database wizardry, my bet
> is that we'll have a fix :-)
I believe I have found a reasonable workaround. Berkeley DB 4.1 and 4.2
are documented to only heed the DB_CHKSUM or DB_CHKSUM_SHA1 flag when
creating (as in DB_CREATE) a data base, but not when opening an existing
data base. So we'll only set the DB_CHKSUM* flags when we're creating
the data base. This appears to work for me with old data bases.
An update patch for my bogofilter-0.92.99.cvs.tar.bz2 tarball is called
bogofilter-0.92.99-patchA.bz2, it is 10,263 bytes in size and available
from http://home.pages.de/~mandree/bogofilter/
The broken-out patch that just fixes the issue is included below:
Log Message:
Rearranged flag setting for Berkeley DB data store, so as only to set
DB_CHKSUM[_SHA1] when creating the data base. Fixes "checksum error:
catastrophic recovery required" and consequential "wordlist.db: page 1:
reference count overflow" errors reported by Torsten Veller.
--- datastore_db.c 29 Oct 2004 01:11:53 -0000 1.112
+++ datastore_db.c 31 Oct 2004 21:53:30 -0000 1.113
@@ -90,8 +90,8 @@
/* Function definitions */
-/** translate BerkeleyDB \a flags bitfield back to symbols */
-static const char *resolveflags(u_int32_t flags) {
+/** translate BerkeleyDB \a flags bitfield for DB->open method back to symbols */
+static const char *resolveopenflags(u_int32_t flags) {
static char buf[160];
char b2[80];
strlcpy(buf, "", sizeof(buf));
@@ -129,10 +129,40 @@
"type=%x, flags=%#lx=%s, mode=%#o) -> %d %s\n",
(unsigned long)getpid(), (void *)db, file,
database ? database : "NIL", type, (unsigned long)flags,
- resolveflags(flags), mode, ret, db_strerror(ret));
+ resolveopenflags(flags), mode, ret, db_strerror(ret));
+
+ return ret;
+}
+
+#if DB_AT_LEAST(4,1)
+/** translate BerkeleyDB \a flags bitfield for DB->set_flags method back to symbols */
+static const char *resolvesetflags(u_int32_t flags) {
+ static char buf[160];
+ char b2[80];
+ strlcpy(buf, "", sizeof(buf));
+#if DB_EQUAL(4,1)
+ if (flags & DB_CHKSUM_SHA1) flags &= ~DB_CHKSUM_SHA1, strlcat(buf, "DB_CHKSUM_SHA1 ", sizeof(buf));
+#endif
+#if DB_EQUAL(4,2)
+ if (flags & DB_CHKSUM) flags &= ~DB_CHKSUM, strlcat(buf, "DB_CHKSUM ", sizeof(buf));
+#endif
+ snprintf(b2, sizeof(b2), "%#lx", (unsigned long)flags);
+ if (flags) strlcat(buf, b2, sizeof(buf));
+ return buf;
+}
+
+/** Set flags and print debugging info */
+static int DB_SET_FLAGS(DB *db, u_int32_t flags)
+{
+ int ret = db->set_flags(db, flags);
+ if (DEBUG_DATABASE(1))
+ fprintf(dbgout, "[pid %lu] DB->set_flags(db=%p, flags=%#lx=%s) -> %d %s\n",
+ (unsigned long)getpid(), (void *)db, (unsigned long)flags,
+ resolvesetflags(flags), ret, db_strerror(ret));
return ret;
}
+#endif
/** "constructor" - allocate our handle and initialize its contents */
static dbh_t *dbh_init(const char *path, const char *name)
@@ -299,9 +329,6 @@
check_db_version();
{
-#if DB_AT_LEAST(4,1)
- int flags;
-#endif
DB *dbp;
uint32_t pagesize;
@@ -319,25 +346,6 @@
handle->dbp = dbp;
- /* set flags */
-#if DB_EQUAL(4,1)
- flags = DB_CHKSUM_SHA1;
-#endif
-#if DB_AT_LEAST(4,2)
- flags = DB_CHKSUM;
-#endif
-
-#if DB_AT_LEAST(4,1)
- ret = dbp->set_flags(dbp, flags);
- if (ret) {
- print_error(__FILE__, __LINE__,
- "(db) DB->set_flags(%d) failed: %s",
- flags, db_strerror(ret));
- dbp->close(dbp, 0);
- goto open_err;
- }
-#endif
-
/* open data base */
if ((t = strrchr(handle->name, DIRSEP_C)))
t++;
@@ -349,6 +357,12 @@
if ((ret = DB_OPEN(dbp, t, NULL, dbtype, opt_flags, 0664)) != 0
&& ( ret != ENOENT || opt_flags == DB_RDONLY ||
((handle->created = true),
+#if DB_EQUAL(4,1)
+ (ret = DB_SET_FLAGS(dbp, DB_CHKSUM_SHA1)) != 0 ||
+#endif
+#if DB_EQUAL(4,2)
+ (ret = DB_SET_FLAGS(dbp, DB_CHKSUM)) != 0 ||
+#endif
(ret = DB_OPEN(dbp, t, NULL, dbtype, opt_flags | DB_CREATE | DB_EXCL, 0664)) != 0)))
{
if (open_mode != DB_RDONLY && ret == EEXIST && --retries) {
--
Matthias Andree
More information about the Bogofilter
mailing list