]> git.sommitrealweird.co.uk Git - onak.git/commitdiff
cscvs to tla changeset 54
authorJonathan McDowell <noodles@earth.li>
Mon, 31 May 2004 23:47:24 +0000 (23:47 +0000)
committerJonathan McDowell <noodles@earth.li>
Mon, 31 May 2004 23:47:24 +0000 (23:47 +0000)
Author: noodles
Date: 2003/01/22 23:31:32
Add transaction support to DB3 backend to attempt to prevent locking with
multiple instances running at once.

keydb_db3.c

index 6177ac70f404adb0ef0764434501e64b4c194a1a..0ccaec33d63857fe0fdf9bc0320ef89078bf3550 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright 2002 Project Purple
  */
 
+#include <assert.h>
 #include <sys/types.h>
 #include <sys/uio.h>
 #include <ctype.h>
 #include "onak-conf.h"
 #include "parsekey.h"
 
+/**
+ *     dbenv - our database environment.
+ */
+static DB_ENV *dbenv = NULL;
+
 /**
  *     dbconn - our connection to the key database.
  */
@@ -37,6 +43,11 @@ static DB *dbconn = NULL;
  */
 static DB *worddb = NULL;
 
+/**
+ *     txn - our current transaction id.
+ */
+static DB_TXN *txn = NULL;
+
 /**
  *     makewordlist - Takes a string and splits it into a set of unique words.
  *     @wordlist: The current word list.
@@ -99,38 +110,50 @@ void initdb(void)
        char buf[1024];
        int ret = 0;
 
-       strcpy(buf, config.db_dir);
-       strcat(buf, "/keydb.db");
-       
-       ret = db_create(&dbconn, NULL, 0);
+       ret = db_env_create(&dbenv, 0);
+       if (ret != 0) {
+               fprintf(stderr, "db_env_create: %s\n", db_strerror(ret));
+               exit(1);
+       }
+
+       ret = dbenv->open(dbenv, config.db_dir,
+                       DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_LOCK |
+                       DB_INIT_TXN |
+                       DB_RECOVER | DB_CREATE,
+                       0);
+       if (ret != 0) {
+               dbenv->err(dbenv, ret, "%s", config.db_dir);
+               exit(1);
+       }
+
+       ret = db_create(&dbconn, dbenv, 0);
        if (ret != 0) {
                fprintf(stderr, "db_create: %s\n", db_strerror(ret));
                exit(1);
        }
 
-       ret = dbconn->open(dbconn, buf, NULL, DB_HASH,
+       ret = dbconn->open(dbconn, "keydb.db", 
+                       NULL,
+                       DB_HASH,
                        DB_CREATE,
                        0664);
        if (ret != 0) {
-               dbconn->err(dbconn, ret, "%s", buf);
+               dbconn->err(dbconn, ret, "keydb.db");
                exit(1);
        }
 
-       strcpy(buf, config.db_dir);
-       strcat(buf, "/worddb");
-       
-       ret = db_create(&worddb, NULL, 0);
+       ret = db_create(&worddb, dbenv, 0);
        if (ret != 0) {
                fprintf(stderr, "db_create: %s\n", db_strerror(ret));
                exit(1);
        }
        ret = worddb->set_flags(worddb, DB_DUP);
 
-       ret = worddb->open(worddb, buf, NULL, DB_BTREE,
+       ret = worddb->open(worddb, "worddb", NULL, DB_BTREE,
                        DB_CREATE,
                        0664);
        if (ret != 0) {
-               worddb->err(worddb, ret, "%s", buf);
+               worddb->err(worddb, ret, "worddb");
                exit(1);
        }
        
@@ -149,6 +172,8 @@ void cleanupdb(void)
        worddb = NULL;
        dbconn->close(dbconn, 0);
        dbconn = NULL;
+       dbenv->close(dbenv, 0);
+       dbenv = NULL;
 }
 
 /**
@@ -160,6 +185,19 @@ void cleanupdb(void)
  */
 bool starttrans(void)
 {
+       int ret;
+
+       assert(txn == NULL);
+
+       ret = txn_begin(dbenv,
+               NULL, /* No parent transaction */
+               &txn,
+               0);
+       if (ret != 0) {
+               dbenv->err(dbenv, ret, "starttrans():");
+               exit(1);
+       }
+
        return true;
 }
 
