#include "utils_dpdk.h"
#define DPDK_DEFAULT_RTE_CONFIG "/var/run/.rte_config"
-#define DPDK_EAL_ARGC 5
-#define DPDK_MAX_BUFFER_SIZE (4096 * 4)
+#define DPDK_EAL_ARGC 10
+// Complete trace should fit into 1024 chars. Trace contain some headers
+// and text together with traced data from pipe. This is the reason why
+// we need to limit DPDK_MAX_BUFFER_SIZE value.
+#define DPDK_MAX_BUFFER_SIZE 896
#define DPDK_CDM_DEFAULT_TIMEOUT 10000
enum DPDK_HELPER_STATUS {
int eal_initialized;
size_t shm_size;
- const char *shm_name;
+ char shm_name[DATA_MAX_NAME_LEN];
sem_t sema_cmd_start;
sem_t sema_cmd_complete;
DPDK_HELPER_TRACE(phc->shm_name);
- ssnprintf(phc->eal_config.coremask, DATA_MAX_NAME_LEN, "%s", "0xf");
- ssnprintf(phc->eal_config.memory_channels, DATA_MAX_NAME_LEN, "%s", "1");
- ssnprintf(phc->eal_config.process_type, DATA_MAX_NAME_LEN, "%s", "secondary");
- ssnprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN, "%s",
- DPDK_DEFAULT_RTE_CONFIG);
+ snprintf(phc->eal_config.coremask, DATA_MAX_NAME_LEN, "%s", "0xf");
+ snprintf(phc->eal_config.memory_channels, DATA_MAX_NAME_LEN, "%s", "1");
+ snprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN, "%s",
+ DPDK_DEFAULT_RTE_CONFIG);
}
int dpdk_helper_eal_config_set(dpdk_helper_ctx_t *phc, dpdk_eal_config_t *ec) {
int status = 0;
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
+
if (strcasecmp("Coremask", child->key) == 0) {
status = cf_util_get_string_buffer(child, phc->eal_config.coremask,
sizeof(phc->eal_config.coremask));
status = cf_util_get_string_buffer(child, phc->eal_config.socket_memory,
sizeof(phc->eal_config.socket_memory));
DEBUG("dpdk_common: EAL:Socket memory %s", phc->eal_config.socket_memory);
- } else if (strcasecmp("ProcessType", child->key) == 0) {
- status = cf_util_get_string_buffer(child, phc->eal_config.process_type,
- sizeof(phc->eal_config.process_type));
- DEBUG("dpdk_common: EAL:Process type %s", phc->eal_config.process_type);
- } else if ((strcasecmp("FilePrefix", child->key) == 0) &&
- (child->values[0].type == OCONFIG_TYPE_STRING)) {
- ssnprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN,
- "/var/run/.%s_config", child->values[0].value.string);
- DEBUG("dpdk_common: EAL:File prefix %s", phc->eal_config.file_prefix);
+ } else if (strcasecmp("FilePrefix", child->key) == 0) {
+ char prefix[DATA_MAX_NAME_LEN];
+
+ status = cf_util_get_string_buffer(child, prefix, sizeof(prefix));
+ if (status == 0) {
+ snprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN,
+ "/var/run/.%s_config", prefix);
+ DEBUG("dpdk_common: EAL:File prefix %s", phc->eal_config.file_prefix);
+ }
+ } else if (strcasecmp("LogLevel", child->key) == 0) {
+ status = cf_util_get_string_buffer(child, phc->eal_config.log_level,
+ sizeof(phc->eal_config.log_level));
+ DEBUG("dpdk_common: EAL:LogLevel %s", phc->eal_config.log_level);
+ } else if (strcasecmp("RteDriverLibPath", child->key) == 0) {
+ status = cf_util_get_string_buffer(
+ child, phc->eal_config.rte_driver_lib_path,
+ sizeof(phc->eal_config.rte_driver_lib_path));
+ DEBUG("dpdk_common: EAL:RteDriverLibPath %s",
+ phc->eal_config.rte_driver_lib_path);
} else {
ERROR("dpdk_common: Invalid '%s' configuration option", child->key);
status = -EINVAL;
static int dpdk_shm_init(const char *name, size_t size, void **map) {
DPDK_HELPER_TRACE(name);
- char errbuf[ERR_BUF_SIZE];
-
int fd = shm_open(name, O_CREAT | O_TRUNC | O_RDWR, 0666);
if (fd < 0) {
- WARNING("dpdk_shm_init: Failed to open %s as SHM:%s", name,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ WARNING("dpdk_shm_init: Failed to open %s as SHM:%s", name, STRERRNO);
*map = NULL;
return -1;
}
int ret = ftruncate(fd, size);
if (ret != 0) {
- WARNING("dpdk_shm_init: Failed to resize SHM:%s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ WARNING("dpdk_shm_init: Failed to resize SHM:%s", STRERRNO);
close(fd);
*map = NULL;
dpdk_shm_cleanup(name, size, NULL);
*map = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (*map == MAP_FAILED) {
- WARNING("dpdk_shm_init:Failed to mmap SHM:%s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ WARNING("dpdk_shm_init:Failed to mmap SHM:%s", STRERRNO);
close(fd);
*map = NULL;
dpdk_shm_cleanup(name, size, NULL);
static void dpdk_shm_cleanup(const char *name, size_t size, void *map) {
DPDK_HELPER_TRACE(name);
- char errbuf[ERR_BUF_SIZE];
+
+ /*
+ * Call shm_unlink first, as 'name' might be no longer accessible after munmap
+ */
+ if (shm_unlink(name))
+ ERROR("shm_unlink failure %s", STRERRNO);
if (map != NULL) {
if (munmap(map, size))
- ERROR("munmap failure %s", sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("munmap failure %s", STRERRNO);
}
-
- if (shm_unlink(name))
- ERROR("shm_unlink failure %s", sstrerror(errno, errbuf, sizeof(errbuf)));
}
void *dpdk_helper_priv_get(dpdk_helper_ctx_t *phc) {
return -EINVAL;
}
- return (phc->shm_size - sizeof(dpdk_helper_ctx_t));
+ return phc->shm_size - sizeof(dpdk_helper_ctx_t);
}
int dpdk_helper_init(const char *name, size_t data_size,
dpdk_helper_ctx_t **pphc) {
dpdk_helper_ctx_t *phc = NULL;
size_t shm_size = sizeof(dpdk_helper_ctx_t) + data_size;
- char errbuf[ERR_BUF_SIZE];
if (pphc == NULL) {
ERROR("%s:Invalid argument(pphc)", __FUNCTION__);
err = sem_init(&phc->sema_cmd_start, 1, 0);
if (err != 0) {
- ERROR("sema_cmd_start semaphore init failed: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("sema_cmd_start semaphore init failed: %s", STRERRNO);
int errno_m = errno;
dpdk_shm_cleanup(name, shm_size, (void *)phc);
return -errno_m;
err = sem_init(&phc->sema_cmd_complete, 1, 0);
if (err != 0) {
- ERROR("sema_cmd_complete semaphore init failed: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("sema_cmd_complete semaphore init failed: %s", STRERRNO);
sem_destroy(&phc->sema_cmd_start);
int errno_m = errno;
dpdk_shm_cleanup(name, shm_size, (void *)phc);
}
phc->shm_size = shm_size;
- phc->shm_name = name;
+ sstrncpy(phc->shm_name, name, sizeof(phc->shm_name));
dpdk_helper_config_default(phc);
return 0;
}
-int dpdk_helper_shutdown(dpdk_helper_ctx_t *phc) {
- if (phc == NULL) {
- ERROR("%s:Invalid argument(phc)", __FUNCTION__);
- return -EINVAL;
- }
+void dpdk_helper_shutdown(dpdk_helper_ctx_t *phc) {
+ if (phc == NULL)
+ return;
DPDK_HELPER_TRACE(phc->shm_name);
sem_destroy(&phc->sema_cmd_start);
sem_destroy(&phc->sema_cmd_complete);
dpdk_shm_cleanup(phc->shm_name, phc->shm_size, (void *)phc);
-
- return 0;
}
static int dpdk_helper_spawn(dpdk_helper_ctx_t *phc) {
- char errbuf[ERR_BUF_SIZE];
if (phc == NULL) {
ERROR("Invalid argument(phc)");
return -EINVAL;
}
if (pipe(phc->pipes) != 0) {
- DEBUG("dpdk_helper_spawn: Could not create helper pipe: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ DEBUG("dpdk_helper_spawn: Could not create helper pipe: %s", STRERRNO);
return -1;
}
int pipe0_flags = fcntl(phc->pipes[0], F_GETFL, 0);
int pipe1_flags = fcntl(phc->pipes[1], F_GETFL, 0);
if (pipe0_flags == -1 || pipe1_flags == -1) {
- WARNING("dpdk_helper_spawn: error setting up pipe flags: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ WARNING("dpdk_helper_spawn: error setting up pipe flags: %s", STRERRNO);
}
int pipe0_err = fcntl(phc->pipes[0], F_SETFL, pipe1_flags | O_NONBLOCK);
int pipe1_err = fcntl(phc->pipes[1], F_SETFL, pipe0_flags | O_NONBLOCK);
if (pipe0_err == -1 || pipe1_err == -1) {
- WARNING("dpdk_helper_spawn: error setting up pipes: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ WARNING("dpdk_helper_spawn: error setting up pipes: %s", STRERRNO);
}
pid_t pid = fork();
dpdk_helper_worker(phc);
exit(0);
} else {
- ERROR("dpdk_helper_start: Failed to fork helper process: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("dpdk_helper_start: Failed to fork helper process: %s", STRERRNO);
return -1;
}
static int dpdk_helper_exit_command(dpdk_helper_ctx_t *phc,
enum DPDK_HELPER_STATUS status) {
- char errbuf[ERR_BUF_SIZE];
DPDK_HELPER_TRACE(phc->shm_name);
close(phc->pipes[1]);
int err = kill(phc->pid, SIGKILL);
if (err) {
- ERROR("%s error sending kill to helper: %s", __FUNCTION__,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("%s error sending kill to helper: %s", __FUNCTION__, STRERRNO);
}
}
} else {
int err = kill(phc->pid, SIGKILL);
if (err) {
- ERROR("%s error sending kill to helper: %s", __FUNCTION__,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("%s error sending kill to helper: %s", __FUNCTION__, STRERRNO);
}
}
/* EAL config must be initialized */
assert(phc->eal_config.coremask[0] != 0);
assert(phc->eal_config.memory_channels[0] != 0);
- assert(phc->eal_config.process_type[0] != 0);
assert(phc->eal_config.file_prefix[0] != 0);
argp[argc++] = "collectd-dpdk";
}
argp[argc++] = "--proc-type";
- argp[argc++] = phc->eal_config.process_type;
+ argp[argc++] = "secondary";
+
+ if (strcasecmp(phc->eal_config.log_level, "") != 0) {
+ argp[argc++] = "--log-level";
+ argp[argc++] = phc->eal_config.log_level;
+ }
+ if (strcasecmp(phc->eal_config.rte_driver_lib_path, "") != 0) {
+ argp[argc++] = "-d";
+ argp[argc++] = phc->eal_config.rte_driver_lib_path;
+ }
assert(argc <= (DPDK_EAL_ARGC * 2 + 1));
DPDK_CHILD_LOG("%s:%s:%d post sema_cmd_complete (pid=%lu)\n", phc->shm_name,
__FUNCTION__, __LINE__, (long)getpid());
if (err) {
- char errbuf[ERR_BUF_SIZE];
DPDK_CHILD_LOG("dpdk_helper_worker: error posting sema_cmd_complete "
"semaphore (%s)\n",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ STRERRNO);
}
#if COLLECT_DEBUG
static int dpdk_helper_status_check(dpdk_helper_ctx_t *phc) {
DEBUG("%s:%s:%d pid=%u %s", phc->shm_name, __FUNCTION__, __LINE__, getpid(),
dpdk_helper_status_str(phc->status));
- char errbuf[ERR_BUF_SIZE];
if (phc->status == DPDK_HELPER_GRACEFUL_QUIT) {
return 0;
__LINE__);
int err = dpdk_helper_spawn(phc);
if (err) {
- ERROR("dpdkstat: error spawning helper %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("dpdkstat: error spawning helper %s", STRERRNO);
}
return -1;
}
__LINE__);
int err = dpdk_helper_spawn(phc);
if (err) {
- ERROR("dpdkstat: error spawning helper %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("dpdkstat: error spawning helper %s", STRERRNO);
}
return -1;
}
.fd = phc->pipes[0], .events = POLLIN,
};
int data_avail = poll(&fds, 1, 0);
+ DEBUG("%s:dpdk_helper_check_pipe: poll data_avail=%d", phc->shm_name,
+ data_avail);
if (data_avail < 0) {
if (errno != EINTR || errno != EAGAIN) {
- char errbuf[ERR_BUF_SIZE];
- ERROR("%s: poll(2) failed: %s", phc->shm_name,
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ ERROR("%s: poll(2) failed: %s", phc->shm_name, STRERRNO);
}
}
while (data_avail) {
- int nbytes = read(phc->pipes[0], buf, sizeof(buf));
+ int nbytes = read(phc->pipes[0], buf, (sizeof(buf) - 1));
+ DEBUG("%s:dpdk_helper_check_pipe: read nbytes=%d", phc->shm_name, nbytes);
if (nbytes <= 0)
break;
- sstrncpy(out, buf, nbytes);
+ buf[nbytes] = '\0';
+ sstrncpy(out, buf, sizeof(out));
DEBUG("%s: helper process:\n%s", phc->shm_name, out);
}
}
/* kick helper to process command */
int err = sem_post(&phc->sema_cmd_start);
if (err) {
- char errbuf[ERR_BUF_SIZE];
ERROR("dpdk_helper_worker: error posting sema_cmd_start semaphore (%s)",
- sstrerror(errno, errbuf, sizeof(errbuf)));
+ STRERRNO);
}
#if COLLECT_DEBUG
return lcore_mask;
} else {
char low_str[DATA_MAX_NAME_LEN];
- char high_str[DATA_MAX_NAME_LEN];
+ char high_str[DATA_MAX_NAME_LEN * 2];
memset(high_str, 0, sizeof(high_str));
memset(low_str, 0, sizeof(low_str));