Ensure libdb handles are properly closed when terminating.
authorFredrik Tolf <fredrik@seatribe.se>
Sat, 18 Jun 2011 13:10:41 +0000 (15:10 +0200)
committerFredrik Tolf <fredrik@seatribe.se>
Sat, 18 Jun 2011 13:10:41 +0000 (15:10 +0200)
dbsrc.c
statserve.c
statserve.h

diff --git a/dbsrc.c b/dbsrc.c
index bb239ae..80a2202 100644 (file)
--- a/dbsrc.c
+++ b/dbsrc.c
@@ -103,6 +103,14 @@ static void dbidle(struct source *src)
     }
 }
 
+static void dbclose(struct source *src)
+{
+    struct dbsrc *d = src->pdata;
+    
+    d->db->close(d->db, 0);
+    d->env->close(d->env, 0);
+}
+
 static void enverror(const DB_ENV *env, const char *prefix, const char *msg)
 {
     flog(LOG_ERR, "dbsource: environment error: %s", msg);
@@ -118,10 +126,11 @@ struct source *mkdbsrc(char *path, char *envpath)
     omalloc(src);
     src->serve = dbserve;
     src->idle = dbidle;
+    src->close = dbclose;
     src->pdata = omalloc(d);
     if((ret = db_env_create(&d->env, 0)) != 0) {
        flog(LOG_ERR, "could not create bdb environment: %s", db_strerror(ret));
-       exit(1);
+       goto fail;
     }
     if(envpath) {
        d->envnm = sstrdup(envpath);
@@ -136,23 +145,32 @@ struct source *mkdbsrc(char *path, char *envpath)
     }
     if((ret = d->env->open(d->env, d->envnm, DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN, 0666)) != 0) {
        flog(LOG_ERR, "could not open bdb environment: %s", db_strerror(ret));
-       exit(1);
+       goto fail;
     }
     d->env->set_lk_detect(d->env, DB_LOCK_RANDOM);
     d->env->set_errcall(d->env, enverror);
     if((ret = db_create(&d->db, d->env, 0)) != 0) {
        flog(LOG_ERR, "could not create bdb database: %s", db_strerror(ret));
-       exit(1);
+       goto fail;
     }
     if(dbpagesize) {
        if((ret = d->db->set_pagesize(d->db, dbpagesize)) != 0) {
            flog(LOG_ERR, "could not set bdb page size (to %i): %s", dbpagesize, db_strerror(ret));
-           exit(1);
+           goto fail;
        }
     }
     if((ret = d->db->open(d->db, NULL, path, NULL, DB_HASH, DB_AUTO_COMMIT | DB_CREATE, 0666)) != 0) {
        flog(LOG_ERR, "could not open bdb database: %s", db_strerror(ret));
-       exit(1);
+       goto fail;
     }
     return(src);
+    
+fail:
+    if(d->db)
+       d->db->close(d->db, 0);
+    if(d->env)
+       d->env->close(d->env, 0);
+    free(d);
+    free(src);
+    return(NULL);
 }
index ab3b346..9bee73b 100644 (file)
@@ -3,6 +3,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
+#include <sys/socket.h>
 #include <ashd/req.h>
 #include <ashd/resp.h>
 #include <ashd/log.h>
@@ -84,6 +85,21 @@ static void listenloop(struct muth *muth, va_list args)
     }
 }
 
+static void sigterm(int sig)
+{
+    shutdown(0, SHUT_RDWR);
+}
+
+static void closeall(void)
+{
+    struct source *src;
+    
+    for(src = sources; src != NULL; src = src->next) {
+       if(src->close)
+           src->close(src);
+    }
+}
+
 int main(int argc, char **argv)
 {
     int c;
@@ -104,7 +120,10 @@ int main(int argc, char **argv)
     }
     last = NULL;
     while(optind < argc) {
-       src = parsesource(argv[optind++]);
+       if((src = parsesource(argv[optind++])) == NULL) {
+           closeall();
+           return(1);
+       }
        if(!sources)
            sources = src;
        if(last)
@@ -113,9 +132,13 @@ int main(int argc, char **argv)
     }
     if(!sources) {
        usage(stderr);
+       closeall();
        return(1);
     }
     mustart(listenloop, 0);
+    signal(SIGINT, sigterm);
+    signal(SIGTERM, sigterm);
     ioloop();
+    closeall();
     return(0);
 }
index b276bc0..507a8da 100644 (file)
@@ -15,6 +15,7 @@ struct source {
     struct source *next;
     struct fileinfo (*serve)(struct source *src, char *nm);
     void (*idle)(struct source *src);
+    void (*close)(struct source *src);
     void *pdata;
 };