This patch makes chunkd to use ncld_foo interface, so procedural
programming is now possible. Also, the code is shorter.

Signed-off-by: Pete Zaitcev <zait...@redhat.com>

---
 server/chunkd.h |    1 
 server/cldu.c   |  656 ++++++++++++++++------------------------------
 server/server.c |   18 -
 3 files changed, 253 insertions(+), 422 deletions(-)

diff --git a/server/chunkd.h b/server/chunkd.h
index cd83f7b..dd86cee 100644
--- a/server/chunkd.h
+++ b/server/chunkd.h
@@ -289,6 +289,7 @@ extern void cli_out_end(struct client *cli);
 extern void cli_in_end(struct client *cli);
 
 /* cldu.c */
+extern void cld_init(void);
 extern void cldu_add_host(const char *host, unsigned int port);
 extern int cld_begin(const char *thishost, const char *thisgroup, uint32_t nid,
                     struct geo *locp, void (*cb)(enum st_cld));
diff --git a/server/cldu.c b/server/cldu.c
index dbcf11d..4409fb4 100644
--- a/server/cldu.c
+++ b/server/cldu.c
@@ -27,16 +27,10 @@
 #include <string.h>
 #include <unistd.h>
 #include <poll.h>
-#include <netdb.h>
-#include <arpa/nameser.h>
-#include <netinet/in.h>
-#include <resolv.h>            /* must follow in.h, nameser.h */
 #include <errno.h>
-#include <cldc.h>
+#include <ncld.h>
 #include "chunkd.h"
 
