// SPDX-License-Identifier: GPL-3.0-or-later
#include "../libnetdata.h"
/*
* @Input:
* Connector / instance to add to an internal structure
* @Return
* The current head of the linked list of connector_instance
*
*/
_CONNECTOR_INSTANCE *add_connector_instance(struct section *connector, struct section *instance)
{
static struct _connector_instance *global_connector_instance = NULL;
struct _connector_instance *local_ci, *local_ci_tmp;
if (unlikely(!connector)) {
if (unlikely(!instance))
return global_connector_instance;
local_ci = global_connector_instance;
while (local_ci) {
local_ci_tmp = local_ci->next;
freez(local_ci);
local_ci = local_ci_tmp;
}
global_connector_instance = NULL;
return NULL;
}
local_ci = callocz(1, sizeof(struct _connector_instance));
local_ci->instance = instance;
local_ci->connector = connector;
strncpy(local_ci->instance_name, instance->name, CONFIG_MAX_NAME);
strncpy(local_ci->connector_name, connector->name, CONFIG_MAX_NAME);
local_ci->next = global_connector_instance;
global_connector_instance = local_ci;
return global_connector_instance;
}
int is_valid_connector(char *type, int check_reserved)
{
int rc = 1;
if (unlikely(!type))
return 0;
if (!check_reserved) {
if (unlikely(is_valid_connector(type,1))) {
return 0;
}
//if (unlikely(*type == ':')
// return 0;
char *separator = strrchr(type, ':');
if (likely(separator)) {
*separator = '\0';
rc = separator - type;
} else
return 0;
}
// else {
// if (unlikely(is_valid_connector(type,1))) {
// error("Section %s invalid -- reserved name", type);
// return 0;
// }
// }
if (!strcmp(type, "graphite") || !strcmp(type, "graphite:plaintext")) {
return rc;
} else if (!strcmp(type, "opentsdb") || !strcmp(type, "opentsdb:telnet")) {
return rc;
} else if (!strcmp(type, "opentsdb:http") || !strcmp(type, "opentsdb:https")) {
return rc;
} else if (!strcmp(type, "json") || !strcmp(type, "json:plaintext")) {
return rc;
} else if (!strcmp(type, "prometheus_remote_write")) {
return rc;
} else if (!strcmp(type, "kinesis") || !strcmp(type, "kinesis:plaintext")) {
return rc;
} else if (!strcmp(type, "mongodb") || !strcmp(type, "mongodb:plaintext")) {
return rc;
}
return 0;
}
// ----------------------------------------------------------------------------
// locking
inline void appconfig_wrlock(struct config *root) {
netdata_mutex_lock(&root->mutex);
}
inline void appconfig_unlock(struct config *root) {
netdata_mutex_unlock(&root->mutex);
}
inline void config_section_wrlock(struct section *co) {
netdata_mutex_lock(&co->mutex);
}
inline void config_section_unlock(struct section *co) {
netdata_mutex_unlock(&co->mutex);
}
// ----------------------------------------------------------------------------
// config name-value index
static int appconfig_option_compare(void *a, void *b) {
if(((struct config_option *)a)->hash < ((struct config_option *)b)->hash) return -1;
else if(((struct config_option *)a)->hash > ((struct config_option *)b)->hash) return 1;
else return strcmp(((struct config_option *)a)->name, ((struct config_option *)b)->name);
}
#define appconfig_option_index_add(co, cv) (struct config_option *)avl_insert_lock(&((co)->values_index), (avl *)(cv))
#define appconfig_option_index_del(co, cv) (struct config_option *)avl_remove_lock(&((co)->values_index), (avl *)(cv))
static struct config_option *appconfig_option_index_find(struct section *co, const char *name, uint32_t hash) {
struct config_option tmp;
tmp.hash = (hash)?hash:simple_hash(name);
tmp.name = (char *)name;
return (struct config_option *)avl_search_lock(&(co->values_index), (avl *) &tmp);
}
// ----------------------------------------------------------------------------
// config sections index
int appconfig_section_compare(void *a, void *b) {
if(((struct section *)a)->hash <