Merge branch 'collectd-5.6'
[collectd.git] / src / perl.c
index 9f7b869..4a11d6c 100644 (file)
@@ -22,6 +22,7 @@
  *
  * Authors:
  *   Sebastian Harl <sh at tokkee.org>
+ *   Pavel Rochnyak <pavel2000 ngs.ru>
  **/
 
 /*
@@ -77,8 +78,9 @@
 #define PLUGIN_LOG      4
 #define PLUGIN_NOTIF    5
 #define PLUGIN_FLUSH    6
+#define PLUGIN_FLUSH_ALL 7  /* For collectd-5.6 only */
 
-#define PLUGIN_TYPES    7
+#define PLUGIN_TYPES    8
 
 #define PLUGIN_CONFIG   254
 #define PLUGIN_DATASET  255
@@ -183,6 +185,8 @@ extern char **environ;
  * private variables
  */
 
+static _Bool register_legacy_flush = 1;
+
 /* if perl_threads != NULL perl_threads->head must
  * point to the "base" thread */
 static c_ithread_list_t *perl_threads = NULL;
@@ -1177,6 +1181,19 @@ static int pplugin_call (pTHX_ int type, ...)
                XPUSHs (sv_2mortal (newSVnv (CDTIME_T_TO_DOUBLE (timeout))));
                XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0)));
        }
+       else if (PLUGIN_FLUSH_ALL == type) {
+               cdtime_t timeout;
+               subname = "Collectd::plugin_call_all";
+               /*
+                * $_[0] = $timeout;
+                * $_[1] = $identifier;
+                */
+               timeout = va_arg (ap, cdtime_t);
+
+               XPUSHs (sv_2mortal (newSViv ((IV)PLUGIN_FLUSH)));
+               XPUSHs (sv_2mortal (newSVnv (CDTIME_T_TO_DOUBLE (timeout))));
+               XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0)));
+       }
        else if (PLUGIN_INIT == type) {
                subname = "Collectd::plugin_call_all";
                XPUSHs (sv_2mortal (newSViv ((IV)type)));
@@ -1228,6 +1245,10 @@ static void c_ithread_destroy (c_ithread_t *ithread)
        assert (NULL != perl_threads);
 
        PERL_SET_CONTEXT (aTHX);
+       /* Mark as running to avoid deadlock:
+          c_ithread_destroy -> log_debug -> perl_log()
+       */
+       ithread->running = 1;
        log_debug ("Shutting down Perl interpreter %p...", aTHX);
 
 #if COLLECT_DEBUG
@@ -1628,7 +1649,7 @@ static void _plugin_register_generic_userdata (pTHX, int type, const char *desc)
 {
        int ret   = 0;
        user_data_t userdata;
-       char cb_name[DATA_MAX_NAME_LEN];
+       char *pluginname;
 
        dXSARGS;
 
@@ -1649,11 +1670,13 @@ static void _plugin_register_generic_userdata (pTHX, int type, const char *desc)
                XSRETURN_EMPTY;
        }
 
+       /* Use pluginname as-is to allow flush a single perl plugin */
+       pluginname = SvPV_nolen (ST (0));
+
        log_debug ("Collectd::plugin_register_%s: "
                        "plugin = \"%s\", sub = \"%s\"",
-                       desc, SvPV_nolen (ST (0)), SvPV_nolen (ST (1)));
+                       desc, pluginname, SvPV_nolen (ST (1)));
 
-       ssnprintf (cb_name, sizeof (cb_name), "perl/%s", SvPV_nolen (ST (0)));
        memset(&userdata, 0, sizeof(userdata));
        userdata.data = strdup(SvPV_nolen (ST (1)));
        userdata.free_func = free;
