PATCH (revised) [was: Bogoutil error ...]
David Relson
relson at osagesoftware.com
Wed Mar 9 02:31:50 CET 2005
On Tue, 8 Mar 2005 20:05:17 -0500
Clint Adams wrote:
> > or you can try this patch; save the body of this email, unpack
>
> The patch doesn't apply cleanly to 0.94.0, and there is a problem with
> number of arguments to dsm_recover_open().
Further, there's a file/directory confusion issue ...
At datastore_db.c:943 is:
dbe = dsm->dsm_recover_open(directory);
However at datastore_db_trad.c:43 is:
static DB_ENV *bft_recover_open (const char *db_file);
Changing datastore_db.c to
dbe = dsm->dsm_recover_open(db_file);
corrects the problem.
Updated patch (with all datastore*.c changes) attached.
David
-------------- next part --------------
diff -u -r --exclude-from=diff.excl 0940/src/datastore.c cvs/src/datastore.c
--- 0940/src/datastore.c 2005-02-24 21:20:27.000000000 -0500
+++ cvs/src/datastore.c 2005-03-08 19:57:41.224079320 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore.c,v 1.65 2005/02/25 00:57:51 m-a Exp $ */
+/* $Id: datastore.c,v 1.66 2005/03/09 00:42:15 m-a Exp $ */
/*****************************************************************************
@@ -471,6 +471,6 @@
return dbe_purgelogs(directory);
}
-int ds_verify(const char *file) {
- return db_verify(file);
+int ds_verify(const char *directory, const char *file) {
+ return db_verify(directory, file);
}
diff -u -r --exclude-from=diff.excl 0940/src/datastore_db.c cvs/src/datastore_db.c
--- 0940/src/datastore_db.c 2005-02-27 19:09:01.000000000 -0500
+++ cvs/src/datastore_db.c 2005-03-08 20:26:57.000000000 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_db.c,v 1.182 2005/02/28 00:09:01 relson Exp $ */
+/* $Id: datastore_db.c,v 1.186 2005/03/09 01:26:57 relson Exp $ */
/*****************************************************************************
@@ -266,21 +266,21 @@
dbe_t *env;
- if (NULL == realpath(directory, norm_dir)) {
+ if (realpath(directory, norm_dir) == NULL) {
print_error(__FILE__, __LINE__,
"error: cannot normalize path \"%s\": %s",
directory, strerror(errno));
exit(EX_ERROR);
}
- if (NULL == realpath(bogohome, norm_home)) {
+ if (realpath(bogohome, norm_home) == NULL) {
print_error(__FILE__, __LINE__,
"error: cannot normalize path \"%s\": %s",
bogohome, strerror(errno));
exit(EX_ERROR);
}
- if (0 != strcmp(norm_dir, norm_home))
+ if (strcmp(norm_dir, norm_home) != 0)
{
fprintf(stderr,
"ERROR: only one database _environment_ (directory) can be used at a time.\n"
@@ -927,7 +927,7 @@
return db_strerror(e);
}
-ex_t db_verify(const char *db_file)
+ex_t db_verify(const char *directory, const char *db_file)
{
DB_ENV *dbe = NULL;
DB *db;
@@ -938,11 +938,23 @@
return EX_ERROR;
}
- dbe = dsm->dsm_recover_open(db_file, &db);
+ dsm_init(directory, db_file);
+
+ dbe = dsm->dsm_recover_open(db_file);
if (dbe == NULL) {
exit(EX_ERROR);
}
+ e = db_create(&db, NULL, 0); /* need not use environment here,
+ DB->verify() does not lock anyways,
+ we must hold the global lock instead */
+
+ if (e != 0) {
+ print_error(__FILE__, __LINE__, "error creating DB handle: %s",
+ db_strerror(e));
+ exit(EX_ERROR);
+ }
+
e = db->verify(db, db_file, NULL, NULL, 0);
if (e) {
print_error(__FILE__, __LINE__, "database %s does not verify: %s",
@@ -950,7 +962,7 @@
exit(EX_ERROR);
}
- e = dsm->dsm_common_close(dbe, db_file);
+ e = dsm->dsm_common_close(dbe, directory);
if (e == 0 && verbose)
printf("%s OK.\n", db_file);
diff -u -r --exclude-from=diff.excl 0940/src/datastore_db.h cvs/src/datastore_db.h
--- 0940/src/datastore_db.h 2005-02-27 14:37:12.000000000 -0500
+++ cvs/src/datastore_db.h 2005-03-08 19:57:41.340061688 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_db.h,v 1.32 2005/02/19 02:01:24 m-a Exp $ */
+/* $Id: datastore_db.h,v 1.33 2005/03/09 00:42:15 m-a Exp $ */
/*****************************************************************************
@@ -102,7 +102,7 @@
ex_t dbe_purgelogs(const char *directory);
/** Check if \a databasefile is a valid database. */
-ex_t db_verify(const char *databasefile);
+ex_t db_verify(const char *directory, const char *databasefile);
/** Returns true if the database is byteswapped. */
bool db_is_swapped(void *vhandle);
diff -u -r --exclude-from=diff.excl 0940/src/datastore_db_private.h cvs/src/datastore_db_private.h
--- 0940/src/datastore_db_private.h 2005-02-27 19:00:21.000000000 -0500
+++ cvs/src/datastore_db_private.h 2005-03-07 23:09:24.000000000 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_db_private.h,v 1.5 2005/02/27 19:46:23 relson Exp $ */
+/* $Id: datastore_db_private.h,v 1.6 2005/03/08 00:39:56 m-a Exp $ */
/*****************************************************************************
@@ -46,7 +46,7 @@
typedef const char *dsm_pc_pc (const char *db_file);
typedef ex_t dsm_x_pnvpc (DB_ENV *dbe, const char *db_file);
typedef dbe_t *dsm_pbe_pc (const char *directory);
-typedef DB_ENV *dsm_pnv_pcpb (const char *db_file, DB **dbp);
+typedef DB_ENV *dsm_pnv_pc (const char *db_file);
typedef DB_ENV *dsm_pnv_pbe (dbe_t *env);
typedef struct {
@@ -60,7 +60,7 @@
dsm_v_pbe *dsm_cleanup_lite;
dsm_pnv_pbe *dsm_get_env_dbe;
dsm_pc_pc *dsm_database_name;
- dsm_pnv_pcpb *dsm_recover_open;
+ dsm_pnv_pc *dsm_recover_open;
dsm_i_v *dsm_auto_commit_flags;
dsm_i_i *dsm_get_rmw_flag;
dsm_i_pvi *dsm_lock;
diff -u -r --exclude-from=diff.excl 0940/src/datastore_db_trad.c cvs/src/datastore_db_trad.c
--- 0940/src/datastore_db_trad.c 2005-02-17 23:28:37.000000000 -0500
+++ cvs/src/datastore_db_trad.c 2005-03-07 23:09:24.000000000 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_db_trad.c,v 1.4 2005/02/18 04:19:02 m-a Exp $ */
+/* $Id: datastore_db_trad.c,v 1.5 2005/03/08 00:39:56 m-a Exp $ */
/*****************************************************************************
@@ -40,7 +40,7 @@
/* private -- used in datastore_db_*.c */
static DB_ENV *bft_get_env_dbe (dbe_t *env);
static const char *bft_database_name (const char *db_file);
-static DB_ENV *bft_recover_open (const char *db_file, DB **dbp);
+static DB_ENV *bft_recover_open (const char *db_file);
static int bft_auto_commit_flags(void);
static int bft_get_rmw_flag (int open_mode);
static int bft_lock (void *handle, int open_mode);
@@ -133,9 +133,8 @@
return 0;
}
-DB_ENV *bft_recover_open(const char *db_file, DB **dbp)
+DB_ENV *bft_recover_open(const char *db_file)
{
- int e;
int fd;
fd = open(db_file, O_RDWR);
@@ -153,13 +152,6 @@
exit(EX_ERROR);
}
- if ((e = db_create (dbp, NULL, 0)) != 0) {
- print_error(__FILE__, __LINE__, "db_create, err: %s",
- db_strerror(e));
- close(fd);
- exit(EX_ERROR);
- }
-
return NULL;
}
diff -u -r --exclude-from=diff.excl 0940/src/datastore_db_trans.c cvs/src/datastore_db_trans.c
--- 0940/src/datastore_db_trans.c 2005-03-05 16:08:11.000000000 -0500
+++ cvs/src/datastore_db_trans.c 2005-03-08 19:57:41.344061080 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_db_trans.c,v 1.7 2005/03/02 23:22:03 m-a Exp $ */
+/* $Id: datastore_db_trans.c,v 1.12 2005/03/08 10:26:31 m-a Exp $ */
/*****************************************************************************
@@ -60,7 +60,7 @@
/* private -- used in datastore_db_*.c */
static DB_ENV *dbx_get_env_dbe (dbe_t *env);
static const char *dbx_database_name (const char *db_file);
-static DB_ENV *dbx_recover_open (const char *db_file, DB **dbp);
+static DB_ENV *dbx_recover_open (const char *db_file);
static int dbx_auto_commit_flags(void);
static int dbx_get_rmw_flag (int open_mode);
static int dbx_lock (void *handle, int open_mode);
@@ -162,6 +162,36 @@
return flag;
}
+/** print user-readable diagnostics and instructions after DB_ENV->open
+ * failed. */
+static void diag_dbeopen(
+ /** DB_ENV->open() flags value */ u_int32_t flags,
+ /** env directory tried to open */ const char *directory)
+{
+ if (flags & DB_RECOVER) {
+ fprintf(stderr,
+ "\n"
+ "### Standard recovery failed. ###\n"
+ "\n"
+ "Please check section 3.3 in bogofilter's README.db file\n"
+ "for help.\n");
+ /* ask that the user runs catastrophic recovery */
+ } else if (flags & DB_RECOVER_FATAL) {
+ fprintf(stderr,
+ "\n"
+ "### Catastrophic recovery failed. ###\n"
+ "\n"
+ "Please check the README.db file that came with bogofilter for hints,\n"
+ "section 3.3, or remove all __db.*, log.* and *.db files in \"%s\"\n"
+ "and start from scratch.\n", directory);
+ /* catastrophic recovery failed */
+ } else {
+ fprintf(stderr, "To recover, run: bogoutil -v --db-recover \"%s\"\n",
+ directory);
+ }
+}
+
+/** run recovery, open environment and keep the exclusive lock */
static DB_ENV *dbe_recover_open(const char *directory, uint32_t flags)
{
const uint32_t local_flags = flags | DB_CREATE;
@@ -189,38 +219,20 @@
e = dbe->open(dbe, directory,
dbenv_defflags | local_flags | DB_RECOVER, DS_MODE);
- if (e == DB_RUNRECOVERY) {
- /* that didn't work, try harder */
- if (DEBUG_DATABASE(0))
- fprintf(dbgout, "running catastrophic data base recovery\n");
- e = dbe->open(dbe, directory,
- dbenv_defflags | local_flags | DB_RECOVER_FATAL, DS_MODE);
- }
if (e) {
print_error(__FILE__, __LINE__, "Cannot recover environment \"%s\": %s",
directory, db_strerror(e));
+ if (e == DB_RUNRECOVERY)
+ diag_dbeopen(flags, directory);
exit(EX_ERROR);
}
return dbe;
}
-static DB_ENV *dbx_recover_open(const char *dir, DB **dbp)
+static DB_ENV *dbx_recover_open(const char *dir)
{
- int e;
- DB_ENV *dbe;
-
- dbe = dbe_recover_open(dir, 0); /* this sets an exclusive lock */
- e = db_create(dbp, NULL, 0); /* do not use environment here, verify
- does not lock by itself, we hold the
- global lock instead! */
- if (e != 0) {
- print_error(__FILE__, __LINE__, "error creating DB handle: %s",
- db_strerror(e));
- return NULL;
- }
-
- return dbe;
+ return dbe_recover_open(dir, 0);
}
static int dbx_begin(void *vhandle)
@@ -536,27 +548,7 @@
print_error(__FILE__, __LINE__, "DB_ENV->open, err: %s", db_strerror(ret));
switch (ret) {
case DB_RUNRECOVERY:
- if (flags & DB_RECOVER) {
- fprintf(stderr,
- "\n"
- "### Standard recovery failed. ###\n"
- "\n"
- "Please check section 3.3 in bogofilter's README.db file\n"
- "for help.\n");
- /* ask that the user runs catastrophic recovery */
- } else if (flags & DB_RECOVER_FATAL) {
- fprintf(stderr,
- "\n"
- "### Catastrophic recovery failed. ###\n"
- "\n"
- "Please check the README.db file that came with bogofilter for hints,\n"
- "section 3.3, or remove all __db.*, log.* and *.db files in \"%s\"\n"
- "and start from scratch.\n", directory);
- /* catastrophic recovery failed */
- } else {
- fprintf(stderr, "To recover, run: bogoutil -v --db-recover \"%s\"\n",
- directory);
- }
+ diag_dbeopen(flags, directory);
break;
case EINVAL:
fprintf(stderr, "\n"
@@ -648,7 +640,6 @@
if (!(force || needs_recovery()))
return EX_OK;
-retry:
if (DEBUG_DATABASE(0))
fprintf(dbgout, "running %s data base recovery\n",
catastrophic ? "catastrophic" : "regular");
@@ -656,20 +647,13 @@
db_max_locks, db_max_objects,
catastrophic ? DB_RECOVER_FATAL : DB_RECOVER);
if (env == NULL) {
- if(!catastrophic) {
- catastrophic = true;
- goto retry;
- }
- goto rec_fail;
+ exit(EX_ERROR);
}
clear_lockfile();
dbx_cleanup_lite(env);
return EX_OK;
-
-rec_fail:
- exit(EX_ERROR);
}
static ex_t dbx_common_close(DB_ENV *dbe, const char *directory)
@@ -679,6 +663,9 @@
if (db_log_autoremove)
dbe_env_purgelogs(dbe);
+ if (DEBUG_DATABASE(0))
+ fprintf(dbgout, "closing environment\n");
+
e = dbe->close(dbe, 0);
if (e != 0) {
print_error(__FILE__, __LINE__, "Error closing environment \"%s\": %s",
@@ -744,9 +731,6 @@
dbe_env_purgelogs(dbe);
- if (DEBUG_DATABASE(0))
- fprintf(dbgout, "closing environment\n");
-
return dbx_common_close(dbe, directory);
}
@@ -902,7 +886,11 @@
return P_ERROR;
}
+#if DB_AT_LEAST(3,2)
r = dbe->open(dbe, directory, DB_JOINENV, DS_MODE);
+#else
+ r = ENOENT;
+#endif
if (r == ENOENT) {
struct stat st;
int w;
@@ -910,11 +898,12 @@
struct dirent *de;
DIR *d;
- /* no environment found by JOINENV */
+ /* no environment found by JOINENV, but clean up handle */
dbe->close(dbe, 0);
- /* retry globbing for log.* files - needed for instance after
- * bogoutil --db-remove DIR */
+ /* retry, looking for log\.[0-9]{10} files - needed for instance
+ * after bogoutil --db-remove DIR or when DB_JOINENV is
+ * unsupported */
d = opendir(directory);
if (!d) {
print_error(__FILE__, __LINE__, "cannot open directory %s: %s",
diff -u -r --exclude-from=diff.excl 0940/src/datastore.h cvs/src/datastore.h
--- 0940/src/datastore.h 2005-02-18 21:32:01.000000000 -0500
+++ cvs/src/datastore.h 2005-03-08 19:57:41.334062600 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore.h,v 1.43 2005/02/19 02:01:24 m-a Exp $ */
+/* $Id: datastore.h,v 1.44 2005/03/09 00:42:15 m-a Exp $ */
/*****************************************************************************
@@ -251,7 +251,7 @@
extern int ds_remove(const char *directory);
/** Verify given database */
-extern int ds_verify(const char *file);
+extern int ds_verify(const char *directory, const char *file);
/** Remove inactive log files in given directory, \return EX_OK. */
extern int ds_purgelogs(const char *directory);
diff -u -r --exclude-from=diff.excl 0940/src/datastore_qdbm.c cvs/src/datastore_qdbm.c
--- 0940/src/datastore_qdbm.c 2005-02-04 23:33:19.000000000 -0500
+++ cvs/src/datastore_qdbm.c 2005-03-08 19:57:41.355059408 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_qdbm.c,v 1.43 2005/01/14 04:43:44 relson Exp $ */
+/* $Id: datastore_qdbm.c,v 1.44 2005/03/09 00:42:16 m-a Exp $ */
/*****************************************************************************
@@ -324,7 +324,8 @@
return dperrmsg(e);
}
-ex_t db_verify(const char *f) {
+ex_t db_verify(const char *d, const char *f) {
(void)f;
+ (void)d;
return EX_OK;
}
diff -u -r --exclude-from=diff.excl 0940/src/datastore_sqlite.c cvs/src/datastore_sqlite.c
--- 0940/src/datastore_sqlite.c 2005-02-27 18:08:22.000000000 -0500
+++ cvs/src/datastore_sqlite.c 2005-03-08 19:57:41.372056824 -0500
@@ -40,10 +40,10 @@
DUMMYVVP(dbe_cleanup)
DUMMYVVP(db_flush)
DUMMYVPVP(db_get_env)
-DUMMYICP(db_verify)
DUMMYICP(dbe_purgelogs)
DUMMYICP(dbe_remove)
void *dbe_init(const char *d1, const char *d2) { (void)d1; (void)d2; return (void *)~0; }
+ex_t db_verify(const char *d1, const char *d2) { (void)d1; (void)d2; return EX_OK; }
/** dummy function, Sqlite recovers automatically. */
ex_t dbe_recover(const char *d1, bool d2, bool d3) { (void)d1; d2=d3; return EX_ERROR; }
@@ -270,10 +270,13 @@
/* check if byteswapped */
{
u_int32_t t;
- k.data = strdup(ENDIAN32);
+ int ee;
+ k.data = xstrdup(ENDIAN32);
k.leng = strlen(k.data);
- switch(db_get_dbvalue(dbh, &k, &v)) {
+ ee = db_get_dbvalue(dbh, &k, &v);
+ free(k.data);
+ switch(ee) {
case 0: /* found endian marker token, read it */
if (v.leng < 4)
goto barf;
diff -u -r --exclude-from=diff.excl 0940/src/datastore_tdb.c cvs/src/datastore_tdb.c
--- 0940/src/datastore_tdb.c 2005-02-04 23:33:19.000000000 -0500
+++ cvs/src/datastore_tdb.c 2005-03-08 19:57:41.374056520 -0500
@@ -1,4 +1,4 @@
-/* $Id: datastore_tdb.c,v 1.43 2005/01/16 17:39:17 relson Exp $ */
+/* $Id: datastore_tdb.c,v 1.44 2005/03/09 00:42:16 m-a Exp $ */
/*****************************************************************************
@@ -348,7 +348,8 @@
return "Invalid error code";
}
-ex_t db_verify(const char *f) {
+ex_t db_verify(const char *d, const char *f) {
(void)f;
+ (void)d;
return EX_OK;
}
-------------- next part --------------
_______________________________________________
Bogofilter mailing list
Bogofilter at bogofilter.org
http://www.bogofilter.org/mailman/listinfo/bogofilter
More information about the bogofilter
mailing list