]> arthur.barton.de Git - netatalk.git/blobdiff - etc/cnid_dbd/main.c
dbd now does many things it should do in the end.
[netatalk.git] / etc / cnid_dbd / main.c
index 6c21d8597aa227f9ed32b71f73fb9ffba500b8eb..21b44379ce6296dc2c0d105b5012ccba7c6f2cf6 100644 (file)
@@ -1,7 +1,8 @@
 /*
- * $Id: main.c,v 1.3 2009-03-31 11:40:26 franklahm Exp $
+ * $Id: main.c,v 1.7 2009-05-14 13:46:08 franklahm Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
+ * Copyright (c) Frank Lahm 2009
  * All Rights Reserved.  See COPYING.
  */
 
 #include "dbd.h"
 #include "comm.h"
 
-
 #define LOCKFILENAME  "lock"
 
-static int exit_sig = 0;
+/* 
+   Note: DB_INIT_LOCK is here so we can run the db_* utilities while netatalk is running.
+   It's a likey performance hit, but it might we worth it.
+ */
+#define DBOPTIONS (DB_CREATE | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN | DB_RECOVER)
 
+static DBD *dbd;
+
+static int exit_sig = 0;
 
 static void sig_exit(int signo)
 {
@@ -83,113 +90,128 @@ static int loop(struct db_param *dbp)
     struct cnid_dbd_rqst rqst;
     struct cnid_dbd_rply rply;
     int ret, cret;
-    time_t now, time_next_flush, time_last_rqst;
     int count;
+    time_t now, time_next_flush, time_last_rqst;
+    char timebuf[64];
     static char namebuf[MAXPATHLEN + 1];
-    u_int32_t checkp_flags;
 
     count = 0;
     now = time(NULL);
     time_next_flush = now + dbp->flush_interval;
     time_last_rqst = now;
-    if (dbp->nosync)
-        checkp_flags = DB_FORCE;
-    else
-        checkp_flags = 0;
 
     rqst.name = namebuf;
 
+    strftime(timebuf, 63, "%b %d %H:%M:%S.",localtime(&time_next_flush));
+    LOG(log_debug, logtype_cnid, "Checkpoint interval: %d seconds. Next checkpoint: %s",
+        dbp->flush_interval, timebuf);
+
     while (1) {
         if ((cret = comm_rcv(&rqst)) < 0)
             return -1;
 
         now = time(NULL);
 
-        if (count > dbp->flush_frequency || now > time_next_flush) {
-#ifdef CNID_BACKEND_DBD_TXN
-            if (dbif_txn_checkpoint(0, 0, checkp_flags) < 0)
-                return -1;
-#else
-            if (dbif_sync() < 0)
-                return -1;
-#endif
-            count = 0;
-            time_next_flush = now + dbp->flush_interval;
-        }
-
         if (cret == 0) {
+            /* comm_rcv returned from select without receiving anything. */
+
+            /* Give signals a chance... */
             block_sigs_onoff(0);
             block_sigs_onoff(1);
             if (exit_sig)
+                /* Received signal (TERM|INT) */
                 return 0;
             if (dbp->idle_timeout && comm_nbe() <= 0 && (now - time_last_rqst) > dbp->idle_timeout)
+                /* Idle timeout */
                 return 0;
-            continue;
-        }
-        /* We got a request */
-        time_last_rqst = now;
-        count++;
+        } else {
+            /* We got a request */
+            time_last_rqst = now;
+
+            memset(&rply, 0, sizeof(rply));
+            switch(rqst.op) {
+                /* ret gets set here */
+            case CNID_DBD_OP_OPEN:
+            case CNID_DBD_OP_CLOSE:
+                /* open/close are noops for now. */
+                rply.namelen = 0;
+                ret = 1;
+                break;
+            case CNID_DBD_OP_ADD:
+                ret = dbd_add(dbd, &rqst, &rply);
+                break;
+            case CNID_DBD_OP_GET:
+                ret = dbd_get(dbd, &rqst, &rply);
+                break;
+            case CNID_DBD_OP_RESOLVE:
+                ret = dbd_resolve(dbd, &rqst, &rply);
+                break;
+            case CNID_DBD_OP_LOOKUP:
+                ret = dbd_lookup(dbd, &rqst, &rply);
+                break;
+            case CNID_DBD_OP_UPDATE:
+                ret = dbd_update(dbd, &rqst, &rply);
+                break;
+            case CNID_DBD_OP_DELETE:
+                ret = dbd_delete(dbd, &rqst, &rply);
+                break;
+            case CNID_DBD_OP_GETSTAMP:
+                ret = dbd_getstamp(dbd, &rqst, &rply);
+                break;
+            case CNID_DBD_OP_REBUILD_ADD:
+                ret = dbd_rebuild_add(dbd, &rqst, &rply);
+                break;
+            default:
+                LOG(log_error, logtype_cnid, "loop: unknown op %d", rqst.op);
+                ret = -1;
+                break;
+            }
+            
+            if ((cret = comm_snd(&rply)) < 0 || ret < 0) {
+                dbif_txn_abort(dbd);
+                return -1;
+            }
+            
+            if (ret == 0 || cret == 0) {
+                if (dbif_txn_abort(dbd) < 0)
+                    return -1;
+            } else {
+                ret = dbif_txn_commit(dbd);
+                if (  ret < 0)
+                    return -1;
+                else if ( ret > 0 )
+                    /* We had a designated txn because we wrote to the db */
+                    count++;
+            }
+        } /* got a request */
+
+        /*
+          Shall we checkpoint bdb ?
+          "flush_interval" seconds passed ?
+        */
+        if (now > time_next_flush) {
+            LOG(log_info, logtype_cnid, "Checkpointing BerkeleyDB for volume '%s'", dbp->dir);
+            if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0)
+                return -1;
+            count = 0;
+            time_next_flush = now + dbp->flush_interval;
 
-#ifdef CNID_BACKEND_DBD_TXN
-        if (dbif_txn_begin() < 0)
-            return -1;
-#endif /* CNID_BACKEND_DBD_TXN */
-
-        memset(&rply, 0, sizeof(rply));
-        switch(rqst.op) {
-            /* ret gets set here */
-        case CNID_DBD_OP_OPEN:
-        case CNID_DBD_OP_CLOSE:
-            /* open/close are noops for now. */
-            rply.namelen = 0;
-            ret = 1;
-            break;
-        case CNID_DBD_OP_ADD:
-            ret = dbd_add(&rqst, &rply);
-            break;
-        case CNID_DBD_OP_GET:
-            ret = dbd_get(&rqst, &rply);
-            break;
-        case CNID_DBD_OP_RESOLVE:
-            ret = dbd_resolve(&rqst, &rply);
-            break;
-        case CNID_DBD_OP_LOOKUP:
-            ret = dbd_lookup(&rqst, &rply);
-            break;
-        case CNID_DBD_OP_UPDATE:
-            ret = dbd_update(&rqst, &rply);
-            break;
-        case CNID_DBD_OP_DELETE:
-            ret = dbd_delete(&rqst, &rply);
-            break;
-        case CNID_DBD_OP_GETSTAMP:
-            ret = dbd_getstamp(&rqst, &rply);
-            break;
-        case CNID_DBD_OP_REBUILD_ADD:
-            ret = dbd_rebuild_add(&rqst, &rply);
-            break;
-        default:
-            LOG(log_error, logtype_cnid, "loop: unknown op %d", rqst.op);
-            ret = -1;
-            break;
+            strftime(timebuf, 63, "%b %d %H:%M:%S.",localtime(&time_next_flush));
+            LOG(log_debug, logtype_cnid, "Checkpoint interval: %d seconds. Next checkpoint: %s",
+                dbp->flush_interval, timebuf);
         }
 
-        if ((cret = comm_snd(&rply)) < 0 || ret < 0) {
-#ifdef CNID_BACKEND_DBD_TXN
-            dbif_txn_abort();
-#endif /* CNID_BACKEND_DBD_TXN */
-            return -1;
-        }
-#ifdef CNID_BACKEND_DBD_TXN
-        if (ret == 0 || cret == 0) {
-            if (dbif_txn_abort() < 0)
-                return -1;
-        } else {
-            if (dbif_txn_commit() < 0)
+        /* 
+           Shall we checkpoint bdb ?
+           Have we commited "count" more changes than "flush_frequency" ?
+        */
+        if (count > dbp->flush_frequency) {
+            LOG(log_info, logtype_cnid, "Checkpointing BerkeleyDB after %d writes for volume '%s'", count, dbp->dir);
+            if (dbif_txn_checkpoint(dbd, 0, 0, 0) < 0)
                 return -1;
+            count = 0;
         }
-#endif /* CNID_BACKEND_DBD_TXN */
-    }
+    } /* while(1) */
 }
 
 /* ------------------------ */
