[Pkg-voip-commits] [asterisk] 01/01: fix regressions due to dahdi_pri_event_removed

tzafrir at debian.org tzafrir at debian.org
Mon May 19 15:11:16 UTC 2014


This is an automated email from the git hooks/post-receive script.

tzafrir pushed a commit to branch master
in repository asterisk.

commit 38e5ad0811644d081862c3a2d7a60710e5d89833
Author: Tzafrir Cohen <tzafrir at debian.org>
Date:   Mon May 19 17:51:07 2014 +0300

    fix regressions due to dahdi_pri_event_removed
    
    pri_destroy_span_prilist.patch, sigpri_handle_enodev_1.patch:
    fix regressions due to dahdi_pri_event_removed.
---
 debian/changelog                              |   4 +
 debian/patches/pri_destroy_span_prilist.patch | 136 ++++++++++++++++++++++++++
 debian/patches/series                         |   2 +
 debian/patches/sigpri_handle_enodev_1.patch   |  77 +++++++++++++++
 4 files changed, 219 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index ef26d48..988ed25 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -12,6 +12,10 @@ asterisk (1:11.9.0~dfsg-1) UNRELEASED; urgency=medium
   [ Daniel Pocock ]
   * Make init script more adaptable for multiple instances.
 
+  [ Tzafrir Cohen ]
+  * pri_destroy_span_prilist.patch, sigpri_handle_enodev_1.patch: fix
+    regressions due to dahdi_pri_event_removed.
+
  -- Jeremy Lainé <jeremy.laine at m4x.org>  Mon, 19 May 2014 09:38:36 +0200
 
 asterisk (1:11.8.1~dfsg-1) unstable; urgency=high
diff --git a/debian/patches/pri_destroy_span_prilist.patch b/debian/patches/pri_destroy_span_prilist.patch
new file mode 100644
index 0000000..66b171d
--- /dev/null
+++ b/debian/patches/pri_destroy_span_prilist.patch
@@ -0,0 +1,136 @@
+From: Tzafrir Cohen <tzafrir.cohen at xorcom.com>
+Subject: defer destructions of pri spans
+Bug: https://issues.asterisk.org/jira/browse/ASTERISK-23554
+
+Fixes a deadlock in destruction of PRI spans
+
+See also: https://reviewboard.asterisk.org/r/3548
+
+---
+ channels/chan_dahdi.c |   82 +++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 files changed, 79 insertions(+), 3 deletions(-)
+
+diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
+index fd5abe2..c21d593 100644
+--- a/channels/chan_dahdi.c
++++ b/channels/chan_dahdi.c
+@@ -1353,6 +1353,14 @@ static struct dahdi_pvt *iflist = NULL;	/*!< Main interface list start */
+ static struct dahdi_pvt *ifend = NULL;	/*!< Main interface list end */
+ 
+ #if defined(HAVE_PRI)
++struct doomed_pri {
++	struct sig_pri_span *pri;
++	AST_LIST_ENTRY(doomed_pri) list;
++};
++static AST_LIST_HEAD_STATIC(doomed_pris, doomed_pri);
++
++static void pri_destroy_span(struct sig_pri_span *pri);
++
+ static struct dahdi_parms_pseudo {
+ 	int buf_no;					/*!< Number of buffers */
+ 	int buf_policy;				/*!< Buffer policy */
+@@ -1754,6 +1762,75 @@ static int analogsub_to_dahdisub(enum analog_sub analogsub)
+ 	return index;
+ }
+ 
++/*!
++ * \internal
++ * \brief release all members on the doomed pris list
++ * \since 13.0
++ *
++ * Called priodically by the monitor threads to release spans marked for
++ * removal.
++ */
++static void release_doomed_pris(void) {
++#ifdef HAVE_PRI
++	struct doomed_pri *entry;
++	AST_LIST_HEAD_NOLOCK(doomed_pris, doomed_pri) doomed_list;
++
++	/* Move the global list to our local list. This prevents deadlocks with
++ 	 * any pri->lock.
++ 	 */
++	AST_LIST_LOCK(&doomed_pris);
++	doomed_list.first = doomed_pris.first;
++	doomed_list.last = doomed_pris.last;
++	doomed_pris.first = doomed_pris.last = NULL;
++	AST_LIST_UNLOCK(&doomed_pris);
++
++	AST_LIST_TRAVERSE_SAFE_BEGIN(&doomed_list, entry, list) {
++		AST_LIST_REMOVE_CURRENT(list);
++		pri_destroy_span(entry->pri);
++		ast_free(entry);
++	}
++	AST_LIST_TRAVERSE_SAFE_END;
++#endif
++}
++
++#ifdef HAVE_PRI
++/*!
++ * \internal
++ * \brief Queue a span for destruction
++ * \since 13.0
++ *
++ * \param pri the span to destroy
++ *
++ * Add a span to the list of spans to be destroyed later on
++ * by the monitor thread. Allows destroying a span while holding its
++ * lock.
++ */
++static void pri_queue_for_destruction(struct sig_pri_span *pri) {
++	struct doomed_pri *entry;
++	int len = 0;
++
++	AST_LIST_LOCK(&doomed_pris);
++	AST_LIST_TRAVERSE(&doomed_pris, entry, list) {
++		if (entry->pri == pri) {
++			AST_LIST_UNLOCK(&doomed_pris);
++			return;
++		}
++		len++;
++	}
++	entry = ast_calloc(sizeof(struct doomed_pri), 1);
++	if (!entry) {
++		/* Nothing useful to do here. Panic? */
++		ast_log(LOG_WARNING, "Failed allocating memory for a doomed_pri.\n");
++		AST_LIST_UNLOCK(&doomed_pris);
++		return;
++	}
++	entry->pri = pri;
++	ast_debug(4, "Queue span %d for destruction.\n", pri->span);
++	AST_LIST_INSERT_TAIL(&doomed_pris, entry, list);
++	AST_LIST_UNLOCK(&doomed_pris);
++}
++#endif
++
+ static enum analog_event dahdievent_to_analogevent(int event);
+ static int bump_gains(struct dahdi_pvt *p);
+ static int dahdi_setlinear(int dfd, int linear);
+@@ -3229,8 +3306,6 @@ static int sig_pri_tone_to_dahditone(enum sig_pri_tone tone)
+ #endif	/* defined(HAVE_PRI) */
+ 
+ #if defined(HAVE_PRI)
+-static void pri_destroy_span(struct sig_pri_span *pri);
+-
+ static void my_handle_dchan_exception(struct sig_pri_span *pri, int index)
+ {
+ 	int x;
+@@ -3259,7 +3334,7 @@ static void my_handle_dchan_exception(struct sig_pri_span *pri, int index)
+ 		pri_event_noalarm(pri, index, 0);
+ 		break;
+ 	case DAHDI_EVENT_REMOVED:
+-		pri_destroy_span(pri);
++		pri_queue_for_destruction(pri);
+ 		break;
+ 	default:
+ 		break;
+@@ -12172,6 +12247,7 @@ static void *do_monitor(void *data)
+ 				dahdi_destroy_channel_range(doomed->channel, doomed->channel);
+ 				doomed = NULL;
+ 			}
++			release_doomed_pris();
+ 			if (!i) {
+ 				break;
+ 			}
+-- 
+1.7.1
+
diff --git a/debian/patches/series b/debian/patches/series
index 5f944e4..dcc6fc3 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -25,6 +25,8 @@ pjproject
 
 # Backport of dynamic generation of DAHDI channels:
 dahdi_create_channels
