Merge branch 'collectd-5.4' into collectd-5.5
authorRuben Kerkhof <ruben@rubenkerkhof.com>
Fri, 5 Aug 2016 11:12:03 +0000 (13:12 +0200)
committerRuben Kerkhof <ruben@rubenkerkhof.com>
Fri, 5 Aug 2016 11:12:03 +0000 (13:12 +0200)
src/daemon/plugin.c
src/network.c
src/pyvalues.c

index e723af0..1deabba 100644 (file)
@@ -1850,10 +1850,10 @@ void plugin_shutdown_all (void)
 {
        llentry_t *le;
 
-       stop_read_threads ();
-
        destroy_all_callbacks (&list_init);
 
+       stop_read_threads ();
+
        pthread_mutex_lock (&read_lock);
        llist_destroy (read_list);
        read_list = NULL;
@@ -1861,6 +1861,10 @@ void plugin_shutdown_all (void)
 
        destroy_read_heap ();
 
+       /* blocks until all write threads have shut down. */
+       stop_write_threads ();
+
+       /* ask all plugins to write out the state they kept. */
        plugin_flush (/* plugin = */ NULL,
                        /* timeout = */ 0,
                        /* identifier = */ NULL);
@@ -1890,8 +1894,6 @@ void plugin_shutdown_all (void)
                plugin_set_ctx (old_ctx);
        }
 
-       stop_write_threads ();
-
        /* Write plugins which use the `user_data' pointer usually need the
         * same data available to the flush callback. If this is the case, set
         * the free_function to NULL when registering the flush callback and to
index 26caa29..c6845eb 100644 (file)
@@ -498,7 +498,7 @@ static int network_dispatch_notification (notification_t *n) /* {{{ */
 } /* }}} int network_dispatch_notification */
 
 #if HAVE_LIBGCRYPT
-static void network_init_gcrypt (void) /* {{{ */
+static int network_init_gcrypt (void) /* {{{ */
 {
   gcry_error_t err;
 
@@ -506,7 +506,7 @@ static void network_init_gcrypt (void) /* {{{ */
    * Because you can't know in a library whether another library has
    * already initialized the library */
   if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
-    return;
+    return (0);
 
  /* http://www.gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
   * To ensure thread-safety, it's important to set GCRYCTL_SET_THREAD_CBS
@@ -520,7 +520,7 @@ static void network_init_gcrypt (void) /* {{{ */
   if (err)
   {
     ERROR ("network plugin: gcry_control (GCRYCTL_SET_THREAD_CBS) failed: %s", gcry_strerror (err));
-    abort ();
+    return (-1);
   }
 # endif
 
@@ -530,11 +530,12 @@ static void network_init_gcrypt (void) /* {{{ */
   if (err)
   {
     ERROR ("network plugin: gcry_control (GCRYCTL_INIT_SECMEM) failed: %s", gcry_strerror (err));
-    abort ();
+    return (-1);
   }
 
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED);
-} /* }}} void network_init_gcrypt */
+  return (0);
+} /* }}} int network_init_gcrypt */
 
 static gcry_cipher_hd_t network_get_aes256_cypher (sockent_t *se, /* {{{ */
     const void *iv, size_t iv_size, const char *username)
