* Krzysztof Matczak <krzysztofx@intel.com>
*/
+#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
+
#include "semaphore.h"
#include "sys/mman.h"
#include "utils_dpdk.h"
#include "utils_time.h"
-#include "collectd.h"
#include <rte_config.h>
#include <rte_eal.h>
#define KEEPALIVE_PLUGIN_INSTANCE "keepalive"
#define RTE_KEEPALIVE_SHM_NAME "/dpdk_keepalive_shm_name"
-#define RTE_VERSION_16_07 RTE_VERSION_NUM(16, 7, 0, 16)
-
typedef struct dpdk_keepalive_shm_s {
sem_t core_died;
enum rte_keepalive_state core_state[RTE_KEEPALIVE_MAXCORES];
dpdk_keepalive_shm_t *shm;
char shm_name[DATA_MAX_NAME_LEN];
int notify;
+ int fd;
} dpdk_keep_alive_config_t;
typedef struct dpdk_events_config_s {
static dpdk_helper_ctx_t *g_hc;
-static int dpdk_event_keep_alive_shm_create(void) {
+static int dpdk_event_keep_alive_shm_open(void) {
dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
char *shm_name;
}
char errbuf[ERR_BUF_SIZE];
- int fd = shm_open(shm_name, O_RDWR, 0);
+ int fd = shm_open(shm_name, O_RDONLY, 0);
if (fd < 0) {
ERROR(DPDK_EVENTS_PLUGIN ": Failed to open %s as SHM:%s. Is DPDK KA "
"primary application running?",
shm_name, sstrerror(errno, errbuf, sizeof(errbuf)));
return errno;
- } else {
- ec->config.keep_alive.shm =
- (dpdk_keepalive_shm_t *)mmap(0, sizeof(*(ec->config.keep_alive.shm)),
- PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- close(fd);
- if (ec->config.keep_alive.shm == MAP_FAILED) {
- ERROR(DPDK_EVENTS_PLUGIN ": Failed to mmap KA SHM:%s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
- return errno;
+ }
+
+ if (ec->config.keep_alive.fd != -1) {
+ struct stat stat_old, stat_new;
+
+ if (fstat(ec->config.keep_alive.fd, &stat_old) || fstat(fd, &stat_new)) {
+ ERROR(DPDK_EVENTS_PLUGIN ": failed to get information about a file");
+ close(fd);
+ return -1;
+ }
+
+ /* Check if inode number has changed. If yes, then create a new mapping */
+ if (stat_old.st_ino == stat_new.st_ino) {
+ close(fd);
+ return 0;
+ }
+
+ if (munmap(ec->config.keep_alive.shm, sizeof(dpdk_keepalive_shm_t)) != 0) {
+ ERROR(DPDK_EVENTS_PLUGIN ": munmap KA monitor failed");
+ close(fd);
+ return -1;
}
+
+ close(ec->config.keep_alive.fd);
+ ec->config.keep_alive.fd = -1;
}
+ ec->config.keep_alive.shm = (dpdk_keepalive_shm_t *)mmap(
+ 0, sizeof(*(ec->config.keep_alive.shm)), PROT_READ, MAP_SHARED, fd, 0);
+ if (ec->config.keep_alive.shm == MAP_FAILED) {
+ ERROR(DPDK_EVENTS_PLUGIN ": Failed to mmap KA SHM:%s",
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ close(fd);
+ return errno;
+ }
+ ec->config.keep_alive.fd = fd;
+
return 0;
}
ec->config.interval = plugin_get_interval();
+ /* In configless mode when no <Plugin/> section is defined in config file
+ * both link_status and keep_alive should be enabled */
+
/* Link Status */
- ec->config.link_status.enabled = 0;
+ ec->config.link_status.enabled = 1;
ec->config.link_status.enabled_port_mask = ~0;
ec->config.link_status.send_updated = 1;
ec->config.link_status.notify = 0;
}
/* Keep Alive */
- ec->config.keep_alive.enabled = 0;
+ ec->config.keep_alive.enabled = 1;
ec->config.keep_alive.send_updated = 1;
ec->config.keep_alive.notify = 0;
- memset(&ec->config.keep_alive.lcore_mask, 0,
+ /* by default enable 128 cores */
+ memset(&ec->config.keep_alive.lcore_mask, 1,
sizeof(ec->config.keep_alive.lcore_mask));
memset(&ec->config.keep_alive.shm_name, 0,
sizeof(ec->config.keep_alive.shm_name));
+ ec->config.keep_alive.shm = MAP_FAILED;
+ ec->config.keep_alive.fd = -1;
}
static int dpdk_events_preinit(void) {
static int dpdk_events_config(oconfig_item_t *ci) {
DPDK_EVENTS_TRACE();
-
int ret = dpdk_events_preinit();
if (ret)
return ret;
dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
+ /* Disabling link_status and keep_alive since <Plugin/> config section
+ * specifies if those should be enabled */
+ ec->config.keep_alive.enabled = ec->config.link_status.enabled = 0;
+ memset(&ec->config.keep_alive.lcore_mask, 0,
+ sizeof(ec->config.keep_alive.lcore_mask));
+
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
if (strcasecmp("EAL", child->key) == 0) {
}
}
+ if (!ec->config.keep_alive.enabled && !ec->config.link_status.enabled) {
+ ERROR(DPDK_EVENTS_PLUGIN ": At least one type of events should be "
+ "configured for collecting. Plugin misconfigured");
+ return -1;
+ }
+
return ret;
}
}
dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(phc);
-
+ int ret = 0;
if (ec->config.link_status.enabled)
- dpdk_helper_link_status_get(phc);
+ ret = dpdk_helper_link_status_get(phc);
- return 0;
+ return ret;
}
static void dpdk_events_notification_dispatch(int severity,
- char *plugin_instance,
- cdtime_t time, char *msg) {
- notification_t n = {0};
- n.severity = severity;
- n.time = time;
+ const char *plugin_instance,
+ cdtime_t time, const char *msg) {
+ notification_t n = {
+ .severity = severity, .time = time, .plugin = DPDK_EVENTS_PLUGIN};
sstrncpy(n.host, hostname_g, sizeof(n.host));
- sstrncpy(n.plugin, DPDK_EVENTS_PLUGIN, sizeof(n.plugin));
sstrncpy(n.plugin_instance, plugin_instance, sizeof(n.plugin_instance));
sstrncpy(n.message, msg, sizeof(n.message));
plugin_dispatch_notification(&n);
}
-static void dpdk_events_gauge_submit(char *plugin_instance, char *type,
- gauge_t value, cdtime_t time) {
+static void dpdk_events_gauge_submit(const char *plugin_instance,
+ const char *type_instance, gauge_t value,
+ cdtime_t time) {
value_list_t vl = {.values = &(value_t){.gauge = value},
.values_len = 1,
.time = time,
.meta = NULL};
sstrncpy(vl.host, hostname_g, sizeof(vl.host));
sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance));
- sstrncpy(vl.type_instance, type, sizeof(vl.type_instance));
+ sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
plugin_dispatch_values(&vl);
}
return 0;
}
-static int dpdk_events_keep_alive_dispatch(dpdk_helper_ctx_t *phc) {
+static void dpdk_events_keep_alive_dispatch(dpdk_helper_ctx_t *phc) {
dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(phc);
/* dispatch Keep Alive values to collectd */
ec->core_info[i].lcore_state = ec->config.keep_alive.shm->core_state[i];
ec->core_info[i].read_time = cdtime();
-#if RTE_VERSION >= RTE_VERSION_16_07
if (ec->config.keep_alive.notify) {
char msg[DATA_MAX_NAME_LEN];
int sev;
ec->config.keep_alive.shm->core_state[i],
ec->core_info[i].read_time);
}
-#else
- dpdk_events_gauge_submit(KEEPALIVE_PLUGIN_INSTANCE, core_name,
- ec->config.keep_alive.shm->core_state[i],
- ec->core_info[i].read_time);
-#endif /* #if RTE_VERSION >= RTE_VERSION_16_07 */
}
}
-
- return 0;
}
static int dpdk_events_read(user_data_t *ud) {
if (g_hc == NULL) {
ERROR(DPDK_EVENTS_PLUGIN ": plugin not initialized.");
- return -EINVAL;
+ return -1;
}
dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
+ int ls_ret = -1, ka_ret = -1;
- if (!ec->config.keep_alive.enabled && !ec->config.link_status.enabled) {
- /* nothing to do */
- return 0;
- }
-
+ int cmd_res = 0;
if (ec->config.link_status.enabled) {
- int cmd_res = 0;
- int ret = dpdk_helper_command(g_hc, DPDK_CMD_GET_EVENTS, &cmd_res,
- ec->config.interval);
- if (cmd_res == 0 && ret == 0) {
+ ls_ret = dpdk_helper_command(g_hc, DPDK_CMD_GET_EVENTS, &cmd_res,
+ ec->config.interval);
+ if (cmd_res == 0 && ls_ret == 0) {
dpdk_events_link_status_dispatch(g_hc);
}
}
if (ec->config.keep_alive.enabled) {
- dpdk_events_keep_alive_dispatch(g_hc);
+ ka_ret = dpdk_event_keep_alive_shm_open();
+ if (ka_ret) {
+ ERROR(DPDK_EVENTS_PLUGIN
+ ": %s : error %d in dpdk_event_keep_alive_shm_open()",
+ __FUNCTION__, ka_ret);
+ } else
+ dpdk_events_keep_alive_dispatch(g_hc);
+ }
+
+ if (!((cmd_res || ls_ret) == 0 || ka_ret == 0)) {
+ ERROR(DPDK_EVENTS_PLUGIN ": Read failure for all enabled event types");
+ return -1;
}
return 0;
if (ret)
return ret;
- dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
-
- if (ec->config.keep_alive.enabled) {
- ret = dpdk_event_keep_alive_shm_create();
- if (ret) {
- ERROR(DPDK_EVENTS_PLUGIN ": %s : error %d in ka_shm_create()",
- __FUNCTION__, ret);
- return ret;
- }
- }
return 0;
}
static int dpdk_events_shutdown(void) {
DPDK_EVENTS_TRACE();
- int ret = 0;
+ int ret;
dpdk_events_ctx_t *ec = DPDK_EVENTS_CTX_GET(g_hc);
if (ec->config.keep_alive.enabled) {
- ret = munmap(ec->config.keep_alive.shm, sizeof(dpdk_keepalive_shm_t));
- if (ret) {
- ERROR(DPDK_EVENTS_PLUGIN ": munmap KA monitor returned %d", ret);
- return ret;
+ if (ec->config.keep_alive.fd != -1) {
+ close(ec->config.keep_alive.fd);
+ ec->config.keep_alive.fd = -1;
+ }
+
+ if (ec->config.keep_alive.shm != MAP_FAILED) {
+ if (munmap(ec->config.keep_alive.shm, sizeof(dpdk_keepalive_shm_t))) {
+ ERROR(DPDK_EVENTS_PLUGIN ": munmap KA monitor failed");
+ return -1;
+ }
+ ec->config.keep_alive.shm = MAP_FAILED;
}
}