From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jacek Piasecki Subject: [PATCH v3 3/3] app/testpmd: add parse arguments from JSON config file Date: Tue, 27 Jun 2017 12:52:40 +0200 Message-ID: <1498560760-104196-4-git-send-email-jacekx.piasecki@intel.com> References: <1498474759-102089-6-git-send-email-jacekx.piasecki@intel.com> <1498560760-104196-1-git-send-email-jacekx.piasecki@intel.com> Cc: bruce.richardson@intel.com, deepak.k.jain@intel.com, Kuba Kozak To: dev@dpdk.org Return-path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by dpdk.org (Postfix) with ESMTP id 75A382C08 for ; Tue, 27 Jun 2017 13:05:35 +0200 (CEST) In-Reply-To: <1498560760-104196-1-git-send-email-jacekx.piasecki@intel.com> List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kuba Kozak This patch shows usage of Jansson library to parse application arguments from JSON config file. https://github.com/akheron/jansson If a --cfgfile-path option is passed into commandline non EAL section, then the disired JSON file is loaded and used by app. In case when JSON doesn't exist an INI file is loaded. The INI file can be passed also from --cfgfile-path option. If a file called config.ini is present in current working directory, and no --cfgfile-path option is passed in, config.ini file will be loaded and used by app. Signed-off-by: Kuba Kozak Suggested-by: Bruce Richardson --- app/test-pmd/Makefile | 6 ++++ app/test-pmd/config.json | 33 +++++++++++++++++ app/test-pmd/testpmd.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++- config/common_base | 5 +++ 4 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 app/test-pmd/config.json diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile index c36be19..a1c84cc 100644 --- a/app/test-pmd/Makefile +++ b/app/test-pmd/Makefile @@ -83,6 +83,12 @@ endif endif +ifeq ($(CONFIG_RTE_JSON_SUPPORT),y) +ifeq ($(CONFIG_RTE_LIBRTE_CFGFILE),y) +LDLIBS += -ljansson +endif +endif + CFLAGS_cmdline.o := -D_GNU_SOURCE include $(RTE_SDK)/mk/rte.app.mk diff --git a/app/test-pmd/config.json b/app/test-pmd/config.json new file mode 100644 index 0000000..4589dbc --- /dev/null +++ b/app/test-pmd/config.json @@ -0,0 +1,33 @@ +{ + "DPDK": + { + "v": "", + "l": "0-4", + "n": "4", + "master-lcore": "0", + "proc-type": "primary" + }, + "TEST-PMD": + { + "i": "", + "portmask": "0xff", + "nb-cores": "4", + "port-topology": "paired" + }, + "DPDK.vdev0": + { + "net_ring0": "" + }, + "DPDK.vdev1": + { + "net_ring1": "" + }, + "DPDK.vdev2": + { + "net_ring2": "" + }, + "DPDK.vdev3": + { + "net_ring3": "" + } +} diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index cd69a6b..9ce1bbe 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -46,6 +46,10 @@ #include #include + +#ifdef RTE_JSON_SUPPORT +#include +#endif #include #include @@ -2275,6 +2279,87 @@ cfgfile_load_path(int argc, char **argv) } return NULL; } + +#ifdef RTE_JSON_SUPPORT +/* + * Decoding JSON structure to rte_cfgfile structure. + * Returns handler to cfgfile object, NULL if error. + */ +static struct +rte_cfgfile *l3fwd_json_to_cfg(json_t *json, int flags) +{ + if (!json) { + printf("Error: JSON structure is NULL, nothing to parse\n"); + return NULL; + } + /* create an empty instance of cfgfile structure */ + struct rte_cfgfile *cfgfile = rte_cfgfile_create(flags); + + if (!cfgfile) + return NULL; + + const char *section; + json_t *entry; + + /* set pointer to first section */ + void *iter_section = json_object_iter(json); + + while (iter_section) { + + section = json_object_iter_key(iter_section); + entry = json_object_iter_value(iter_section); + + /* add parsed section name of current section to cfgfile */ + rte_cfgfile_add_section(cfgfile, section); + + /* set pointer to first entry */ + void *iter_entry = json_object_iter(entry); + + while (iter_entry) { + + const char *key; + const char *value; + + key = json_object_iter_key(iter_entry); + value = json_string_value( + json_object_iter_value(iter_entry)); + + /* add parsed key and value of current entry */ + /* to cfgfile */ + rte_cfgfile_add_entry(cfgfile, section, key, value); + + /* pointer to next entry */ + iter_entry = json_object_iter_next(entry, iter_entry); + } + /* pointer to next section */ + iter_section = json_object_iter_next(json, iter_section); + } + return cfgfile; +} + +/* + * Check presence and load JSON file to rte_cfgfile structure. + * Returns handler to cfgfile object, NULL if error. + */ +static struct +rte_cfgfile *l3fwd_load_json_to_cfg(const char *path) +{ + struct rte_cfgfile *cfgfile = NULL; + /* check if config file exist */ + if (access(path, F_OK) != -1) { + /* parse JSON file */ + json_error_t error; + json_t *json = json_load_file(path, 0, &error); + + if (json) + cfgfile = l3fwd_json_to_cfg(json, 0); + else + fprintf(stderr, "JSON error on line %d: %s\n", + error.line, error.text); + } + return cfgfile; +} +#endif #endif #define APP_NAME "TEST-PMD" @@ -2303,9 +2388,16 @@ main(int argc, char** argv) "in default directory)\n"); config_file = strdup("config.ini"); } - +#ifndef RTE_JSON_SUPPORT cfg = rte_cfgfile_load(config_file, CFG_FLAG_EMPTY_VALUES); +#endif +#ifdef RTE_JSON_SUPPORT + if (strstr(config_file, ".ini")) + cfg = rte_cfgfile_load(config_file, CFG_FLAG_EMPTY_VALUES); + else if (strstr(config_file, ".json")) + cfg = l3fwd_load_json_to_cfg(config_file); +#endif if (cfg == NULL) { printf("Info: Valid cfgfile not found\n"); cfg = rte_cfgfile_create(CFG_FLAG_EMPTY_VALUES); diff --git a/config/common_base b/config/common_base index c1d0e69..0eed278 100644 --- a/config/common_base +++ b/config/common_base @@ -734,3 +734,8 @@ CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n # Compile the crypto performance application # CONFIG_RTE_APP_CRYPTO_PERF=y + +# +# Compile JSON support +# +CONFIG_RTE_JSON_SUPPORT=n -- 2.7.4