On Tue, May 30, 2017 at 10:30:36AM +0200, Jacek Piasecki wrote:
> From: Kuba Kozak <kubax.kozak@intel.com>
>
> added function rte_eal_configure which translate
> options from config file into argc, **argv form.
>
> changed function rte_eal_init to meld
> argc, argv** options from config file with
> these from command line and then parse as
> before
>
Hi,
while this approach to merging the values from two sources (config
struct and cmdline) works, I'm not sure it's the best way to implement
this. I would have thought it more logical to separate out cmdline args
into name-value pairs to add to the cfgfile struct internally instead.
However, this has the disadvantage of forcing a dependency on cfgfile,
or adding a third name-value pair struct to DPDK [after kvargs, which
supports flat pairs, and cfgfile, which supports sections and pairs].
Using the cfgfile struct also saves us from "flattening out"
hierarchical information we may wish to add in the config file. For
example, consider the following cfgfile structure:
[DPDK]
lcores = 20-25
socket-mem = 2048, 1024
vdevs = 2
[DPDK.vdev0]
name = eth_pcap0
rx_pcap = /path/to/file
tx_pcap = /path/to/other_file
[DPDK.vdev1]
name = eth_tap0
iface = iface_arg
Longer term, it would be good to keep those vdev entries separated as passed
as such to the driver, rather than merging them back into a single
string to be separated out again by kvargs lib.
/Bruce
@@ -32,7 +32,11 @@
include $(RTE_SDK)/mk/rte.vars.mk
DIRS-y += librte_compat
+DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
DIRS-$(CONFIG_RTE_LIBRTE_EAL) += librte_eal
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+DEPDIRS-librte_eal := librte_cfgfile
+endif
DIRS-$(CONFIG_RTE_LIBRTE_RING) += librte_ring
DEPDIRS-librte_ring := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += librte_mempool
@@ -41,8 +45,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_MBUF) += librte_mbuf
DEPDIRS-librte_mbuf := librte_eal librte_mempool
DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += librte_timer
DEPDIRS-librte_timer := librte_eal
-DIRS-$(CONFIG_RTE_LIBRTE_CFGFILE) += librte_cfgfile
-DEPDIRS-librte_cfgfile := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_CMDLINE) += librte_cmdline
DEPDIRS-librte_cmdline := librte_eal
DIRS-$(CONFIG_RTE_LIBRTE_ETHER) += librte_ether
@@ -49,6 +49,8 @@
*
***/
+struct rte_cfgfile; /* forward declaration of struct */
+
#ifndef CFG_NAME_LEN
#define CFG_NAME_LEN 64
#endif
@@ -50,6 +50,10 @@ EXPORT_MAP := rte_eal_version.map
LIBABIVER := 4
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+LDLIBS += -lrte_cfgfile
+endif
+
# specific to bsdapp exec-env
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) := eal.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
@@ -73,6 +73,7 @@
#include <rte_version.h>
#include <rte_atomic.h>
#include <malloc_heap.h>
+#include <rte_cfgfile.h>
#include "eal_private.h"
#include "eal_thread.h"
@@ -92,6 +93,12 @@
* duration of the program, as we hold a write lock on it in the primary proc */
static int mem_cfg_fd = -1;
+static int cfg_argc;
+#ifdef RTE_LIBRTE_CFGFILE
+static char **cfg_argv;
+#endif
+
+
static struct flock wr_lock = {
.l_type = F_WRLCK,
.l_whence = SEEK_SET,
@@ -492,10 +499,28 @@ static void rte_eal_init_alert(const char *msg)
RTE_LOG(ERR, EAL, "%s\n", msg);
}
+#ifdef RTE_LIBRTE_CFGFILE
+static void
+free_pointer_array(char **pkt)
+{
+ int i = 0;
+
+ if (pkt) {
+ while (pkt[i]) {
+ free(pkt[i]);
+ pkt[i++] = 0;
+ }
+ free(pkt);
+ pkt = 0;
+ }
+}
+#endif
+
/* Launch threads, called at application init(). */
int
rte_eal_init(int argc, char **argv)
{
+ int combined_argc; /* combine cfg and param versions */
int i, fctret, ret;
pthread_t thread_id;
static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0);
@@ -519,8 +544,25 @@ static void rte_eal_init_alert(const char *msg)
eal_reset_internal_config(&internal_config);
+#ifdef RTE_LIBRTE_CFGFILE
+ combined_argc = argc + cfg_argc;
+ char *combined_argv[combined_argc + 1];
+
+ combined_argv[0] = argv[0];
+ for (i = 0; i < cfg_argc; i++)
+ combined_argv[i + 1] = cfg_argv[i];
+ for (i = 1; i < argc; i++)
+ combined_argv[i + cfg_argc] = argv[i];
+ combined_argv[combined_argc] = NULL;
+#else
+ combined_argc = argc;
+ char **combined_argv;
+
+ combined_argv = argv;
+#endif
+
/* set log level as early as possible */
- eal_log_level_parse(argc, argv);
+ eal_log_level_parse(combined_argc, combined_argv);
if (rte_eal_cpu_init() < 0) {
rte_eal_init_alert("Cannot detect lcores.");
@@ -528,13 +570,21 @@ static void rte_eal_init_alert(const char *msg)
return -1;
}
- fctret = eal_parse_args(argc, argv);
+ fctret = eal_parse_args(combined_argc, combined_argv);
if (fctret < 0) {
rte_eal_init_alert("Invalid 'command line' arguments.");
rte_errno = EINVAL;
rte_atomic32_clear(&run_once);
return -1;
}
+ fctret -= cfg_argc;
+
+#ifdef RTE_LIBRTE_CFGFILE
+ free_pointer_array(cfg_argv);
+#endif
+
+ if (fctret)
+ argv[fctret] = argv[0];
if (internal_config.no_hugetlbfs == 0 &&
internal_config.process_type != RTE_PROC_SECONDARY &&
@@ -677,3 +727,77 @@ enum rte_proc_type_t
{
return rte_config.process_type;
}
+
+#ifdef RTE_LIBRTE_CFGFILE
+
+static char *strdup_with_prefix(const char *p)
+{
+ char *np;
+
+ if (strlen(p) > 1) {
+ np = (char *)malloc(strlen(p)+3);
+ if (np)
+ strcpy(np, "--");
+ } else {
+ np = (char *)malloc(strlen(p)+2);
+ if (np)
+ strcpy(np, "-");
+ }
+ return np ? strcat(np, p) : np;
+}
+
+int
+rte_eal_configure(struct rte_cfgfile *cfg)
+{
+ int i, num_entries;
+
+ if (cfg == NULL) {
+ rte_errno = -EINVAL;
+ return -1;
+ }
+
+ if (!rte_cfgfile_has_section(cfg, "DPDK"))
+ return 0;
+
+ num_entries = rte_cfgfile_section_num_entries(cfg, "DPDK");
+ if (num_entries <= 0)
+ return 0;
+
+ cfg_argv = malloc((num_entries * 2 + 1) * sizeof(cfg_argv[0]));
+ if (cfg_argv == NULL) {
+ rte_errno = -ENOMEM;
+ return -1;
+ }
+
+ struct rte_cfgfile_entry cfg_entries[num_entries];
+
+ rte_cfgfile_section_entries(cfg, "DPDK", cfg_entries, num_entries);
+
+ cfg_argc = 0;
+ for (i = 0; i < num_entries; i++) {
+ cfg_argv[cfg_argc] = strdup_with_prefix(cfg_entries[i].name);
+ if (!(cfg_argv[cfg_argc]))
+ goto allocation_error;
+ cfg_argc++;
+ if (strlen(cfg_entries[i].value)) {
+ cfg_argv[cfg_argc] = strdup(cfg_entries[i].value);
+ if (!(cfg_argv[cfg_argc]))
+ goto allocation_error;
+ cfg_argc++;
+ }
+ }
+ /* set last pointer to 0 */
+ cfg_argv[cfg_argc] = 0;
+
+ return cfg_argc;
+
+allocation_error:
+ rte_eal_init_alert("Cannot allocate memory in rte_eal_configure()\n");
+ rte_errno = ENOMEM;
+ for (i = 1; i < cfg_argc; i++) {
+ free(cfg_argv[i]);
+ cfg_argv[i] = 0;
+ }
+ return -1;
+}
+#endif
@@ -193,3 +193,8 @@ DPDK_17.05 {
vfio_get_group_no;
} DPDK_17.02;
+
+DPDK_17.08 {
+ rte_eal_configure;
+} DPDK_17.05;
+
@@ -46,6 +46,8 @@
#include <rte_per_lcore.h>
#include <rte_config.h>
+struct rte_cfgfile; /* forward declaration of struct */
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -188,6 +190,10 @@ struct rte_config {
*/
int rte_eal_init(int argc, char **argv);
+#ifdef RTE_LIBRTE_CFGFILE
+int rte_eal_configure(struct rte_cfgfile *cfg);
+#endif
+
/**
* Check if a primary process is currently alive
*
@@ -50,6 +50,9 @@ LDLIBS += -ldl
LDLIBS += -lpthread
LDLIBS += -lgcc_s
LDLIBS += -lrt
+ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y)
+LDLIBS += -lrte_cfgfile
+endif
# specific to linuxapp exec-env
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) := eal.c
@@ -78,6 +78,7 @@
#include <rte_version.h>
#include <rte_atomic.h>
#include <malloc_heap.h>
+#include <rte_cfgfile.h>
#include "eal_private.h"
#include "eal_thread.h"
@@ -122,6 +123,12 @@
/* used by rte_rdtsc() */
int rte_cycles_vmware_tsc_map;
+
+static int cfg_argc;
+#ifdef RTE_LIBRTE_CFGFILE
+static char **cfg_argv;
+#endif
+
/* Return a pointer to the configuration structure */
struct rte_config *
rte_eal_get_configuration(void)
@@ -745,10 +752,12 @@ static void rte_eal_init_alert(const char *msg)
RTE_LOG(ERR, EAL, "%s\n", msg);
}
+
/* Launch threads, called at application init(). */
int
rte_eal_init(int argc, char **argv)
{
+ int combined_argc; /* combine cfg and param versions */
int i, fctret, ret;
pthread_t thread_id;
static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0);
@@ -776,8 +785,25 @@ static void rte_eal_init_alert(const char *msg)
eal_reset_internal_config(&internal_config);
+#ifdef RTE_LIBRTE_CFGFILE
+ combined_argc = argc + cfg_argc;
+ char *combined_argv[combined_argc + 1];
+
+ combined_argv[0] = argv[0];
+ for (i = 0; i < cfg_argc; i++)
+ combined_argv[i + 1] = cfg_argv[i];
+ for (i = 1; i < argc; i++)
+ combined_argv[i + cfg_argc] = argv[i];
+ combined_argv[combined_argc] = NULL;
+#else
+ combined_argc = argc;
+ char **combined_argv;
+
+ combined_argv = argv;
+#endif
+
/* set log level as early as possible */
- eal_log_level_parse(argc, argv);
+ eal_log_level_parse(combined_argc, combined_argv);
if (rte_eal_cpu_init() < 0) {
rte_eal_init_alert("Cannot detect lcores.");
@@ -785,13 +811,17 @@ static void rte_eal_init_alert(const char *msg)
return -1;
}
- fctret = eal_parse_args(argc, argv);
+ fctret = eal_parse_args(combined_argc, combined_argv);
if (fctret < 0) {
rte_eal_init_alert("Invalid 'command line' arguments.");
rte_errno = EINVAL;
rte_atomic32_clear(&run_once);
return -1;
}
+ fctret -= cfg_argc;
+
+ if (fctret)
+ argv[fctret] = argv[0];
if (internal_config.no_hugetlbfs == 0 &&
internal_config.process_type != RTE_PROC_SECONDARY &&
@@ -995,3 +1025,77 @@ int rte_eal_has_hugepages(void)
/* Module has been found */
return 1;
}
+
+#ifdef RTE_LIBRTE_CFGFILE
+
+static char *strdup_with_prefix(const char *p)
+{
+ char *np;
+
+ if (strlen(p) > 1) {
+ np = (char *)malloc(strlen(p)+3);
+ if (np)
+ strcpy(np, "--");
+ } else {
+ np = (char *)malloc(strlen(p)+2);
+ if (np)
+ strcpy(np, "-");
+ }
+ return np ? strcat(np, p) : np;
+}
+
+int
+rte_eal_configure(struct rte_cfgfile *cfg)
+{
+ int i, num_entries;
+
+ if (cfg == NULL) {
+ rte_errno = -EINVAL;
+ return -1;
+ }
+
+ if (!rte_cfgfile_has_section(cfg, "DPDK"))
+ return 0;
+
+ num_entries = rte_cfgfile_section_num_entries(cfg, "DPDK");
+ if (num_entries <= 0)
+ return 0;
+
+ cfg_argv = malloc((num_entries * 2 + 1) * sizeof(cfg_argv[0]));
+ if (cfg_argv == NULL) {
+ rte_errno = -ENOMEM;
+ return -1;
+ }
+
+ struct rte_cfgfile_entry cfg_entries[num_entries];
+
+ rte_cfgfile_section_entries(cfg, "DPDK", cfg_entries, num_entries);
+
+ cfg_argc = 0;
+ for (i = 0; i < num_entries; i++) {
+ cfg_argv[cfg_argc] = strdup_with_prefix(cfg_entries[i].name);
+ if (!(cfg_argv[cfg_argc]))
+ goto allocation_error;
+ cfg_argc++;
+ if (strlen(cfg_entries[i].value)) {
+ cfg_argv[cfg_argc] = strdup(cfg_entries[i].value);
+ if (!(cfg_argv[cfg_argc]))
+ goto allocation_error;
+ cfg_argc++;
+ }
+ }
+ /* set last pointer to 0 */
+ cfg_argv[cfg_argc] = 0;
+
+ return cfg_argc;
+
+allocation_error:
+ rte_eal_init_alert("Cannot allocate memory in rte_eal_configure()\n");
+ rte_errno = ENOMEM;
+ for (i = 1; i < cfg_argc; i++) {
+ free(cfg_argv[i]);
+ cfg_argv[i] = 0;
+ }
+ return -1;
+}
+#endif
@@ -198,3 +198,7 @@ DPDK_17.05 {
vfio_get_group_no;
} DPDK_17.02;
+
+DPDK_17.08 {
+ rte_eal_configure;
+} DPDK_17.05;
@@ -80,7 +80,6 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_POWER) += -lrte_power
_LDLIBS-$(CONFIG_RTE_LIBRTE_TIMER) += -lrte_timer
_LDLIBS-$(CONFIG_RTE_LIBRTE_EFD) += -lrte_efd
-_LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE) += -lrte_cfgfile
_LDLIBS-y += --whole-archive
@@ -96,6 +95,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += -lrte_mempool
_LDLIBS-$(CONFIG_RTE_DRIVER_MEMPOOL_RING) += -lrte_mempool_ring
_LDLIBS-$(CONFIG_RTE_LIBRTE_RING) += -lrte_ring
_LDLIBS-$(CONFIG_RTE_LIBRTE_EAL) += -lrte_eal
+_LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE) += -lrte_cfgfile
_LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE) += -lrte_cmdline
_LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER) += -lrte_reorder