removed some debugs
[citadel.git] / citadel / database.c
index 0f6121e1fa7837865bb7f9f808e89632d4b739aa..45b5d27342f5c066083aa19876d723b9c605ed62 100644 (file)
@@ -1,16 +1,14 @@
-/*
- * This is a data store backend for the Citadel server which uses Berkeley DB.
- *
- * Copyright (c) 1987-2020 by the citadel.org team
- *
- * This program is open source software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
+// This is a data store backend for the Citadel server which uses Berkeley DB.
+//
+// Copyright (c) 1987-2021 by the citadel.org team
+//
+// This program is open source software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License version 3.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
 
 /*****************************************************************************
        Tunable configuration parameters for the Berkeley DB back end
@@ -32,7 +30,6 @@
 #include <stdio.h>
 #include <dirent.h>
 #include <zlib.h>
-
 #include <db.h>
 
 #if DB_VERSION_MAJOR < 5
@@ -40,7 +37,6 @@
 #endif
 
 #include <libcitadel.h>
-
 #include "ctdl_module.h"
 #include "control.h"
 #include "citserver.h"
@@ -193,14 +189,14 @@ void open_databases(void) {
        /*
         * Silently try to create the database subdirectory.  If it's already there, no problem.
         */
-       if ((mkdir(ctdl_data_dir, 0700) != 0) && (errno != EEXIST)) {
-               syslog(LOG_ERR, "db: unable to create database directory [%s]: %m", ctdl_data_dir);
+       if ((mkdir(ctdl_db_dir, 0700) != 0) && (errno != EEXIST)) {
+               syslog(LOG_ERR, "db: unable to create database directory [%s]: %m", ctdl_db_dir);
        }
-       if (chmod(ctdl_data_dir, 0700) != 0) {
-               syslog(LOG_ERR, "db: unable to set database directory permissions [%s]: %m", ctdl_data_dir);
+       if (chmod(ctdl_db_dir, 0700) != 0) {
+               syslog(LOG_ERR, "db: unable to set database directory permissions [%s]: %m", ctdl_db_dir);
        }
-       if (chown(ctdl_data_dir, CTDLUID, (-1)) != 0) {
-               syslog(LOG_ERR, "db: unable to set the owner for [%s]: %m", ctdl_data_dir);
+       if (chown(ctdl_db_dir, CTDLUID, (-1)) != 0) {
+               syslog(LOG_ERR, "db: unable to set the owner for [%s]: %m", ctdl_db_dir);
        }
        syslog(LOG_DEBUG, "db: Setting up DB environment");
        // db_env_set_func_yield((int (*)(u_long,  u_long))sched_yield);
@@ -238,20 +234,20 @@ void open_databases(void) {
        }
 
        flags = DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE | DB_INIT_TXN | DB_INIT_LOCK | DB_THREAD | DB_INIT_LOG;
-       syslog(LOG_DEBUG, "db: dbenv->open(dbenv, %s, %d, 0)", ctdl_data_dir, flags);
-       ret = dbenv->open(dbenv, ctdl_data_dir, flags, 0);                              // try opening the database cleanly
+       syslog(LOG_DEBUG, "db: dbenv->open(dbenv, %s, %d, 0)", ctdl_db_dir, flags);
+       ret = dbenv->open(dbenv, ctdl_db_dir, flags, 0);                                // try opening the database cleanly
        if (ret == DB_RUNRECOVERY) {
                syslog(LOG_ERR, "db: dbenv->open: %s", db_strerror(ret));
                syslog(LOG_ERR, "db: attempting recovery...");
                flags |= DB_RECOVER;
-               ret = dbenv->open(dbenv, ctdl_data_dir, flags, 0);                      // try recovery
+               ret = dbenv->open(dbenv, ctdl_db_dir, flags, 0);                        // try recovery
        }
        if (ret == DB_RUNRECOVERY) {
                syslog(LOG_ERR, "db: dbenv->open: %s", db_strerror(ret));
                syslog(LOG_ERR, "db: attempting catastrophic recovery...");
                flags &= ~DB_RECOVER;
                flags |= DB_RECOVER_FATAL;
-               ret = dbenv->open(dbenv, ctdl_data_dir, flags, 0);                      // try catastrophic recovery
+               ret = dbenv->open(dbenv, ctdl_db_dir, flags, 0);                        // try catastrophic recovery
        }
        if (ret) {
                syslog(LOG_ERR, "db: dbenv->open: %s", db_strerror(ret));
@@ -291,11 +287,11 @@ void cdb_chmod_data(void) {
        struct dirent *d;
        char filename[PATH_MAX];
 
-       dp = opendir(ctdl_data_dir);
+       dp = opendir(ctdl_db_dir);
        if (dp != NULL) {
                while (d = readdir(dp), d != NULL) {
                        if (d->d_name[0] != '.') {
-                               snprintf(filename, sizeof filename, "%s/%s", ctdl_data_dir, d->d_name);
+                               snprintf(filename, sizeof filename, "%s/%s", ctdl_db_dir, d->d_name);
                                syslog(LOG_DEBUG, "db: chmod(%s, 0600) returned %d", filename, chmod(filename, 0600));
                                syslog(LOG_DEBUG, "db: chown(%s, CTDLUID, -1) returned %d",
                                        filename, chown(filename, CTDLUID, (-1))
@@ -317,7 +313,7 @@ void close_databases(void) {
 
        syslog(LOG_INFO, "db: performing final checkpoint");
        if ((ret = dbenv->txn_checkpoint(dbenv, 0, 0, 0))) {
-               syslog(LOG_ERR, "txn_checkpoint: %s", db_strerror(ret));
+               syslog(LOG_ERR, "db: txn_checkpoint: %s", db_strerror(ret));
        }
 
        syslog(LOG_INFO, "db: flushing the database logs");
@@ -325,11 +321,6 @@ void close_databases(void) {
                syslog(LOG_ERR, "db: log_flush: %s", db_strerror(ret));
        }
 
-#ifdef DB_STAT_ALL
-       /* print some statistics... */
-       dbenv->lock_stat_print(dbenv, DB_STAT_ALL);
-#endif
-
        /* close the tables */
        syslog(LOG_INFO, "db: closing databases");
        for (i = 0; i < MAXCDB; ++i) {
@@ -341,10 +332,16 @@ void close_databases(void) {
 
        }
 
+       // This seemed nifty at the time but did anyone really look at it?
+       // #ifdef DB_STAT_ALL
+       // /* print some statistics... */
+       // dbenv->lock_stat_print(dbenv, DB_STAT_ALL);
+       // #endif
+
        /* Close the handle. */
        ret = dbenv->close(dbenv, 0);
        if (ret) {
-               syslog(LOG_EMERG, "db: DBENV->close: %s", db_strerror(ret));
+               syslog(LOG_ERR, "db: DBENV->close: %s", db_strerror(ret));
        }
 }
 
@@ -383,7 +380,7 @@ void cdb_decompress_if_necessary(struct cdbdata *cdb) {
 
        if (uncompress((Bytef *) uncompressed_data,
                       (uLongf *) & destLen, (const Bytef *) compressed_data, (uLong) sourceLen) != Z_OK) {
-               syslog(LOG_EMERG, "db: uncompress() error");
+               syslog(LOG_ERR, "db: uncompress() error");
                cdb_abort();
        }
 
@@ -425,7 +422,7 @@ int cdb_store(int cdb, const void *ckey, int ckeylen, void *cdata, int cdatalen)
                compressed_data = malloc(buffer_len);
                if (compress2((Bytef *) (compressed_data + sizeof(struct CtdlCompressHeader)),
                              &destLen, (Bytef *) cdata, (uLongf) cdatalen, 1) != Z_OK) {
-                       syslog(LOG_EMERG, "db: compress2() error");
+                       syslog(LOG_ERR, "db: compress2() error");
                        cdb_abort();
                }
                zheader.compressed_len = (size_t) destLen;
@@ -442,7 +439,7 @@ int cdb_store(int cdb, const void *ckey, int ckeylen, void *cdata, int cdatalen)
                                    0           // flags
                );
                if (ret) {
-                       syslog(LOG_EMERG, "db: cdb_store(%d): %s", cdb, db_strerror(ret));
+                       syslog(LOG_ERR, "db: cdb_store(%d): %s", cdb, db_strerror(ret));
                        cdb_abort();
                }
                if (compressing) {
@@ -464,7 +461,7 @@ int cdb_store(int cdb, const void *ckey, int ckeylen, void *cdata, int cdatalen)
                                txabort(tid);
                                goto retry;
                        } else {
-                               syslog(LOG_EMERG, "db: cdb_store(%d): %s", cdb, db_strerror(ret));
+                               syslog(LOG_ERR, "db: cdb_store(%d): %s", cdb, db_strerror(ret));
                                cdb_abort();
                        }
                } else {
@@ -494,7 +491,7 @@ int cdb_delete(int cdb, void *key, int keylen) {
        if (TSD->tid != NULL) {
                ret = dbp[cdb]->del(dbp[cdb], TSD->tid, &dkey, 0);
                if (ret) {
-                       syslog(LOG_EMERG, "db: cdb_delete(%d): %s", cdb, db_strerror(ret));
+                       syslog(LOG_ERR, "db: cdb_delete(%d): %s", cdb, db_strerror(ret));
                        if (ret != DB_NOTFOUND) {
                                cdb_abort();
                        }
@@ -510,7 +507,7 @@ int cdb_delete(int cdb, void *key, int keylen) {
                                txabort(tid);
                                goto retry;
                        } else {
-                               syslog(LOG_EMERG, "db: cdb_delete(%d): %s", cdb, db_strerror(ret));
+                               syslog(LOG_ERR, "db: cdb_delete(%d): %s", cdb, db_strerror(ret));
                                cdb_abort();
                        }
                } else {
@@ -533,7 +530,7 @@ static DBC *localcursor(int cdb) {
        }
 
        if (ret) {
-               syslog(LOG_EMERG, "db: localcursor: %s", db_strerror(ret));
+               syslog(LOG_ERR, "db: localcursor: %s", db_strerror(ret));
                cdb_abort();
        }
 
@@ -547,6 +544,11 @@ static DBC *localcursor(int cdb) {
  * using the cdb_free() routine.
  */
 struct cdbdata *cdb_fetch(int cdb, const void *key, int keylen) {
+
+       if (keylen == 0) {              // key length zero is impossible
+               return(NULL);
+       }
+
        struct cdbdata *tempcdb;
        DBT dkey, dret;
        int ret;
@@ -558,8 +560,9 @@ struct cdbdata *cdb_fetch(int cdb, const void *key, int keylen) {
        if (TSD->tid != NULL) {
                memset(&dret, 0, sizeof(DBT));
                dret.flags = DB_DBT_MALLOC;
-               ret = dbp[cdb]->get(dbp[cdb], TSD->tid, &dkey, &dret, 0);               // crashing here
-       } else {
+               ret = dbp[cdb]->get(dbp[cdb], TSD->tid, &dkey, &dret, 0);
+       }
+       else {
                DBC *curs;
 
                do {
@@ -568,12 +571,11 @@ struct cdbdata *cdb_fetch(int cdb, const void *key, int keylen) {
                        curs = localcursor(cdb);
                        ret = curs->c_get(curs, &dkey, &dret, DB_SET);
                        cclose(curs);
-               }
-               while (ret == DB_LOCK_DEADLOCK);
+               } while (ret == DB_LOCK_DEADLOCK);
        }
 
        if ((ret != 0) && (ret != DB_NOTFOUND)) {
-               syslog(LOG_EMERG, "db: cdb_fetch(%d): %s", cdb, db_strerror(ret));
+               syslog(LOG_ERR, "db: cdb_fetch(%d): %s", cdb, db_strerror(ret));
                cdb_abort();
        }
 
@@ -582,12 +584,12 @@ struct cdbdata *cdb_fetch(int cdb, const void *key, int keylen) {
        }
 
        tempcdb = (struct cdbdata *) malloc(sizeof(struct cdbdata));
-
        if (tempcdb == NULL) {
-               syslog(LOG_EMERG, "db: cdb_fetch: Cannot allocate memory for tempcdb");
+               syslog(LOG_ERR, "db: cdb_fetch() cannot allocate memory for tempcdb: %m");
                cdb_abort();
                return NULL;    /* make it easier for static analysis... */
-       } else {
+       }
+       else {
                tempcdb->len = dret.size;
                tempcdb->ptr = dret.data;
                cdb_decompress_if_necessary(tempcdb);
@@ -630,7 +632,7 @@ void cdb_rewind(int cdb) {
        int ret = 0;
 
        if (TSD->cursors[cdb] != NULL) {
-               syslog(LOG_EMERG, "db: cdb_rewind: must close cursor on database %d before reopening", cdb);
+               syslog(LOG_ERR, "db: cdb_rewind: must close cursor on database %d before reopening", cdb);
                cdb_abort();
                /* cclose(TSD->cursors[cdb]); */
        }
@@ -640,7 +642,7 @@ void cdb_rewind(int cdb) {
         */
        ret = dbp[cdb]->cursor(dbp[cdb], TSD->tid, &TSD->cursors[cdb], 0);
        if (ret) {
-               syslog(LOG_EMERG, "db: cdb_rewind: db_cursor: %s", db_strerror(ret));
+               syslog(LOG_ERR, "db: cdb_rewind: db_cursor: %s", db_strerror(ret));
                cdb_abort();
        }
 }
@@ -664,7 +666,7 @@ struct cdbdata *cdb_next_item(int cdb) {
 
        if (ret) {
                if (ret != DB_NOTFOUND) {
-                       syslog(LOG_EMERG, "db: cdb_next_item(%d): %s", cdb, db_strerror(ret));
+                       syslog(LOG_ERR, "db: cdb_next_item(%d): %s", cdb, db_strerror(ret));
                        cdb_abort();
                }
                cdb_close_cursor(cdb);
@@ -687,7 +689,7 @@ void cdb_begin_transaction(void) {
        bailIfCursor(TSD->cursors, "can't begin transaction during r/o cursor");
 
        if (TSD->tid != NULL) {
-               syslog(LOG_EMERG, "db: cdb_begin_transaction: ERROR: nested transaction");
+               syslog(LOG_ERR, "db: cdb_begin_transaction: ERROR: nested transaction");
                cdb_abort();
        }
 
@@ -698,17 +700,19 @@ void cdb_begin_transaction(void) {
 void cdb_end_transaction(void) {
        int i;
 
-       for (i = 0; i < MAXCDB; i++)
+       for (i = 0; i < MAXCDB; i++) {
                if (TSD->cursors[i] != NULL) {
                        syslog(LOG_WARNING, "db: cdb_end_transaction: WARNING: cursor %d still open at transaction end", i);
                        cclose(TSD->cursors[i]);
                        TSD->cursors[i] = NULL;
                }
+       }
 
        if (TSD->tid == NULL) {
                syslog(LOG_ERR, "db: cdb_end_transaction: ERROR: txcommit(NULL) !!");
                cdb_abort();
-       } else {
+       }
+       else {
                txcommit(TSD->tid);
        }
 
@@ -725,9 +729,10 @@ void cdb_trunc(int cdb) {
        u_int32_t count;
 
        if (TSD->tid != NULL) {
-               syslog(LOG_EMERG, "db: cdb_trunc must not be called in a transaction.");
+               syslog(LOG_ERR, "db: cdb_trunc must not be called in a transaction.");
                cdb_abort();
-       } else {
+       }
+       else {
                bailIfCursor(TSD->cursors, "attempt to write during r/o cursor");
 
              retry:
@@ -741,22 +746,21 @@ void cdb_trunc(int cdb) {
                                /* txabort(tid); */
                                goto retry;
                        } else {
-                               syslog(LOG_EMERG, "db: cdb_truncate(%d): %s", cdb, db_strerror(ret));
+                               syslog(LOG_ERR, "db: cdb_truncate(%d): %s", cdb, db_strerror(ret));
                                if (ret == ENOMEM) {
-                                       syslog(LOG_EMERG, "db: You may need to tune your database; please read http://www.citadel.org/doku.php?id=faq:troubleshooting:out_of_lock_entries for more information.");
+                                       syslog(LOG_ERR, "db: You may need to tune your database; please read http://www.citadel.org/doku.php?id=faq:troubleshooting:out_of_lock_entries for more information.");
                                }
                                exit(CTDLEXIT_DB);
                        }
-               } else {
+               }
+               else {
                        /* txcommit(tid); */
                }
        }
 }
 
 
-/*
- * compact (defragment) the database , possibly returning space back to the underlying filesystem
- */
+// compact (defragment) the database, possibly returning space back to the underlying filesystem
 void cdb_compact(void) {
        int ret;
        int i;