[Asterisk-code-review] chan sip: Prevent deadlock when issuing "sip show channels" (asterisk[14])

George Joseph asteriskteam at digium.com
Thu Jul 21 12:01:38 CDT 2016


George Joseph has uploaded a new change for review.

  https://gerrit.asterisk.org/3281

Change subject: chan_sip: Prevent deadlock when issuing "sip show channels"
......................................................................

chan_sip: Prevent deadlock when issuing "sip show channels"

sip_show_channels locks the dialogs container first then locks each
sip_pvt so it can spit out the details.  The rest of sip dialog
processing locks the sip_pvt first then locks the dialogs container
if it needs to.  Both lock in the order they need but deadlocks can
result.  To fix, sip_show_channels and sip_show_channelstats have
been converted to use an iterator rather than ao2_callback.  This way
the container is locked only while getting the next entry and is
unlocked when the callback is called.

ASTERISK-23013 #close

Change-Id: Id9980419909e811f89484950ed46ef117b9eb990
---
M channels/chan_sip.c
1 file changed, 17 insertions(+), 4 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/81/3281/1

diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index b2522b6..5e57f3a 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -21389,6 +21389,8 @@
 static char *sip_show_channelstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 };
+	struct sip_pvt *cur;
+	struct ao2_iterator i;
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -21406,8 +21408,14 @@
 		return CLI_SHOWUSAGE;
 
 	ast_cli(a->fd, FORMAT2, "Peer", "Call ID", "Duration", "Recv: Pack", "Lost", "Jitter", "Send: Pack", "Lost", "Jitter");
+
 	/* iterate on the container and invoke the callback on each item */
-	ao2_t_callback(dialogs, OBJ_NODATA, show_chanstats_cb, &arg, "callback to sip show chanstats");
+	i = ao2_iterator_init(dialogs, 0);
+	for (; (cur = ao2_iterator_next(&i)); ao2_ref(cur, -1)) {
+		show_chanstats_cb(cur, &arg, 0);
+	}
+	ao2_iterator_destroy(&i);
+
 	ast_cli(a->fd, "%d active SIP channel%s\n", arg.numchans, (arg.numchans != 1) ? "s" : "");
 	return CLI_SUCCESS;
 }
@@ -21782,7 +21790,8 @@
 static char *sip_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
 	struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 };
-
+	struct sip_pvt *cur;
+	struct ao2_iterator i;
 
 	if (cmd == CLI_INIT) {
 		e->command = "sip show {channels|subscriptions}";
@@ -21804,8 +21813,12 @@
 		ast_cli(arg.fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry");
 
 	/* iterate on the container and invoke the callback on each item */
-	ao2_t_callback(dialogs, OBJ_NODATA, show_channels_cb, &arg, "callback to show channels");
-
+	i = ao2_iterator_init(dialogs, 0);
+	for (; (cur = ao2_iterator_next(&i)); ao2_ref(cur, -1)) {
+		show_channels_cb(cur, &arg, 0);
+	}
+	ao2_iterator_destroy(&i);
+	
 	/* print summary information */
 	ast_cli(arg.fd, "%d active SIP %s%s\n", arg.numchans,
 		(arg.subscriptions ? "subscription" : "dialog"),

-- 
To view, visit https://gerrit.asterisk.org/3281
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id9980419909e811f89484950ed46ef117b9eb990
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 14
Gerrit-Owner: George Joseph <gjoseph at digium.com>



More information about the asterisk-code-review mailing list