Merge pull request #1308 from mfournier/openldap-persistent-connection
authorMarc Fournier <marc.fournier@camptocamp.com>
Tue, 10 May 2016 08:24:29 +0000 (10:24 +0200)
committerMarc Fournier <marc.fournier@camptocamp.com>
Tue, 10 May 2016 08:24:29 +0000 (10:24 +0200)
Openldap: persistent connection + sane default timeout

src/collectd.conf.pod
src/openldap.c

index 23af31a..0853fff 100644 (file)
@@ -4766,8 +4766,9 @@ client configuration mechanisms. See ldap.conf(5) for the details.
 
 =item B<Timeout> I<Seconds>
 
-Sets the timeout value for ldap operations. Defaults to B<-1> which results in
-an infinite timeout.
+Sets the timeout value for ldap operations, in seconds. By default, the
+configured B<Interval> is used to set the timeout. Use B<-1> to disable
+(infinite timeout).
 
 =item B<Version> I<Version>
 
index 36a29f8..615aee3 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * collectd - src/openldap.c
  * Copyright (C) 2011       Kimo Rosenbaum
- * Copyright (C) 2014       Marc Fournier
+ * Copyright (C) 2014-2015  Marc Fournier
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -58,6 +58,9 @@ struct cldap_s /* {{{ */
 };
 typedef struct cldap_s cldap_t; /* }}} */
 
+static cldap_t **databases   = NULL;
+static size_t  databases_num = 0;
+
 static void cldap_free (cldap_t *st) /* {{{ */
 {
        if (st == NULL)
@@ -79,6 +82,13 @@ static int cldap_init_host (cldap_t *st) /* {{{ */
 {
        LDAP *ld;
        int rc;
+
+       if (st->state && st->ld)
+       {
+               DEBUG ("openldap plugin: Already connected to %s", st->url);
+               return (0);
+       }
+
        rc = ldap_initialize (&ld, st->url);
        if (rc != LDAP_SUCCESS)
        {
@@ -96,6 +106,8 @@ static int cldap_init_host (cldap_t *st) /* {{{ */
        ldap_set_option (st->ld, LDAP_OPT_TIMEOUT,
                &(const struct timeval){st->timeout, 0});
 
+       ldap_set_option (st->ld, LDAP_OPT_RESTART, LDAP_OPT_ON);
+
        if (st->cacert != NULL)
                ldap_set_option (st->ld, LDAP_OPT_X_TLS_CACERTFILE, st->cacert);
 
@@ -160,13 +172,9 @@ static void cldap_submit_value (const char *type, const char *type_instance, /*
        if ((st->host == NULL)
                        || (strcmp ("", st->host) == 0)
                        || (strcmp ("localhost", st->host) == 0))
-       {
                sstrncpy (vl.host, hostname_g, sizeof (vl.host));
-       }
        else
-       {
                sstrncpy (vl.host, st->host, sizeof (vl.host));
-       }
 
        sstrncpy (vl.plugin, "openldap", sizeof (vl.plugin));
        if (st->name != NULL)
@@ -236,6 +244,7 @@ static int cldap_read_host (user_data_t *ud) /* {{{ */
                ERROR ("openldap plugin: Failed to execute search: %s",
                                ldap_err2string (rc));
                ldap_msgfree (result);
+               st->state = 0;
                ldap_unbind_ext_s (st->ld, NULL, NULL);
                return (-1);
        }
@@ -533,7 +542,6 @@ static int cldap_read_host (user_data_t *ud) /* {{{ */
        }
 
        ldap_msgfree (result);
-       ldap_unbind_ext_s (st->ld, NULL, NULL);
        return (0);
 } /* }}} int cldap_read_host */
 
@@ -568,7 +576,7 @@ static int cldap_config_add (oconfig_item_t *ci) /* {{{ */
        }
 
        st->starttls = 0;
-       st->timeout = -1;
+       st->timeout = (long) (CDTIME_T_TO_MS(plugin_get_interval()) / 1000);
        st->verifyhost = 1;
        st->version = LDAP_VERSION3;
 
@@ -627,32 +635,47 @@ static int cldap_config_add (oconfig_item_t *ci) /* {{{ */
                }
 
                if ((status == 0) && (ludpp->lud_host != NULL))
-               {
                        st->host = strdup (ludpp->lud_host);
-               }
 
                ldap_free_urldesc (ludpp);
        }
 
        if (status == 0)
        {
-               user_data_t ud;
-               char callback_name[3*DATA_MAX_NAME_LEN];
-
-               memset (&ud, 0, sizeof (ud));
-               ud.data = st;
-
-               memset (callback_name, 0, sizeof (callback_name));
-               ssnprintf (callback_name, sizeof (callback_name),
-                               "openldap/%s/%s",
-                               (st->host != NULL) ? st->host : hostname_g,
-                               (st->name != NULL) ? st->name : "default"),
-
-               status = plugin_register_complex_read (/* group = */ NULL,
-                               /* name      = */ callback_name,
-                               /* callback  = */ cldap_read_host,
-                               /* interval  = */ 0,
-                               /* user_data = */ &ud);
+               cldap_t **temp;
+
+               temp = (cldap_t **) realloc (databases,
+                       sizeof (*databases) * (databases_num + 1));
+
+               if (temp == NULL)
+               {
+                       ERROR ("openldap plugin: realloc failed");
+                       status = -1;
+               }
+               else
+               {
+                       user_data_t ud;
+                       char callback_name[3*DATA_MAX_NAME_LEN];
+
+                       databases = temp;
+                       databases[databases_num] = st;
+                       databases_num++;
+
+                       memset (&ud, 0, sizeof (ud));
+                       ud.data = st;
+
+                       memset (callback_name, 0, sizeof (callback_name));
+                       ssnprintf (callback_name, sizeof (callback_name),
+                                       "openldap/%s/%s",
+                                       (st->host != NULL) ? st->host : hostname_g,
+                                       (st->name != NULL) ? st->name : "default"),
+
+                       status = plugin_register_complex_read (/* group = */ NULL,
+                                       /* name      = */ callback_name,
+                                       /* callback  = */ cldap_read_host,
+                                       /* interval  = */ 0,
+                                       /* user_data = */ &ud);
+               }
        }
 
        if (status != 0)
@@ -697,10 +720,24 @@ static int cldap_init (void) /* {{{ */
        return (0);
 } /* }}} int cldap_init */
 
+static int cldap_shutdown (void) /* {{{ */
+{
+       size_t i;
+
+       for (i = 0; i < databases_num; i++)
+               if (databases[i]->ld != NULL)
+                       ldap_unbind_ext_s (databases[i]->ld, NULL, NULL);
+       sfree (databases);
+       databases_num = 0;
+
+       return (0);
+} /* }}} int cldap_shutdown */
+
 void module_register (void) /* {{{ */
 {
        plugin_register_complex_config ("openldap", cldap_config);
        plugin_register_init ("openldap", cldap_init);
+       plugin_register_shutdown ("openldap", cldap_shutdown);
 } /* }}} void module_register */
 
 #if defined(__APPLE__)