From 48972087d132bca8221e01e0a556bcc39768dde4 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Wed, 24 Mar 2010 23:31:59 +0100 Subject: [PATCH] plugin: Introduced a concept of ``read groups''. Using a new parameter added to plugin_register_complex_read(), it's now possible to specify a group name for the registered callback. This name may later be used to unregister *all* callbacks belonging to that group using the newly added function plugin_unregister_read_group(). This might come in handy for plugins that register multiple read callbacks but do not want to keep track of all of them in order to be able to unregister them. --- src/apache.c | 3 ++- src/curl_json.c | 2 +- src/curl_xml.c | 2 +- src/java.c | 2 +- src/mysql.c | 3 ++- src/netapp.c | 2 +- src/onewire.c | 2 +- src/plugin.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/plugin.h | 3 ++- src/python.c | 3 ++- src/routeros.c | 4 ++-- src/snmp.c | 5 +++-- 12 files changed, 86 insertions(+), 14 deletions(-) diff --git a/src/apache.c b/src/apache.c index 39849e6e..3d6d957c 100644 --- a/src/apache.c +++ b/src/apache.c @@ -313,7 +313,8 @@ static int config_add (oconfig_item_t *ci) (st->host != NULL) ? st->host : hostname_g, (st->name != NULL) ? st->name : "default"), - status = plugin_register_complex_read (callback_name, + status = plugin_register_complex_read (/* group = */ NULL, + /* name = */ callback_name, /* callback = */ apache_read_host, /* interval = */ NULL, /* user_data = */ &ud); diff --git a/src/curl_json.c b/src/curl_json.c index 53e8abda..03ef6a34 100644 --- a/src/curl_json.c +++ b/src/curl_json.c @@ -673,7 +673,7 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */ ssnprintf (cb_name, sizeof (cb_name), "curl_json-%s-%s", db->instance, db->url); - plugin_register_complex_read (cb_name, cj_read, + plugin_register_complex_read (/* group = */ NULL, cb_name, cj_read, /* interval = */ NULL, &ud); } else diff --git a/src/curl_xml.c b/src/curl_xml.c index 240be662..c10955cb 100644 --- a/src/curl_xml.c +++ b/src/curl_xml.c @@ -870,7 +870,7 @@ static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */ ssnprintf (cb_name, sizeof (cb_name), "curl_xml-%s-%s", db->instance, db->url); - plugin_register_complex_read (cb_name, cx_read, + plugin_register_complex_read (/* group = */ NULL, cb_name, cx_read, /* interval = */ NULL, &ud); } else diff --git a/src/java.c b/src/java.c index 87b189fa..528ec9c4 100644 --- a/src/java.c +++ b/src/java.c @@ -1419,7 +1419,7 @@ static jint JNICALL cjni_api_register_read (JNIEnv *jvm_env, /* {{{ */ ud.data = (void *) cbi; ud.free_func = cjni_callback_info_destroy; - plugin_register_complex_read (cbi->name, cjni_read, + plugin_register_complex_read (/* group = */ NULL, cbi->name, cjni_read, /* interval = */ NULL, &ud); (*jvm_env)->DeleteLocalRef (jvm_env, o_read); diff --git a/src/mysql.c b/src/mysql.c index 30f5504a..c7b796b1 100644 --- a/src/mysql.c +++ b/src/mysql.c @@ -342,7 +342,8 @@ static int mysql_config (oconfig_item_t *ci) /* {{{ */ else sstrncpy (cb_name, "mysql", sizeof (cb_name)); - plugin_register_complex_read (cb_name, mysql_read, + plugin_register_complex_read (/* group = */ NULL, cb_name, + mysql_read, /* interval = */ NULL, &ud); } else diff --git a/src/netapp.c b/src/netapp.c index fc653582..317b0fe4 100644 --- a/src/netapp.c +++ b/src/netapp.c @@ -2559,7 +2559,7 @@ static int cna_config (oconfig_item_t *ci) { /* {{{ */ ud.data = host; ud.free_func = (void (*) (void *)) free_host_config; - plugin_register_complex_read (cb_name, + plugin_register_complex_read (/* group = */ NULL, cb_name, /* callback = */ cna_read, /* interval = */ (host->interval > 0) ? &interval : NULL, /* user data = */ &ud); diff --git a/src/onewire.c b/src/onewire.c index cae0d63d..462458c7 100644 --- a/src/onewire.c +++ b/src/onewire.c @@ -310,7 +310,7 @@ static int cow_init (void) if (ow_interval > 0) cb_interval.tv_sec = (time_t) ow_interval; - plugin_register_complex_read ("onewire", cow_read, + plugin_register_complex_read (/* group = */ NULL, "onewire", cow_read, &cb_interval, /* user data = */ NULL); plugin_register_shutdown ("onewire", cow_shutdown); diff --git a/src/plugin.c b/src/plugin.c index 1eed532c..a134446b 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -59,6 +59,7 @@ struct read_func_s #define rf_callback rf_super.cf_callback #define rf_udata rf_super.cf_udata callback_func_t rf_super; + char rf_group[DATA_MAX_NAME_LEN]; char rf_name[DATA_MAX_NAME_LEN]; int rf_type; struct timespec rf_interval; @@ -772,6 +773,7 @@ int plugin_register_read (const char *name, rf->rf_callback = (void *) callback; rf->rf_udata.data = NULL; rf->rf_udata.free_func = NULL; + rf->rf_group[0] = '\0'; sstrncpy (rf->rf_name, name, sizeof (rf->rf_name)); rf->rf_type = RF_SIMPLE; rf->rf_interval.tv_sec = 0; @@ -781,7 +783,7 @@ int plugin_register_read (const char *name, return (plugin_insert_read (rf)); } /* int plugin_register_read */ -int plugin_register_complex_read (const char *name, +int plugin_register_complex_read (const char *group, const char *name, plugin_read_cb callback, const struct timespec *interval, user_data_t *user_data) @@ -797,6 +799,10 @@ int plugin_register_complex_read (const char *name, memset (rf, 0, sizeof (read_func_t)); rf->rf_callback = (void *) callback; + if (group != NULL) + sstrncpy (rf->rf_group, group, sizeof (rf->rf_group)); + else + rf->rf_group[0] = '\0'; sstrncpy (rf->rf_name, name, sizeof (rf->rf_name)); rf->rf_type = RF_COMPLEX; if (interval != NULL) @@ -948,6 +954,67 @@ int plugin_unregister_read (const char *name) /* {{{ */ return (0); } /* }}} int plugin_unregister_read */ +static int compare_read_func_group (llentry_t *e, void *ud) /* {{{ */ +{ + read_func_t *rf = e->value; + char *group = ud; + + return strcmp (rf->rf_group, (const char *)group); +} /* }}} int compare_read_func_group */ + +int plugin_unregister_read_group (const char *group) /* {{{ */ +{ + llentry_t *le; + read_func_t *rf; + + int found = 0; + + if (group == NULL) + return (-ENOENT); + + pthread_mutex_lock (&read_lock); + + if (read_list == NULL) + { + pthread_mutex_unlock (&read_lock); + return (-ENOENT); + } + + while (42) + { + le = llist_search_custom (read_list, + compare_read_func_group, (void *)group); + + if (le == NULL) + break; + + ++found; + + llist_remove (read_list, le); + + rf = le->value; + assert (rf != NULL); + rf->rf_type = RF_REMOVE; + + llentry_destroy (le); + + DEBUG ("plugin_unregister_read_group: " + "Marked `%s' (group `%s') for removal.", + rf->rf_name, group); + } + + pthread_mutex_unlock (&read_lock); + + if (found == 0) + { + WARNING ("plugin_unregister_read_group: No such " + "group of read function: %s", group); + return (-ENOENT); + } + + return (0); +} /* }}} int plugin_unregister_read_group */ + int plugin_unregister_write (const char *name) { return (plugin_unregister (list_write, name)); diff --git a/src/plugin.h b/src/plugin.h index 868f44ab..8b9449ee 100644 --- a/src/plugin.h +++ b/src/plugin.h @@ -264,7 +264,7 @@ int plugin_register_init (const char *name, plugin_init_cb callback); int plugin_register_read (const char *name, int (*callback) (void)); -int plugin_register_complex_read (const char *name, +int plugin_register_complex_read (const char *group, const char *name, plugin_read_cb callback, const struct timespec *interval, user_data_t *user_data); @@ -284,6 +284,7 @@ int plugin_unregister_config (const char *name); int plugin_unregister_complex_config (const char *name); int plugin_unregister_init (const char *name); int plugin_unregister_read (const char *name); +int plugin_unregister_read_group (const char *group); int plugin_unregister_write (const char *name); int plugin_unregister_flush (const char *name); int plugin_unregister_shutdown (const char *name); diff --git a/src/python.c b/src/python.c index 5664b0c6..2f4f01e1 100644 --- a/src/python.c +++ b/src/python.c @@ -568,7 +568,8 @@ static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwd user_data->data = c; ts.tv_sec = interval; ts.tv_nsec = (interval - ts.tv_sec) * 1000000000; - plugin_register_complex_read(buf, cpy_read_callback, &ts, user_data); + plugin_register_complex_read(/* group = */ NULL, buf, + cpy_read_callback, &ts, user_data); return cpy_string_to_unicode_or_bytes(buf); } diff --git a/src/routeros.c b/src/routeros.c index 2512613c..a020692e 100644 --- a/src/routeros.c +++ b/src/routeros.c @@ -408,8 +408,8 @@ static int cr_config_router (oconfig_item_t *ci) /* {{{ */ user_data.data = router_data; user_data.free_func = (void *) cr_free_data; if (status == 0) - status = plugin_register_complex_read (read_name, cr_read, - /* interval = */ NULL, &user_data); + status = plugin_register_complex_read (/* group = */ NULL, read_name, + cr_read, /* interval = */ NULL, &user_data); if (status != 0) cr_free_data (router_data); diff --git a/src/snmp.c b/src/snmp.c index 00df3779..24707611 100644 --- a/src/snmp.c +++ b/src/snmp.c @@ -655,8 +655,9 @@ static int csnmp_config_add_host (oconfig_item_t *ci) if (hd->interval != 0) cb_interval.tv_sec = (time_t) hd->interval; - status = plugin_register_complex_read (cb_name, csnmp_read_host, - /* interval = */ &cb_interval, /* user_data = */ &cb_data); + status = plugin_register_complex_read (/* group = */ NULL, cb_name, + csnmp_read_host, /* interval = */ &cb_interval, + /* user_data = */ &cb_data); if (status != 0) { ERROR ("snmp plugin: Registering complex read function failed."); -- 2.11.0