X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Futils_db_query.c;h=e734358f80e5ff05cd0f3827122a2afd6726b1e9;hp=fcded6b414687f10d3773d7a42f58ad8c90581eb;hb=ec9ed6fe4108f7fd3d4ef84e887bb6d3dc022e14;hpb=9d3906a53e086d520b5ed71ca57118e8f589574b diff --git a/src/utils_db_query.c b/src/utils_db_query.c index fcded6b4..e734358f 100644 --- a/src/utils_db_query.c +++ b/src/utils_db_query.c @@ -25,6 +25,7 @@ **/ #include "collectd.h" + #include "common.h" #include "plugin.h" #include "configfile.h" @@ -54,6 +55,7 @@ struct udb_query_s /* {{{ */ char *name; char *statement; void *user_data; + char *plugin_instance_from; unsigned int min_version; unsigned int max_version; @@ -70,6 +72,7 @@ struct udb_result_preparation_area_s /* {{{ */ char **instances_buffer; char **values_buffer; char **metadata_buffer; + char *plugin_instance; struct udb_result_preparation_area_s *next; }; /* }}} */ @@ -78,6 +81,7 @@ typedef struct udb_result_preparation_area_s udb_result_preparation_area_t; struct udb_query_preparation_area_s /* {{{ */ { size_t column_num; + size_t plugin_instance_pos; char *host; char *plugin; char *db_name; @@ -122,7 +126,6 @@ static int udb_config_add_string (char ***ret_array, /* {{{ */ { char **array; size_t array_len; - int i; if (ci->values_num < 1) { @@ -131,7 +134,7 @@ static int udb_config_add_string (char ***ret_array, /* {{{ */ return (-1); } - for (i = 0; i < ci->values_num; i++) + for (int i = 0; i < ci->values_num; i++) { if (ci->values[i].type != OCONFIG_TYPE_STRING) { @@ -142,7 +145,7 @@ static int udb_config_add_string (char ***ret_array, /* {{{ */ } array_len = *ret_array_len; - array = (char **) realloc (*ret_array, + array = realloc (*ret_array, sizeof (char *) * (array_len + ci->values_num)); if (array == NULL) { @@ -151,7 +154,7 @@ static int udb_config_add_string (char ***ret_array, /* {{{ */ } *ret_array = array; - for (i = 0; i < ci->values_num; i++) + for (int i = 0; i < ci->values_num; i++) { array[array_len] = strdup (ci->values[i].value.string); if (array[array_len] == NULL) @@ -196,23 +199,21 @@ static int udb_result_submit (udb_result_t *r, /* {{{ */ udb_query_t const *q, udb_query_preparation_area_t *q_area) { value_list_t vl = VALUE_LIST_INIT; - size_t i; - int status; assert (r != NULL); assert (r_area->ds != NULL); assert (((size_t) r_area->ds->ds_num) == r->values_num); assert (r->values_num > 0); - vl.values = (value_t *) calloc (r->values_num, sizeof (value_t)); + vl.values = calloc (r->values_num, sizeof (*vl.values)); if (vl.values == NULL) { - ERROR ("db query utils: malloc failed."); + ERROR ("db query utils: calloc failed."); return (-1); } vl.values_len = r_area->ds->ds_num; - for (i = 0; i < r->values_num; i++) + for (size_t i = 0; i < r->values_num; i++) { char *value_str = r_area->values_buffer[i]; @@ -221,6 +222,7 @@ static int udb_result_submit (udb_result_t *r, /* {{{ */ ERROR ("db query utils: udb_result_submit: Parsing `%s' as %s failed.", value_str, DS_TYPE_TO_STRING (r_area->ds->ds[i].type)); errno = EINVAL; + free (vl.values); return (-1); } } @@ -230,11 +232,18 @@ static int udb_result_submit (udb_result_t *r, /* {{{ */ sstrncpy (vl.host, q_area->host, sizeof (vl.host)); sstrncpy (vl.plugin, q_area->plugin, sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, q_area->db_name, sizeof (vl.plugin_instance)); sstrncpy (vl.type, r->type, sizeof (vl.type)); + /* Set vl.plugin_instance */ + if (q->plugin_instance_from != NULL) { + sstrncpy (vl.plugin_instance, r_area->plugin_instance, sizeof (vl.plugin_instance)); + } + else { + sstrncpy (vl.plugin_instance, q_area->db_name, sizeof (vl.plugin_instance)); + } + /* Set vl.type_instance {{{ */ - if (r->instances_num <= 0) + if (r->instances_num == 0) { if (r->instance_prefix == NULL) vl.type_instance[0] = 0; @@ -286,9 +295,9 @@ static int udb_result_submit (udb_result_t *r, /* {{{ */ return (-ENOMEM); } - for (i = 0; i < r->metadata_num; i++) + for (size_t i = 0; i < r->metadata_num; i++) { - status = meta_data_add_string (vl.meta, r->metadata[i], + int status = meta_data_add_string (vl.meta, r->metadata[i], r_area->metadata_buffer[i]); if (status != 0) { @@ -332,19 +341,20 @@ static int udb_result_handle_result (udb_result_t *r, /* {{{ */ udb_result_preparation_area_t *r_area, udb_query_t const *q, char **column_values) { - size_t i; - assert (r && q_area && r_area); - for (i = 0; i < r->instances_num; i++) + for (size_t i = 0; i < r->instances_num; i++) r_area->instances_buffer[i] = column_values[r_area->instances_pos[i]]; - for (i = 0; i < r->values_num; i++) + for (size_t i = 0; i < r->values_num; i++) r_area->values_buffer[i] = column_values[r_area->values_pos[i]]; - for (i = 0; i < r->metadata_num; i++) + for (size_t i = 0; i < r->metadata_num; i++) r_area->metadata_buffer[i] = column_values[r_area->metadata_pos[i]]; + if (q->plugin_instance_from) + r_area->plugin_instance = column_values[q_area->plugin_instance_pos]; + return udb_result_submit (r, r_area, q, q_area); } /* }}} int udb_result_handle_result */ @@ -352,8 +362,6 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */ udb_result_preparation_area_t *prep_area, char **column_names, size_t column_num) { - size_t i; - if ((r == NULL) || (prep_area == NULL)) return (-EINVAL); @@ -383,10 +391,10 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */ BAIL_OUT (-1); } - if (((size_t) prep_area->ds->ds_num) != r->values_num) + if (prep_area->ds->ds_num != r->values_num) { ERROR ("db query utils: udb_result_prepare_result: The type `%s' " - "requires exactly %i value%s, but the configuration specifies %zu.", + "requires exactly %zu value%s, but the configuration specifies %zu.", r->type, prep_area->ds->ds_num, (prep_area->ds->ds_num == 1) ? "" : "s", r->values_num); @@ -402,7 +410,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */ = (size_t *) calloc (r->instances_num, sizeof (size_t)); if (prep_area->instances_pos == NULL) { - ERROR ("db query utils: udb_result_prepare_result: malloc failed."); + ERROR ("db query utils: udb_result_prepare_result: calloc failed."); BAIL_OUT (-ENOMEM); } @@ -410,7 +418,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */ = (char **) calloc (r->instances_num, sizeof (char *)); if (prep_area->instances_buffer == NULL) { - ERROR ("db query utils: udb_result_prepare_result: malloc failed."); + ERROR ("db query utils: udb_result_prepare_result: calloc failed."); BAIL_OUT (-ENOMEM); } } /* if (r->instances_num > 0) */ @@ -419,7 +427,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */ = (size_t *) calloc (r->values_num, sizeof (size_t)); if (prep_area->values_pos == NULL) { - ERROR ("db query utils: udb_result_prepare_result: malloc failed."); + ERROR ("db query utils: udb_result_prepare_result: calloc failed."); BAIL_OUT (-ENOMEM); } @@ -427,7 +435,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */ = (char **) calloc (r->values_num, sizeof (char *)); if (prep_area->values_buffer == NULL) { - ERROR ("db query utils: udb_result_prepare_result: malloc failed."); + ERROR ("db query utils: udb_result_prepare_result: calloc failed."); BAIL_OUT (-ENOMEM); } @@ -435,7 +443,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */ = (size_t *) calloc (r->metadata_num, sizeof (size_t)); if (prep_area->metadata_pos == NULL) { - ERROR ("db query utils: udb_result_prepare_result: malloc failed."); + ERROR ("db query utils: udb_result_prepare_result: calloc failed."); BAIL_OUT (-ENOMEM); } @@ -443,14 +451,14 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */ = (char **) calloc (r->metadata_num, sizeof (char *)); if (prep_area->metadata_buffer == NULL) { - ERROR ("db query utils: udb_result_prepare_result: malloc failed."); + ERROR ("db query utils: udb_result_prepare_result: calloc failed."); BAIL_OUT (-ENOMEM); } /* }}} */ - /* Determine the position of the instance columns {{{ */ - for (i = 0; i < r->instances_num; i++) + /* Determine the position of the plugin instance column {{{ */ + for (size_t i = 0; i < r->instances_num; i++) { size_t j; @@ -472,8 +480,9 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */ } } /* }}} for (i = 0; i < r->instances_num; i++) */ + /* Determine the position of the value columns {{{ */ - for (i = 0; i < r->values_num; i++) + for (size_t i = 0; i < r->values_num; i++) { size_t j; @@ -496,7 +505,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */ } /* }}} for (i = 0; i < r->values_num; i++) */ /* Determine the position of the metadata columns {{{ */ - for (i = 0; i < r->metadata_num; i++) + for (size_t i = 0; i < r->metadata_num; i++) { size_t j; @@ -524,22 +533,21 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */ static void udb_result_free (udb_result_t *r) /* {{{ */ { - size_t i; - if (r == NULL) return; sfree (r->type); + sfree (r->instance_prefix); - for (i = 0; i < r->instances_num; i++) + for (size_t i = 0; i < r->instances_num; i++) sfree (r->instances[i]); sfree (r->instances); - for (i = 0; i < r->values_num; i++) + for (size_t i = 0; i < r->values_num; i++) sfree (r->values[i]); sfree (r->values); - for (i = 0; i < r->metadata_num; i++) + for (size_t i = 0; i < r->metadata_num; i++) sfree (r->metadata[i]); sfree (r->metadata); @@ -553,7 +561,6 @@ static int udb_result_create (const char *query_name, /* {{{ */ { udb_result_t *r; int status; - int i; if (ci->values_num != 0) { @@ -562,13 +569,12 @@ static int udb_result_create (const char *query_name, /* {{{ */ ci->values_num, (ci->values_num == 1) ? "" : "s"); } - r = (udb_result_t *) malloc (sizeof (*r)); + r = calloc (1, sizeof (*r)); if (r == NULL) { - ERROR ("db query utils: malloc failed."); + ERROR ("db query utils: calloc failed."); return (-1); } - memset (r, 0, sizeof (*r)); r->type = NULL; r->instance_prefix = NULL; r->instances = NULL; @@ -578,7 +584,7 @@ static int udb_result_create (const char *query_name, /* {{{ */ /* Fill the `udb_result_t' structure.. */ status = 0; - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -657,6 +663,7 @@ static void udb_query_free_one (udb_query_t *q) /* {{{ */ sfree (q->name); sfree (q->statement); + sfree (q->plugin_instance_from); udb_result_free (q->results); @@ -675,7 +682,6 @@ int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */ udb_query_t *q; int status; - int i; if ((ret_query_list == NULL) || (ret_query_list_len == NULL)) return (-EINVAL); @@ -690,15 +696,17 @@ int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */ return (-1); } - q = (udb_query_t *) malloc (sizeof (*q)); + q = calloc (1, sizeof (*q)); if (q == NULL) { - ERROR ("db query utils: malloc failed."); + ERROR ("db query utils: calloc failed."); return (-1); } - memset (q, 0, sizeof (*q)); q->min_version = 0; q->max_version = UINT_MAX; + q->statement = NULL; + q->results = NULL; + q->plugin_instance_from = NULL; status = udb_config_set_string (&q->name, ci); if (status != 0) @@ -708,7 +716,7 @@ int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */ } /* Fill the `udb_query_t' structure.. */ - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -720,6 +728,8 @@ int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */ status = udb_config_set_uint (&q->min_version, child); else if (strcasecmp ("MaxVersion", child->key) == 0) status = udb_config_set_uint (&q->max_version, child); + else if (strcasecmp ("PluginInstanceFrom", child->key) == 0) + status = udb_config_set_string (&q->plugin_instance_from, child); /* Call custom callbacks */ else if (cb != NULL) @@ -764,7 +774,7 @@ int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */ { udb_query_t **temp; - temp = (udb_query_t **) realloc (query_list, + temp = realloc (query_list, sizeof (*query_list) * (query_list_len + 1)); if (temp == NULL) { @@ -793,12 +803,10 @@ int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */ void udb_query_free (udb_query_t **query_list, size_t query_list_len) /* {{{ */ { - size_t i; - if (query_list == NULL) return; - for (i = 0; i < query_list_len; i++) + for (size_t i = 0; i < query_list_len; i++) udb_query_free_one (query_list[i]); sfree (query_list); @@ -808,7 +816,6 @@ int udb_query_pick_from_list_by_name (const char *name, /* {{{ */ udb_query_t **src_list, size_t src_list_len, udb_query_t ***dst_list, size_t *dst_list_len) { - size_t i; int num_added; if ((name == NULL) || (src_list == NULL) || (dst_list == NULL) @@ -820,7 +827,7 @@ int udb_query_pick_from_list_by_name (const char *name, /* {{{ */ } num_added = 0; - for (i = 0; i < src_list_len; i++) + for (size_t i = 0; i < src_list_len; i++) { udb_query_t **tmp_list; size_t tmp_list_len; @@ -829,7 +836,7 @@ int udb_query_pick_from_list_by_name (const char *name, /* {{{ */ continue; tmp_list_len = *dst_list_len; - tmp_list = (udb_query_t **) realloc (*dst_list, (tmp_list_len + 1) + tmp_list = realloc (*dst_list, (tmp_list_len + 1) * sizeof (udb_query_t *)); if (tmp_list == NULL) { @@ -981,9 +988,7 @@ int udb_query_handle_result (udb_query_t const *q, /* {{{ */ #if defined(COLLECT_DEBUG) && COLLECT_DEBUG /* {{{ */ do { - size_t i; - - for (i = 0; i < prep_area->column_num; i++) + for (size_t i = 0; i < prep_area->column_num; i++) { DEBUG ("db query utils: udb_query_handle_result (%s, %s): " "column[%zu] = %s;", @@ -1044,9 +1049,7 @@ int udb_query_prepare_result (udb_query_t const *q, /* {{{ */ #if defined(COLLECT_DEBUG) && COLLECT_DEBUG do { - size_t i; - - for (i = 0; i < column_num; i++) + for (size_t i = 0; i < column_num; i++) { DEBUG ("db query utils: udb_query_prepare_result: " "query = %s; column[%zu] = %s;", @@ -1055,6 +1058,31 @@ int udb_query_prepare_result (udb_query_t const *q, /* {{{ */ } while (0); #endif + /* Determine the position of the PluginInstance column {{{ */ + if (q->plugin_instance_from != NULL) + { + size_t i; + + for (i = 0; i < column_num; i++) + { + if (strcasecmp (q->plugin_instance_from, column_names[i]) == 0) + { + prep_area->plugin_instance_pos = i; + break; + } + } + + if (i >= column_num) + { + ERROR ("db query utils: udb_query_prepare_result: " + "Column `%s' from `PluginInstanceFrom' could not be found.", + q->plugin_instance_from); + udb_query_finish_result (q, prep_area); + return (-ENOENT); + } + } + /* }}} */ + for (r = q->results, r_area = prep_area->result_prep_areas; r != NULL; r = r->next, r_area = r_area->next) { @@ -1084,17 +1112,16 @@ udb_query_allocate_preparation_area (udb_query_t *q) /* {{{ */ udb_result_preparation_area_t **next_r_area; udb_result_t *r; - q_area = malloc (sizeof (*q_area)); + q_area = calloc (1, sizeof (*q_area)); if (q_area == NULL) return NULL; - memset (q_area, 0, sizeof (*q_area)); next_r_area = &q_area->result_prep_areas; for (r = q->results; r != NULL; r = r->next) { udb_result_preparation_area_t *r_area; - r_area = malloc (sizeof (*r_area)); + r_area = calloc (1, sizeof (*r_area)); if (r_area == NULL) { udb_result_preparation_area_t *a = q_area->result_prep_areas; @@ -1110,8 +1137,6 @@ udb_query_allocate_preparation_area (udb_query_t *q) /* {{{ */ return NULL; } - memset (r_area, 0, sizeof (*r_area)); - *next_r_area = r_area; next_r_area = &r_area->next; }