From e7ff9f8506dbbc57538e562b277f216bc31ecc93 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Fri, 9 Apr 2010 16:03:54 -0400 Subject: [PATCH] Fix for sangoma_boost crashing on start due to queue unitialised Updated cpu monitor to support different /proc/cpustats format --- libs/freetdm/src/ftdm_cpu_monitor.c | 51 +++++++++++++++++++++++------ libs/freetdm/src/ftdm_io.c | 3 ++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/libs/freetdm/src/ftdm_cpu_monitor.c b/libs/freetdm/src/ftdm_cpu_monitor.c index 7c79a2e65c..b02f5a0d1f 100644 --- a/libs/freetdm/src/ftdm_cpu_monitor.c +++ b/libs/freetdm/src/ftdm_cpu_monitor.c @@ -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 diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 2cacf69d90..8e56937a39 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -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); }