]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Fix for sangoma_boost crashing on start due to queue unitialised
authorDavid Yat Sin <dyatsin@sangoma.com>
Fri, 9 Apr 2010 20:03:54 +0000 (16:03 -0400)
committerDavid Yat Sin <dyatsin@sangoma.com>
Fri, 9 Apr 2010 20:03:54 +0000 (16:03 -0400)
Updated cpu monitor to support different /proc/cpustats format

libs/freetdm/src/ftdm_cpu_monitor.c
libs/freetdm/src/ftdm_io.c

index 7c79a2e65ce8575b58e736128139ecfc3bfa3a1c..b02f5a0d1f42fc16b408213aa160e3c4d216ddfc 100644 (file)
@@ -61,6 +61,9 @@ struct ftdm_cpu_monitor_stats
        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 @@ static ftdm_status_t ftdm_cpu_read_stats(struct ftdm_cpu_monitor_stats *p,
 {
 // 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 @@ static ftdm_status_t ftdm_cpu_read_stats(struct ftdm_cpu_monitor_stats *p,
                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 @@ FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time (struct ftdm_cpu_monitor
        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 @@ FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_
 #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
index 2cacf69d9045715697acba215506f20267dc556a..8e56937a3968d186eb290fb293b7a34979cc2821 100644 (file)
@@ -3407,6 +3407,9 @@ FT_DECLARE(ftdm_status_t) ftdm_configure_span_signaling(const char *type, ftdm_s
 
        if (mod->configure_span_signaling) {
                status = mod->configure_span_signaling(span, sig_cb, parameters);
+               if (status == FTDM_SUCCESS && ftdm_test_flag(span, FTDM_SPAN_USE_CHAN_QUEUE)) {
+                       status = ftdm_queue_create(&span->pendingchans, SPAN_PENDING_CHANS_QUEUE_SIZE);
+               }
        } else {
                ftdm_log(FTDM_LOG_ERROR, "Module %s did not implement the signaling configuration method\n", type);
        }