Revision
17271
Author
dyatsin
Date
2010-04-09 15:03:54 -0500 (Fri, 09 Apr 2010)

Log Message

Fix for sangoma_boost crashing on start due to queue unitialised
Updated cpu monitor to support different /proc/cpustats format

Modified Paths

Diff

Modified: freeswitch/trunk/libs/freetdm/src/ftdm_cpu_monitor.c (17270 => 17271)


--- freeswitch/trunk/libs/freetdm/src/ftdm_cpu_monitor.c	2010-04-08 16:51:37 UTC (rev 17270)
+++ freeswitch/trunk/libs/freetdm/src/ftdm_cpu_monitor.c	2010-04-09 20:03:54 UTC (rev 17271)
@@ -61,6 +61,9 @@
 	double last_percentage_of_idle_time;
 
 #ifdef __linux__
+	/* the cpu feature gets disabled on errors */
+	int disabled;
+
 	/* all of these are the Linux jiffies last retrieved count */
 	unsigned long long last_user_time;
 	unsigned long long last_system_time;
@@ -97,15 +100,23 @@
 {
 // the output of proc should not change that often from one kernel to other
 // see fs/proc/proc_misc.c or fs/proc/stat.c in the Linux kernel for more details
-// also man 5 proc is useful
-#define CPU_ELEMENTS 8 // change this if you change the format string
-#define CPU_INFO_FORMAT "cpu  %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu"
+// also man 5 proc is useful.
+#define CPU_ELEMENTS_1 7 // change this if you change the format string
+#define CPU_INFO_FORMAT_1 "cpu  %llu %llu %llu %llu %llu %llu %llu"
+
+#define CPU_ELEMENTS_2 8 // change this if you change the format string
+#define CPU_INFO_FORMAT_2 "cpu  %llu %llu %llu %llu %llu %llu %llu %llu"
+
+#define CPU_ELEMENTS_3 9 // change this if you change the format string
+#define CPU_INFO_FORMAT_3 "cpu  %llu %llu %llu %llu %llu %llu %llu %llu %llu"
+
 	static const char procfile[] = "/proc/stat";
 	int rc = 0;
 	int myerrno = 0;
 	int elements = 0;
 	const char *cpustr = NULL;
 	char statbuff[1024];
+	unsigned long long guest = 0;
 
 	if (!p->initd) {
 		p->procfd = open(procfile, O_RDONLY, 0);
@@ -131,12 +142,26 @@
 		return FTDM_FAIL;
 	}
 
-	elements = sscanf(cpustr, CPU_INFO_FORMAT, user, nice, system, idle, iowait, irq, softirq, steal);
-	if (elements != CPU_ELEMENTS) {
-		ftdm_log(FTDM_LOG_ERROR, "wrong format for Linux proc cpu statistics: expected %d elements, but just found %d\n", CPU_ELEMENTS, elements);
-		return FTDM_FAIL;
+	/* test each of the known formats starting from the bigger one */
+	elements = sscanf(cpustr, CPU_INFO_FORMAT_3, user, nice, system, idle, iowait, irq, softirq, steal, &guest);
+	if (elements == CPU_ELEMENTS_3) {
+		user += guest; /* guest operating system's run in user space */
+		return FTDM_SUCCESS;
 	}
-	return FTDM_SUCCESS;
+
+	elements = sscanf(cpustr, CPU_INFO_FORMAT_2, user, nice, system, idle, iowait, irq, softirq, steal);
+	if (elements == CPU_ELEMENTS_2) {
+		return FTDM_SUCCESS;
+	}
+
+	elements = sscanf(cpustr, CPU_INFO_FORMAT_1, user, nice, system, idle, iowait, irq, softirq);
+	if (elements == CPU_ELEMENTS_1) {
+		*steal = 0;
+		return FTDM_SUCCESS;
+	}
+
+	ftdm_log(FTDM_LOG_ERROR, "Unexpected format for Linux proc cpu statistics:%s\n", cpustr);
+	return FTDM_FAIL;
 }
 #endif
 
@@ -146,8 +171,13 @@
 	unsigned long long user, nice, system, idle, iowait, irq, softirq, steal;
 	unsigned long long usertime, kerneltime, idletime, totaltime, halftime;
 
+	*idle_percentage = 100.0;
+	if (p->disabled) {
+		return FTDM_FAIL;
+	}
 	if (ftdm_cpu_read_stats(p, &user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal)) {
-		ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve Linux CPU statistics\n");
+		ftdm_log(FTDM_LOG_ERROR, "Failed to retrieve Linux CPU statistics - disabling cpu monitor\n");
+		p->disabled = 1;
 		return FTDM_FAIL;
 	}
 
@@ -243,7 +273,8 @@
 #else
 /* Unsupported */
 FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
-{
+{'
+	*idle_percentate = 100.0;
 	return FTDM_FAIL;
 }
 #endif

Modified: freeswitch/trunk/libs/freetdm/src/ftdm_io.c (17270 => 17271)


--- freeswitch/trunk/libs/freetdm/src/ftdm_io.c	2010-04-08 16:51:37 UTC (rev 17270)
+++ freeswitch/trunk/libs/freetdm/src/ftdm_io.c	2010-04-09 20:03:54 UTC (rev 17271)
@@ -3360,11 +3360,6 @@
 	ftdm_module_t *mod = (ftdm_module_t *) hashtable_search(globals.module_hash, (void *)type);
 	ftdm_status_t status = FTDM_FAIL;
 
-	if (!span->chan_count) {
-		ftdm_log(FTDM_LOG_WARNING, "Cannot configure signaling on span with no channels\n");
-		return FTDM_FAIL;
-	}
-
 	if (!mod) {
 		ftdm_load_module_assume(type);
 		if ((mod = (ftdm_module_t *) hashtable_search(globals.module_hash, (void *)type))) {
@@ -3376,10 +3371,10 @@
 		va_list ap;
 		va_start(ap, sig_cb);
 		status = mod->sig_configure(span, sig_cb, ap);
-		va_end(ap);
 		if (status == FTDM_SUCCESS && ftdm_test_flag(span, FTDM_SPAN_USE_CHAN_QUEUE)) {
 			status = ftdm_queue_create(&span->pendingchans, SPAN_PENDING_CHANS_QUEUE_SIZE);
 		}
+		va_end(ap);
 	} else {
 		ftdm_log(FTDM_LOG_ERROR, "can't find '%s'\n", type);
 		status = FTDM_FAIL;
@@ -3398,11 +3393,6 @@
 	ftdm_assert_return(sig_cb != NULL, FTDM_FAIL, "No signaling callback");
 	ftdm_assert_return(parameters != NULL, FTDM_FAIL, "No parameters");
 
-	if (!span->chan_count) {
-		ftdm_log(FTDM_LOG_WARNING, "Cannot configure signaling on span with no channels\n");
-		return FTDM_FAIL;
-	}
-
 	if (!mod) {
 		ftdm_load_module_assume(type);
 		if ((mod = (ftdm_module_t *) hashtable_search(globals.module_hash, (void *)type))) {