@@ -2077,7 +2078,12 @@ static int sockent_init_crypto (sockent_t *se) /* {{{ */
        {
                if (se->data.client.security_level > SECURITY_LEVEL_NONE)
                {
-                       network_init_gcrypt ();
+                       if (network_init_gcrypt () < 0)
+                       {
+                               ERROR ("network plugin: Cannot configure client socket with "
+                                               "security: Failed to initialize crypto library.");
+                               return (-1);
+                       }
 
                        if ((se->data.client.username == NULL)
                                        || (se->data.client.password == NULL))
@@ -2097,7 +2103,12 @@ static int sockent_init_crypto (sockent_t *se) /* {{{ */
        {
                if (se->data.server.security_level > SECURITY_LEVEL_NONE)
                {
-                       network_init_gcrypt ();
+                       if (network_init_gcrypt () < 0)
+                       {
+                               ERROR ("network plugin: Cannot configure server socket with "
+                                               "security: Failed to initialize crypto library.");
+                               return (-1);
+                       }
 
                        if (se->data.server.auth_file == NULL)
                        {
@@ -2909,6 +2920,11 @@ static int network_write (const data_set_t *ds, const value_list_t *vl,
 {
        int status;
 
+       /* listen_loop is set to non-zero in the shutdown callback, which is
+        * guaranteed to be called *after* all the write threads have been shut
+        * down. */
+       assert (listen_loop == 0);
+
        if (!check_send_okay (vl))
        {
 #if COLLECT_DEBUG
@@ -3548,7 +3564,11 @@ static int network_init (void)
        have_init = 1;
 
 #if HAVE_LIBGCRYPT
-       network_init_gcrypt ();
+       if (network_init_gcrypt () < 0)
+       {
+               ERROR ("network plugin: Failed to initialize crypto library.");
+               return (-1);
+       }
 #endif
 
        if (network_config_stats != 0)
index 78e6cf9..0ea81f8 100644 (file)
@@ -551,19 +551,22 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
        for (i = 0; i < size; ++i) {
                PyObject *item, *num;
                item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */
-               if (ds->ds->type == DS_TYPE_COUNTER) {
+               switch (ds->ds[i].type) {
+               case DS_TYPE_COUNTER:
                        num = PyNumber_Long(item); /* New reference. */
                        if (num != NULL) {
                                value[i].counter = PyLong_AsUnsignedLongLong(num);
                                Py_XDECREF(num);
                        }
-               } else if (ds->ds->type == DS_TYPE_GAUGE) {
+                       break;
+               case DS_TYPE_GAUGE:
                        num = PyNumber_Float(item); /* New reference. */
                        if (num != NULL) {
                                value[i].gauge = PyFloat_AsDouble(num);
                                Py_XDECREF(num);
                        }
-               } else if (ds->ds->type == DS_TYPE_DERIVE) {
+                       break;
+               case DS_TYPE_DERIVE:
                        /* This might overflow without raising an exception.
                         * Not much we can do about it */
                        num = PyNumber_Long(item); /* New reference. */
@@ -571,7 +574,8 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
                                value[i].derive = PyLong_AsLongLong(num);
                                Py_XDECREF(num);
                        }
-               } else if (ds->ds->type == DS_TYPE_ABSOLUTE) {
+                       break;
+               case DS_TYPE_ABSOLUTE:
                        /* This might overflow without raising an exception.
                         * Not much we can do about it */
                        num = PyNumber_Long(item); /* New reference. */
@@ -579,9 +583,10 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
                                value[i].absolute = PyLong_AsUnsignedLongLong(num);
                                Py_XDECREF(num);
                        }
-               } else {
+                       break;
+               default:
                        free(value);
-                       PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds->type, value_list.type);
+                       PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds[i].type, value_list.type);
                        return NULL;
                }
                if (PyErr_Occurred() != NULL) {
@@ -655,19 +660,22 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
        for (i = 0; i < size; ++i) {
                PyObject *item, *num;
                item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */
-               if (ds->ds->type == DS_TYPE_COUNTER) {
+               switch (ds->ds[i].type) {
+               case DS_TYPE_COUNTER:
                        num = PyNumber_Long(item); /* New reference. */
                        if (num != NULL) {
                                value[i].counter = PyLong_AsUnsignedLongLong(num);
                                Py_XDECREF(num);
                        }
-               } else if (ds->ds->type == DS_TYPE_GAUGE) {
+                       break;
+               case DS_TYPE_GAUGE:
                        num = PyNumber_Float(item); /* New reference. */
                        if (num != NULL) {
                                value[i].gauge = PyFloat_AsDouble(num);
                                Py_XDECREF(num);
                        }
-               } else if (ds->ds->type == DS_TYPE_DERIVE) {
+                       break;
+               case DS_TYPE_DERIVE:
                        /* This might overflow without raising an exception.
                         * Not much we can do about it */
                        num = PyNumber_Long(item); /* New reference. */
@@ -675,7 +683,8 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
                                value[i].derive = PyLong_AsLongLong(num);
                                Py_XDECREF(num);
                        }
-               } else if (ds->ds->type == DS_TYPE_ABSOLUTE) {
+                       break;
+               case DS_TYPE_ABSOLUTE:
                        /* This might overflow without raising an exception.
                         * Not much we can do about it */
                        num = PyNumber_Long(item); /* New reference. */
@@ -683,9 +692,10 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
                                value[i].absolute = PyLong_AsUnsignedLongLong(num);
                                Py_XDECREF(num);
                        }
-               } else {
+                       break;
+               default:
                        free(value);
-                       PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds->type, value_list.type);
+                       PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds[i].type, value_list.type);
                        return NULL;
                }
                if (PyErr_Occurred() != NULL) {