@@ -1661,22 +1684,28 @@ static void _plugin_register_generic_userdata (pTHX, int type, const char *desc)
        if (PLUGIN_READ == type) {
                ret = plugin_register_complex_read(
                        "perl",                /* group */
-                       cb_name,
+                       pluginname,
                        perl_read,
                        plugin_get_interval(), /* Default interval */
                        &userdata);
        }
        else if (PLUGIN_WRITE == type) {
-               ret = plugin_register_write(cb_name, perl_write, &userdata);
+               ret = plugin_register_write(pluginname, perl_write, &userdata);
        }
        else if (PLUGIN_LOG == type) {
-               ret = plugin_register_log(cb_name, perl_log, &userdata);
+               ret = plugin_register_log(pluginname, perl_log, &userdata);
        }
        else if (PLUGIN_NOTIF == type) {
-               ret = plugin_register_notification(cb_name, perl_notify, &userdata);
+               ret = plugin_register_notification(pluginname, perl_notify, &userdata);
        }
        else if (PLUGIN_FLUSH == type) {
-               ret = plugin_register_flush(cb_name, perl_flush, &userdata);
+               if (1 == register_legacy_flush) { /* For collectd-5.7 only, #1731 */
+                       register_legacy_flush = 0;
+                       ret = plugin_register_flush("perl", perl_flush, /* user_data = */ NULL);
+               }
+
+               if (0 == ret)
+                       ret = plugin_register_flush(pluginname, perl_flush, &userdata);
        }
        else {
                ret = -1;
@@ -1725,8 +1754,6 @@ typedef int perl_unregister_function_t(const char *name);
 static void _plugin_unregister_generic (pTHX,
                                perl_unregister_function_t *unreg, const char *desc)
 {
-       char cb_name[DATA_MAX_NAME_LEN];
-
        dXSARGS;
 
        if (1 != items) {
@@ -1743,9 +1770,7 @@ static void _plugin_unregister_generic (pTHX,
        log_debug ("Collectd::plugin_unregister_%s: plugin = \"%s\"",
                        desc, SvPV_nolen (ST (0)));
 
-       ssnprintf (cb_name, sizeof (cb_name), "perl/%s", SvPV_nolen (ST (0)));
-
-       unreg(cb_name);
+       unreg(SvPV_nolen (ST (0)));
 
        XSRETURN_EMPTY;
 
@@ -2314,6 +2339,11 @@ static int perl_flush (cdtime_t timeout, const char *identifier,
 
                aTHX = t->interp;
        }
+
+       /* For collectd-5.6 only, #1731 */
+       if (user_data == NULL || user_data->data == NULL)
+               return pplugin_call (aTHX_ PLUGIN_FLUSH_ALL, timeout, identifier);
+
        return pplugin_call (aTHX_ PLUGIN_FLUSH, user_data->data, timeout, identifier);
 } /* static int perl_flush (const int) */
 
@@ -2342,6 +2372,7 @@ static int perl_shutdown (void)
                        aTHX, perl_threads->number_of_threads);
 
        plugin_unregister_init ("perl");
+       plugin_unregister_flush ("perl"); /* For collectd-5.6 only, #1731 */
 
        ret = pplugin_call (aTHX_ PLUGIN_SHUTDOWN);
 
@@ -2368,10 +2399,6 @@ static int perl_shutdown (void)
                        pthread_kill (thr->pthread, SIGTERM);
                        ERROR ("perl shutdown: Thread hangs inside Perl. Thread killed.");
                }
-               /* Mark as running to avoid deadlock:
-                  c_ithread_destroy -> log_debug -> perl_log()
-               */
-               thr->running = 1; 
                c_ithread_destroy (thr);
        }
 
@@ -2779,6 +2806,8 @@ static int perl_config (oconfig_item_t *ci)
                        current_status = perl_config_includedir (aTHX_ c);
                else if (0 == strcasecmp (c->key, "Plugin"))
                        current_status = perl_config_plugin (aTHX_ c);
+               else if (0 == strcasecmp (c->key, "RegisterLegacyFlush"))
+                       cf_util_get_boolean (c, &register_legacy_flush);
                else
                {
                        log_warn ("Ignoring unknown config key \"%s\".", c->key);