THIS IS AN AUTOMATED MESSAGE, DO NOT REPLY.
The following task is now closed:
FS#434 - Sometimes some kamailio processes eat 100% CPU
User who did this - Henning Westerholt (henningw)
Reason for closing: Fixed
More information can be found at the following URL:
http://sip-router.org/tracker/index.php?do=details&task_id=434
You are receiving this message because you have requested it from the Flyspray bugtracking system. If you did not expect this message or don't want to receive mails in future, you can change your notification settings at the URL shown above.
THIS IS AN AUTOMATED MESSAGE, DO NOT REPLY.
The following task has a new comment added:
FS#434 - Sometimes some kamailio processes eat 100% CPU
User who did this - Henning Westerholt (henningw)
----------
Thank you, it was fixed in master and also 4.1 from Daniel.
----------
More information can be found at the following URL:
http://sip-router.org/tracker/index.php?do=details&task_id=434#comment1479
You are receiving this message because you have requested it from the Flyspray bugtracking system. If you did not expect this message or don't want to receive mails in future, you can change your notification settings at the URL shown above.
Module: sip-router
Branch: master
Commit: 0d7d5dc4d7219c5beb9a150cc56e74edac9dc4d5
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=0d7d5dc…
Author: Henning Westerholt <hw(a)kamailio.org>
Committer: Henning Westerholt <hw(a)kamailio.org>
Date: Tue May 27 12:14:24 2014 +0200
db_mysql: fixes FS#434, Kamailio will eat sometimes 100% CPU due a bug in db_mysql
* Fixes FS#434 reported from Maxim, incorrect mysql API usage for mysql_next_result(..)
* According MySQL doc, return values for mysql_next_result(..) can be the following:
0 - Successful and there are more results
-1 - Successful and there are no more results
>0 - An error occured
* Thus, if there will be an error when reading a next result, the code will be infinitely
looped in “while” cycle and current process will eat 100% CPU (The mysql_more_results
will not help here because it just checks a local flag that will be set to TRUE in cases
when there will be more than one result).
* The solution is to replace " > 0” with " == 0”:
---
modules/db_mysql/km_dbase.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/db_mysql/km_dbase.c b/modules/db_mysql/km_dbase.c
index cf22e4c..d2ef5c5 100644
--- a/modules/db_mysql/km_dbase.c
+++ b/modules/db_mysql/km_dbase.c
@@ -258,7 +258,7 @@ static int db_mysql_store_result(const db1_con_t* _h, db1_res_t** _r)
db_mysql_free_result(_h, *_r);
*_r = 0;
#if (MYSQL_VERSION_ID >= 40100)
- while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) > 0 ) {
+ while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) == 0 ) {
MYSQL_RES *res = mysql_store_result( CON_CONNECTION(_h) );
mysql_free_result(res);
}
@@ -268,7 +268,7 @@ static int db_mysql_store_result(const db1_con_t* _h, db1_res_t** _r)
done:
#if (MYSQL_VERSION_ID >= 40100)
- while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) > 0 ) {
+ while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) == 0 ) {
MYSQL_RES *res = mysql_store_result( CON_CONNECTION(_h) );
mysql_free_result(res);
}
THIS IS AN AUTOMATED MESSAGE, DO NOT REPLY.
A new Flyspray task has been opened. Details are below.
User who did this - Maxim (simax)
Attached to Project - sip-router
Summary - Sometimes some kamailio processes eat 100% CPU
Task Type - Bug Report
Category - Module
Status - Unconfirmed
Assigned To -
Operating System - All
Severity - Medium
Priority - Normal
Reported Version - Development
Due in Version - Undecided
Due Date - Undecided
Details - Some time ago we had some problems with our MysSQL server and some kamailio processes were got stuck and ate 100% CPU. We use sqlops module to call mysql procedure. The procedure returns two results (a result set and status of the "CALL" command).
It seems there is a bug in db_mysql module in file km_dbase.c, function db_mysql_store_result(..). The bug is in incorrect using of MysQL API function mysql_next_result(..). That function is used to skip rest of results returned by DB query (because mysql connection is opened with flag CLIENT_MULTI_STATEMENTS). Part of the code that causes the problem is
<code>#if (MYSQL_VERSION_ID >= 40100)
while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) > 0 ) {
MYSQL_RES *res = mysql_store_result( CON_CONNECTION(_h) );
mysql_free_result(res);
}
#endif</code>
According MySQL doc, return values for mysql_next_result(..) can be the following:
0 - Successful and there are more results
-1 - Successful and there are no more results
>0 - An error occured
Thus, if there will be an error when reading a next result, the code will be infinitely looped in "while" cycle and current process will eat 100% CPU (The mysql_more_results will not help here because it just checks a local flag that will be set to TRUE in cases when there will be more than one result).
The solution is to replace " > 0" with " == 0":
<code>#if (MYSQL_VERSION_ID >= 40100)
while( mysql_more_results(CON_CONNECTION(_h)) && mysql_next_result(CON_CONNECTION(_h)) == 0 ) {
MYSQL_RES *res = mysql_store_result( CON_CONNECTION(_h) );
mysql_free_result(res);
}
#endif</code>
More information can be found at the following URL:
http://sip-router.org/tracker/index.php?do=details&task_id=434
You are receiving this message because you have requested it from the Flyspray bugtracking system. If you did not expect this message or don't want to receive mails in future, you can change your notification settings at the URL shown above.
Hello,
Maybe it is a good idea to have some internationalized docs which will be
somewhere near to default lang, e.g. docs/{en_US, ru_RU, ...} ?
If so, then how to organize that do have some standard rules to keep the
correct docs structure.
I'd like to hear your opinion.
Thanks!
Hi,
I am confused by the TM reply processing logic in a particular scenario.
For example, if an INVITE transaction has had a final reply (let's assume
500 Error in this case). Now, if a 200 OK comes through the proxy to accept
the call then according to the code below, the relay will be relayed to the
calling party.... why? This will also cause the tm transaction state to
change from state 5 (deleted) to state (4) confirmed.... Is this correct?
(a result of this scenario is that the A UAC will receive a 500 followed by
a 200....)
static enum rps t_should_relay_response( struct cell *Trans , int new_code,
int branch , int *should_store, int *should_relay,
struct cancel_info *cancel_data, struct sip_msg *reply )
{
int branch_cnt;
int picked_code;
int new_branch;
int inv_through;
int extra_flags;
int i;
int replies_dropped;
/* note: this code never lets replies to CANCEL go through;
we generate always a local 200 for CANCEL; 200s are
not relayed because it's not an INVITE transaction;
>= 300 are not relayed because 200 was already sent
out
*/
DBG("->>>>>>>>> T_code=%d, new_code=%d\n",Trans->uas.status,new_code);
inv_through=new_code>=200 && new_code<300 && is_invite(Trans);
/* if final response sent out, allow only INVITE 2xx */
if ( Trans->uas.status >= 200 ) {
if (inv_through) {
DBG("DBG: t_should_relay_response: 200 INV after final sent\n");
*should_store=0;
Trans->uac[branch].last_received=new_code;
*should_relay=branch;
return RPS_PUSHED_AFTER_COMPLETION;
}
/* except the exception above, too late messages will
be discarded */
goto discard;
}
/* if final response received at this branch, allow only INVITE 2xx */
if (Trans->uac[branch].last_received>=200
&& !(inv_through && Trans->uac[branch].last_received<300)) {
/* don't report on retransmissions */
if (Trans->uac[branch].last_received==new_code) {
DBG("DEBUG: final reply retransmission\n");
goto discard;
}
/* if you FR-timed-out, faked a local 408 and 487 came or
* faked a CANCEL on a non-replied branch don't
* report on it either */
if ((Trans->uac[branch].last_received==487) ||
(Trans->uac[branch].last_received==408 && new_code==487)) {
DBG("DEBUG: %d came for a %d branch (ignored)\n",
new_code, Trans->uac[branch].last_received);
goto discard;
}
/* this looks however how a very strange status rewrite attempt;
* report on it */
LOG(L_ERR, "ERROR: t_should_relay_response: status rewrite by UAS: "
"stored: %d, received: %d\n",
Trans->uac[branch].last_received, new_code );
goto discard;
}
/* no final response sent yet */