-#define ALIGN8(n)      ((8 - ((n) & 7)) & 7)
-
 #define N_CLD          10      /* 5 * (v4+v6) */
 
 struct cld_host {
@@ -46,8 +40,8 @@ struct cld_host {
 
 struct cld_session {
        bool forced_hosts;              /* Administrator overrode default CLD */
-       bool sess_open;
-       struct cldc_udp *lib;           /* library state */
+       bool is_dead;
+       struct ncld_sess *nsess;        /* library state */
 
        int actx;               /* Active host cldv[actx] */
        struct cld_host cldv[N_CLD];
@@ -55,9 +49,8 @@ struct cld_session {
        struct timer timer;
 
        char *cfname;           /* /chunk-GROUP directory */
-       struct cldc_fh *cfh;    /* /chunk-GROUP directory fh */
        char *ffname;           /* /chunk-GROUP/NID */
-       struct cldc_fh *ffh;    /* /chunk-GROUP/NID, keep open for lock */
+       struct ncld_fh *ffh;    /* /chunk-GROUP/NID, keep open for lock */
        uint32_t nid;
        const char *ourhost;    /* N.B. points to some global data. */
        struct geo *ploc;       /* N.B. points to some global data. */
@@ -65,14 +58,7 @@ struct cld_session {
        void (*state_cb)(enum st_cld);
 };
 
-static int cldu_set_cldc(struct cld_session *sp, int newactive);
-static int cldu_new_sess(struct cldc_call_opts *carg, enum cle_err_codes errc);
-static int cldu_open_c_cb(struct cldc_call_opts *carg, enum cle_err_codes 
errc);
-static int cldu_close_c_cb(struct cldc_call_opts *carg, enum cle_err_codes 
errc);
-static int cldu_open_f_cb(struct cldc_call_opts *carg, enum cle_err_codes 
errc);
-static int cldu_lock_cb(struct cldc_call_opts *carg, enum cle_err_codes errc);
-static int cldu_put_cb(struct cldc_call_opts *carg, enum cle_err_codes errc);
-static int cldu_make_ffile(char **ret, struct cld_session *sp);
+static int cldu_set_cldc(struct cld_session *cs, int newactive);
 
 #define SVC "chunk"
 static char svc[] = SVC;
@@ -86,26 +72,26 @@ struct hail_log cldu_hail_log = {
  *
  * In theory we should at least look at priorities, if not weights. Maybe 
later.
  */
-static int cldu_nextactive(struct cld_session *sp)
+static int cldu_nextactive(struct cld_session *cs)
 {
        int i;
        int n;
 
-       if ((n = sp->actx + 1) >= N_CLD)
+       if ((n = cs->actx + 1) >= N_CLD)
                n = 0;
        for (i = 0; i < N_CLD; i++) {
-               if (sp->cldv[n].known)
+               if (cs->cldv[n].known)
                        return n;
                if (++n >= N_CLD)
                        n = 0;
        }
        /* Full circle, end on the old actx */
-       return sp->actx;
+       return cs->actx;
 }
 
 static int cldu_setgroup(struct cld_session *sp, const char *thisgroup,
                         uint32_t thisnid, const char *thishost,
-                        struct geo *locp)
+                        struct geo *loc)
 {
        size_t cnlen;
        size_t mlen;
@@ -138,378 +124,70 @@ static int cldu_setgroup(struct cld_session *sp, const 
char *thisgroup,
 
        sp->nid = thisnid;
        sp->ourhost = thishost;
-       sp->ploc = locp;
+       sp->ploc = loc;
 
        return 0;
 }
 
-static bool cldu_event(int fd, short events, void *userdata)
-{
-       struct cld_session *sp = userdata;
-       int rc;
-
-       if (!sp->lib) {
-               applog(LOG_WARNING, "Stray UDP event");
-               return true; /* continue main loop; do NOT terminate server */
-       }
-
-       rc = cldc_udp_receive_pkt(sp->lib);
-       if (rc) {
-               applog(LOG_INFO, "cldc_udp_receive_pkt failed: %d", rc);
-               /*
-                * Reacting to ICMP messages is a bad idea, because
-                *  - it makes us loop hard in case CLD is down, unless we
-                *    insert additional tricky timeouts
-                *  - it deals poorly with transient problems like CLD reboots
-                */
-#if 0
-               if (rc == -ECONNREFUSED) {      /* ICMP tells us */
-                       int newactive;
-                       /* P3 */ applog(LOG_INFO, "Restarting session");
-                       // timer_del(&sp->tm);
-                       cldc_kill_sess(sp->lib->sess);
-                       sp->lib->sess = NULL;
-                       newactive = cldu_nextactive(sp);
-                       if (cldu_set_cldc(sp, newactive))
-                               return true; /* continue main loop */
-                       // timer_add(&sp->tm, &cldc_to_delay);
-               }
-               return true; /* continue main loop; do NOT terminate server */
-#endif
-       }
-
-       srv_poll_ready(fd);
-
-       return true;    /* continue main loop; do NOT terminate server */
-}
-
 static void cldu_timer_event(struct timer *timer)
 {
-       struct cld_session *sp = timer->userdata;
-       struct cldc_udp *udp = sp->lib;
-
-       if (udp->cb)
-               udp->cb(udp->sess, udp->cb_private);
-}
-
-static bool cldu_p_timer_ctl(void *priv, bool add,
-                            int (*cb)(struct cldc_session *, void *),
-                            void *cb_priv, time_t secs)
-{
-       struct cld_session *sp = priv;
+       struct cld_session *cs = timer->userdata;
+       int newactive;
 
-       if (add) {
-               sp->lib->cb = cb;
-               sp->lib->cb_private = cb_priv;
-               timer_add(&sp->timer, time(NULL) + secs);
-       } else
-               timer_del(&sp->timer);
+       if (cs->is_dead) {
+               /* This would be the perfect time to call cs->state_cb. XXX */
 
-       return true;
-}
+               if (debugging)
+                       applog(LOG_DEBUG, "Reopening Chunk in %s", cs->ffname);
 
-static int cldu_p_pkt_send(void *priv, const void *addr, size_t addrlen,
-                              const void *buf, size_t buflen)
-{
-       struct cld_session *sp = priv;
-       return cldc_udp_pkt_send(sp->lib, addr, addrlen, buf, buflen);
+               ncld_sess_close(cs->nsess);
+               cs->nsess = NULL;
+               cs->ffh = NULL;                 /* closed automatically */
+               cs->is_dead = false;
+               newactive = cldu_nextactive(cs);
+               if (cldu_set_cldc(cs, newactive)) {
+                       /* Oops, should not happen. Just loop, then... */
+                       timer_add(&cs->timer, time(NULL) + 30);
+                       return;
+               }
+       }
 }
 
-static void cldu_p_event(void *priv, struct cldc_session *csp,
-                        struct cldc_fh *fh, uint32_t what)
+static void cldu_sess_event(void *priv, uint32_t what)
 {
-       struct cld_session *sp = priv;
-       int newactive;
+       struct cld_session *cs = priv;
 
        if (what == CE_SESS_FAILED) {
-               sp->sess_open = false;
-               if (sp->lib->sess != csp)
-                       applog(LOG_ERR, "Stray session failed, sid " SIDFMT,
-                              SIDARG(csp->sid));
-               else
+               /*
+                * In ncld, we are not allowed to free the session structures
+                * from an event (it's wages of all-conquering 100% reliable
+                * ncld_close_sess), so we bounce that off to a thread. Which
+                * we do not have, so we steal a timer for an erzatz thread.
+                */
+               if (cs->nsess) {
                        applog(LOG_ERR, "Session failed, sid " SIDFMT,
-                              SIDARG(csp->sid));
-               // timer_del(&sp->tm);
-               sp->lib->sess = NULL;
-               newactive = cldu_nextactive(sp);
-               if (cldu_set_cldc(sp, newactive))
-                       return;
-               // timer_add(&sp->tm, &cldc_to_delay);
+                              SIDARG(cs->nsess->udp->sess->sid));
+               } else {
+                       applog(LOG_ERR, "Session open failed");
+               }
+               cs->is_dead = true;
+               timer_add(&cs->timer, time(NULL) + 1);
        } else {
-               if (csp)
+               if (cs)
                        applog(LOG_INFO, "cldc event 0x%x sid " SIDFMT,
-                              what, SIDARG(csp->sid));
+                              what, SIDARG(cs->nsess->udp->sess->sid));
                else
                        applog(LOG_INFO, "cldc event 0x%x no sid", what);
        }
 }
 
-static struct cldc_ops cld_ops = {
-       .timer_ctl =    cldu_p_timer_ctl,
-       .pkt_send =     cldu_p_pkt_send,
-       .event =        cldu_p_event,
-};
-
-/*
- * Open the library, start its session, and reguster its socket with libevent.
- * Our session remains consistent in case of an error in this function,
- * so that we can continue and retry meaningfuly.
- */
-static int cldu_set_cldc(struct cld_session *sp, int newactive)
-{
-       struct cldc_host *hp;
-       struct cldc_udp *lib;
-       struct cldc_call_opts copts;
-       int rc;
-       struct server_poll *spoll;
-
-       if (sp->lib) {
-               if (sp->lib->fd >= 0)
-                       srv_poll_del(sp->lib->fd);
-               cldc_udp_free(sp->lib);
-               sp->lib = NULL;
-       }
-
-       sp->actx = newactive;
-       if (!sp->cldv[sp->actx].known) {
-               applog(LOG_ERR, "No CLD hosts");
-               goto err_addr;
-       }
-       hp = &sp->cldv[sp->actx].h;
-
-       rc = cldc_udp_new(hp->host, hp->port, &sp->lib);
-       if (rc) {
-               applog(LOG_ERR, "cldc_udp_new(%s,%u) error: %d",
-                      hp->host, hp->port, rc);
-               goto err_lib_new;
-       }
-       lib = sp->lib;
-
-       if (debugging)
-               applog(LOG_INFO, "Selected CLD host %s port %u",
-                      hp->host, hp->port);
-
-       spoll = calloc(1, sizeof(*spoll));
-       if (!spoll)
-               goto err_sess;
-
-       spoll->fd = sp->lib->fd;
-       spoll->events = POLLIN;
-       spoll->cb = cldu_event;
-       spoll->userdata = sp;
-
-       g_hash_table_insert(chunkd_srv.fd_info, GINT_TO_POINTER(sp->lib->fd),
-                           spoll);
-
-       memset(&copts, 0, sizeof(struct cldc_call_opts));
-       copts.cb = cldu_new_sess;
-       copts.private = sp;
-       rc = cldc_new_sess(&cld_ops, &copts, lib->addr, lib->addr_len,
-                          "tabled", "tabled", sp, &lib->sess);
-       if (rc) {
-               applog(LOG_INFO,
-                      "Failed to start CLD session on host %s port %u",
-                      hp->host, hp->port);
-               goto err_sess;
-       }
-
-       // if (debugging)
-       //      lib->sess->verbose = true;
-
-       return 0;
-
-err_sess:
-       cldc_udp_free(sp->lib);
-       sp->lib = NULL;
-err_lib_new:
-err_addr:
-       return -1;
-}
-
-static int cldu_new_sess(struct cldc_call_opts *carg, enum cle_err_codes errc)
-{
-       struct cld_session *sp = carg->private;
-       struct cldc_call_opts copts;
-       int rc;
-
-       if (errc != CLE_OK) {
-               applog(LOG_INFO, "New CLD session creation failed: %d", errc);
-               return 0;
-       }
-
-       sp->sess_open = true;
-       applog(LOG_INFO, "New CLD session created, sid " SIDFMT,
-              SIDARG(sp->lib->sess->sid));
-
-       /*
-        * First, make sure the base directory exists.
-        */
-       memset(&copts, 0, sizeof(copts));
-       copts.cb = cldu_open_c_cb;
-       copts.private = sp;
-       rc = cldc_open(sp->lib->sess, &copts, sp->cfname,
-                      COM_READ | COM_WRITE | COM_CREATE | COM_DIRECTORY,
-                      CE_MASTER_FAILOVER | CE_SESS_FAILED, &sp->cfh);
-       if (rc) {
-               applog(LOG_ERR, "cldc_open(%s) call error: %d\n",
-                      sp->cfname, rc);
-       }
-       return 0;
-}
-
-static int cldu_open_c_cb(struct cldc_call_opts *carg, enum cle_err_codes errc)
-{
-       struct cld_session *sp = carg->private;
-       struct cldc_call_opts copts;
-       int rc;
-
-       if (errc != CLE_OK) {
-               applog(LOG_ERR, "CLD open(%s) failed: %d", sp->cfname, errc);
-               return 0;
-       }
-       if (sp->cfh == NULL) {
-               applog(LOG_ERR, "CLD open(%s) failed: NULL fh", sp->cfname);
-               return 0;
-       }
-       if (!sp->cfh->valid) {
-               applog(LOG_ERR, "CLD open(%s) failed: invalid fh", sp->cfname);
-               return 0;
-       }
-
-       /*
-        * We don't use directory handle to open files in it, so close it.
-        */
-       memset(&copts, 0, sizeof(copts));
-       copts.cb = cldu_close_c_cb;
-       copts.private = sp;
-       rc = cldc_close(sp->cfh, &copts);
-       if (rc) {
-               applog(LOG_ERR, "cldc_close call error %d", rc);
-       }
-
-       return 0;
-}
-
-static int cldu_close_c_cb(struct cldc_call_opts *carg, enum cle_err_codes 
errc)
-{
-       struct cld_session *sp = carg->private;
-       struct cldc_call_opts copts;
-       int rc;
-
-       if (errc != CLE_OK) {
-               applog(LOG_ERR, "CLD close(%s) failed: %d", sp->cfname, errc);
-               return 0;
-       }
-
-       /*
-        * Then, create the membership file for us.
-        *
-        * It is a bit racy to create a file like this, applications can see
-        * an empty file, or a file with stale contents. But what to do?
-        */
-       memset(&copts, 0, sizeof(copts));
-       copts.cb = cldu_open_f_cb;
-       copts.private = sp;
-       rc = cldc_open(sp->lib->sess, &copts, sp->ffname,
-                      COM_WRITE | COM_LOCK | COM_CREATE,
-                      CE_MASTER_FAILOVER | CE_SESS_FAILED, &sp->ffh);
-       if (rc) {
-               applog(LOG_ERR, "cldc_open(%s) call error: %d\n",
-                      sp->ffname, rc);
-       }
-       return 0;
-}
-
-static int cldu_open_f_cb(struct cldc_call_opts *carg, enum cle_err_codes errc)
-{
-       struct cld_session *sp = carg->private;
-       struct cldc_call_opts copts;
-       int rc;
-
-       if (errc != CLE_OK) {
-               applog(LOG_ERR, "CLD open(%s) failed: %d", sp->ffname, errc);
-               return 0;
-       }
-       if (sp->ffh == NULL) {
-               applog(LOG_ERR, "CLD open(%s) failed: NULL fh", sp->ffname);
-               return 0;
-       }
-       if (!sp->ffh->valid) {
-               applog(LOG_ERR, "CLD open(%s) failed: invalid fh", sp->ffname);
-               return 0;
-       }
-
-       if (debugging)
-               applog(LOG_DEBUG, "CLD file \"%s\" created", sp->ffname);
-
-       /*
-        * Lock the file, in case two hosts got the same NID.
-        */
-       memset(&copts, 0, sizeof(copts));
-       copts.cb = cldu_lock_cb;
-       copts.private = sp;
-       rc = cldc_lock(sp->ffh, &copts, 0, false);
-       if (rc) {
-               applog(LOG_ERR, "cldc_lock call error %d", rc);
-       }
-
-       return 0;
-}
-
-static int cldu_lock_cb(struct cldc_call_opts *carg, enum cle_err_codes errc)
-{
-       struct cld_session *sp = carg->private;
-       char *buf = NULL; /* stupid gcc 4.4.1 throws a warning */
-       int len;
-       struct cldc_call_opts copts;
-       int rc;
-
-       if (errc != CLE_OK) {
-               applog(LOG_ERR, "CLD lock(%s) failed: %d", sp->ffname, errc);
-               return 0;
-       }
-
-       if (cldu_make_ffile(&buf, sp))
-               return 0;
-       len = strlen(buf);
-
-       memset(&copts, 0, sizeof(copts));
-       copts.cb = cldu_put_cb;
-       copts.private = sp;
-       rc = cldc_put(sp->ffh, &copts, buf, len);
-       if (rc) {
-               applog(LOG_ERR, "cldc_put(%s) call error: %d\n",
-                      sp->ffname, rc);
-       }
-
-       free(buf);
-
-       return 0;
-}
-
-static int cldu_put_cb(struct cldc_call_opts *carg, enum cle_err_codes errc)
-{
-       struct cld_session *sp = carg->private;
-       // struct cldc_call_opts copts;
-       // int rc;
-
-       if (errc != CLE_OK) {
-               applog(LOG_ERR, "CLD put(%s) failed: %d", sp->ffname, errc);
-               return 0;
-       }
-
-       if (debugging)
-               applog(LOG_DEBUG, "CLD file \"%s\" written", sp->ffname);
-
-       return 0;
-}
-
 /*
  * Create the file with our parameters in memory, return as ret.
  */
-static int cldu_make_ffile(char **ret, struct cld_session *sp)
+static int cldu_make_ffile(char **ret, struct cld_session *cs)
 {
        GList *str_list = NULL;
+       struct geo *loc = cs->ploc;
        char *buf;
        char *str;
        size_t len;
@@ -517,9 +195,9 @@ static int cldu_make_ffile(char **ret, struct cld_session 
*sp)
        int rc;
 
        rc = asprintf(&str,
-               "<Chunk>\r\n"
-               " <NID>%u</NID>\r\n",
-               sp->nid);
+                     "<Chunk>\r\n"
+                     " <NID>%u</NID>\r\n",
+                     cs->nid);
        if (rc == -1) {
                applog(LOG_ERR, "OOM in asprintf\n");
                goto error;
@@ -536,7 +214,7 @@ static int cldu_make_ffile(char **ret, struct cld_session 
*sp)
 
                host = cfg->node;
                if (host == NULL || host[0] == 0)
-                       host = sp->ourhost;
+                       host = cs->ourhost;
 
                rc = asprintf(&str,
                        " <Socket>\r\n"
@@ -559,9 +237,9 @@ static int cldu_make_ffile(char **ret, struct cld_session 
*sp)
                "  <Rack>%s</Rack>\r\n"
                " </Geo>\r\n"
                "</Chunk>\r\n",
-               sp->ploc->area ? sp->ploc->area : "-",
-               sp->ploc->zone ? sp->ploc->zone : "-",
-               sp->ploc->rack ? sp->ploc->rack : "-");
+               loc->area ? loc->area : "-",
+               loc->zone ? loc->zone : "-",
+               loc->rack ? loc->rack : "-");
        if (rc == -1) {
                applog(LOG_ERR, "OOM in asprintf\n");
                goto error;
@@ -597,10 +275,156 @@ error:
 }
 
 /*
+ * Open the library, start its session, and reguster its socket with libevent.
+ * Our session remains consistent in case of an error in this function,
+ * so that we can continue and retry meaningfuly.
+ */
+static int cldu_set_cldc(struct cld_session *cs, int newactive)
+{
+       struct cldc_host *hp;
+       struct ncld_fh *cfh;    /* /chunk-GROUP directory fh */
+       struct timespec tm;
+       char *buf = NULL; /* stupid gcc 4.4.1 throws a warning */
+       int len;
+       int error;
+       int rc;
+
+       if (cs->nsess) {
+               ncld_sess_close(cs->nsess);
+               cs->nsess = NULL;
+       }
+
+       cs->actx = newactive;
+       if (!cs->cldv[cs->actx].known) {
+               applog(LOG_ERR, "No CLD hosts");
+               goto err_addr;
+       }
+       hp = &cs->cldv[cs->actx].h;
+
+       if (debugging)
+               applog(LOG_INFO, "Selected CLD host %s port %u",
+                      hp->host, hp->port);
+
+       cs->nsess = ncld_sess_open(hp->host, hp->port, &error,
+                                  cldu_sess_event, cs, "tabled", "tabled");
+       if (cs->nsess == NULL) {
+               if (error < 1000) {
+                       applog(LOG_ERR, "ncld_sess_open(%s,%u) error: %s",
+                              hp->host, hp->port, strerror(error));
+               } else {
+                       applog(LOG_ERR, "ncld_sess_open(%s,%u) error: %d",
+                              hp->host, hp->port, error);
+               }
+               goto err_nsess;
+       }
+
+       applog(LOG_INFO, "New CLD session created, sid " SIDFMT,
+              SIDARG(cs->nsess->udp->sess->sid));
+
+       /*
+        * First, make sure the base directory exists.
+        */
+       cfh = ncld_open(cs->nsess, cs->cfname,
+                       COM_READ | COM_WRITE | COM_CREATE | COM_DIRECTORY,
+                       &error, 0 /* CE_MASTER_FAILOVER | CE_SESS_FAILED */,
+                       NULL, NULL);
+       if (!cfh) {
+               applog(LOG_ERR, "CLD open(%s) failed: %d", cs->cfname, error);
+               goto err_copen;
+       }
+
+       /*
+        * We don't use directory handle to open files in it, so close it.
+        */
+       ncld_close(cfh);
+
+       /*
+        * Then, create the membership file for us.
+        *
+        * It is a bit racy to create a file like this, applications can see
+        * an empty file, or a file with stale contents. But what to do?
+        */
+       cs->ffh = ncld_open(cs->nsess, cs->ffname,
+                           COM_WRITE | COM_LOCK | COM_CREATE,
+                           &error, 0 /* CE_MASTER_FAILOVER | CE_SESS_FAILED */,
+                           NULL, NULL);
+       if (cs->ffh == NULL) {
+               applog(LOG_ERR, "CLD open(%s) failed: NULL fh", cs->ffname);
+               goto err_fopen;
+       }
+
+       if (debugging)
+               applog(LOG_DEBUG, "CLD file \"%s\" created", cs->ffname);
+
+       /*
+        * Lock the file, in case two hosts got the same NID.
+        */
+       for (;;) {
+               rc = ncld_trylock(cs->ffh);
+               if (!rc)
+                       break;
+
+               applog(LOG_ERR, "CLD lock(%s) failed: %d", cs->ffname, rc);
+               if (rc != CLE_LOCK_CONFLICT + 1100)
+                       goto err_lock;
+
+               /*
+                * The usual reason why we get a lock conflict is
+                * restarting too quickly and hitting the previous lock
+                * that is going to disappear soon.
+                */
+               tm.tv_sec = 10;
+               tm.tv_nsec = 0;
+               nanosleep(&tm, NULL);
+       }
+
+       if (cldu_make_ffile(&buf, cs))
+               goto err_buf;
+       len = strlen(buf);
+
+       rc = ncld_write(cs->ffh, buf, len);
+       if (rc) {
+               applog(LOG_ERR, "CLD put(%s) failed: %d", cs->ffname, rc);
+               goto err_write;
+       }
+
+       free(buf);
+
+       if (debugging)
+               applog(LOG_DEBUG, "CLD file \"%s\" written", cs->ffname);
+
+       /*
+        * At this point we just hang here with cs->ffh open and locked
+        * until session fails or we shut down completely.
+        */
+       return 0;
+
+err_write:
+err_buf:
+err_lock:
+       ncld_close(cs->ffh);    /* session-close closes these, maybe drop */
+err_fopen:
+err_copen:
+       ncld_sess_close(cs->nsess);
+       cs->nsess = NULL;
+err_nsess:
+err_addr:
+       return -1;
+}
+
+/*
  */
 static struct cld_session ses;
 
 /*
+ * Global and 1-instance initialization.
+ */
+void cld_init()
+{
+       ncld_init();
+}
+
+/*
  * This initiates our sole session with a CLD instance.
  *
  * Mostly due to our laziness and lack of need, thishost and locp are saved
@@ -610,10 +434,10 @@ static struct cld_session ses;
 int cld_begin(const char *thishost, const char *thisgroup, uint32_t nid,
              struct geo *locp, void (*cb)(enum st_cld))
 {
+       static struct cld_session *cs = &ses;
 
        if (!nid)
                return 0;
-       cldc_init();
 
        /*
         * As long as we permit pre-seeding lists of CLD hosts,
@@ -621,16 +445,16 @@ int cld_begin(const char *thishost, const char 
*thisgroup, uint32_t nid,
         * as cld_end terminates it right, we can call cld_begin again.
         */
        // memset(&ses, 0, sizeof(struct cld_session));
-       ses.state_cb = cb;
+       cs->state_cb = cb;
 
-       timer_init(&ses.timer, "chunkd_cldu_timer", cldu_timer_event, &ses);
+       timer_init(&cs->timer, "chunkd_cldu_timer", cldu_timer_event, cs);
 
-       if (cldu_setgroup(&ses, thisgroup, nid, thishost, locp)) {
+       if (cldu_setgroup(cs, thisgroup, nid, thishost, locp)) {
                /* Already logged error */
                goto err_group;
        }
 
-       if (!ses.forced_hosts) {
+       if (!cs->forced_hosts) {
                GList *tmp, *host_list = NULL;
                int i;
 
@@ -646,9 +470,9 @@ int cld_begin(const char *thishost, const char *thisgroup, 
uint32_t nid,
                for (tmp = host_list; tmp; tmp = tmp->next) {
                        struct cldc_host *hp = tmp->data;
                        if (i < N_CLD) {
-                               memcpy(&ses.cldv[i].h, hp,
+                               memcpy(&cs->cldv[i].h, hp,
                                       sizeof(struct cldc_host));
-                               ses.cldv[i].known = 1;
+                               cs->cldv[i].known = 1;
                                i++;
                        } else {
                                free(hp->host);
@@ -665,7 +489,7 @@ int cld_begin(const char *thishost, const char *thisgroup, 
uint32_t nid,
         * -- Actually, it only works when recovering from CLD failure.
         *    Thereafter, any slave CLD redirects us to the master.
         */
-       if (cldu_set_cldc(&ses, 0)) {
+       if (cldu_set_cldc(cs, 0)) {
                /* Already logged error */
                goto err_net;
        }
@@ -678,41 +502,14 @@ err_group:
        return -1;
 }
 
-void cld_end(void)
-{
-       int i;
-
-       if (!ses.nid)
-               return;
-
-       if (ses.lib) {
-               // if (ses.sess_open)   /* kill it always, include half-open */
-               cldc_kill_sess(ses.lib->sess);
-               if (ses.lib->fd >= 0)
-                       srv_poll_del(ses.lib->fd);
-               cldc_udp_free(ses.lib);
-               ses.lib = NULL;
-       }
-
-       if (!ses.forced_hosts) {
-               for (i = 0; i < N_CLD; i++) {
-                       if (ses.cldv[i].known)
-                               free(ses.cldv[i].h.host);
-               }
-       }
-
-       free(ses.cfname);
-       free(ses.ffname);
-}
-
 void cldu_add_host(const char *hostname, unsigned int port)
 {
-       static struct cld_session *sp = &ses;
+       static struct cld_session *cs = &ses;
        struct cld_host *hp;
        int i;
 
        for (i = 0; i < N_CLD; i++) {
-               hp = &sp->cldv[i];
+               hp = &cs->cldv[i];
                if (!hp->known)
                        break;
        }
@@ -724,5 +521,36 @@ void cldu_add_host(const char *hostname, unsigned int port)
                return;
        hp->known = 1;
 
-       sp->forced_hosts = true;
+       cs->forced_hosts = true;
 }
+
+void cld_end(void)
+{
+       static struct cld_session *cs = &ses;
+       int i;
+
+       if (!cs->nid)
+               return;
+
+       timer_del(&cs->timer);
+
+       if (cs->nsess) {
+               ncld_sess_close(cs->nsess);
+               cs->nsess = NULL;
+       }
+
+       if (!cs->forced_hosts) {
+               for (i = 0; i < N_CLD; i++) {
+                       if (cs->cldv[i].known) {
+                               free(cs->cldv[i].h.host);
+                               cs->cldv[i].known = false;
+                       }
+               }
+       }
+
+       free(cs->cfname);
+       cs->cfname = NULL;
+       free(cs->ffname);
+       cs->ffname = NULL;
+}
+
diff --git a/server/server.c b/server/server.c
index 5b34725..b2a30bc 100644
--- a/server/server.c
+++ b/server/server.c
@@ -1756,6 +1756,8 @@ int main (int argc, char *argv[])
        SSL_CTX_set_mode(ssl_ctx, SSL_CTX_get_mode(ssl_ctx) |
                         SSL_MODE_ENABLE_PARTIAL_WRITE);
 
+       cld_init();
+
        /*
         * Next, read master configuration. This should be done as
         * early as possible, so that tunables are available.
@@ -1817,12 +1819,6 @@ int main (int argc, char *argv[])
                goto err_out_fs;
        }
 
-       if (cld_begin(chunkd_srv.ourhost, chunkd_srv.group, chunkd_srv.nid,
-                     &chunkd_srv.loc, NULL)) {
-               rc = 1;
-               goto err_out_cld;
-       }
-
        /* set up server networking */
        for (tmpl = chunkd_srv.listeners; tmpl; tmpl = tmpl->next) {
                rc = net_open(tmpl->data);
@@ -1830,16 +1826,22 @@ int main (int argc, char *argv[])
                        goto err_out_listen;
        }
 
+       if (cld_begin(chunkd_srv.ourhost, chunkd_srv.group, chunkd_srv.nid,
+                     &chunkd_srv.loc, NULL)) {
+               rc = 1;
+               goto err_out_cld;
+       }
+
        applog(LOG_INFO, "initialized");
 
        rc = main_loop();
 
        applog(LOG_INFO, "shutting down");
 
+       /* cld_end(); */
+err_out_cld:
        /* net_close(); */
 err_out_listen:
-       cld_end();
-err_out_cld:
        fs_close();
 err_out_fs:
        cmd = CHK_CMD_EXIT;
--
To unsubscribe from this list: send the line "unsubscribe hail-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to