* Volodymyr Mytnyk <volodymyrx.mytnyk@intel.com>
**/
+#include "collectd.h"
+
#include "common.h" /* auxiliary functions */
#include "utils_ovs.h" /* OVS helpers */
#define OVS_EVENTS_IFACE_UUID_SIZE 64
#define OVS_EVENTS_EXT_IFACE_ID_SIZE 64
#define OVS_EVENTS_EXT_VM_UUID_SIZE 64
-#define OVS_EVENTS_OVS_DB_URL_SIZE 64
#define OVS_EVENTS_PLUGIN "ovs_events"
#define OVS_EVENTS_CTX_LOCK \
for (int __i = ovs_events_ctx_lock(); __i != 0; __i = ovs_events_ctx_unlock())
/* OVS events configuration data */
struct ovs_events_config_s {
- _Bool send_notification; /* sent notification to collectd? */
- char ovs_db_server_url[OVS_EVENTS_OVS_DB_URL_SIZE]; /* OVS DB server URL */
- ovs_events_iface_list_t *ifaces; /* interface info */
+ _Bool send_notification; /* sent notification to collectd? */
+ char ovs_db_node[OVS_DB_ADDR_NODE_SIZE]; /* OVS DB node */
+ char ovs_db_serv[OVS_DB_ADDR_SERVICE_SIZE]; /* OVS DB service */
+ char ovs_db_unix[OVS_DB_ADDR_UNIX_SIZE]; /* OVS DB unix socket path */
+ ovs_events_iface_list_t *ifaces; /* interface info */
};
typedef struct ovs_events_config_s ovs_events_config_t;
*/
static ovs_events_ctx_t ovs_events_ctx = {
.mutex = PTHREAD_MUTEX_INITIALIZER,
- .config = {.send_notification = 0, /* do not send notification */
- .ovs_db_server_url =
- "tcp:127.0.0.1:6640", /* use default OVS DB URL */
+ .config = {.send_notification = 0, /* do not send notification */
+ .ovs_db_node = "localhost", /* use default OVS DB node */
+ .ovs_db_serv = "6640", /* use default OVS DB service */
+ .ovs_db_unix = "", /* UNIX path empty by default */
.ifaces = NULL},
.ovs_db_select_params = NULL,
.is_db_available = 0,
/* This function is used only by "OVS_EVENTS_CTX_LOCK" define (see above).
* It always returns 1 when context is locked.
*/
-static inline int ovs_events_ctx_lock() {
+static int ovs_events_ctx_lock() {
pthread_mutex_lock(&ovs_events_ctx.mutex);
return (1);
}
/* This function is used only by "OVS_EVENTS_CTX_LOCK" define (see above).
* It always returns 0 when context is unlocked.
*/
-static inline int ovs_events_ctx_unlock() {
+static int ovs_events_ctx_unlock() {
pthread_mutex_unlock(&ovs_events_ctx.mutex);
return (0);
}
*/
static int ovs_events_config_iface_exists(const char *ifname) {
if (ovs_events_ctx.config.ifaces == NULL)
- return -1;
+ return (-1);
/* check if given interface exists */
for (ovs_events_iface_list_t *iface = ovs_events_ctx.config.ifaces; iface;
iface = iface->next)
- return (strcmp(ifname, iface->name) == 0);
+ if (strcmp(ifname, iface->name) == 0)
+ return (1);
- return 0;
+ return (0);
}
/* Get OVS DB select parameter request based on rfc7047,
* "Transact" & "Select" section
*/
-static inline char *ovs_events_get_select_params() {
+static char *ovs_events_get_select_params() {
int ret = 0;
size_t buff_size = 0;
- size_t offset = 0;
- char *buff = NULL;
- char *new_buff = NULL;
+ size_t buff_off = 0;
+ char *opt_buff = NULL;
const char params_fmt[] = "[\"Open_vSwitch\"%s]";
const char option_fmt[] = ",{\"op\":\"select\",\"table\":\"Interface\","
"\"where\":[[\"name\",\"==\",\"%s\"]],"
"\"external_ids\",\"name\",\"_uuid\"]}";
/* setup OVS DB interface condition */
for (ovs_events_iface_list_t *iface = ovs_events_ctx.config.ifaces; iface;
- iface = iface->next, offset += ret) {
+ iface = iface->next, buff_off += ret) {
/* allocate new buffer (format size + ifname len is good enough) */
buff_size += (sizeof(option_fmt) + strlen(iface->name));
- new_buff = realloc(buff, buff_size);
- if (new_buff == NULL)
- goto failure;
- buff = new_buff;
- ret = ssnprintf(buff + offset, buff_size, option_fmt, iface->name);
- if (ret < 0)
- goto failure;
+ char *new_buff = realloc(opt_buff, buff_size);
+ if (new_buff == NULL) {
+ sfree(opt_buff);
+ return NULL;
+ }
+ opt_buff = new_buff;
+ ret = ssnprintf(opt_buff + buff_off, buff_size - buff_off, option_fmt,
+ iface->name);
+ if (ret < 0) {
+ sfree(opt_buff);
+ return NULL;
+ }
}
/* if no interfaces are configured, use default params */
- if (buff == NULL) {
- buff = strdup(default_opt);
- offset = strlen(default_opt);
- }
+ if (opt_buff == NULL)
+ opt_buff = strdup(default_opt);
/* allocate memory for OVS DB select params */
- buff_size = offset + sizeof(params_fmt);
- new_buff = malloc(buff_size);
- if (new_buff == NULL)
- goto failure;
+ size_t params_size = sizeof(params_fmt) + strlen(opt_buff);
+ char *params_buff = malloc(params_size);
+ if (params_buff == NULL) {
+ sfree(opt_buff);
+ return NULL;
+ }
/* create OVS DB select params */
- if (ssnprintf(new_buff, buff_size, params_fmt, buff) < 0)
- goto failure;
+ if (ssnprintf(params_buff, params_size, params_fmt, opt_buff) < 0)
+ sfree(params_buff);
- sfree(buff);
- return new_buff;
-
-failure:
- sfree(new_buff);
- sfree(buff);
- return NULL;
+ sfree(opt_buff);
+ return params_buff;
}
/* Release memory allocated for configuration data */
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
if (strcasecmp("SendNotification", child->key) == 0) {
- if (cf_util_get_boolean(child, &ovs_events_ctx.config.send_notification) <
- 0)
+ if (cf_util_get_boolean(child,
+ &ovs_events_ctx.config.send_notification) != 0)
+ OVS_EVENTS_CONFIG_ERROR(child->key);
+ } else if (strcasecmp("Address", child->key) == 0) {
+ if (cf_util_get_string_buffer(
+ child, ovs_events_ctx.config.ovs_db_node,
+ sizeof(ovs_events_ctx.config.ovs_db_node)) != 0)
+ OVS_EVENTS_CONFIG_ERROR(child->key);
+ } else if (strcasecmp("Port", child->key) == 0) {
+ if (cf_util_get_string_buffer(
+ child, ovs_events_ctx.config.ovs_db_serv,
+ sizeof(ovs_events_ctx.config.ovs_db_serv)) != 0)
OVS_EVENTS_CONFIG_ERROR(child->key);
- } else if (strcasecmp("OvsDbServerUrl", child->key) == 0) {
+ } else if (strcasecmp("Socket", child->key) == 0) {
if (cf_util_get_string_buffer(
- child, ovs_events_ctx.config.ovs_db_server_url,
- sizeof(ovs_events_ctx.config.ovs_db_server_url)) < 0)
+ child, ovs_events_ctx.config.ovs_db_unix,
+ sizeof(ovs_events_ctx.config.ovs_db_unix)) != 0)
OVS_EVENTS_CONFIG_ERROR(child->key);
} else if (strcasecmp("Interfaces", child->key) == 0) {
for (int j = 0; j < child->values_num; j++) {
if (!YAJL_IS_OBJECT(jobject))
return (-1);
+ /* zero the interface info structure */
+ memset(ifinfo, 0, sizeof(*ifinfo));
+
/* try to find external_ids, name and link_state fields */
jexternal_ids = ovs_utils_get_value_by_key(jobject, "external_ids");
if (jexternal_ids == NULL || ifinfo == NULL)
" :unexpected interface information data received");
return;
}
- if (ovs_events_config_iface_exists(ifinfo.name) != 0)
+ if (ovs_events_config_iface_exists(ifinfo.name) != 0) {
+ DEBUG("name=%s, uuid=%s, ext_iface_id=%s, ext_vm_uuid=%s", ifinfo.name,
+ ifinfo.uuid, ifinfo.ext_iface_id, ifinfo.ext_vm_uuid);
/* dispatch notification */
ovs_events_dispatch_notification(&ifinfo);
+ }
}
}
-/* OVD DB reply callback. It parses reply, receives
+/* OVS DB reply callback. It parses reply, receives
* interface information and dispatches the info to
- * collecd
+ * collectd
*/
static void ovs_events_poll_result_cb(yajl_val jresult, yajl_val jerror) {
yajl_val *jvalues = NULL;
}
/* get interfaces info */
for (int j = 0; j < YAJL_GET_ARRAY(jvalue)->len; j++) {
- memset(&ifinfo, 0, sizeof(ifinfo));
if (ovs_events_get_iface_info(YAJL_GET_ARRAY(jvalue)->values[j],
&ifinfo) < 0) {
ERROR(OVS_EVENTS_PLUGIN
}
}
OVS_EVENTS_CTX_LOCK { ovs_events_ctx.is_db_available = 1; }
- DEBUG(OVS_EVENTS_PLUGIN ": OVS DB has been initialized");
+ DEBUG(OVS_EVENTS_PLUGIN ": OVS DB connection has been initialized");
}
/* OVS DB terminate connection notification callback */
ovs_db_callback_t cb = {.post_conn_init = ovs_events_conn_initialize,
.post_conn_terminate = ovs_events_conn_terminate};
- DEBUG(OVS_EVENTS_PLUGIN ": OVS DB url = %s",
- ovs_events_ctx.config.ovs_db_server_url);
+ DEBUG(OVS_EVENTS_PLUGIN ": OVS DB address=%s, service=%s, unix=%s",
+ ovs_events_ctx.config.ovs_db_node, ovs_events_ctx.config.ovs_db_serv,
+ ovs_events_ctx.config.ovs_db_unix);
/* generate OVS DB select condition based on list on configured interfaces */
ovs_events_ctx.ovs_db_select_params = ovs_events_get_select_params();
}
/* initialize OVS DB */
- ovs_db = ovs_db_init(ovs_events_ctx.config.ovs_db_server_url, &cb);
+ ovs_db = ovs_db_init(ovs_events_ctx.config.ovs_db_node,
+ ovs_events_ctx.config.ovs_db_serv,
+ ovs_events_ctx.config.ovs_db_unix, &cb);
if (ovs_db == NULL) {
ERROR(OVS_EVENTS_PLUGIN ": fail to connect to OVS DB server");
goto ovs_events_failure;