The parsing of the odp.conf configuration file is added.
The file is searched first in filename specified in the environment
variable $ODP_SYSCONFIG_FILE (where the special string "none" prevent
any file loading)
The file is then searched in the user home directory (~) and
then is the $prefix/etc directory.
This requires libconfig (sudo apt-get install libconfig-dev)

Signed-off-by: Christophe Milard <christophe.mil...@linaro.org>
---
 .travis.yml                                   |  2 +-
 DEPENDENCIES                                  |  8 +--
 platform/linux-generic/Makefile.am            |  1 +
 platform/linux-generic/include/odp_internal.h |  2 +
 platform/linux-generic/m4/configure.m4        | 11 ++++
 platform/linux-generic/odp_init.c             | 80 +++++++++++++++++++++++++++
 6 files changed, 99 insertions(+), 5 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 03e61b1..a6f770c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,7 +19,7 @@ sudo: required
 
 before_install:
         - sudo apt-get -qq update
-        - sudo apt-get install automake autoconf libtool libssl-dev graphviz 
mscgen doxygen
+        - sudo apt-get install automake autoconf libtool libssl-dev graphviz 
mscgen doxygen libconfig-dev
         - sudo apt-get install libpcap-dev linux-headers-`uname -r`
         - gem install asciidoctor
 
diff --git a/DEPENDENCIES b/DEPENDENCIES
index f1f0edd..f285783 100644
--- a/DEPENDENCIES
+++ b/DEPENDENCIES
@@ -18,18 +18,18 @@ Prerequisites for building the OpenDataPlane (ODP) API
 
 3. Required libraries
 
-   Libraries currently required to link: openssl
+   Libraries currently required to link: openssl, libconfig
 
-3.1 OpenSSL native compile
+3.1 OpenSSL and libconf native compile
 
    For native compilation, simply load the necessary libraries using the 
appropriate
    tool set.
 
    On Debian/Ubuntu systems:
-   $ sudo apt-get install libssl-dev
+   $ sudo apt-get install libssl-dev libconfig-dev
 
    On CentOS/RedHat/Fedora systems:
-   $ sudo yum install openssl-devel
+   $ sudo yum install openssl-devel libconfig-devel
 
 3.2 OpenSSL cross compilation
 
diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index 2d97414..579fc3c 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -8,6 +8,7 @@ AM_CFLAGS +=  -I$(srcdir)/include
 AM_CFLAGS +=  -I$(top_srcdir)/include
 AM_CFLAGS +=  -I$(top_builddir)/include
 AM_CFLAGS +=  -Iinclude
+AM_CFLAGS +=  -DSYSCONFDIR=\"@sysconfdir@\"
 
 include_HEADERS = \
                  $(top_srcdir)/include/odp.h \
