From: Mytnyk, VolodymyrX Date: Tue, 4 Oct 2016 14:20:37 +0000 (+0100) Subject: OVS events: Address all PR comments X-Git-Tag: collectd-5.8.0~256^2~8 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=4c5d22285e8a149a82909061f320faa22531326e OVS events: Address all PR comments - Change OVS implementation to use suggested configuration: OvsDbAddress "127.0.0.1" "6640" OvsDbAddress "2001:DB8::c011:ec7d" "6640" OvsDbAddress "2001:DB8::c011:ec7d" "service-name" OvsDbAddress "unix:/path/to/socket" - Update documentation; - Change OVS utils to use getaddrinfo(); - Clean-up compilation warnings on FreeBSD system. - Add IPv6 support; Change-Id: I60ca700c15406c783b62ee52135266d67b60393a Signed-off-by: Mytnyk, VolodymyrX --- diff --git a/src/collectd.conf.in b/src/collectd.conf.in index ae4f6022..883a079f 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -993,7 +993,7 @@ # # -# OvsDbServerUrl "tcp:127.0.0.1:6640" +# OvsDbAddress "127.0.0.1" "6640" # Interfaces "br0" "veth0" # SendNotification false # diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 7f4b3e9c..061c4baf 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -5463,7 +5463,7 @@ notification. B - OvsDbServerUrl "tcp:127.0.0.1:6640" + OvsDbAddress "127.0.0.1" "6640" Interfaces "br0" "veth0" SendNotification false @@ -5472,29 +5472,31 @@ The plugin provides the following configuration options: =over 4 -=item B I +=item B I I -The URL is an address of OVS DB server JSON-RPC interface used by the plugin. +The address of OVS DB server JSON-RPC interface used by the plugin. To enable the interface, OVS DB daemon should be running with '--remote=ptcp:' -or '--remote=punix:' option. See L for more details. The URL -must take one of the following forms: +or '--remote=punix:' option. See L for more details. The +address arguments must take one of the following forms: =over 4 -=item BI:I +=item I -Connect to the given tcp I on I, where I is IPv4 address -of OVS DB server which is listening on TCP I for incoming -JSON-RPC client connection. +The I argument of the address can be either network hostname, IPv4 +numbers-and-dots notation or IPv6 hexadecimal string format. In case of Unix +domain socket, the "Ifile" format should be used, where I is +the full name of OVS DB Unix domain socket. -=item BI +=item I -Connect to the unix domain server socket named I which is -used by OVS DB for incoming JSON-RPC client connection. +The I argument of the address specifies the service name used to +connect to OVS DB. See L for more details. This argument is +skipped if Unix domain address is used. =back -Default: C +Default: C<"localhost" "6640"> =item B [I ...] diff --git a/src/ovs_events.c b/src/ovs_events.c index d9735913..7521b280 100644 --- a/src/ovs_events.c +++ b/src/ovs_events.c @@ -25,6 +25,8 @@ * Volodymyr Mytnyk **/ +#include "collectd.h" + #include "common.h" /* auxiliary functions */ #include "utils_ovs.h" /* OVS helpers */ @@ -33,7 +35,6 @@ #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()) @@ -67,9 +68,10 @@ typedef struct ovs_events_iface_list_s ovs_events_iface_list_t; /* 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 */ + ovs_events_iface_list_t *ifaces; /* interface info */ }; typedef struct ovs_events_config_s ovs_events_config_t; @@ -88,9 +90,9 @@ typedef struct ovs_events_ctx_s ovs_events_ctx_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 */ .ifaces = NULL}, .ovs_db_select_params = NULL, .is_db_available = 0, @@ -99,7 +101,7 @@ static ovs_events_ctx_t ovs_events_ctx = { /* 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); } @@ -107,7 +109,7 @@ static inline int ovs_events_ctx_lock() { /* 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); } @@ -131,7 +133,7 @@ static int ovs_events_config_iface_exists(const char *ifname) { /* 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; @@ -206,11 +208,28 @@ static int ovs_events_plugin_config(oconfig_item_t *ci) { if (cf_util_get_boolean(child, &ovs_events_ctx.config.send_notification) < 0) OVS_EVENTS_CONFIG_ERROR(child->key); - } else if (strcasecmp("OvsDbServerUrl", 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) - OVS_EVENTS_CONFIG_ERROR(child->key); + } else if (strcasecmp("OvsDbAddress", child->key) == 0) { + if (child->values_num < 1) { + ERROR(OVS_EVENTS_PLUGIN ": invalid OVS DB address specified"); + goto failure; + } + /* check node type and get the value */ + if (child->values[0].type != OCONFIG_TYPE_STRING) { + ERROR(OVS_EVENTS_PLUGIN ": OVS DB node is not a string"); + goto failure; + } + sstrncpy(ovs_events_ctx.config.ovs_db_node, child->values[0].value.string, + sizeof(ovs_events_ctx.config.ovs_db_node)); + /* get OVS DB address service name (optional) */ + if (child->values_num > 1) { + if (child->values[1].type != OCONFIG_TYPE_STRING) { + ERROR(OVS_EVENTS_PLUGIN ": OVS DB service is not a string"); + goto failure; + } + sstrncpy(ovs_events_ctx.config.ovs_db_serv, + child->values[1].value.string, + sizeof(ovs_events_ctx.config.ovs_db_serv)); + } } else if (strcasecmp("Interfaces", child->key) == 0) { for (int j = 0; j < child->values_num; j++) { /* check value type */ @@ -556,8 +575,8 @@ static int ovs_events_plugin_init(void) { 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 node = %s, service=%s", + ovs_events_ctx.config.ovs_db_node, ovs_events_ctx.config.ovs_db_serv); /* generate OVS DB select condition based on list on configured interfaces */ ovs_events_ctx.ovs_db_select_params = ovs_events_get_select_params(); @@ -567,7 +586,8 @@ static int ovs_events_plugin_init(void) { } /* 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, &cb); if (ovs_db == NULL) { ERROR(OVS_EVENTS_PLUGIN ": fail to connect to OVS DB server"); goto ovs_events_failure; diff --git a/src/utils_ovs.c b/src/utils_ovs.c index 92914ce6..2a4bdf83 100644 --- a/src/utils_ovs.c +++ b/src/utils_ovs.c @@ -65,16 +65,28 @@ /* clang-format on */ /* collectd headers */ +#include "collectd.h" + #include "common.h" /* private headers */ #include "utils_ovs.h" /* system libraries */ +#if HAVE_NETDB_H +#include +#endif +#if HAVE_ARPA_INET_H #include +#endif +#if HAVE_POLL_H #include -#include +#endif +#if HAVE_SYS_UN_H #include +#endif + +#include #define OVS_ERROR(fmt, ...) \ do { \ @@ -145,19 +157,6 @@ struct ovs_callback_s { }; typedef struct ovs_callback_s ovs_callback_t; -/* Connection declaration */ -struct ovs_conn_s { - int sock; - int domain; - int type; - int addr_size; - union { - struct sockaddr_in s_inet; - struct sockaddr_un s_unix; - } addr; -}; -typedef struct ovs_conn_s ovs_conn_t; - /* Event thread data declaration */ struct ovs_event_thread_s { pthread_t tid; @@ -182,9 +181,10 @@ struct ovs_db_s { pthread_mutex_t mutex; ovs_callback_t *remote_cb; ovs_db_callback_t cb; - ovs_conn_t conn; + char service[OVS_DB_ADDR_SERVICE_SIZE]; + char node[OVS_DB_ADDR_NODE_SIZE]; + int sock; }; -typedef struct ovs_db_s ovs_db_t; /* Post an event to event thread. * Possible events are: @@ -201,7 +201,7 @@ static void ovs_db_event_post(ovs_db_t *pdb, int event) { /* Check if POLL thread is still running. Returns * 1 if running otherwise 0 is returned */ -static inline int ovs_db_poll_is_running(ovs_db_t *pdb) { +static _Bool ovs_db_poll_is_running(ovs_db_t *pdb) { int state = 0; pthread_mutex_lock(&pdb->poll_thread.mutex); state = pdb->poll_thread.state; @@ -210,7 +210,7 @@ static inline int ovs_db_poll_is_running(ovs_db_t *pdb) { } /* Terminate POLL thread */ -static inline void ovs_db_poll_terminate(ovs_db_t *pdb) { +static void ovs_db_poll_terminate(ovs_db_t *pdb) { pthread_mutex_lock(&pdb->poll_thread.mutex); pdb->poll_thread.state = OVS_DB_POLL_STATE_EXITING; pthread_mutex_unlock(&pdb->poll_thread.mutex); @@ -263,7 +263,7 @@ static void ovs_db_callback_remove_all(ovs_db_t *pdb) { pthread_mutex_lock(&pdb->mutex); for (ovs_callback_t *del_cb = pdb->remote_cb; pdb->remote_cb; del_cb = pdb->remote_cb) { - pdb->remote_cb = pdb->remote_cb->next; + pdb->remote_cb = del_cb->next; free(del_cb); } pdb->remote_cb = NULL; @@ -271,15 +271,16 @@ static void ovs_db_callback_remove_all(ovs_db_t *pdb) { } /* Get/find callback in OVS DB object by UID. Returns pointer - * to requested callback otherwise NULL is returned */ + * to requested callback otherwise NULL is returned. + * + * IMPORTANT NOTE: + * The OVS DB mutex should be locked by the caller + * to make sure that returned callback is still valid. + */ static ovs_callback_t *ovs_db_callback_get(ovs_db_t *pdb, uint64_t uid) { - pthread_mutex_lock(&pdb->mutex); for (ovs_callback_t *cb = pdb->remote_cb; cb != NULL; cb = cb->next) - if (cb->uid == uid) { - pthread_mutex_unlock(&pdb->mutex); + if (cb->uid == uid) return cb; - } - pthread_mutex_unlock(&pdb->mutex); return NULL; } @@ -292,7 +293,7 @@ static int ovs_db_data_send(const ovs_db_t *pdb, const char *data, size_t len) { size_t off = 0; while (rem > 0) { - if ((nbytes = send(pdb->conn.sock, data + off, rem, 0)) <= 0) + if ((nbytes = send(pdb->sock, data + off, rem, 0)) <= 0) return (-1); rem -= (size_t)nbytes; off += (size_t)nbytes; @@ -300,70 +301,6 @@ static int ovs_db_data_send(const ovs_db_t *pdb, const char *data, size_t len) { return (0); } -/* Parse OVS server URL. - * Format of the URL: - * "tcp:a.b.c.d:port" - define TCP connection (INET domain) - * "unix:file" - define UNIX socket file (UNIX domain) - */ -static int ovs_db_url_parse(const char *surl, ovs_conn_t *conn) { - ovs_conn_t tmp_conn; - char *nexttok = NULL; - char *in_str = NULL; - char *saveptr; - int ret = 0; - - /* sanity check */ - if ((surl == NULL) || (strlen(surl) < 1)) - return (-1); - - /* parse domain */ - tmp_conn = *conn; - in_str = sstrdup(surl); - if ((nexttok = strtok_r(in_str, ":", &saveptr)) != NULL) { - if (strcmp("tcp", nexttok) == 0) { - tmp_conn.domain = AF_INET; - tmp_conn.type = SOCK_STREAM; - tmp_conn.addr_size = sizeof(tmp_conn.addr.s_inet); - } else if (strcmp("unix", nexttok) == 0) { - tmp_conn.domain = AF_UNIX; - tmp_conn.type = SOCK_STREAM; - tmp_conn.addr_size = sizeof(tmp_conn.addr.s_unix); - } else - goto failure; - } else - goto failure; - - /* parse url depending on domain */ - if ((nexttok = strtok_r(NULL, ":", &saveptr)) != NULL) { - if (tmp_conn.domain == AF_UNIX) { - /* */ - tmp_conn.addr.s_inet.sin_family = AF_UNIX; - sstrncpy(tmp_conn.addr.s_unix.sun_path, nexttok, strlen(nexttok) + 1); - } else { - /* */ - tmp_conn.addr.s_inet.sin_family = AF_INET; - ret = inet_pton(AF_INET, nexttok, (void *)&tmp_conn.addr.s_inet.sin_addr); - if (ret == 1) { - if ((nexttok = strtok_r(NULL, ":", &saveptr)) != NULL) - tmp_conn.addr.s_inet.sin_port = htons(atoi(nexttok)); - else - goto failure; - } else - goto failure; - } - } - - /* save result and return success */ - *conn = tmp_conn; - sfree(in_str); - return (0); - -failure: - OVS_ERROR("invalid OVS DB URL provided [url=%s]", surl); - sfree(in_str); - return (-1); -} - /* * YAJL (Yet Another JSON Library) helper functions * Documentation (https://lloyd.github.io/yajl/) @@ -376,9 +313,9 @@ failure: * jgen - YAJL generator handle allocated by yajl_gen_alloc() * string - Null-terminated string */ -static inline yajl_gen_status ovs_yajl_gen_tstring(yajl_gen hander, - const char *string) { - return yajl_gen_string(hander, string, strlen(string)); +static yajl_gen_status ovs_yajl_gen_tstring(yajl_gen hander, + const char *string) { + return yajl_gen_string(hander, (const unsigned char *)string, strlen(string)); } /* Add YAJL value into YAJL generator handle (JSON object) @@ -495,7 +432,8 @@ yajl_gen_failure: /* Get OVS DB registered callback by YAJL val. The YAJL * value should be YAJL string (UID). Returns NULL if - * callback hasn't been found. + * callback hasn't been found. See also ovs_db_callback_get() + * description for addition info. */ static ovs_callback_t *ovs_db_table_callback_get(ovs_db_t *pdb, yajl_val jid) { char *endptr = NULL; @@ -543,12 +481,16 @@ static int ovs_db_table_update_cb(ovs_db_t *pdb, yajl_val jnode) { goto ovs_failure; /* find registered callback based on */ + pthread_mutex_lock(&pdb->mutex); cb = ovs_db_table_callback_get(pdb, jvalue); - if (cb == NULL || cb->table.call == NULL) + if (cb == NULL || cb->table.call == NULL) { + pthread_mutex_unlock(&pdb->mutex); goto ovs_failure; + } /* call registered callback */ cb->table.call(jtable_updates); + pthread_mutex_unlock(&pdb->mutex); return 0; ovs_failure: @@ -579,6 +521,7 @@ static int ovs_db_result_cb(ovs_db_t *pdb, yajl_val jnode) { return (-1); /* try to find registered callback */ + pthread_mutex_lock(&pdb->mutex); cb = ovs_db_table_callback_get(pdb, jid); if (cb != NULL && cb->result.call != NULL) { /* call registered callback */ @@ -587,6 +530,7 @@ static int ovs_db_result_cb(ovs_db_t *pdb, yajl_val jnode) { sem_post(&cb->result.sync); } + pthread_mutex_unlock(&pdb->mutex); return (0); } @@ -621,7 +565,7 @@ static int ovs_db_json_data_process(ovs_db_t *pdb, const char *data, } /* get method name */ - if (jval = yajl_tree_get(jnode, method_path, yajl_t_string)) { + if ((jval = yajl_tree_get(jnode, method_path, yajl_t_string)) != NULL) { method = YAJL_GET_STRING(jval); if (strcmp("echo", method) == 0) { /* echo request from the server */ @@ -632,7 +576,7 @@ static int ovs_db_json_data_process(ovs_db_t *pdb, const char *data, if (ovs_db_table_update_cb(pdb, jnode) < 0) OVS_ERROR("handle update notification failed"); } - } else if (jval = yajl_tree_get(jnode, result_path, yajl_t_any)) { + } else if ((jval = yajl_tree_get(jnode, result_path, yajl_t_any)) != NULL) { /* result notification */ if (ovs_db_result_cb(pdb, jnode) < 0) OVS_ERROR("handle result reply failed"); @@ -654,7 +598,7 @@ static int ovs_db_json_data_process(ovs_db_t *pdb, const char *data, */ /* Allocate JSON reader instance */ -static inline ovs_json_reader_t *ovs_json_reader_alloc() { +static ovs_json_reader_t *ovs_json_reader_alloc() { ovs_json_reader_t *jreader = NULL; if ((jreader = calloc(sizeof(ovs_json_reader_t), 1)) == NULL) @@ -664,8 +608,8 @@ static inline ovs_json_reader_t *ovs_json_reader_alloc() { } /* Push raw data into into the JSON reader for processing */ -static inline int ovs_json_reader_push_data(ovs_json_reader_t *jreader, - const char *data, size_t data_len) { +static int ovs_json_reader_push_data(ovs_json_reader_t *jreader, + const char *data, size_t data_len) { char *new_buff = NULL; size_t available = jreader->buff_size - jreader->buff_offset; @@ -693,9 +637,8 @@ static inline int ovs_json_reader_push_data(ovs_json_reader_t *jreader, /* Pop one fully-fledged JSON if already exists. Returns 0 if * completed JSON already exists otherwise negative value is * returned */ -static inline int ovs_json_reader_pop(ovs_json_reader_t *jreader, - const char **json_ptr, - size_t *json_len_ptr) { +static int ovs_json_reader_pop(ovs_json_reader_t *jreader, + const char **json_ptr, size_t *json_len_ptr) { size_t nbraces = 0; size_t json_len = 0; char *json = NULL; @@ -742,7 +685,7 @@ static inline int ovs_json_reader_pop(ovs_json_reader_t *jreader, /* Reset JSON reader. It is useful when start processing * new raw data. E.g.: in case of lost stream connection. */ -static inline void ovs_json_reader_reset(ovs_json_reader_t *jreader) { +static void ovs_json_reader_reset(ovs_json_reader_t *jreader) { if (jreader) { jreader->buff_offset = 0; jreader->json_offset = 0; @@ -750,41 +693,85 @@ static inline void ovs_json_reader_reset(ovs_json_reader_t *jreader) { } /* Release internal data allocated for JSON reader */ -static inline void ovs_json_reader_free(ovs_json_reader_t *jreader) { +static void ovs_json_reader_free(ovs_json_reader_t *jreader) { if (jreader) { free(jreader->buff_ptr); free(jreader); } } -/* Reconnect to OVD DB and call init OVS DB callback - * 'init_cb' if connection has been established. +/* Reconnect to OVD DB and call the OVS DB post connection init callback + * if connection has been established. */ static int ovs_db_reconnect(ovs_db_t *pdb) { char errbuff[OVS_ERROR_BUFF_SIZE]; + const char unix_prefix[] = "unix:"; + struct addrinfo *result, *rp; + _Bool is_connected = 0; + struct sockaddr_un saunix; /* remove all registered OVS DB table/result callbacks */ ovs_db_callback_remove_all(pdb); - /* open new socket */ - if ((pdb->conn.sock = socket(pdb->conn.domain, pdb->conn.type, 0)) < 0) { - sstrerror(errno, errbuff, sizeof(errbuff)); - OVS_ERROR("socket(): %s", errbuff); - return (-1); + if (strncmp(pdb->node, unix_prefix, strlen(unix_prefix)) == 0) { + /* create unix socket address */ + rp = calloc(1, sizeof(struct addrinfo)); + struct sockaddr_un *sa_unix = calloc(1, sizeof(struct sockaddr_un)); + if (rp == NULL || sa_unix == NULL) { + sfree(rp); + sfree(sa_unix); + return (1); + } + rp->ai_family = AF_UNIX; + rp->ai_socktype = SOCK_STREAM; + rp->ai_addrlen = sizeof(*sa_unix); + rp->ai_addr = (struct sockaddr *)sa_unix; + sa_unix->sun_family = rp->ai_family; + sstrncpy(sa_unix->sun_path, (pdb->node + strlen(unix_prefix)), + sizeof(sa_unix->sun_path)); + result = rp; + } else { + /* intet socket address */ + int ret = 0; + struct addrinfo hints; + + /* setup criteria for selecting the socket address */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + /* get socket addresses */ + if ((ret = getaddrinfo(pdb->node, pdb->service, &hints, &result)) != 0) { + OVS_ERROR("getaddrinfo(): %s", gai_strerror(ret)); + return (1); + } } - - /* try to connect to server */ - if (connect(pdb->conn.sock, (struct sockaddr *)&pdb->conn.addr, - pdb->conn.addr_size) < 0) { - sstrerror(errno, errbuff, sizeof(errbuff)); - OVS_ERROR("connect(): %s", errbuff); - close(pdb->conn.sock); - return (-1); + /* try to connect to the server */ + for (rp = result; rp != NULL; rp = rp->ai_next) { + if ((pdb->sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < + 0) { + sstrerror(errno, errbuff, sizeof(errbuff)); + OVS_DEBUG("socket(): %s", errbuff); + continue; + } + if (connect(pdb->sock, rp->ai_addr, rp->ai_addrlen) < 0) { + sstrerror(errno, errbuff, sizeof(errbuff)); + OVS_DEBUG("connect(): %s [family=%d]", errbuff, rp->ai_family); + close(pdb->sock); + } else { + is_connected = 1; + break; + } } /* send notification to event thread */ - ovs_db_event_post(pdb, OVS_DB_EVENT_CONN_ESTABLISHED); - return (0); + if (is_connected) + ovs_db_event_post(pdb, OVS_DB_EVENT_CONN_ESTABLISHED); + else + OVS_ERROR("connect to \"%s\" failed", pdb->node); + + freeaddrinfo(result); + return !is_connected; } /* POLL worker thread. @@ -808,7 +795,7 @@ static void *ovs_poll_worker(void *arg) { } /* start polling data */ - poll_fd.fd = pdb->conn.sock; + poll_fd.fd = pdb->sock; poll_fd.events = POLLIN | POLLPRI; poll_fd.revents = 0; @@ -823,7 +810,7 @@ static void *ovs_poll_worker(void *arg) { usleep(OVS_DB_RECONNECT_TIMEOUT * 1000000); } ovs_json_reader_reset(jreader); - poll_fd.fd = pdb->conn.sock; + poll_fd.fd = pdb->sock; } else if ((poll_fd.revents & POLLERR) || (poll_fd.revents & POLLHUP)) { /* connection is broken */ OVS_ERROR("poll() peer closed its end of the channel"); @@ -934,7 +921,8 @@ static int ovs_db_poll_thread_stop(ovs_db_t *pdb) { * Public OVS DB API implementation */ -ovs_db_t *ovs_db_init(const char *surl, ovs_db_callback_t *cb) { +ovs_db_t *ovs_db_init(const char *node, const char *service, + ovs_db_callback_t *cb) { pthread_mutexattr_t mutex_attr; ovs_db_t *pdb = NULL; @@ -942,9 +930,14 @@ ovs_db_t *ovs_db_init(const char *surl, ovs_db_callback_t *cb) { if ((pdb = calloc(1, sizeof(*pdb))) == NULL) return (NULL); - /* convert string url to socket addr */ - if (ovs_db_url_parse(surl, &pdb->conn) < 0) - goto failure; + /* node cannot be unset */ + if (node == NULL || strlen(node) == 0) + return (NULL); + + /* store the OVS DB address */ + sstrncpy(pdb->node, node, sizeof(pdb->node)); + if (service != NULL) + sstrncpy(pdb->service, service, sizeof(pdb->service)); /* setup OVS DB callbacks */ if (cb) @@ -982,9 +975,9 @@ ovs_db_t *ovs_db_init(const char *surl, ovs_db_callback_t *cb) { return pdb; failure: - if (pdb->conn.sock) + if (pdb->sock) /* close connection */ - close(pdb->conn.sock); + close(pdb->sock); if (pdb->event_thread.tid != 0) /* stop event thread */ if (ovs_db_event_thread_stop(pdb) < 0) @@ -1193,7 +1186,7 @@ int ovs_db_destroy(ovs_db_t *pdb) { return (-1); /* try to lock the structure before releasing */ - if (ret = pthread_mutex_lock(&pdb->mutex)) { + if ((ret = pthread_mutex_lock(&pdb->mutex))) { OVS_ERROR("pthread_mutex_lock() DB mutext lock failed (%d)", ret); return (-1); } @@ -1214,8 +1207,8 @@ int ovs_db_destroy(ovs_db_t *pdb) { ovs_db_callback_remove_all(pdb); /* close connection */ - if (pdb->conn.sock) - close(pdb->conn.sock); + if (pdb->sock) + close(pdb->sock); /* release DB handler */ pthread_mutex_unlock(&pdb->mutex); diff --git a/src/utils_ovs.h b/src/utils_ovs.h index 1ddda4de..e90bda31 100644 --- a/src/utils_ovs.h +++ b/src/utils_ovs.h @@ -93,6 +93,10 @@ struct ovs_db_callback_s { }; typedef struct ovs_db_callback_s ovs_db_callback_t; +/* OVS DB defines */ +#define OVS_DB_ADDR_NODE_SIZE 256 +#define OVS_DB_ADDR_SERVICE_SIZE 128 + /* OVS DB prototypes */ /* @@ -104,13 +108,15 @@ typedef struct ovs_db_callback_s ovs_db_callback_t; * shall destroy the returned object. * * PARAMETERS - * `surl' OVS DB communication URL. + * `node' OVS DB Address. + * `service' OVS DB service name. * `cb' OVS DB callbacks. * * RETURN VALUE * New ovs_db_t object upon success or NULL if an error occurred. */ -ovs_db_t *ovs_db_init(const char *surl, ovs_db_callback_t *cb); +ovs_db_t *ovs_db_init(const char *node, const char *service, + ovs_db_callback_t *cb); /* * NAME