Integrated the DKIM signer into serv_smtpclient, but disabled it
[citadel.git] / citadel / server / backends / berkeley_db / berkeley_db.c
index 3e7d2af9002a399378a86161e8377fdc1d85500c..56a5f14fb1ccfcfba63ae68d9ddfe58385ee6732 100644 (file)
@@ -215,10 +215,8 @@ void bdb_checkpoint(void) {
 }
 
 
-// Open the various tables we'll be using.  Any table which
-// 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.
+// Open the various tables we'll be using.  Any table which 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 bdb_open_databases(void) {
        int ret;
        int i;
@@ -255,7 +253,7 @@ void bdb_open_databases(void) {
        bdb_env->set_verbose(bdb_env, DB_VERB_DEADLOCK, 1);
        bdb_env->set_verbose(bdb_env, DB_VERB_RECOVERY, 1);
 
-       flags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_RECOVER | DB_THREAD;
+       flags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_RECOVER | DB_THREAD ;
        syslog(LOG_DEBUG, "bdb: bdb_env->open(bdb_env, %s, %d, 0)", ctdl_db_dir, flags);
        ret = bdb_env->open(bdb_env, ctdl_db_dir, flags, 0);                            // try opening the database cleanly
        if (ret) {
@@ -266,7 +264,6 @@ void bdb_open_databases(void) {
        }
 
        for (i = 0; i < MAXCDB; ++i) {
-               syslog(LOG_INFO, "bdb: mounting database %02x", i);
                ret = db_create(&bdb_table[i], bdb_env, 0);                             // Create a database handle
                if (ret) {
                        syslog(LOG_ERR, "bdb: db_create: %s", db_strerror(ret));
@@ -312,7 +309,6 @@ void bdb_close_databases(void) {
        // close the tables
        syslog(LOG_INFO, "bdb: closing databases");
        for (i = 0; i < MAXCDB; ++i) {
-               syslog(LOG_INFO, "bdb: closing database %02x", i);
                ret = bdb_table[i]->close(bdb_table[i], 0);
                if (ret) {
                        syslog(LOG_ERR, "bdb: db_close: %s", db_strerror(ret));
@@ -360,8 +356,7 @@ void bdb_decompress_if_necessary(DBT *d) {
        destLen = (uLongf) zheader.uncompressed_len;
        uncompressed_data = malloc(zheader.uncompressed_len);
 
-       if (uncompress((Bytef *) uncompressed_data,
-                      (uLongf *) &destLen, (const Bytef *) compressed_data, (uLong) sourceLen) != Z_OK) {
+       if (uncompress((Bytef *) uncompressed_data, (uLongf *) &destLen, (const Bytef *) compressed_data, (uLong) sourceLen) != Z_OK) {
                syslog(LOG_ERR, "bdb: uncompress() error");
                bdb_abort();
        }
@@ -420,17 +415,21 @@ int bdb_store(int cdb, const void *ckey, int ckeylen, void *cdata, int cdatalen)
                bdb_begin_transaction();                // create our own for this operation.
        }
 
-       ret = bdb_table[cdb]->put(bdb_table[cdb],       // db
-                           TSD->tid,                   // transaction ID
-                           &dkey,                      // key
-                           &ddata,                     // data
-                           0                           // flags
-       );
-
-       if (ret) {
-               syslog(LOG_ERR, "bdb: bdb_store(%02x): %s", cdb, db_strerror(ret));
-               bdb_abort();
-       }
+       do {
+               ret = bdb_table[cdb]->put(bdb_table[cdb],       // db
+                               TSD->tid,                       // transaction ID
+                               &dkey,                  // key
+                               &ddata,                 // data
+                               0                               // flags
+               );
+               if ((ret != 0) && (ret != DB_LOCK_DEADLOCK)) {
+                       syslog(LOG_ERR, "bdb: bdb_store(%02x): error %d: %s", cdb, ret, db_strerror(ret));
+                       bdb_abort();
+               }
+               if (ret == DB_LOCK_DEADLOCK) {
+                       syslog(LOG_DEBUG, "bdb: bdb_store(%02x): would deadlock, trying again", cdb);
+               }
+       } while (ret == DB_LOCK_DEADLOCK);
 
        if (!existing_txn) {
                bdb_end_transaction();
@@ -497,12 +496,14 @@ struct cdbdata bdb_fetch(int cdb, const void *key, int keylen) {
        dkey.data = (void *) key;
 
        TSD->dbdata[cdb].flags = DB_DBT_REALLOC;
-       ret = bdb_table[cdb]->get(bdb_table[cdb], TSD->tid, &dkey, &TSD->dbdata[cdb], 0);
 
-       if ((ret != 0) && (ret != DB_NOTFOUND)) {
-               syslog(LOG_ERR, "bdb: bdb_fetch(%d): %s", cdb, db_strerror(ret));
-               bdb_abort();
-       }
+       do {
+               ret = bdb_table[cdb]->get(bdb_table[cdb], TSD->tid, &dkey, &TSD->dbdata[cdb], 0);
+               if ((ret != 0) && (ret != DB_NOTFOUND) && (ret != DB_LOCK_DEADLOCK)) {
+                       syslog(LOG_ERR, "bdb: bdb_fetch(%d): error %d: %s", cdb, ret, db_strerror(ret));
+                       bdb_abort();
+               }
+       } while (ret == DB_LOCK_DEADLOCK);
 
        if (ret == 0) {
                bdb_decompress_if_necessary(&TSD->dbdata[cdb]);
@@ -552,8 +553,8 @@ struct cdbkeyval bdb_next_item(int cdb) {
        memset(&kv, 0, sizeof(struct cdbkeyval));
 
        // reuse memory from the previous call.
-       TSD->dbkey[cdb].flags = DB_DBT_MALLOC;
-       TSD->dbdata[cdb].flags = DB_DBT_MALLOC;
+       TSD->dbkey[cdb].flags = DB_DBT_REALLOC;
+       TSD->dbdata[cdb].flags = DB_DBT_REALLOC;
 
        assert(TSD->cursors[cdb] != NULL);
        ret = TSD->cursors[cdb]->c_get(TSD->cursors[cdb], &TSD->dbkey[cdb], &TSD->dbdata[cdb], DB_NEXT);
@@ -632,10 +633,7 @@ void bdb_tick(void) {
        }
        else if (rejected) {
                syslog(LOG_DEBUG, "bdb: rejected lock %d", rejected);
-               bdb_abort();            // FIXME remove this, we want to unlock, not abort
        }
-
-       syslog(LOG_DEBUG, "bdb: tick...");
 }
 
 
@@ -660,7 +658,7 @@ void bdb_init_backend(void) {
        cdb_tick = bdb_tick;
 
        // Some functions in this backend need to store some per-thread data.
-       // We crerate the key here, during module initialization.
+       // We create the key here, during module initialization.
        if (pthread_key_create(&bdb_thread_key, NULL) != 0) {
                syslog(LOG_ERR, "pthread_key_create() : %m");
                exit(CTDLEXIT_THREAD);