@@ -283,7 +305,6 @@ int main(int argc, char *argv[])
 {
     struct db_param *dbp;
     int err = 0;
-    int ret;
     int lockfd, ctrlfd, clntfd;
     char *dir, *logconfig;
 
@@ -315,70 +336,38 @@ int main(int argc, char *argv[])
        only shut down after one second of inactivity. */
     block_sigs_onoff(1);
 
-    if ((dbp = db_param_read(dir)) == NULL)
+    if ((dbp = db_param_read(dir, CNID_DBD)) == NULL)
         exit(1);
+    LOG(log_maxdebug, logtype_cnid, "Finished parsing db_param config file");
 
-    if (dbif_env_init(dbp) < 0)
-        exit(2); /* FIXME: same exit code as failure for dbif_open() */
+    if (NULL == (dbd = dbif_init(".", "cnid2.db")))
+        exit(2);
 
-#ifdef CNID_BACKEND_DBD_TXN
-    if (dbif_txn_begin() < 0)
-        exit(6);
-#endif
+    if (dbif_env_open(dbd, dbp, DBOPTIONS) < 0)
+        exit(2); /* FIXME: same exit code as failure for dbif_open() */
+    LOG(log_debug, logtype_cnid, "Finished initializing BerkeleyDB environment");
 
-    if (dbif_open(dbp, 0) < 0) {
-#ifdef CNID_BACKEND_DBD_TXN
-        dbif_txn_abort();
-#endif
-        dbif_close();
+    if (dbif_open(dbd, dbp, 0) < 0) {
+        dbif_close(dbd);
         exit(2);
     }
+    LOG(log_debug, logtype_cnid, "Finished opening BerkeleyDB databases");
 
-#ifndef CNID_BACKEND_DBD_TXN
-    if (dbp->check && (ret = dbd_check(dir))) {
-        if (ret < 0) {
-            dbif_close();
-            exit(2);
-        }
-        dbif_closedb();
-        LOG(log_info, logtype_cnid, "main: re-opening, secondaries will be rebuilt. This may take some time");
-        if (dbif_open(dbp, 1) < 0) {
-            LOG(log_info, logtype_cnid, "main: re-opening databases failed");
-            dbif_close();
-            exit(2);
-        }
-        LOG(log_info, logtype_cnid, "main: rebuilt done");
-    }
-#endif
-
-    if (dbd_stamp() < 0) {
-#ifdef CNID_BACKEND_DBD_TXN
-        dbif_txn_abort();
-#endif
-        dbif_close();
+    if (dbd_stamp(dbd) < 0) {
+        dbif_close(dbd);
         exit(5);
     }
-#ifdef CNID_BACKEND_DBD_TXN
-    if (dbif_txn_commit() < 0)
-        exit(6);
-#endif
+    LOG(log_maxdebug, logtype_cnid, "Finished checking database stamp");
 
     if (comm_init(dbp, ctrlfd, clntfd) < 0) {
-        dbif_close();
+        dbif_close(dbd);
         exit(3);
     }
 
     if (loop(dbp) < 0)
         err++;
 
-#ifndef CNID_BACKEND_DBD_TXN
-    /* FIXME: Do we really need to sync before closing the DB? Just closing it
-       should be enough. */
-    if (dbif_sync() < 0)
-        err++;
-#endif
-
-    if (dbif_close() < 0)
+    if (dbif_close(dbd) < 0)
         err++;
 
     free_lock(lockfd);