--- zaptel-1.4.9.2.oslec/kernel/zaptel-base.c 2008-06-16 18:09:27.719196772 +0700 +++ zaptel/kernel/zaptel-base.c 2008-06-16 17:41:30.554380521 +0700 @@ -34,6 +34,12 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* + 2008.03.28, pavel[AT]parabel.ru + + Implemented: correct master arbitrage + Implemented: export to procfs, who is the current master for zaptel + */ #include "zconfig.h" #include "../version.h" @@ -251,7 +257,8 @@ static sumtype *conf_sums; static sumtype *conf_sums_prev; -static struct zt_span *master; +static struct zt_span *master = NULL; +static struct zt_span *pref_master = NULL; static struct file_operations zt_fops; struct file_operations *zt_transcode_fops = NULL; @@ -2960,6 +2967,43 @@ spin_unlock_irqrestore(&chan->lock, flags); } +static inline int __can_be_master (struct zt_span *span) { + if (span && !span->alarms && (span->flags & ZT_FLAG_RUNNING)) return 1; + return 0; +} + +/* + 1. trying preffered master SPAN + 2. trying non-zero channel SPANS + 3. trying zero-channel SPANS (ztdummy,...) + */ +void zt_checkmaster (void) { + int x; + struct zt_span *dummy = NULL; + struct zt_span *newmaster = NULL; + struct zt_span *curmaster = master; + + if (__can_be_master(pref_master)) { + newmaster = pref_master; + } else { + /* Switch to other master if current master in alarm */ + for (x=1; xchannels > 0) { + newmaster = spans[x]; + break; //We're happy now. + } else + if (!dummy) dummy = spans[x]; + + } + } + } + + master = (newmaster) ? newmaster : dummy; + if (master != curmaster) + printk("Zaptel: Master changed to %s\n", (master)? master->name: "no master"); +} + void zt_alarm_notify(struct zt_span *span) { int x; @@ -2976,16 +3020,8 @@ span->lastalarms = span->alarms; for (x = 0; x < span->channels; x++) zt_alarm_channel(&span->chans[x], span->alarms); - /* Switch to other master if current master in alarm */ - for (x=1; xalarms && (spans[x]->flags & ZT_FLAG_RUNNING)) { - if(master != spans[x]) - printk("Zaptel: Master changed to %s\n", spans[x]->name); - master = spans[x]; - break; - } - } } + zt_checkmaster (); } #define VALID_SPAN(j) do { \ @@ -3474,6 +3510,7 @@ spin_unlock_irqrestore(&spans[j]->chans[x].lock, flags); spans[j]->chans[x].rxhooksig = ZT_RXSIG_INITIAL; } + zt_checkmaster (); } return 0; case ZT_SHUTDOWN: @@ -4950,11 +4987,9 @@ if (debug) printk("Registered Span %d ('%s') with %d channels\n", span->spanno, span->name, span->channels); - if (!master || prefmaster) { - master = span; - if (debug) - printk("Span ('%s') is new master\n", span->name); - } + if (prefmaster) { + pref_master = span; + } return 0; } @@ -4962,7 +4997,6 @@ { int x; int new_maxspans; - static struct zt_span *new_master; #ifdef CONFIG_PROC_FS char tempfile[17]; @@ -5008,22 +5042,17 @@ for (x=0;xchannels;x++) zt_chan_unreg(&span->chans[x]); new_maxspans = 0; - new_master = master; /* FIXME: locking */ if (master == span) - new_master = NULL; + master = NULL; + if (pref_master == span) + pref_master = NULL; for (x=1;xname: "no master"); - master = new_master; + zt_checkmaster (); return 0; }