diff --git a/platform/linux-generic/include/odp_internal.h 
b/platform/linux-generic/include/odp_internal.h
index b313b1f..9d1fc58 100644
--- a/platform/linux-generic/include/odp_internal.h
+++ b/platform/linux-generic/include/odp_internal.h
@@ -22,6 +22,7 @@ extern "C" {
 #include <odp/api/thread.h>
 #include <stdio.h>
 #include <sys/types.h>
+#include <libconfig.h>
 
 extern __thread int __odp_errno;
 
@@ -50,6 +51,7 @@ struct odp_global_data_s {
        odp_cpumask_t control_cpus;
        odp_cpumask_t worker_cpus;
        int num_cpus_installed;
+       config_t configuration;
 };
 
 enum init_stage {
diff --git a/platform/linux-generic/m4/configure.m4 
b/platform/linux-generic/m4/configure.m4
index d3e5528..5fab0cc 100644
--- a/platform/linux-generic/m4/configure.m4
+++ b/platform/linux-generic/m4/configure.m4
@@ -28,6 +28,17 @@ AC_LINK_IFELSE(
     echo "Use newer version. For gcc > 4.7.0"
     exit -1)
 
+# Check for libconfig (required)
+AC_CHECK_HEADERS([libconfig.h], HEADER_LIBCONFIG="yes")
+PKG_CHECK_MODULES([PKGCONFIG], [libconfig >= 1.3.2], LIBRARY_LIBCONFIG="yes")
+if test "x$LIBRARY_LIBCONFIG" != "x" && test "x$HEADER_LIBCONFIG" != "x" ; then
+    CFLAGS="$CFLAGS $PKGCONFIG_CFLAGS"
+    LIBS="$LIBS $PKGCONFIG_LIBS"
+    AM_CPPFLAGS="$AM_CPPFLAGS `pkg-config --cflags-only-I libconfig`"
+else
+    AC_MSG_FAILURE([libconfig not found (required)])
+fi
+
 m4_include([platform/linux-generic/m4/odp_pthread.m4])
 m4_include([platform/linux-generic/m4/odp_openssl.m4])
 m4_include([platform/linux-generic/m4/odp_pcap.m4])
diff --git a/platform/linux-generic/odp_init.c 
b/platform/linux-generic/odp_init.c
index 06c6143..0e9167c 100644
--- a/platform/linux-generic/odp_init.c
+++ b/platform/linux-generic/odp_init.c
@@ -10,6 +10,8 @@
 #include <odp_internal.h>
 #include <odp_schedule_if.h>
 #include <string.h>
+#include <libconfig.h>
+#include <stdlib.h>
 #include <stdio.h>
 #include <linux/limits.h>
 #include <dirent.h>
@@ -21,6 +23,15 @@
 #define _ODP_FILES_FMT "odp-%d-"
 #define _ODP_TMPDIR    "/tmp"
 
+/* the name of the ODP configuration file: */
+#define CONFIGURATION_FILE_ENV_NONE "none"
+#define CONFIGURATION_FILE "odp.conf"
+#define CONFIGURATION_FILE_USR ("." CONFIGURATION_FILE)
+#define CONFIGURATION_FILE_SYS (SYSCONFDIR "/" CONFIGURATION_FILE)
+
+/* the ODP configuration file name can also be oveerwritten by env. variable: 
*/
+#define ODP_SYSCONFIG_FILE_ENV "ODP_SYSCONFIG_FILE"
+
 struct odp_global_data_s odp_global_data;
 
 /* remove all files staring with "odp-<pid>" from a directory "dir" */
@@ -65,6 +76,72 @@ static int cleanup_files(const char *dirpath, int odp_pid)
        return 0;
 }
 
+/* read the odp configuration file
+ *
+ * the configuration file is read from:
+ * 1) Wherever env variable ODP_SYSCONFIG_FILE says (or "none")
+ * 2) ./odp.conf
+ * 3) the @sysconfig@/odp.conf
+ * (checked in reverse order overwritting each-other)
+ * So the environment variable setting supperseeds any other file.
+ * If the environment variable exists and set to the string "none"
+ * the configuration file reading is inibited (used to prevent
+ * test which do not need a file to read the user or system files)
+ */
+static int read_configfile(void)
+{
+       config_t *cf;
+       const char *config_filename;
+       char user_config_filename[PATH_MAX];
+       char *env_config_filename;
+
+       /* initialize and read the configuration file if any: */
+       cf = &odp_global_data.configuration;
+       config_init(cf);
+       config_filename = NULL;
+       /* check if the system config file can be reached :*/
+       if (access(CONFIGURATION_FILE_SYS, R_OK) != -1)
+               config_filename = CONFIGURATION_FILE_SYS;
+       /* check if the user config file can be reached (overwrite if so) :*/
+       strncpy(user_config_filename, getenv("HOME"), PATH_MAX);
+       if (user_config_filename[0]) {
+               strncat(user_config_filename, "/", PATH_MAX);
+               strncat(user_config_filename, CONFIGURATION_FILE_USR, PATH_MAX);
+               if ((access(user_config_filename, R_OK) != -1))
+                       config_filename = user_config_filename;
+       }
+       /* check if other config file is specified via env (overwrite if so):*/
+       env_config_filename = getenv(ODP_SYSCONFIG_FILE_ENV);
+       if (env_config_filename) {
+               /* none means "read no file": */
+               if (!strcmp(env_config_filename, CONFIGURATION_FILE_ENV_NONE))
+                       return 0;
+               if (access(env_config_filename, R_OK) != -1) {
+                       config_filename = env_config_filename;
+               } else {
+                       ODP_ERR("Cannot read ODP configurattion file %s "
+                               "(set by env variable "
+                               ODP_SYSCONFIG_FILE_ENV ")\n",
+                               env_config_filename);
+                       config_filename = NULL;
+                       return -1;
+               }
+       }
+       if (config_filename) {
+               ODP_DBG("Reading configuration file: %s\n", config_filename);
+               if (!config_read_file(cf, config_filename)) {
+                       ODP_ERR("%s:%d - %s\n",
+                               config_error_file(cf),
+                               config_error_line(cf),
+                               config_error_text(cf));
+                       config_destroy(cf);
+                       return(-1);
+               }
+       }
+
+       return 0;
+}
+
 int odp_init_global(odp_instance_t *instance,
                    const odp_init_t *params,
                    const odp_platform_init_t *platform_params ODP_UNUSED)
@@ -87,6 +164,9 @@ int odp_init_global(odp_instance_t *instance,
 
        cleanup_files(_ODP_TMPDIR, odp_global_data.main_pid);
 
+       if (read_configfile())
+               goto init_failed;
+
        if (odp_cpumask_init_global(params)) {
                ODP_ERR("ODP cpumask init failed.\n");
                goto init_failed;
-- 
2.7.4

Reply via email to