static int ethstat_add_map(const oconfig_item_t *ci) /* {{{ */ { value_map_t *map; int status; char *key; if ((ci->values_num < 2) || (ci->values_num > 3) || (ci->values[0].type != OCONFIG_TYPE_STRING) || (ci->values[1].type != OCONFIG_TYPE_STRING) || ((ci->values_num == 3) && (ci->values[2].type != OCONFIG_TYPE_STRING))) { ERROR("ethstat plugin: The %s option requires " "two or three string arguments.", ci->key); return -1; } key = strdup(ci->values[0].value.string); if (key == NULL) { ERROR("ethstat plugin: strdup(3) failed."); return ENOMEM; } map = calloc(1, sizeof(*map)); if (map == NULL) { sfree(key); ERROR("ethstat plugin: calloc failed."); return ENOMEM; } sstrncpy(map->type, ci->values[1].value.string, sizeof(map->type)); if (ci->values_num == 3) sstrncpy(map->type_instance, ci->values[2].value.string, sizeof(map->type_instance)); if (value_map == NULL) { value_map = c_avl_create((int (*)(const void *, const void *))strcmp); if (value_map == NULL) { sfree(map); sfree(key); ERROR("ethstat plugin: c_avl_create() failed."); return -1; } } status = c_avl_insert(value_map, /* key = */ key, /* value = */ map); if (status != 0) { if (status > 0) ERROR("ethstat plugin: Multiple mappings for \"%s\".", key); else ERROR("ethstat plugin: c_avl_insert(\"%s\") failed.", key); sfree(map); sfree(key); return -1; } return 0; } /* }}} int ethstat_add_map */
/* * Public functions */ lookup_t *lookup_create (lookup_class_callback_t cb_user_class, /* {{{ */ lookup_obj_callback_t cb_user_obj, lookup_free_class_callback_t cb_free_class, lookup_free_obj_callback_t cb_free_obj) { lookup_t *obj = calloc (1, sizeof (*obj)); if (obj == NULL) { ERROR ("utils_vl_lookup: calloc failed."); return (NULL); } obj->by_type_tree = c_avl_create ((int (*) (const void *, const void *)) strcmp); if (obj->by_type_tree == NULL) { ERROR ("utils_vl_lookup: c_avl_create failed."); sfree (obj); return (NULL); } obj->cb_user_class = cb_user_class; obj->cb_user_obj = cb_user_obj; obj->cb_free_class = cb_free_class; obj->cb_free_obj = cb_free_obj; return (obj); } /* }}} lookup_t *lookup_create */
static c_avl_tree_t *zone_scandir(DIR *procdir) { pid_t pid; dirent_t *direntp; psinfo_t psinfo; c_avl_tree_t *tree; zone_stats_t *stats; if (!(tree = c_avl_create(zone_compare))) { WARNING("zone plugin: Failed to create tree"); return (NULL); } rewinddir(procdir); while ((direntp = readdir(procdir))) { char const *pidstr = direntp->d_name; if (pidstr[0] == '.') /* skip "." and ".." */ continue; pid = atoi(pidstr); if (pid == 0 || pid == 2 || pid == 3) continue; /* skip sched, pageout and fsflush */ if (zone_read_procfile(pidstr, "psinfo", &psinfo, sizeof(psinfo_t)) != 0) continue; stats = zone_find_stats(tree, psinfo.pr_zoneid); if (stats) { stats->pctcpu += psinfo.pr_pctcpu; stats->pctmem += psinfo.pr_pctmem; } } return (tree); }
static int statsd_init (void) /* {{{ */ { pthread_mutex_lock (&metrics_lock); if (metrics_tree == NULL) metrics_tree = c_avl_create ((void *) strcmp); if (!network_thread_running) { int status; status = pthread_create (&network_thread, /* attr = */ NULL, statsd_network_thread, /* args = */ NULL); if (status != 0) { char errbuf[1024]; pthread_mutex_unlock (&metrics_lock); ERROR ("statsd plugin: pthread_create failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (status); } } network_thread_running = 1; pthread_mutex_unlock (&metrics_lock); return (0); } /* }}} int statsd_init */
int uc_init (void) { if (cache_tree == NULL) cache_tree = c_avl_create ((int (*) (const void *, const void *)) cache_compare); return (0); } /* int uc_init */
static int ethstat_add_map (const oconfig_item_t *ci) /* {{{ */ { value_map_t *map; int status; if ((ci->values_num < 2) || (ci->values_num > 3) || (ci->values[0].type != OCONFIG_TYPE_STRING) || (ci->values[1].type != OCONFIG_TYPE_STRING) || ((ci->values_num == 3) && (ci->values[2].type != OCONFIG_TYPE_STRING))) { ERROR ("ethstat plugin: The %s option requires " "two or three string arguments.", ci->key); return (-1); } map = malloc (sizeof (*map)); if (map == NULL) { ERROR ("ethstat plugin: malloc(3) failed."); return (ENOMEM); } memset (map, 0, sizeof (*map)); sstrncpy (map->type, ci->values[1].value.string, sizeof (map->type)); if (ci->values_num == 2) sstrncpy (map->type_instance, ci->values[2].value.string, sizeof (map->type_instance)); if (value_map == NULL) { value_map = c_avl_create ((void *) strcmp); if (value_map == NULL) { sfree (map); ERROR ("ethstat plugin: c_avl_create() failed."); return (-1); } } status = c_avl_insert (value_map, /* key = */ ci->values[0].value.string, /* value = */ map); if (status != 0) { sfree (map); if (status > 0) ERROR ("ethstat plugin: Multiple mappings for \"%s\".", ci->values[0].value.string); else ERROR ("ethstat plugin: c_avl_insert(\"%s\") failed.", ci->values[0].value.string); return (-1); } return (0); } /* }}} int ethstat_add_map */
static int statsd_handle_set (statsd_config_t *conf, char const *name, /* {{{ */ char const *set_key_orig) { statsd_metric_t *metric = NULL; char *set_key; int status; pthread_mutex_lock (&conf->metrics_lock); metric = statsd_metric_lookup_unsafe (conf, name, STATSD_SET); if (metric == NULL) { pthread_mutex_unlock (&conf->metrics_lock); return (-1); } /* Make sure metric->set exists. */ if (metric->set == NULL) metric->set = c_avl_create ((void *) strcmp); if (metric->set == NULL) { pthread_mutex_unlock (&conf->metrics_lock); ERROR ("statsd plugin: c_avl_create failed."); return (-1); } set_key = strdup (set_key_orig); if (set_key == NULL) { pthread_mutex_unlock (&conf->metrics_lock); ERROR ("statsd plugin: strdup failed."); return (-1); } status = c_avl_insert (metric->set, set_key, /* value = */ NULL); if (status < 0) { pthread_mutex_unlock (&conf->metrics_lock); if (status < 0) ERROR ("statsd plugin: c_avl_insert (\"%s\") failed with status %i.", set_key, status); sfree (set_key); return (-1); } else if (status > 0) /* key already exists */ { sfree (set_key); } metric->updates_num++; pthread_mutex_unlock (&conf->metrics_lock); return (0); } /* }}} int statsd_handle_set */
static by_type_entry_t *lu_search_by_type (lookup_t *obj, /* {{{ */ char const *type, _Bool allocate_if_missing) { by_type_entry_t *by_type; char *type_copy; int status; status = c_avl_get (obj->by_type_tree, type, (void *) &by_type); if (status == 0) return (by_type); if (!allocate_if_missing) return (NULL); type_copy = strdup (type); if (type_copy == NULL) { ERROR ("utils_vl_lookup: strdup failed."); return (NULL); } by_type = malloc (sizeof (*by_type)); if (by_type == NULL) { ERROR ("utils_vl_lookup: malloc failed."); sfree (type_copy); return (NULL); } memset (by_type, 0, sizeof (*by_type)); by_type->wildcard_plugin_list = NULL; by_type->by_plugin_tree = c_avl_create ((void *) strcmp); if (by_type->by_plugin_tree == NULL) { ERROR ("utils_vl_lookup: c_avl_create failed."); sfree (by_type); sfree (type_copy); return (NULL); } status = c_avl_insert (obj->by_type_tree, /* key = */ type_copy, /* value = */ by_type); assert (status <= 0); /* >0 => entry exists => race condition. */ if (status != 0) { ERROR ("utils_vl_lookup: c_avl_insert failed."); c_avl_destroy (by_type->by_plugin_tree); sfree (by_type); sfree (type_copy); return (NULL); } return (by_type); } /* }}} by_type_entry_t *lu_search_by_type */
int ut_config (const oconfig_item_t *ci) { int i; int status = 0; threshold_t th; if (ci->values_num != 0) { ERROR ("threshold values: The `Threshold' block may not have any " "arguments."); return (-1); } if (threshold_tree == NULL) { threshold_tree = c_avl_create ((void *) strcmp); if (threshold_tree == NULL) { ERROR ("ut_config: c_avl_create failed."); return (-1); } } memset (&th, '\0', sizeof (th)); th.warning_min = NAN; th.warning_max = NAN; th.failure_min = NAN; th.failure_max = NAN; for (i = 0; i < ci->children_num; i++) { oconfig_item_t *option = ci->children + i; status = 0; if (strcasecmp ("Type", option->key) == 0) status = ut_config_type (&th, option); else if (strcasecmp ("Plugin", option->key) == 0) status = ut_config_plugin (&th, option); else if (strcasecmp ("Host", option->key) == 0) status = ut_config_host (&th, option); else { WARNING ("threshold values: Option `%s' not allowed here.", option->key); status = -1; } if (status != 0) break; } return (status); } /* int um_config */
static int basic_aggregator_read (aggregator_definition_t *agg) { int aggid; c_avl_tree_t *ds_data; int status = 0; /* Check if we already have data in the cache */ if(NULL == instances_of_types_tree) return(0); ds_data = c_avl_create ((void *) strcmp); for(aggid=0; aggid < agg->type_list_size; aggid++) { if(NULL == agg->type_list[aggid]) continue; if(agg->is_alltypesof[aggid]) { char **names; int i; if(0 == basic_aggregator_config_aggregator_get_all_instances_of_type(&names, agg->type_list[aggid])) { if(names) { for(i=0; names[i]; i++) { status = basic_aggregator_update_aggregator(names[i], ds_data, agg); sfree(names[i]); if(status != 0) continue; } sfree(names); } } } else { status = basic_aggregator_update_aggregator(agg->type_list[aggid], ds_data, agg); } if(status == 1) { free(agg->type_list[aggid]); agg->type_list[aggid]=NULL; } if(status > 0) continue; if(status < 0) { free_data_tree(ds_data); return(status); } } if(0 != basic_aggregator_submit_resultvalue(agg, ds_data)) { free_data_tree(ds_data); return(-1); } /* Free the tree */ free_data_tree(ds_data); return (0); }
static statsd_config_t *statsd_config_alloc(void) { statsd_config_t *conf = NULL; conf = malloc(sizeof(statsd_config_t)); if (NULL == conf) { ERROR ("statsd plugin: malloc failed."); return NULL; } memset(conf, 0, sizeof(statsd_config_t)); pthread_mutex_init (&conf->metrics_lock, /* attr = */ NULL); conf->metrics_tree = c_avl_create ((void *) strcmp); return conf; }
static int gmond_init(void) /* {{{ */ { create_sockets( &mc_send_sockets, &mc_send_sockets_num, (mc_receive_group != NULL) ? mc_receive_group : MC_RECEIVE_GROUP_DEFAULT, (mc_receive_port != NULL) ? mc_receive_port : MC_RECEIVE_PORT_DEFAULT, /* listen = */ 0); staging_tree = c_avl_create((int (*)(const void *, const void *))strcmp); if (staging_tree == NULL) { ERROR("gmond plugin: c_avl_create failed."); return (-1); } mc_receive_thread_start(); return (0); } /* }}} int gmond_init */
static int statsd_init(void) /* {{{ */ { pthread_mutex_lock(&metrics_lock); if (metrics_tree == NULL) metrics_tree = c_avl_create((int (*)(const void *, const void *))strcmp); if (!network_thread_running) { int status; status = pthread_create(&network_thread, /* attr = */ NULL, statsd_network_thread, /* args = */ NULL); if (status != 0) { pthread_mutex_unlock(&metrics_lock); ERROR("statsd plugin: pthread_create failed: %s", STRERRNO); return status; } } network_thread_running = 1; pthread_mutex_unlock(&metrics_lock); return 0; } /* }}} int statsd_init */
static c_avl_tree_t *cj_avl_create(void) { return c_avl_create ((int (*) (const void *, const void *)) strcmp); }
static int basic_aggregator_read_config_file_and_update_aggregator_definitions(char *filename) { oconfig_item_t *ci; int status = 0; int i; int nb_aggregators = 0; char *k; aggregator_definition_t *agg; ci = oconfig_parse_file (filename); if(NULL == ci) { WARNING (OUTPUT_PREFIX_STRING "Failed to read default config ('%s').", filename); return(-1); } /* Free the aggregator tree : it will be reconfigured from scratch from the file */ if(NULL != aggregator) { while (c_avl_pick (aggregator, (void *)&k, (void *)&agg) == 0) { aggregator_definition_free(agg,1); } c_avl_destroy (aggregator); } aggregator = c_avl_create((void *) strcmp); if(NULL == aggregator) return (-1); /* Parse the configuration file */ for (i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("aggregator", child->key) == 0) { agg = basic_aggregator_config_aggregator (child); if(agg) { int r; r = c_avl_insert(aggregator, agg->resultvalue, agg); if(r != 0) { ERROR (OUTPUT_PREFIX_STRING "Could not insert aggregator '%s' in the list of aggregators (duplicate ?)", agg->resultvalue); aggregator_definition_free(agg,1); } else { nb_aggregators++; } } } else if (strcasecmp ("database", child->key) == 0) { if ((child->values_num < 1) || (child->values[0].type != OCONFIG_TYPE_STRING)) { WARNING (OUTPUT_PREFIX_STRING "`database' needs 1 string arguments."); status = -1; } else { if (strcasecmp ("mysql", child->values[0].value.string) == 0) { /* Not implemented yet basic_aggregator_config_mysql_database (child); */ } else if (strcasecmp ("postgresql", child->values[0].value.string) == 0) { /* Not supported yet */ } else { WARNING (OUTPUT_PREFIX_STRING "'%s' is not a known type for `database'.", ci->values[0].value.string); status = -1; } } } else WARNING (OUTPUT_PREFIX_STRING "Option \"%s\" not allowed here.", child->key); } INFO(OUTPUT_PREFIX_STRING "Registered %d aggregators", nb_aggregators); return(status); }
static int basic_aggregator_update_aggregator(char *identifier, c_avl_tree_t *ds_data, aggregator_definition_t *agg) { char *identifier_copy; char *hostname; char *plugin; char *plugin_instance; char *type; char *type_instance; gauge_t *values; size_t values_num; int status; size_t i; const data_set_t *ds; /* parse_identifier() modifies its first argument, * returning pointers into it */ identifier_copy = sstrdup (identifier); status = parse_identifier (identifier_copy, &hostname, &plugin, &plugin_instance, &type, &type_instance); if (status != 0) { WARNING (OUTPUT_PREFIX_STRING "Cannot parse value `%s'.", identifier); WARNING (OUTPUT_PREFIX_STRING "Value `%s' is removed from the aggregator '%s'.", identifier, agg->resultvalue); sfree (identifier_copy); return(1); } ds = plugin_get_ds (type); if (ds == NULL) { WARNING (OUTPUT_PREFIX_STRING "plugin_get_ds (%s) == NULL;", type); WARNING (OUTPUT_PREFIX_STRING "Value `%s' is removed from the aggregator '%s'.", identifier, agg->resultvalue); sfree (identifier_copy); return(1); } values = NULL; values_num = 0; status = uc_get_rate_by_name (identifier, &values, &values_num); if (status != 0) { DEBUG(OUTPUT_PREFIX_STRING "uc_get_rate_by_name failed for %s", identifier); sfree (identifier_copy); return(2); } if ((size_t) ds->ds_num != values_num) { ERROR ("ds[%s]->ds_num = %i, " "but uc_get_rate_by_name returned %u values.", ds->type, ds->ds_num, (unsigned int) values_num); sfree (values); sfree (identifier_copy); return (-1); } for (i = 0; i < values_num; i++) { if ( ! isnan (values[i])) { char *k; c_avl_tree_t *t; value_and_nb_t *v; if(0 != c_avl_get(ds_data, type_instance?type_instance:"",(void*)&t)) { if(NULL == (t = c_avl_create((void *) strcmp))) { ERROR (OUTPUT_PREFIX_STRING "Could not allocate memory for tree"); sfree (identifier_copy); return(-1); } if(NULL == (k=strdup(type_instance?type_instance:""))) { ERROR (OUTPUT_PREFIX_STRING "Could not allocate memory"); c_avl_destroy(t); sfree (identifier_copy); return(-1); } if(0 != c_avl_insert(ds_data, k,t)) { ERROR (OUTPUT_PREFIX_STRING "Could insert data into AVL tree"); c_avl_destroy(t); sfree (identifier_copy); return(-1); } } if(0 != c_avl_get(t, ds->ds[i].name,(void*)&v)) { if(NULL == (k=strdup(ds->ds[i].name))) { ERROR (OUTPUT_PREFIX_STRING "Could not allocate memory"); sfree (identifier_copy); return(-1); } if(NULL == (v=malloc(sizeof(*v)))) { ERROR (OUTPUT_PREFIX_STRING "Could not allocate memory"); sfree (identifier_copy); return(-1); } v->val=0; v->nb=0; if(0 != c_avl_insert(t, k,v)) { ERROR (OUTPUT_PREFIX_STRING "Could insert data into AVL tree"); sfree (identifier_copy); return(-1); } } v->val += values[i]; v->nb +=1; #ifdef DEBUG_THIS if(values[i] > 1000) { INFO(OUTPUT_PREFIX_STRING "DEBUG : ATTENTION '%s/%s-%s/%s%s%s DS '%s'=%12e", hostname, plugin, plugin_instance, type, (type_instance && type_instance[0])?"-":"", type_instance?type_instance:"(null)", ds->ds[i].name, values[i] ); } #endif } } sfree (values); sfree (identifier_copy); return(status); }
static int instances_of_types_tree_update (void) { char **names = NULL; cdtime_t *times = NULL; size_t number = 0; int i; int status = 0; if(NULL == instances_of_types_tree) { instances_of_types_tree = c_avl_create ((void *) strcmp); } status = uc_get_names (&names, ×, &number); if (status != 0) { size_t j; DEBUG (OUTPUT_PREFIX_STRING "uc_get_names failed with status %i", status); for (j = 0; j < number; j++) { sfree(names[j]); } sfree(names); sfree(times); return(status); } if(number == 0) { return(0); } pthread_mutex_lock (&instances_of_types_mutex); for(i=0; i<number; i++) { char *type; int l1,l2; int pos =0; instances_list_t *v; char *type_instance; int type_instance_is_missing = 1; for(l1=0; names[i][l1] && (pos < 2); l1++) { if(names[i][l1] == '/') pos++; } if(names[i][l1] == '\0') { sfree(names[i]); continue; } l2 = l1; while(names[i][l2] && (names[i][l2] != '-')) l2++; if(names[i][l2] == '\0') { sfree(names[i]); continue; } type = names[i]+l1; names[i][l2] = '\0'; type_instance = names[i]+l2+1; if(0 == c_avl_get(instances_of_types_tree, type,(void*)&v)) { int i; for(i=0; v->instance[i]; i++) { if(0 == strcmp(v->instance[i], type_instance)) { type_instance_is_missing = 0; break; } } if(type_instance_is_missing) { if(i >= v->nb) { v->nb += 128; if(NULL == (v->instance = realloc(v->instance, v->nb*sizeof(*(v->instance))))) { ERROR(OUTPUT_PREFIX_STRING "Could not allocate memory"); pthread_mutex_unlock (&instances_of_types_mutex); return(-1); } } v->instance[i+1] = NULL; if(NULL == (v->instance[i] = sstrdup(type_instance))) { ERROR(OUTPUT_PREFIX_STRING "Could not allocate memory"); pthread_mutex_unlock (&instances_of_types_mutex); return(-1); } } } else { char *k; if(NULL == (v = malloc(sizeof(*v)))) { ERROR(OUTPUT_PREFIX_STRING "Could not allocate memory"); pthread_mutex_unlock (&instances_of_types_mutex); return(-1); } v->nb = 128; if(NULL == (v->instance = malloc(v->nb*sizeof(*(v->instance))))) { ERROR(OUTPUT_PREFIX_STRING "Could not allocate memory"); sfree(v); pthread_mutex_unlock (&instances_of_types_mutex); return(-1); } if(NULL == (k = sstrdup(type))) { ERROR(OUTPUT_PREFIX_STRING "Could not allocate memory"); sfree(v); pthread_mutex_unlock (&instances_of_types_mutex); return(-1); } if(NULL == (v->instance[0] = sstrdup(type_instance))) { ERROR(OUTPUT_PREFIX_STRING "Could not allocate memory"); sfree(v); pthread_mutex_unlock (&instances_of_types_mutex); return(-1); } v->instance[1] = NULL; if(0 != c_avl_insert(instances_of_types_tree, k,v)) { ERROR (OUTPUT_PREFIX_STRING "Could insert data into AVL tree"); sfree(v->instance[0]); sfree(v); pthread_mutex_unlock (&instances_of_types_mutex); return(-1); } } sfree(names[i]); } pthread_mutex_unlock (&instances_of_types_mutex); sfree(names); sfree(times); return(0); }
static int fbh_read_file (fbhash_t *h) /* {{{ */ { FILE *fh; char buffer[4096]; struct flock fl; c_avl_tree_t *tree; int status; fh = fopen (h->filename, "r"); if (fh == NULL) return (-1); memset (&fl, 0, sizeof (fl)); fl.l_type = F_RDLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; /* == entire file */ /* TODO: Lock file? -> fcntl */ status = fcntl (fileno (fh), F_SETLK, &fl); if (status != 0) { fclose (fh); return (-1); } tree = c_avl_create ((void *) strcmp); if (tree == NULL) { fclose (fh); return (-1); } /* Read `fh' into `tree' */ while (fgets (buffer, sizeof (buffer), fh) != NULL) /* {{{ */ { size_t len; char *key; char *value; char *key_copy; char *value_copy; buffer[sizeof (buffer) - 1] = 0; len = strlen (buffer); /* Remove trailing newline characters. */ while ((len > 0) && ((buffer[len - 1] == '\n') || (buffer[len - 1] == '\r'))) { len--; buffer[len] = 0; } /* Seek first non-space character */ key = buffer; while ((*key != 0) && isspace ((int) *key)) key++; /* Skip empty lines and comments */ if ((key[0] == 0) || (key[0] == '#')) continue; /* Seek first colon */ value = strchr (key, ':'); if (value == NULL) continue; /* Null-terminate `key'. */ *value = 0; value++; /* Skip leading whitespace */ while ((*value != 0) && isspace ((int) *value)) value++; /* Skip lines without value */ if (value[0] == 0) continue; key_copy = strdup (key); value_copy = strdup (value); if ((key_copy == NULL) || (value_copy == NULL)) { free (key_copy); free (value_copy); continue; } status = c_avl_insert (tree, key_copy, value_copy); if (status != 0) { free (key_copy); free (value_copy); continue; } DEBUG ("utils_fbhash: fbh_read_file: key = %s; value = %s;", key, value); } /* }}} while (fgets) */ fclose (fh); fbh_free_tree (h->tree); h->tree = tree; return (0); } /* }}} int fbh_read_file */