int cerebro_handle_destroy(cerebro_t handle) { if (_cerebro_handle_check(handle) < 0) return -1; if (handle->loaded_state & CEREBRO_CONFIG_LOADED) { if (_cerebro_unload_config(handle) < 0) return -1; if (handle->loaded_state & CEREBRO_CONFIG_LOADED) { CEREBRO_DBG(("loaded_state invalid")); handle->errnum = CEREBRO_ERR_INTERNAL; return -1; } } list_destroy(handle->namelists); handle->namelists = NULL; list_destroy(handle->nodelists); handle->nodelists = NULL; list_destroy(handle->event_fds); handle->event_fds = NULL; handle->errnum = CEREBRO_ERR_SUCCESS; handle->magic = ~CEREBRO_MAGIC_NUMBER; free(handle); return 0; }
int cerebro_event_unregister(cerebro_t handle, int fd) { if (_cerebro_handle_check(handle) < 0) return -1; if (fd < 0) { handle->errnum = CEREBRO_ERR_PARAMETERS; return -1; } if (!list_find_first(handle->event_fds, _event_fd_find, &fd)) { handle->errnum = CEREBRO_ERR_PARAMETERS; return -1; } if (!list_delete_all(handle->event_fds, _event_fd_find, &fd)) { handle->errnum = CEREBRO_ERR_INTERNAL; return -1; } /* ignore potential error, just return result */ close(fd); handle->errnum = CEREBRO_ERR_SUCCESS; return 0; }
cerebro_nodelist_t cerebro_get_metric_data(cerebro_t handle, const char *metric_name) { struct cerebro_nodelist *nodelist = NULL; if (_cerebro_handle_check(handle) < 0) goto cleanup; if (!metric_name || strlen(metric_name) > CEREBRO_MAX_METRIC_NAME_LEN) { handle->errnum = CEREBRO_ERR_PARAMETERS; goto cleanup; } if (!(nodelist = _cerebro_nodelist_create(handle, metric_name))) goto cleanup; if (_cerebro_metric_get_data(handle, nodelist, metric_name, _receive_metric_data_response) < 0) goto cleanup; if (_cerebro_nodelist_sort(nodelist) < 0) goto cleanup; handle->errnum = CEREBRO_ERR_SUCCESS; return nodelist; cleanup: if (nodelist) (void)cerebro_nodelist_destroy(nodelist); return NULL; }
cerebro_namelist_t cerebro_get_event_names(cerebro_t handle) { struct cerebro_namelist *namelist = NULL; int fd = -1; if (_cerebro_handle_check(handle) < 0) goto cleanup; if (!(namelist = _cerebro_namelist_create(handle))) goto cleanup; if ((fd = _setup_event_connection(handle, CEREBRO_EVENT_NAMES)) < 0) goto cleanup; if (_get_event_names(handle, fd, namelist) < 0) goto cleanup; /* ignore potential error, just return result */ close(fd); handle->errnum = CEREBRO_ERR_SUCCESS; return namelist; cleanup: if (namelist) (void)cerebro_namelist_destroy(namelist); /* ignore potential error, we're in the error path already */ if (fd >= 0) close(fd); return NULL; }
int cerebro_get_flags(cerebro_t handle) { if (_cerebro_handle_check(handle) < 0) return -1; return handle->flags; }
int cerebro_get_timeout_len(cerebro_t handle) { if (_cerebro_handle_check(handle) < 0) return -1; return handle->timeout_len; }
int cerebro_get_port(cerebro_t handle) { if (_cerebro_handle_check(handle) < 0) return -1; return handle->port; }
char * cerebro_get_hostname(cerebro_t handle) { if (_cerebro_handle_check(handle) < 0) return NULL; return handle->hostname; }
int cerebro_set_timeout_len(cerebro_t handle, unsigned int timeout_len) { if (_cerebro_handle_check(handle) < 0) return -1; handle->timeout_len = timeout_len; return 0; }
int cerebro_set_port(cerebro_t handle, unsigned int port) { if (_cerebro_handle_check(handle) < 0) return -1; handle->port = port; return 0; }
int cerebro_set_flags(cerebro_t handle, unsigned int flags) { if (_cerebro_handle_check(handle) < 0) return -1; if (flags & ~CEREBRO_METRIC_FLAGS_MASK) { handle->errnum = CEREBRO_ERR_PARAMETERS; return -1; } handle->flags = flags; return 0; }
/* * _cerebro_metric_control * * Common code for cerebro metric control API * * Returns 0 on success, -1 on error */ static int _cerebro_metric_control(cerebro_t handle, unsigned int command, const char *metric_name, unsigned int metric_value_type, unsigned int metric_value_len, void *metric_value) { int fd = -1, rv = -1; if (_cerebro_handle_check(handle) < 0) return -1; if (!metric_name || strlen(metric_name) > CEREBRO_MAX_METRIC_NAME_LEN) { handle->errnum = CEREBRO_ERR_PARAMETERS; return -1; } if (_cerebro_load_config(handle) < 0) goto cleanup; if ((fd = _setup_metric_control_fd(handle)) < 0) goto cleanup; if (_metric_control_request_send(handle, fd, command, metric_name, metric_value_type, metric_value_len, metric_value) < 0) goto cleanup; if (_metric_control_response_receive(handle, fd) < 0) goto cleanup; handle->errnum = CEREBRO_ERR_SUCCESS; rv = 0; cleanup: /* ignore potential error, just return result */ close(fd); return rv; }
int cerebro_set_hostname(cerebro_t handle, const char *hostname) { if (_cerebro_handle_check(handle) < 0) return -1; if (hostname && strlen(hostname) > CEREBRO_MAX_HOSTNAME_LEN) { handle->errnum = CEREBRO_ERR_OVERFLOW; return -1; } if (hostname) strcpy(handle->hostname, hostname); else memset(handle->hostname, '\0', CEREBRO_MAX_HOSTNAME_LEN+1); return 0; }
/* * _receive_metric_data_response * * Receive a metric server data response. * * Returns 0 on success, -1 on error */ static int _receive_metric_data_response(cerebro_t handle, void *list, struct cerebro_metric_server_response *res, unsigned int bytes_read, int fd) { struct cerebro_nodelist *nodelist; char nodename_buf[CEREBRO_MAX_NODENAME_LEN+1]; u_int32_t mtype, mlen; int rv = -1; if (_cerebro_handle_check(handle) < 0) { CEREBRO_DBG(("handle invalid")); handle->errnum = CEREBRO_ERR_INTERNAL; goto cleanup; } if (!list || !res || fd <= 0) { CEREBRO_DBG(("invalid parameters")); handle->errnum = CEREBRO_ERR_INTERNAL; goto cleanup; } res->metric_value = NULL; nodelist = (struct cerebro_nodelist *)list; if (nodelist->magic != CEREBRO_NODELIST_MAGIC_NUMBER) { CEREBRO_DBG(("invalid parameters")); handle->errnum = CEREBRO_ERR_INTERNAL; goto cleanup; } mtype = res->metric_value_type; mlen = res->metric_value_len; if (check_data_type_len(mtype, mlen) < 0) { handle->errnum = CEREBRO_ERR_PROTOCOL; goto cleanup; } if (mlen) { if (_receive_metric_value(handle, res, fd) < 0) goto cleanup; } /* Guarantee ending '\0' character */ memset(nodename_buf, '\0', CEREBRO_MAX_NODENAME_LEN+1); memcpy(nodename_buf, res->name, CEREBRO_MAX_NODENAME_LEN); if (_cerebro_nodelist_append(nodelist, nodename_buf, res->metric_value_received_time, res->metric_value_type, res->metric_value_len, res->metric_value) < 0) goto cleanup_metric_value; rv = 0; cleanup_metric_value: free(res->metric_value); cleanup: return rv; }
int cerebro_event_parse(cerebro_t handle, int fd, char **nodename, unsigned int *event_value_type, unsigned int *event_value_len, void **event_value) { struct cerebro_event event; char buf[CEREBRO_MAX_PACKET_LEN]; struct pollfd pfd; int bytes_read, vbytes_read, n; unsigned int errnum; char *vbuf = NULL; void *event_value_ptr = NULL; memset(&event, '\0', sizeof(struct cerebro_event)); if (_cerebro_handle_check(handle) < 0) goto cleanup; if (fd < 0) { handle->errnum = CEREBRO_ERR_PARAMETERS; goto cleanup; } if (!list_find_first(handle->event_fds, _event_fd_find, &fd)) { handle->errnum = CEREBRO_ERR_PARAMETERS; goto cleanup; } pfd.fd = fd; pfd.events = POLLIN; pfd.revents = 0; if ((n = poll(&pfd, 1, 0)) < 0) { CEREBRO_DBG(("poll: %s", strerror(errno))); handle->errnum = CEREBRO_ERR_INTERNAL; goto cleanup; } if (!n) { handle->errnum = CEREBRO_ERR_EVENT_NOT_RECEIVED; goto cleanup; } if (!(pfd.revents & POLLIN)) { handle->errnum = CEREBRO_ERR_EVENT_NOT_RECEIVED; goto cleanup; } if ((bytes_read = receive_data(fd, CEREBRO_EVENT_HEADER_LEN, buf, CEREBRO_MAX_PACKET_LEN, CEREBRO_EVENT_SERVER_PROTOCOL_CLIENT_TIMEOUT_LEN, &errnum)) < 0) { handle->errnum = errnum; goto cleanup; } if (bytes_read < CEREBRO_EVENT_HEADER_LEN) { handle->errnum = CEREBRO_ERR_PROTOCOL; goto cleanup; } if (_event_server_err_check(handle, buf, bytes_read) < 0) goto cleanup; if (_event_header_unmarshall(handle, &event, buf, bytes_read) < 0) goto cleanup; if (check_data_type_len(event.event_value_type, event.event_value_len) < 0) { handle->errnum = CEREBRO_ERR_PROTOCOL; goto cleanup; } if (event.event_value_len) { if (!(vbuf = malloc(event.event_value_len))) { handle->errnum = CEREBRO_ERR_OUTMEM; goto cleanup; } if ((vbytes_read = receive_data(fd, event.event_value_len, vbuf, event.event_value_len, CEREBRO_EVENT_SERVER_PROTOCOL_CLIENT_TIMEOUT_LEN, &errnum)) < 0) { handle->errnum = errnum; goto cleanup; } if (vbytes_read != event.event_value_len) { handle->errnum = CEREBRO_ERR_PROTOCOL; goto cleanup; } if (event_value) { if (_event_value_unmarshall(handle, &event, &event_value_ptr, vbuf, vbytes_read) < 0) goto cleanup; event.event_value = event_value_ptr; event_value_ptr = NULL; } else event.event_value = NULL; free(vbuf); vbuf = NULL; } if (nodename) { char nodename_buf[CEREBRO_MAX_NODENAME_LEN + 1]; /* To ensure null string at end */ memset(nodename_buf, '\0', CEREBRO_MAX_NODENAME_LEN + 1); memcpy(nodename_buf, event.nodename, CEREBRO_MAX_NODENAME_LEN); if (!(*nodename = strdup(nodename_buf))) { handle->errnum = CEREBRO_ERR_OUTMEM; goto cleanup; } } if (event_value_type) *event_value_type = event.event_value_type; if (event_value_len) *event_value_len = event.event_value_len; if (event_value) { *event_value = event.event_value; /* Remove other pointer to the data, so it can't be freed */ event.event_value = NULL; } handle->errnum = CEREBRO_ERR_SUCCESS; return 0; cleanup: if (vbuf) free(vbuf); if (event_value_ptr) free(event_value_ptr); if (event.event_value) free(event.event_value); return -1; }
int cerebro_event_register(cerebro_t handle, const char *event_name) { char buf[CEREBRO_MAX_PACKET_LEN]; int bytes_read; int fd = -1, *fdPtr = NULL; unsigned int errnum; if (_cerebro_handle_check(handle) < 0) goto cleanup; if (!event_name || strlen(event_name) > CEREBRO_MAX_EVENT_NAME_LEN) { handle->errnum = CEREBRO_ERR_PARAMETERS; goto cleanup; } if ((fd = _setup_event_connection(handle, event_name)) < 0) goto cleanup; if ((bytes_read = receive_data(fd, CEREBRO_EVENT_SERVER_RESPONSE_LEN, buf, CEREBRO_MAX_PACKET_LEN, CEREBRO_EVENT_SERVER_PROTOCOL_CLIENT_TIMEOUT_LEN, &errnum)) < 0) { handle->errnum = errnum; goto cleanup; } if (bytes_read < CEREBRO_EVENT_SERVER_RESPONSE_LEN) { handle->errnum = CEREBRO_ERR_PROTOCOL; goto cleanup; } if (_event_server_err_check(handle, buf, bytes_read) < 0) goto cleanup; if (!(fdPtr = (int *)malloc(sizeof(int)))) { handle->errnum = CEREBRO_ERR_OUTMEM; goto cleanup; } *fdPtr = fd; if (!list_append(handle->event_fds, fdPtr)) { CEREBRO_DBG(("list_append: %s", strerror(errno))); handle->errnum = CEREBRO_ERR_INTERNAL; goto cleanup; } handle->errnum = CEREBRO_ERR_SUCCESS; return fd; cleanup: /* ignore potential error, we're in the error path already */ if (fd >= 0) close(fd); if (fdPtr) free(fdPtr); return -1; }