==== dpdk-2.1.0/lib/librte_eal/common/eal_common_log.c - dpdk-2.1.0/lib/librte_eal/common/eal_common_log.c ====
==== dpdk-2.1.0/lib/librte_eal/common/include/rte_eal.h - dpdk-2.1.0/lib/librte_eal/common/include/rte_eal.h ====
--- /tmp/tmp.6220.37	2015-10-08 16:15:22.402607404 +0200
+++ dpdk-2.1.0/lib/librte_eal/common/include/rte_eal.h	2015-10-08 15:57:21.442627152 +0200
@@ -141,6 +141,9 @@
  * returning. See also the rte_eal_get_configuration() function. Note:
  * This behavior may change in the future.
  *
+ * This function will log and eventually abort the entire application if
+ * initialization fails.
+ *
  * @param argc
  *   The argc argument that was given to the main() function.
  * @param argv
@@ -153,6 +156,27 @@
  *   - On failure, a negative error value.
  */
 int rte_eal_init(int argc, char **argv);
+
+/**
+ * Initialize the Environment Abstraction Layer (EAL).
+ *
+ * Please refer to rte_eal_init() for more information.
+ * The difference between rte_eal_init() and rte_eal_init_raw()
+ * is that the latter will never abort the entire process but rather
+ * will just log an error and return an error code.
+ *
+ * @param logid
+ *   A string that identifies the whole process, used to prefix log messages;
+ *   on Linux will be used as the 'ident' parameter of the syslog facility openlog().
+ * @param cfg
+ *   The internal configuration for RTE EAL.
+ * @return
+ *   - On success, zero.
+ *   - On failure, a negative error value.
+ */
+struct internal_config;
+int rte_eal_init_raw(const char* logid, struct internal_config *cfg);
+
 /**
  * Usage function typedef used by the application usage function.
  *
==== dpdk-2.1.0/lib/librte_eal/linuxapp/eal/eal.c - dpdk-2.1.0/lib/librte_eal/linuxapp/eal/eal.c ====
--- /tmp/tmp.6220.75	2015-10-08 16:15:22.406607404 +0200
+++ dpdk-2.1.0/lib/librte_eal/linuxapp/eal/eal.c	2015-10-08 16:15:10.106607628 +0200
@@ -178,7 +178,7 @@
  * on other parts, e.g. memzones, to detect if there are running secondary
  * processes. */
 static void
