[API-NEXT,PATCHv11,3/5] linux-gen: init: adding configuration file parsing

Message ID 1485280086-3958-4-git-send-email-christophe.milard@linaro.org
State New
Headers show
Series
  • driver initialisation framework
Related show

Commit Message

Christophe Milard Jan. 24, 2017, 5:48 p.m.
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.milard@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(-)

-- 
2.7.4

Patch

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;