]> code.citadel.org Git - citadel.git/blobdiff - citadel/database_sleepycat.c
* Variable names, comments, documentation, etc... removed the acronym 'BBS'
[citadel.git] / citadel / database_sleepycat.c
index b24379ce05ee7d44191c6ac03d4e9731b72518c4..473071c340e84ab1f3505fa3e04498978c612485 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * $Id$
  *
- * Sleepycat (Berkeley) DB driver for Citadel/UX
+ * Sleepycat (Berkeley) DB driver for Citadel
  *
  */
 
@@ -55,6 +55,7 @@
 #include "database.h"
 #include "msgbase.h"
 #include "sysdep_decls.h"
+#include "config.h"
 
 static DB *dbp[MAXCDB];                /* One DB handle for each Citadel database */
 static DB_ENV *dbenv;          /* The DB environment (global) */
@@ -80,7 +81,7 @@ static void txabort(DB_TXN *tid) {
        ret = tid->abort(tid);
 
         if (ret) {
-                lprintf(1, "cdb_*: txn_abort: %s\n", db_strerror(ret));
+                lprintf(CTDL_EMERG, "cdb_*: txn_abort: %s\n", db_strerror(ret));
                abort();
        }
 }
@@ -92,7 +93,7 @@ static void txcommit(DB_TXN *tid) {
        ret = tid->commit(tid, 0);
 
         if (ret) {
-                lprintf(1, "cdb_*: txn_commit: %s\n", db_strerror(ret));
+                lprintf(CTDL_EMERG, "cdb_*: txn_commit: %s\n", db_strerror(ret));
                abort();
        }
 }
@@ -104,16 +105,21 @@ static void txbegin(DB_TXN **tid) {
        ret = dbenv->txn_begin(dbenv, NULL, tid, 0);
 
         if (ret) {
-                lprintf(1, "cdb_*: txn_begin: %s\n", db_strerror(ret));
+                lprintf(CTDL_EMERG, "cdb_*: txn_begin: %s\n", db_strerror(ret));
                abort();
        }
 }
 
+static void dbpanic(DB_ENV* env, int errval)
+{
+       lprintf(CTDL_EMERG, "cdb_*: Berkeley DB panic: %d\n", errval);
+}
+
 static void cclose(DBC *cursor) {
        int ret;
 
        if ((ret = cursor->c_close(cursor))) {
-               lprintf(1, "cdb_*: c_close: %s\n", db_strerror(ret));
+               lprintf(CTDL_EMERG, "cdb_*: c_close: %s\n", db_strerror(ret));
                abort();
        }
 }
@@ -125,7 +131,7 @@ static void bailIfCursor(DBC **cursors, const char *msg)
   for (i = 0; i < MAXCDB; i++)
     if (cursors[i] != NULL)
       {
-       lprintf(1, "cdb_*: cursor still in progress on cdb %d: %s\n", i, msg);
+       lprintf(CTDL_EMERG, "cdb_*: cursor still in progress on cdb %d: %s\n", i, msg);
        abort();
       }
 }
@@ -137,7 +143,7 @@ static void check_handles(void *arg) {
                bailIfCursor(tsd->cursors, "in check_handles");
 
                if (tsd->tid != NULL) {
-                       lprintf(1, "cdb_*: transaction still in progress!");
+                       lprintf(CTDL_EMERG, "cdb_*: transaction still in progress!");
                        abort();
                }
        }