-rte_eal_config_create(void)
+rte_eal_config_create(void)			// TODO
 {
 	void *rte_mem_cfg_addr;
 	int retval;
@@ -232,7 +232,7 @@
 
 /* attach to an existing shared memory config */
 static void
-rte_eal_config_attach(void)
+rte_eal_config_attach(void)			// TODO
 {
 	struct rte_mem_config *mem_config;
 
@@ -258,7 +258,7 @@
 
 /* reattach the shared config at exact memory location primary process has it */
 static void
-rte_eal_config_reattach(void)
+rte_eal_config_reattach(void)		// TODO
 {
 	struct rte_mem_config *mem_config;
 	void *rte_mem_cfg_addr;
@@ -305,7 +305,7 @@
 
 /* Sets up rte_config structure with the pointer to shared memory config.*/
 static void
-rte_config_init(void)
+rte_config_init(void)		// TODO
 {
 	rte_config.process_type = internal_config.process_type;
 
@@ -724,25 +724,17 @@
 #endif
 }
 
-/* Launch threads, called at application init(). */
+
+/* Launch threads, called at application init(). Logs and aborts on critical errors. */
 int
 rte_eal_init(int argc, char **argv)
 {
-	int i, fctret, ret;
-	pthread_t thread_id;
-	static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0);
-	struct shared_driver *solib = NULL;
+	int fctret;
 	const char *logid;
-	char cpuset[RTE_CPU_AFFINITY_STR_LEN];
-
-	if (!rte_atomic32_test_and_set(&run_once))
-		return -1;
 
 	logid = strrchr(argv[0], '/');
 	logid = strdup(logid ? logid + 1: argv[0]);
 
-	thread_id = pthread_self();
-
 	if (rte_eal_log_early_init() < 0)
 		rte_panic("Cannot init early logs\n");
 
@@ -751,18 +743,54 @@
 	/* set log level as early as possible */
 	rte_set_log_level(internal_config.log_level);
 
-	if (rte_eal_cpu_init() < 0)
-		rte_panic("Cannot detect lcores\n");
-
 	fctret = eal_parse_args(argc, argv);
 	if (fctret < 0)
 		exit(1);
 
+	if (rte_eal_init_raw(logid, NULL) < 0)
+		rte_panic("Errors encountered during initialization. Cannot proceed.\n");
+
+	return fctret;
+}
+
+/* Library-style init(), will attempt initialization, log on errors and return;
+ * This function does not rte_panic() or exit() the whole process. */
+int
+rte_eal_init_raw(const char* logid, struct internal_config *cfg)
+{
+	int i, ret;
+	pthread_t thread_id;
+	static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0);
+	struct shared_driver *solib = NULL;
+	char cpuset[RTE_CPU_AFFINITY_STR_LEN];
+
+	if (!rte_atomic32_test_and_set(&run_once))
+		return -1;
+
+	thread_id = pthread_self();
+	if (rte_eal_log_early_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot init early logs\n");
+		return -1;
+	}
+
+	if (cfg)
+		memcpy(&internal_config, cfg, sizeof(*cfg));
+
+	/* set log level as early as possible */
+	rte_set_log_level(internal_config.log_level);
+
+	if (rte_eal_cpu_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot detect lcores\n");
+		return -1;
+	}
+
 	if (internal_config.no_hugetlbfs == 0 &&
 			internal_config.process_type != RTE_PROC_SECONDARY &&
 			internal_config.xen_dom0_support == 0 &&
-			eal_hugepage_info_init() < 0)
-		rte_panic("Cannot get hugepage information\n");
+			eal_hugepage_info_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot get hugepage information\n");
+		return -1;
+	}
 
 	if (internal_config.memory == 0 && internal_config.force_sockets == 0) {
 		if (internal_config.no_hugetlbfs)
@@ -786,42 +814,62 @@
 
 	rte_config_init();
 
-	if (rte_eal_pci_init() < 0)
-		rte_panic("Cannot init PCI\n");
+	if (rte_eal_pci_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot init PCI\n");
+		return -1;
+	}
 
 #ifdef RTE_LIBRTE_IVSHMEM
-	if (rte_eal_ivshmem_init() < 0)
-		rte_panic("Cannot init IVSHMEM\n");
+	if (rte_eal_ivshmem_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot init IVSHMEM\n");
+		return -1;
+	}
 #endif
 
-	if (rte_eal_memory_init() < 0)
-		rte_panic("Cannot init memory\n");
+	if (rte_eal_memory_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot init memory\n");
+		return -1;
+	}
 
 	/* the directories are locked during eal_hugepage_info_init */
 	eal_hugedirs_unlock();
 
-	if (rte_eal_memzone_init() < 0)
-		rte_panic("Cannot init memzone\n");
+	if (rte_eal_memzone_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot init memzone\n");
+		return -1;
+	}
 
-	if (rte_eal_tailqs_init() < 0)
-		rte_panic("Cannot init tail queues for objects\n");
+	if (rte_eal_tailqs_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot init tail queues for objects\n");
+		return -1;
+	}
 
 #ifdef RTE_LIBRTE_IVSHMEM
-	if (rte_eal_ivshmem_obj_init() < 0)
-		rte_panic("Cannot init IVSHMEM objects\n");
+	if (rte_eal_ivshmem_obj_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot init IVSHMEM objects\n");
+		return -1;
+	}
 #endif
 
-	if (rte_eal_log_init(logid, internal_config.syslog_facility) < 0)
-		rte_panic("Cannot init logs\n");
+	if (rte_eal_log_init(logid, internal_config.syslog_facility) < 0) {
+		RTE_LOG (ERR, EAL, "Cannot init logs\n");
+		return -1;
+	}
 
-	if (rte_eal_alarm_init() < 0)
-		rte_panic("Cannot init interrupt-handling thread\n");
+	if (rte_eal_alarm_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot init alarm\n");
+		return -1;
+	}
 
-	if (rte_eal_intr_init() < 0)
-		rte_panic("Cannot init interrupt-handling thread\n");
+	if (rte_eal_intr_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot init interrupt-handling thread\n");
+		return -1;
+	}
 
-	if (rte_eal_timer_init() < 0)
-		rte_panic("Cannot init HPET or TSC timers\n");
+	if (rte_eal_timer_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot init HPET or TSC timers\n");
+		return -1;
+	}
 
 	eal_check_mem_on_local_socket();
 
@@ -842,8 +890,10 @@
 		rte_config.master_lcore, (int)thread_id, cpuset,
 		ret == 0 ? "" : "...");
 
-	if (rte_eal_dev_init() < 0)
-		rte_panic("Cannot init pmd devices\n");
+	if (rte_eal_dev_init() < 0) {
+		RTE_LOG (ERR, EAL, "Cannot init pmd devices\n");
+		return -1;
+	}
 
 	RTE_LCORE_FOREACH_SLAVE(i) {
 
@@ -851,18 +901,24 @@
 		 * create communication pipes between master thread
 		 * and children
 		 */
-		if (pipe(lcore_config[i].pipe_master2slave) < 0)
-			rte_panic("Cannot create pipe\n");
-		if (pipe(lcore_config[i].pipe_slave2master) < 0)
-			rte_panic("Cannot create pipe\n");
+		if (pipe(lcore_config[i].pipe_master2slave) < 0) {
+			RTE_LOG (ERR, EAL, "Cannot create pipe\n");
+			return -1;
+		}
+		if (pipe(lcore_config[i].pipe_slave2master) < 0) {
+			RTE_LOG (ERR, EAL, "Cannot create pipe\n");
+			return -1;
+		}
 
 		lcore_config[i].state = WAIT;
 
 		/* create a thread for each lcore */
 		ret = pthread_create(&lcore_config[i].thread_id, NULL,
 				     eal_thread_loop, NULL);
-		if (ret != 0)
-			rte_panic("Cannot create thread\n");
+		if (ret != 0) {
+			RTE_LOG (ERR, EAL, "Cannot create thread\n");
+			return -1;
+		}
 	}
 
 	/*
@@ -873,12 +929,15 @@
 	rte_eal_mp_wait_lcore();
 
 	/* Probe & Initialize PCI devices */
-	if (rte_eal_pci_probe())
-		rte_panic("Cannot probe PCI\n");
+	if (rte_eal_pci_probe()) {
+		RTE_LOG (ERR, EAL, "Cannot probe PCI\n");
+		return -1;
+	}
 
-	return fctret;
+	return 0;
 }
 
+
 /* get core role */
 enum rte_lcore_role_t
 rte_eal_lcore_role(unsigned lcore_id)
