Summary:ASTERISK-26074: res_odbc: Deadlock within UnixODBC
Reporter:Ross Beer (rossbeer)Labels:
Date Opened:2016-05-30 10:51:56Date Closed:2016-06-07 12:11:15
Versions:SVN 13.9.1 Frequency of
Environment:CentOS 7 / Fedora Server 23Attachments:( 0) backtrace-threads-clean.txt
( 1) core-show-locks.txt
Description:The appears to be a lock in the sorcery real-time identify module in the latest versions of asterisk. I have tried multiple versions of unixODBC and mysql-connector-odbc with out any luck.

The locks cause all registrations to fail.

The CLI is showing a couple of message types:

[2016-05-30 16:49:43] WARNING[25214]: pjproject:0 <?>:  sip_transactio Unable to register REGISTER transaction (key exists)
[2016-05-30 16:49:43] WARNING[25477]: pjproject:0 <?>:  sip_transactio Unable to register REGISTER transaction (key exists)
[2016-05-30 16:49:43] WARNING[25479]: pjproject:0 <?>:  sip_transactio Unable to register REGISTER transaction (key exists)

[2016-05-30 16:49:29] ERROR[25207]: res_pjsip.c:2899 ast_sip_create_dialog_uas: Could not create dialog with endpoint 20937*407. Object already exists (PJ_EEXISTS)
Comments:By: Asterisk Team (asteriskteam) 2016-05-30 10:51:57.504-0500

Thanks for creating a report! The issue has entered the triage process. That means the issue will wait in this status until a Bug Marshal has an opportunity to review the issue. Once the issue has been reviewed you will receive comments regarding the next steps towards resolution.

A good first step is for you to review the [Asterisk Issue Guidelines|https://wiki.asterisk.org/wiki/display/AST/Asterisk+Issue+Guidelines] if you haven't already. The guidelines detail what is expected from an Asterisk issue report.

Then, if you are submitting a patch, please review the [Patch Contribution Process|https://wiki.asterisk.org/wiki/display/AST/Patch+Contribution+Process].

By: Joshua C. Colp (jcolp) 2016-05-30 11:03:38.968-0500

The backtrace shows this to be within unixodbc itself, and not Asterisk. Previously we only ever had 1 connection to the database and protect it ourselves. We now rely on unixodbc to do this and it seems to be having issues. There's no immediate solution, except to use an earlier version of Asterisk.

By: Ross Beer (rossbeer) 2016-05-30 11:06:22.978-0500

Can you suggest the version of Asterisk to use?

By: Ross Beer (rossbeer) 2016-05-30 11:27:15.497-0500

Maybe 13.7.2?


By: Joshua C. Colp (jcolp) 2016-05-30 11:29:53.648-0500

Yes, that version is before the ODBC changes went in.

By: Ross Beer (rossbeer) 2016-05-30 12:32:19.825-0500

Ok, using 13.7.2 and patching it with https://gerrit.asterisk.org/#/c/2236/ has resolved the issue.

The question is how do we resolve the issue with unixODBC?

By: Kevin Harwell (kharwell) 2016-05-31 11:31:45.452-0500

Do you have a threading level specified in your unixodbc configuration for your driver? If so make sure it is set to 0. Doing so passes threading control to the underlying driver. From the unixodbc DriverManager/__handles.c code:
* use just one mutex for all the lists, this avoids any issues                                                                                                                      
* with deadlocks, the performance issue should be minimal, if it                                                                                                                    
* turns out to be a problem, we can readdress this                                                                                                                                  
* We also have a mutex to protect the connection pooling code                                                                                                                      
* If compiled with thread support the DM allows four different                                                                                                                      
* thread strategies:                                                                                                                                                                
* Level 0 - Only the DM internal structures are protected.                                                                                                                          
* The driver is assumed to take care of itself                                                                                                                                      
* Level 1 - The driver is protected down to the statement level.                                                                                                                    
* Each statement will be protected, and the same for the connect                                                                                                                    
* level for connect functions. Note that descriptors are considered                                                                                                                
* equal to statements when it comes to thread protection.                                                                                                                          
* Level 2 - The driver is protected at the connection level. Only                                                                                                                  
* one thread can be in a particular driver at one time.                                                                                                                            
* Level 3 - The driver is protected at the env level, only one thing                                                                                                                
* at a time.                                                                                                                                                                        
* By default the driver opens connections with lock level 0; drivers                                                                                                                
* are expected to be thread safe now. This can be changed by adding                                                                                                                
* the line                                                                                                                                                                          
* Threading = N                                                                                                                                                                    
* to the driver entry in odbcinst.ini, where N is the locking level                                                                                                                
* (0-3)                                                                                                                                                                            

By: Ross Beer (rossbeer) 2016-05-31 11:59:25.797-0500

I'm using threading=0 with the latest unixODBC and MySQL-connector-ODBC.

Pooling has also been enabled to improve performance, however with this disabled the issue still occurs.