]> arthur.barton.de Git - netatalk.git/blobdiff - etc/cnid_dbd/main.c
cnid dbd don't fall back to 1 sec timeout after an idle timer if active connections
[netatalk.git] / etc / cnid_dbd / main.c
index 0a3806f13429f293ecba123612d0f6eaab6c8576..dcb46511651fa4148fc5231e004c07ad442f9e78 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: main.c,v 1.6 2009-05-06 11:54:24 franklahm Exp $
+ * $Id: main.c,v 1.14 2009-10-19 07:46:35 didg Exp $
  *
  * Copyright (C) Joerg Lenneis 2003
  * Copyright (c) Frank Lahm 2009
@@ -77,23 +77,34 @@ static void block_sigs_onoff(int block)
 
   1: Success, if transactions are used commit.
   0: Failure, but we continue to serve requests. If transactions are used abort/rollback.
-  -1: Fatal error, either from the database or from the socket. Abort the transaction if applicable
+  -1: Fatal error, either from t
+  he database or from the socket. Abort the transaction if applicable
   (which might fail as well) and then exit.
 
   We always try to notify the client process about the outcome, the result field
   of the cnid_dbd_rply structure contains further details.
 
 */
+#ifndef min
+#define min(a,b)        ((a)<(b)?(a):(b))
+#endif
 
 static int loop(struct db_param *dbp)
 {
     struct cnid_dbd_rqst rqst;
     struct cnid_dbd_rply rply;
+    time_t timeout;
     int ret, cret;
     int count;
     time_t now, time_next_flush, time_last_rqst;
     char timebuf[64];
     static char namebuf[MAXPATHLEN + 1];
+    sigset_t set;
+
+    sigemptyset(&set);
+    sigprocmask(SIG_SETMASK, NULL, &set);
+    sigdelset(&set, SIGINT);
+    sigdelset(&set, SIGTERM);
 
     count = 0;
     now = time(NULL);
@@ -107,23 +118,29 @@ static int loop(struct db_param *dbp)
         dbp->flush_interval, timebuf);
 
     while (1) {
-        if ((cret = comm_rcv(&rqst)) < 0)
+        timeout = min(time_next_flush, time_last_rqst +dbp->idle_timeout);
+        if (timeout > now)
+            timeout -= now;
+        else
+            timeout = 1;
+
+        if ((cret = comm_rcv(&rqst, timeout, &set)) < 0)
             return -1;
 
         now = time(NULL);
 
         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)
+            if (exit_sig) {
                 /* Received signal (TERM|INT) */
                 return 0;
-            if (dbp->idle_timeout && comm_nbe() <= 0 && (now - time_last_rqst) > dbp->idle_timeout)
+            }
+            if (now - time_last_rqst >= dbp->idle_timeout && comm_nbe() <= 0) {
                 /* Idle timeout */
                 return 0;
+            }
+            /* still active connections, reset time_last_rqst */
+            time_last_rqst = now;
         } else {
             /* We got a request */
             time_last_rqst = now;
@@ -153,7 +170,7 @@ static int loop(struct db_param *dbp)
                 ret = dbd_update(dbd, &rqst, &rply);
                 break;
             case CNID_DBD_OP_DELETE:
-                ret = dbd_delete(dbd, &rqst, &rply);
+                ret = dbd_delete(dbd, &rqst, &rply, DBIF_CNID);
                 break;
             case CNID_DBD_OP_GETSTAMP:
                 ret = dbd_getstamp(dbd, &rqst, &rply);
@@ -189,7 +206,7 @@ static int loop(struct db_param *dbp)
           Shall we checkpoint bdb ?
           "flush_interval" seconds passed ?
         */
-        if (now > time_next_flush) {
+        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;
@@ -238,7 +255,7 @@ static void switch_to_user(char *dir)
 }
 
 /* ------------------------ */
-int get_lock(void)
+static int get_lock(void)
 {
     int lockfd;
     struct flock lock;
@@ -266,7 +283,7 @@ int get_lock(void)
 }
 
 /* ----------------------- */
-void set_signal(void)
+static void set_signal(void)
 {
     struct sigaction sv;
 
@@ -288,7 +305,7 @@ void set_signal(void)
 }
 
 /* ----------------------- */
-void free_lock(int lockfd)
+static void free_lock(int lockfd)
 {
     struct flock lock;
 
@@ -310,6 +327,7 @@ int main(int argc, char *argv[])
 
     set_processname("cnid_dbd");
 
+    /* FIXME: implement -d from cnid_metad */
     if (argc  != 5) {
         LOG(log_error, logtype_cnid, "main: not enough arguments");
         exit(1);
@@ -331,16 +349,14 @@ int main(int argc, char *argv[])
 
     set_signal();
 
-    /* SIGINT and SIGTERM are always off, unless we get a return code of 0 from
-       comm_rcv (no requests for one second, see above in loop()). That means we
-       only shut down after one second of inactivity. */
+    /* SIGINT and SIGTERM are always off, unless we are in pselect */
     block_sigs_onoff(1);
 
     if ((dbp = db_param_read(dir, CNID_DBD)) == NULL)
         exit(1);
     LOG(log_maxdebug, logtype_cnid, "Finished parsing db_param config file");
 
-    if (NULL == (dbd = dbif_init("cnid2.db")))
+    if (NULL == (dbd = dbif_init(".", "cnid2.db")))
         exit(2);
 
     if (dbif_env_open(dbd, dbp, DBOPTIONS) < 0)
@@ -370,6 +386,9 @@ int main(int argc, char *argv[])
     if (dbif_close(dbd) < 0)
         err++;
 
+    if (dbif_prep_upgrade(dir) < 0)
+        err++;
+
     free_lock(lockfd);
 
     if (err)