@@ -146,7 +152,7 @@ static void check_handles(void *arg) {
 static void dest_tsd(void *arg) {
        if (arg != NULL) {
                check_handles(arg);
-               phree(arg);
+               free(arg);
        }
 }
 
@@ -164,7 +170,7 @@ void cdb_allocate_tsd(void) {
        if (pthread_getspecific(tsdkey) != NULL)
                return;
 
-       tsd = mallok(sizeof(struct cdbtsd));
+       tsd = malloc(sizeof(struct cdbtsd));
 
        tsd->tid = NULL;
 
@@ -204,20 +210,20 @@ static void cdb_cull_logs(void) {
        char **file, **list;
        char errmsg[SIZ];
 
-       lprintf(5, "Database log file cull started.\n");
+       lprintf(CTDL_INFO, "Database log file cull started.\n");
 
        flags = DB_ARCH_ABS;
 
        /* Get the list of names. */
        if ((ret = dbenv->log_archive(dbenv, &list, flags)) != 0) {
-               lprintf(1, "cdb_cull_logs: %s\n", db_strerror(ret));
+               lprintf(CTDL_ERR, "cdb_cull_logs: %s\n", db_strerror(ret));
                return;
        }
 
        /* Print the list of names. */
        if (list != NULL) {
                for (file = list; *file != NULL; ++file) {
-                       lprintf(9, "Deleting log: %s\n", *file);
+                       lprintf(CTDL_DEBUG, "Deleting log: %s\n", *file);
                        ret = unlink(*file);
                        if (ret != 0) {
                                snprintf(errmsg, sizeof(errmsg),
@@ -235,7 +241,7 @@ static void cdb_cull_logs(void) {
                free(list);
        }
 
-       lprintf(5, "Database log file cull ended.\n");
+       lprintf(CTDL_INFO, "Database log file cull ended.\n");
 }
 
 
@@ -252,7 +258,7 @@ static void cdb_checkpoint(void) {
                                0);
 
        if (ret != 0) {
-               lprintf(1, "cdb_checkpoint: txn_checkpoint: %s\n",
+               lprintf(CTDL_EMERG, "cdb_checkpoint: txn_checkpoint: %s\n",
                        db_strerror(ret));
                abort();
        }
@@ -267,9 +273,9 @@ static void cdb_checkpoint(void) {
 
 /*
  * Open the various databases we'll be using.  Any database which
- * does not exist should be created.  Note that we don't need an S_DATABASE
- * critical section here, because there aren't any active threads manipulating
- * the database yet -- and besides, it causes problems on BSDI.
+ * does not exist should be created.  Note that we don't need a
+ * critical section here, because there aren't any active threads
+ * manipulating the database yet.
  */
 void open_databases(void)
 {
@@ -277,27 +283,39 @@ void open_databases(void)
        int i;
        char dbfilename[SIZ];
        u_int32_t flags = 0;
+       char dbdirname[PATH_MAX];
+       DIR *dp;
+       struct dirent *d;
+       char filename[PATH_MAX];
 
-       lprintf(9, "cdb_*: open_databases() starting\n");
-       lprintf(5, "%s\n", db_version(NULL, NULL, NULL));
+
+       getcwd(dbdirname, sizeof dbdirname);
+       strcat(dbdirname, "/data");
+
+       lprintf(CTDL_DEBUG, "cdb_*: open_databases() starting\n");
+       lprintf(CTDL_DEBUG, "Compiled db: %s\n", DB_VERSION_STRING);
+       lprintf(CTDL_INFO, "  Linked db: %s\n", db_version(NULL, NULL, NULL));
 #ifdef HAVE_ZLIB
-       lprintf(5, "zlib compression version %s\n", zlibVersion());
+       lprintf(CTDL_INFO, "Linked zlib: %s\n", zlibVersion());
 #endif
 
         /*
          * Silently try to create the database subdirectory.  If it's
          * already there, no problem.
          */
-        system("exec mkdir data 2>/dev/null");
+       mkdir(dbdirname, 0700);
+       chmod(dbdirname, 0700);
+       chown(dbdirname, CTDLUID, (-1) );
 
-       lprintf(9, "cdb_*: Setting up DB environment\n");
+       lprintf(CTDL_DEBUG, "cdb_*: Setting up DB environment\n");
        db_env_set_func_yield(sched_yield);
        ret = db_env_create(&dbenv, 0);
        if (ret) {
-               lprintf(1, "cdb_*: db_env_create: %s\n", db_strerror(ret));
+               lprintf(CTDL_EMERG, "cdb_*: db_env_create: %s\n", db_strerror(ret));
                exit(ret);
        }
        dbenv->set_errpfx(dbenv, "citserver");
+       dbenv->set_paniccall(dbenv, dbpanic);
 
         /*
          * We want to specify the shared memory buffer pool cachesize,
@@ -305,34 +323,35 @@ void open_databases(void)
          */
         ret = dbenv->set_cachesize(dbenv, 0, 64 * 1024, 0);
        if (ret) {
-               lprintf(1, "cdb_*: set_cachesize: %s\n", db_strerror(ret));
+               lprintf(CTDL_EMERG, "cdb_*: set_cachesize: %s\n", db_strerror(ret));
                 dbenv->close(dbenv, 0);
                 exit(ret);
         }
 
        if ((ret = dbenv->set_lk_detect(dbenv, DB_LOCK_DEFAULT))) {
-               lprintf(1, "cdb_*: set_lk_detect: %s\n", db_strerror(ret));
+               lprintf(CTDL_EMERG, "cdb_*: set_lk_detect: %s\n", db_strerror(ret));
                dbenv->close(dbenv, 0);
                exit(ret);
        }
 
         flags = DB_CREATE|DB_RECOVER|DB_INIT_MPOOL|DB_PRIVATE|DB_INIT_TXN|
                DB_INIT_LOCK|DB_THREAD;
-        ret = dbenv->open(dbenv, "./data", flags, 0);
+       lprintf(CTDL_DEBUG, "dbenv->open(dbenv, %s, %d, 0)\n", dbdirname, flags);
+        ret = dbenv->open(dbenv, dbdirname, flags, 0);
        if (ret) {
-               lprintf(1, "cdb_*: dbenv->open: %s\n", db_strerror(ret));
+               lprintf(CTDL_DEBUG, "cdb_*: dbenv->open: %s\n", db_strerror(ret));
                 dbenv->close(dbenv, 0);
                 exit(ret);
         }
 
-       lprintf(7, "cdb_*: Starting up DB\n");
+       lprintf(CTDL_INFO, "cdb_*: Starting up DB\n");
 
        for (i = 0; i < MAXCDB; ++i) {
 
                /* Create a database handle */
                ret = db_create(&dbp[i], dbenv, 0);
                if (ret) {
-                       lprintf(1, "cdb_*: db_create: %s\n", db_strerror(ret));
+                       lprintf(CTDL_DEBUG, "cdb_*: db_create: %s\n", db_strerror(ret));
                        exit(ret);
                }
 
@@ -347,24 +366,40 @@ void open_databases(void)
                                dbfilename,
                                NULL,
                                DB_BTREE,
-                               DB_CREATE|DB_THREAD
-                               |DB_AUTO_COMMIT
+                               DB_CREATE|DB_AUTO_COMMIT|DB_THREAD
                                ,
                                0600);
                if (ret) {
-                       lprintf(1, "cdb_*: db_open[%d]: %s\n", i, db_strerror(ret));
+                       lprintf(CTDL_EMERG, "cdb_*: db_open[%d]: %s\n", i, db_strerror(ret));
                        exit(ret);
                }
        }
 
        if ((ret = pthread_key_create(&tsdkey, dest_tsd))) {
-               lprintf(1, "cdb_*: pthread_key_create: %s\n", strerror(ret));
+               lprintf(CTDL_EMERG, "cdb_*: pthread_key_create: %s\n", strerror(ret));
                exit(1);
        }
 
        cdb_allocate_tsd();
        CtdlRegisterSessionHook(cdb_checkpoint, EVT_TIMER);
-       lprintf(9, "cdb_*: open_databases() finished\n");
+
+       /* Now make sure we own all the files, because in a few milliseconds
+        * we're going to drop root privs.
+        */
+       dp = opendir(dbdirname);
+       if (dp != NULL) {
+               while (d = readdir(dp), d != NULL) {
+                       if (d->d_name[0] != '.') {
+                               snprintf(filename, sizeof filename, "%s/%s",
+                                       dbdirname, d->d_name);
+                               chmod(filename, 0600);
+                               chown(filename, CTDLUID, (-1) );
+                       }
+               }
+               closedir(dp);
+       }
+
+       lprintf(CTDL_DEBUG, "cdb_*: open_databases() finished\n");
 }
 
 
@@ -380,16 +415,18 @@ void close_databases(void)
        cdb_free_tsd();
 
        if ((ret = dbenv->txn_checkpoint(dbenv, 0, 0, 0))) {
-               lprintf(1, "cdb_*: txn_checkpoint: %s\n", db_strerror(ret));
-               abort();
+               lprintf(CTDL_EMERG,
+                       "cdb_*: txn_checkpoint: %s\n",
+                       db_strerror(ret));
        }
 
        for (a = 0; a < MAXCDB; ++a) {
-               lprintf(7, "cdb_*: Closing database %d\n", a);
+               lprintf(CTDL_INFO, "cdb_*: Closing database %d\n", a);
                ret = dbp[a]->close(dbp[a], 0);
                if (ret) {
-                       lprintf(1, "cdb_*: db_close: %s\n", db_strerror(ret));
-                       abort();
+                       lprintf(CTDL_EMERG,
+                               "cdb_*: db_close: %s\n",
+                               db_strerror(ret));
                }
                
        }
@@ -397,8 +434,9 @@ void close_databases(void)
         /* Close the handle. */
         ret = dbenv->close(dbenv, 0);
        if (ret) {
-                lprintf(1, "cdb_*: DBENV->close: %s\n", db_strerror(ret));
-               abort();
+                lprintf(CTDL_EMERG,
+                       "cdb_*: DBENV->close: %s\n",
+                       db_strerror(ret));
         }
 }
 
@@ -427,18 +465,18 @@ void cdb_decompress_if_necessary(struct cdbdata *cdb) {
 
        sourceLen = (uLongf) zheader.compressed_len;
        destLen = (uLongf) zheader.uncompressed_len;
-       uncompressed_data = mallok(zheader.uncompressed_len);
+       uncompressed_data = malloc(zheader.uncompressed_len);
 
        if (uncompress( (Bytef *) uncompressed_data,
-                       &destLen,
-                       compressed_data,
-                       sourceLen
+                       (uLongf *)&destLen,
+                       (const Bytef *)compressed_data,
+                       (uLong)sourceLen
        ) != Z_OK) {
-               lprintf(1, "uncompress() error\n");
+               lprintf(CTDL_EMERG, "uncompress() error\n");
                abort();
        }
 
-       phree(cdb->ptr);
+       free(cdb->ptr);
        cdb->len = (size_t) destLen;
        cdb->ptr = uncompressed_data;
 }
@@ -483,7 +521,7 @@ int cdb_store(int cdb,
                buffer_len = ( (cdatalen * 101) / 100 ) + 100
                                + sizeof(struct CtdlCompressHeader) ;
                destLen = (uLongf) buffer_len;
-               compressed_data = mallok(buffer_len);
+               compressed_data = malloc(buffer_len);
                if (compress2(
                        (Bytef *) (compressed_data +
                                        sizeof(struct CtdlCompressHeader)),
@@ -492,7 +530,7 @@ int cdb_store(int cdb,
                        (uLongf) cdatalen,
                        1
                ) != Z_OK) {
-                       lprintf(1, "compress2() error\n");
+                       lprintf(CTDL_EMERG, "compress2() error\n");
                        abort();
                }
                zheader.compressed_len = (size_t) destLen;
@@ -513,12 +551,11 @@ int cdb_store(int cdb,
                          0);           /* flags */
       if (ret)
        {
-         lprintf(1, "cdb_store(%d): %s\n", cdb,
-                 db_strerror(ret));
+         lprintf(CTDL_EMERG, "cdb_store(%d): %s\n", cdb, db_strerror(ret));
          abort();
        }
 #ifdef HAVE_ZLIB
-      if (compressing) phree(compressed_data);
+      if (compressing) free(compressed_data);
 #endif
       return ret;
       
@@ -543,8 +580,7 @@ int cdb_store(int cdb,
            }
          else
            {
-             lprintf(1, "cdb_store(%d): %s\n", cdb,
-                     db_strerror(ret));
+             lprintf(CTDL_EMERG, "cdb_store(%d): %s\n", cdb, db_strerror(ret));
              abort();
            }
        }
@@ -552,7 +588,7 @@ int cdb_store(int cdb,
        {
          txcommit(tid);
 #ifdef HAVE_ZLIB
-         if (compressing) phree(compressed_data);
+         if (compressing) free(compressed_data);
 #endif
          return ret;
        }
@@ -579,8 +615,7 @@ int cdb_delete(int cdb, void *key, int keylen)
       ret = dbp[cdb]->del(dbp[cdb], MYTID, &dkey, 0);
       if (ret)
        {
-         lprintf(1, "cdb_delete(%d): %s\n", cdb,
-                 db_strerror(ret));
+         lprintf(CTDL_EMERG, "cdb_delete(%d): %s\n", cdb, db_strerror(ret));
          if (ret != DB_NOTFOUND)
            abort();
        }
@@ -602,8 +637,7 @@ int cdb_delete(int cdb, void *key, int keylen)
            }
          else
            {
-             lprintf(1, "cdb_delete(%d): %s\n", cdb,
-                     db_strerror(ret));
+             lprintf(CTDL_EMERG, "cdb_delete(%d): %s\n", cdb, db_strerror(ret));
              abort();
            }
        }
@@ -627,7 +661,7 @@ static DBC *localcursor(int cdb)
 
   if (ret)
     {
-      lprintf(1, "localcursor: %s\n", db_strerror(ret));
+      lprintf(CTDL_EMERG, "localcursor: %s\n", db_strerror(ret));
       abort();
     }
 
@@ -677,16 +711,16 @@ struct cdbdata *cdb_fetch(int cdb, void *key, int keylen)
 
   if ((ret != 0) && (ret != DB_NOTFOUND))
     {
-      lprintf(1, "cdb_fetch(%d): %s\n", cdb, db_strerror(ret));
+      lprintf(CTDL_EMERG, "cdb_fetch(%d): %s\n", cdb, db_strerror(ret));
       abort();
     }
 
   if (ret != 0) return NULL;
-  tempcdb = (struct cdbdata *) mallok(sizeof(struct cdbdata));
+  tempcdb = (struct cdbdata *) malloc(sizeof(struct cdbdata));
 
   if (tempcdb == NULL)
     {
-      lprintf(2, "cdb_fetch: Cannot allocate memory for tempcdb\n");
+      lprintf(CTDL_EMERG, "cdb_fetch: Cannot allocate memory for tempcdb\n");
       abort();
     }
 
@@ -705,8 +739,8 @@ struct cdbdata *cdb_fetch(int cdb, void *key, int keylen)
  */
 void cdb_free(struct cdbdata *cdb)
 {
-       phree(cdb->ptr);
-       phree(cdb);
+       free(cdb->ptr);
+       free(cdb);
 }
 
 void cdb_close_cursor(int cdb)
@@ -726,15 +760,18 @@ void cdb_rewind(int cdb)
 {
        int ret = 0;
 
-       if (MYCURSORS[cdb] != NULL)
-               cclose(MYCURSORS[cdb]);
+       if (MYCURSORS[cdb] != NULL) {
+               lprintf(CTDL_EMERG, "cdb_rewind: must close cursor on database %d before reopening.\n", cdb);
+               abort();
+               /* cclose(MYCURSORS[cdb]); */
+       }
 
        /*
         * Now initialize the cursor
         */
        ret = dbp[cdb]->cursor(dbp[cdb], MYTID, &MYCURSORS[cdb], 0);
        if (ret) {
-               lprintf(1, "cdb_rewind: db_cursor: %s\n", db_strerror(ret));
+               lprintf(CTDL_EMERG, "cdb_rewind: db_cursor: %s\n", db_strerror(ret));
                abort();
        }
 }
@@ -760,7 +797,7 @@ struct cdbdata *cdb_next_item(int cdb)
        
        if (ret) {
                if (ret != DB_NOTFOUND) {
-                       lprintf(1, "cdb_next_item(%d): %s\n",
+                       lprintf(CTDL_EMERG, "cdb_next_item(%d): %s\n",
                                cdb, db_strerror(ret));
                        abort();
                }
@@ -769,7 +806,7 @@ struct cdbdata *cdb_next_item(int cdb)
                return NULL;            /* presumably, end of file */
        }
 
-       cdbret = (struct cdbdata *) mallok(sizeof(struct cdbdata));
+       cdbret = (struct cdbdata *) malloc(sizeof(struct cdbdata));
        cdbret->len = data.size;
        cdbret->ptr = data.data;
 #ifdef HAVE_ZLIB
@@ -791,7 +828,7 @@ void cdb_begin_transaction(void) {
 
   if (MYTID != NULL)
     {
-      lprintf(1, "cdb_begin_transaction: ERROR: nested transaction\n");
+      lprintf(CTDL_EMERG, "cdb_begin_transaction: ERROR: nested transaction\n");
       abort();
     }
 
@@ -803,14 +840,14 @@ void cdb_end_transaction(void) {
 
   for (i = 0; i < MAXCDB; i++)
     if (MYCURSORS[i] != NULL) {
-      lprintf(1, "cdb_end_transaction: WARNING: cursor %d still open at transaction end\n", i);
+      lprintf(CTDL_WARNING, "cdb_end_transaction: WARNING: cursor %d still open at transaction end\n", i);
       cclose(MYCURSORS[i]);
       MYCURSORS[i] = NULL;
     }
 
   if (MYTID == NULL)
     {
-      lprintf(1, "cdb_end_transaction: ERROR: txcommit(NULL) !!\n");
+      lprintf(CTDL_EMERG, "cdb_end_transaction: ERROR: txcommit(NULL) !!\n");
       abort();
     }
   else
@@ -830,7 +867,7 @@ void cdb_trunc(int cdb)
   
   if (MYTID != NULL)
     {
-      lprintf(1, "cdb_trunc must not be called in a transaction.\n");
+      lprintf(CTDL_EMERG, "cdb_trunc must not be called in a transaction.\n");
       abort();
     }
   else
@@ -852,8 +889,7 @@ void cdb_trunc(int cdb)
            }
          else
            {
-             lprintf(1, "cdb_truncate(%d): %s\n", cdb,
-                     db_strerror(ret));
+             lprintf(CTDL_EMERG, "cdb_truncate(%d): %s\n", cdb, db_strerror(ret));
              abort();
            }
        }