@@ -170,6 +208,18 @@ bool starttrans(void)
  */
 void endtrans(void)
 {
+       int ret;
+
+       assert(txn != NULL);
+
+       ret = txn_commit(txn,
+               0);
+       if (ret != 0) {
+               dbenv->err(dbenv, ret, "endtrans():");
+               exit(1);
+       }
+       txn = NULL;
+
        return;
 }
 
@@ -204,8 +254,12 @@ int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey,
        key.data = &keyid;
        keyid &= 0xFFFFFFFF;
 
+       if (!intrans) {
+               starttrans();
+       }
+
        ret = dbconn->get(dbconn,
-                       NULL, /* txn id */
+                       txn,
                        &key,
                        &data,
                        0); /* flags*/
@@ -224,6 +278,10 @@ int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey,
                dbconn->err(dbconn, ret, "Problem retrieving key");
        }
 
+       if (!intrans) {
+               endtrans();
+       }
+
        return (numkeys);
 }
 
@@ -258,9 +316,10 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey)
        searchtext = strdup(search);
        wordlist = makewordlist(wordlist, searchtext);
 
+       starttrans();
 
        ret = worddb->cursor(worddb,
-                       NULL, /* txn */
+                       txn,
                        &cursor,
                        0);   /* flags */
 
@@ -322,7 +381,7 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey)
 
                        numkeys += fetch_key(keyid,
                                        publickey,
-                                       false);
+                                       true);
        }
        llfree(keylist, free);
        keylist = NULL;
@@ -331,6 +390,8 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey)
 
        ret = cursor->c_close(cursor);
        cursor = NULL;
+
+       endtrans();
        
        return (numkeys);
 }
@@ -366,6 +427,10 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update)
 
        keyid = get_keyid(publickey);
 
+       if (!intrans) {
+               starttrans();
+       }
+
        /*
         * Delete the key if we already have it.
         *
@@ -404,7 +469,7 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update)
        data.data = storebuf.buffer;
 
        ret = dbconn->put(dbconn,
-                       NULL, /* txn id */
+                       txn,
                        &key,
                        &data,
                        0); /* flags*/
@@ -455,7 +520,7 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update)
                        worddb_data[10] = (keyid >>  8) & 0xFF;
                        worddb_data[11] = keyid & 0xFF; 
                        ret = worddb->put(worddb,
-                               0,
+                               txn,
                                &key,
                                &data,
                                0);
@@ -477,6 +542,10 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update)
                uids = NULL;
        }
 
+       if (!intrans) {
+               endtrans();
+       }
+
        return 0;
 }
 
@@ -503,7 +572,11 @@ int delete_key(uint64_t keyid, bool intrans)
 
        keyid &= 0xFFFFFFFF;
 
-       fetch_key(keyid, &publickey, intrans);
+       if (!intrans) {
+               starttrans();
+       }
+
+       fetch_key(keyid, &publickey, true);
 
        /*
         * Walk through the uids removing the words from the worddb.
@@ -517,7 +590,7 @@ int delete_key(uint64_t keyid, bool intrans)
                }
                                
                ret = worddb->cursor(worddb,
-                       NULL, /* txn */
+                       txn,
                        &cursor,
                        0);   /* flags */
 
@@ -551,8 +624,13 @@ int delete_key(uint64_t keyid, bool intrans)
                                &key,
                                &data,
                                DB_GET_BOTH);
+
                        if (ret == 0) {
                                ret = cursor->c_del(cursor, 0);
+                               if (ret != 0) {
+                                       worddb->err(worddb, ret,
+                                               "Problem deleting word.");
+                               }
                        }
 
                        if (ret != 0) {
@@ -581,10 +659,14 @@ int delete_key(uint64_t keyid, bool intrans)
        key.size = sizeof(keyid);
 
        dbconn->del(dbconn,
-                       NULL, /* txn id */
+                       txn,
                        &key,
                        0); /* flags */
 
+       if (!intrans) {
+               endtrans();
+       }
+
        return (ret == DB_NOTFOUND);
 }