+pri_destroy_span_prilist.patch
+sigpri_handle_enodev_1.patch
 
 reenable
 ignore_failed_channels.patch
diff --git a/debian/patches/sigpri_handle_enodev_1.patch b/debian/patches/sigpri_handle_enodev_1.patch
new file mode 100644
index 0000000..3ee4789
--- /dev/null
+++ b/debian/patches/sigpri_handle_enodev_1.patch
@@ -0,0 +1,77 @@
+From: Tzafrir Cohen <tzafrir.cohen at xorcom.com
+Subject: handle ENODEV on sig_pri
+Bug: https://issues.asterisk.org/jira/browse/ASTERISK-23554
+
+Handle ENODEV error in libpri following a device removal.
+
+See also: https://reviewboard.asterisk.org/r/3548
+
+---
+ channels/chan_dahdi.c |    3 ++-
+ channels/sig_pri.c    |    8 ++++++++
+ channels/sig_pri.h    |    2 ++
+ 3 files changed, 12 insertions(+), 1 deletions(-)
+
+diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
+index c21d593..b6b644f 100644
+--- a/channels/chan_dahdi.c
++++ b/channels/chan_dahdi.c
+@@ -1795,7 +1795,6 @@ static void release_doomed_pris(void) {
+ 
+ #ifdef HAVE_PRI
+ /*!
+- * \internal
+  * \brief Queue a span for destruction
+  * \since 13.0
+  *
+@@ -3617,6 +3616,7 @@ struct sig_pri_callback sig_pri_callbacks =
+ 	.dial_digits = my_pri_dial_digits,
+ 	.open_media = my_pri_ss7_open_media,
+ 	.ami_channel_event = my_ami_channel_event,
++	.destroy_later = pri_queue_for_destruction,
+ };
+ #endif	/* defined(HAVE_PRI) */
+ 
+@@ -15146,6 +15146,7 @@ static void pri_destroy_span(struct sig_pri_span *pri)
+ 	for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
+ 		ast_debug(4, "closing pri_fd %d\n", i);
+ 		dahdi_close_pri_fd(dahdi_pri, i);
++		dahdi_pri->dchannels[i] = 0;
+ 	}
+ 	sig_pri_init_pri(pri);
+ 	ast_debug(1, "PRI span %d destroyed\n", pri->span);
+diff --git a/channels/sig_pri.c b/channels/sig_pri.c
+index 1d9067a..5636594 100644
+--- a/channels/sig_pri.c
++++ b/channels/sig_pri.c
+@@ -6301,6 +6301,14 @@ static void *pri_dchannel(void *vpri)
+ 				}
+ 				if (e)
+ 					break;
++				
++				if ((errno != 0) && (errno != EINTR)) {
++					ast_log(LOG_NOTICE, "pri_check_event returned error %d (%s)\n",
++						errno, strerror(errno));
++				}
++				if (errno == ENODEV) {
++					sig_pri_callbacks.destroy_later(pri);
++				}
+ 			}
+ 		} else if (errno != EINTR)
+ 			ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
+diff --git a/channels/sig_pri.h b/channels/sig_pri.h
+index 43acb12..7bfbc79 100644
+--- a/channels/sig_pri.h
++++ b/channels/sig_pri.h
+@@ -229,6 +229,8 @@ struct sig_pri_callback {
+ 	void (*module_ref)(void);
+ 	/*! Unreference the parent module. */
+ 	void (*module_unref)(void);
++	/*! Mark the span for destruction. */
++	void (*destroy_later)(struct sig_pri_span *pri);
+ };
+ 
+ /*! Global sig_pri callbacks to the upper layer. */
+-- 
+1.7.1
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/asterisk.git



More information about the Pkg-voip-commits mailing list