소스 검색

pipelimit: implemented support for RPC commands

Ovidiu Sas 12 년 전
부모
커밋
f432022f94
5개의 변경된 파일465개의 추가작업 그리고 17개의 파일을 삭제
  1. 121 12
      modules/pipelimit/README
  2. 9 0
      modules/pipelimit/doc/pipelimit.xml
  3. 149 5
      modules/pipelimit/doc/pipelimit_admin.xml
  4. 88 0
      modules/pipelimit/pipelimit.c
  5. 98 0
      modules/pipelimit/pl_ht.c

+ 121 - 12
modules/pipelimit/README

@@ -6,11 +6,17 @@ Hendrik Scholz
 
 Edited by
 
+Ovidiu Sas
+
+Edited by
+
 Daniel-Constantin Mierla
 
-   Copyright © 2010 Asipto.com
+   Copyright © 2013 VoIPEmbedded Inc.
+
+   Copyright © 2010 Asipto.com
 
-   Copyright © 2006 Freenet Cityline GmbH
+   Copyright © 2006 Freenet Cityline GmbH
      __________________________________________________________________
 
    Table of Contents
@@ -48,6 +54,15 @@ Daniel-Constantin Mierla
               5.5. pl_get_pid
               5.6. pl_push_load
 
+        6. RPC Commands
+
+              6.1. pl.stats
+              6.2. pl.set_pipe
+              6.3. pl.get_pipes
+              6.4. pl.set_pid
+              6.5. pl.get_pid
+              6.6. pl.push_load
+
    List of Examples
 
    1.1. Set db_url parameter
@@ -98,6 +113,15 @@ Chapter 1. Admin Guide
         5.5. pl_get_pid
         5.6. pl_push_load
 
+   6. RPC Commands
+
+        6.1. pl.stats
+        6.2. pl.set_pipe
+        6.3. pl.get_pipes
+        6.4. pl.set_pid
+        6.5. pl.get_pid
+        6.6. pl.push_load
+
 1. Overview
 
    This module implements traffic limiting for SIP requests.
@@ -145,7 +169,7 @@ Chapter 1. Admin Guide
 
    URL of the database server to be used.
 
-   Default value is "mysql://kamailio:kamailiorw@localhost/kamailio".
+   Default value is “mysql://kamailio:kamailiorw@localhost/kamailio�.
 
    Example 1.1. Set db_url parameter
 ...
@@ -156,7 +180,7 @@ modparam("pipelimit", "db_url", "dbdriver://username:password@dbhost/dbname")
 
    Name of DB table where data definition for pipes is stores.
 
-   Default value is "pl_pipes".
+   Default value is “pl_pipes�.
 
    Example 1.2. Set plp_table_name parameter
 ...
@@ -167,7 +191,7 @@ modparam("pipelimit", "plp_table_name", "mypipes")
 
    Name of 'pipeid' column.
 
-   Default value is "pipeid".
+   Default value is “pipeid�.
 
    Example 1.3. Set plp_pipeid_column parameter
 ...
@@ -178,7 +202,7 @@ modparam("pipelimit", "plp_pipeid_column", "name")
 
    Name of 'limit' column.
 
-   Default value is "limit".
+   Default value is “limit�.
 
    Example 1.4. Set plp_limit_column parameter
 ...
@@ -189,7 +213,7 @@ modparam("pipelimit", "plp_limit_column", "name")
 
    Name of 'algorithm' column.
 
-   Default value is "algorithm".
+   Default value is “algorithm�.
 
    Example 1.5. Set plp_algorithm_column parameter
 ...
@@ -209,7 +233,7 @@ modparam("pipelimit", "plp_algorithm_column", "name")
 
    Example 1.6. Set timer_interval parameter
 ...
-modparam("ratelimit", "timer_interval", 5)
+modparam("pipelimit", "timer_interval", 5)
 ...
 
 3.7. reply_code (integer)
@@ -220,13 +244,13 @@ modparam("ratelimit", "timer_interval", 5)
 
    Example 1.7. Set reply_code parameter
 ...
-modparam("ratelimit", "reply_code", 505)
+modparam("pipelimit", "reply_code", 505)
 ...
 
    This value can be modified at runtime using kamcmd
 
    Example 1.8.  Set reply_code parameter at runtime
-kamcmd cfg.set_now_int ratelimit reply_code 505
+kamcmd cfg.set_now_int pipelimit reply_code 505
 
 3.8. reply_reason (string)
 
@@ -236,13 +260,13 @@ kamcmd cfg.set_now_int ratelimit reply_code 505
 
    Example 1.9. Set reply_reason parameter
 ...
-modparam("ratelimit", "reply_reason", "Limiting")
+modparam("pipelimit", "reply_reason", "Limiting")
 ...
 
    This value can be modified at runtime using kamcmd
 
    Example 1.10.  Set reply_reason parameter at runtime
-kamcmd cfg.set_now_string ratelimit reply_reason "Limiting"
+kamcmd cfg.set_now_string pipelimit reply_reason "Limiting"
 
 4. Functions
 
@@ -400,3 +424,88 @@ kamcmd cfg.set_now_string ratelimit reply_reason "Limiting"
                 :pl_push_load:_reply_fifo_file_
                 0.85
                 _empty_line_
+
+6. RPC Commands
+
+   6.1. pl.stats
+   6.2. pl.set_pipe
+   6.3. pl.get_pipes
+   6.4. pl.set_pid
+   6.5. pl.get_pid
+   6.6. pl.push_load
+
+6.1.  pl.stats
+
+   Lists the parameters and variabiles in the pipelimit module: pipe id,
+   pipe load and pipe couter.
+
+   Name: pl.stats
+
+   Parameters: none
+
+   RPC Command Format:
+        kamcmd pl.stats
+
+6.2.  pl.set_pipe
+
+   Sets the pipe parameters for the given pipe id.
+
+   Name: pl.set_pipe
+
+   Parameters:
+     * pipe_id - pipe id.
+     * pipe_algorithm - the algorithm assigned to the given pipe id.
+     * pipe_limit - the limit assigned to the given pipe id.
+
+   RPC Command Format:
+        kamcmd pl.set_pipe 2 RED 10
+
+6.3.  pl.get_pipes
+
+   Gets the list of in use pipes.
+
+   Name: pl.get_pipes
+
+   Parameters: none
+
+   RPC Command Format:
+        kamcmd pl.get_pipes
+
+6.4.  pl.set_pid
+
+   Sets the PID Controller parameters for the Feedback Algorithm.
+
+   Name: pl.set_pid
+
+   Parameters:
+     * ki - the integral parameter.
+     * kp - the proportional parameter.
+     * kd - the derivative parameter.
+
+   RPC Command Format:
+        kamcmd pl.set_pid 0.5 0.5 0.5
+
+6.5.  pl.get_pid
+
+   Gets the list of in use PID Controller parameters.
+
+   Name: pl.get_pid
+
+   Parameters: none
+
+   RPC Command Format:
+        kamcmd pl.get_pid
+
+6.6.  pl.push_load
+
+   Force the value of the load parameter. This command is useful for
+   testing the Feedback algorithm.
+
+   Name: pl.push_load
+
+   Parameters:
+     * load - the forced value of load (it must be greater then 0.0 and
+       smaller then 1.0).
+
+   RPC Command Format:
+        kamcmd pl.push_load 0.85

+ 9 - 0
modules/pipelimit/doc/pipelimit.xml

@@ -28,6 +28,11 @@
 		</address>
 		</author>
 		<editor>
+		<firstname>Ovidiu</firstname>
+		<surname>Sas</surname>
+		<address><email>[email protected]</email></address>
+		</editor>
+		<editor>
 		<firstname>Daniel-Constantin</firstname>
 		<surname>Mierla</surname>
 		<address>
@@ -35,6 +40,10 @@
 		</address>
 		</editor>
 	</authorgroup>
+	<copyright>
+		<year>2013</year>
+		<holder><ulink url='http://www.voipembedded.com'>VoIPEmbedded Inc.</ulink></holder>
+	</copyright>
 	<copyright>
 		<year>2010</year>
 		<holder>Asipto.com</holder>

+ 149 - 5
modules/pipelimit/doc/pipelimit_admin.xml

@@ -185,7 +185,7 @@ modparam("pipelimit", "plp_algorithm_column", "name")
 		<title>Set <varname>timer_interval</varname> parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("ratelimit", "timer_interval", 5)
+modparam("pipelimit", "timer_interval", 5)
 ...
 </programlisting>
 		</example>
@@ -205,7 +205,7 @@ modparam("ratelimit", "timer_interval", 5)
 		<title>Set <varname>reply_code</varname> parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("ratelimit", "reply_code", 505)
+modparam("pipelimit", "reply_code", 505)
 ...
 </programlisting>
 		</example>
@@ -216,7 +216,7 @@ modparam("ratelimit", "reply_code", 505)
 		<title> Set <varname>reply_code</varname> parameter at runtime </title>
 		<programlisting format="linespecific">
 
-&sercmd; cfg.set_now_int ratelimit reply_code 505
+&sercmd; cfg.set_now_int pipelimit reply_code 505
 
 		</programlisting>
 		</example>
@@ -235,7 +235,7 @@ modparam("ratelimit", "reply_code", 505)
 		<title>Set <varname>reply_reason</varname> parameter</title>
 		<programlisting format="linespecific">
 ...
-modparam("ratelimit", "reply_reason", "Limiting")
+modparam("pipelimit", "reply_reason", "Limiting")
 ...
 </programlisting>
 		</example>
@@ -246,7 +246,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
 		<title> Set <varname>reply_reason</varname> parameter at runtime </title>
 		<programlisting format="linespecific">
 
-&sercmd; cfg.set_now_string ratelimit reply_reason "Limiting"
+&sercmd; cfg.set_now_string pipelimit reply_reason "Limiting"
 
 		</programlisting>
 		</example>
@@ -495,4 +495,148 @@ modparam("ratelimit", "reply_reason", "Limiting")
 	</section>
 	</section>
 	
+	<section>
+	<title>RPC Commands</title>
+	<section>
+		<title>
+		<function moreinfo="none">pl.stats</function>
+		</title>
+		<para>
+		Lists the parameters and variabiles in the pipelimit module:
+		pipe id, pipe load and pipe couter.
+		</para>
+		<para>
+		Name: <emphasis>pl.stats</emphasis>
+		</para>
+		<para>Parameters: <emphasis>none</emphasis></para>
+ 		<para>
+		RPC Command Format:
+		</para>
+		<programlisting  format="linespecific">
+	kamcmd pl.stats
+		</programlisting>
+	</section>
+	<section>
+		<title>
+		<function moreinfo="none">pl.set_pipe</function>
+		</title>
+		<para>
+		Sets the pipe parameters for the given pipe id.
+		</para>
+		<para>
+		Name: <emphasis>pl.set_pipe</emphasis>
+		</para>
+		<para>Parameters:</para>
+		<itemizedlist>
+			<listitem><para>
+			<emphasis>pipe_id</emphasis> - pipe id.
+			</para></listitem>
+			<listitem><para>
+			<emphasis>pipe_algorithm</emphasis> - the
+			algorithm assigned to the given pipe id.
+			</para></listitem>
+			<listitem><para>
+			<emphasis>pipe_limit</emphasis> - the limit
+			assigned to the given pipe id.
+			</para></listitem>
+		</itemizedlist>
+		<para>
+		RPC Command Format:
+		</para>
+		<programlisting  format="linespecific">
+	kamcmd pl.set_pipe 2 RED 10
+		</programlisting>
+	</section>
+	<section>
+		<title>
+		<function moreinfo="none">pl.get_pipes</function>
+		</title>
+		<para>
+		Gets the list of in use pipes.
+		</para>
+		<para>
+		Name: <emphasis>pl.get_pipes</emphasis>
+		</para>
+		<para>Parameters: <emphasis>none</emphasis></para>
+		<para>
+		RPC Command Format:
+		</para>
+		<programlisting  format="linespecific">
+	kamcmd pl.get_pipes
+		</programlisting>
+	</section>
+	<section>
+		<title>
+		<function moreinfo="none">pl.set_pid</function>
+		</title>
+		<para>
+		Sets the PID Controller parameters for the Feedback Algorithm.
+		</para>
+		<para>
+		Name: <emphasis>pl.set_pid</emphasis>
+		</para>
+		<para>Parameters:</para>
+		<itemizedlist>
+			<listitem><para>
+			<emphasis>ki</emphasis> - the integral parameter.
+			</para></listitem>
+			<listitem><para>
+			<emphasis>kp</emphasis> - the proportional parameter.
+			</para></listitem>
+			<listitem><para>
+			<emphasis>kd</emphasis> - the derivative parameter.
+			</para></listitem>
+		</itemizedlist>
+		<para>
+		RPC Command Format:
+		</para>
+		<programlisting  format="linespecific">
+	kamcmd pl.set_pid 0.5 0.5 0.5
+		</programlisting>
+	</section>
+	<section>
+		<title>
+		<function moreinfo="none">pl.get_pid</function>
+		</title>
+		<para>
+		Gets the list of in use PID Controller parameters.
+		</para>
+		<para>
+		Name: <emphasis>pl.get_pid</emphasis>
+		</para>
+		<para>Parameters: <emphasis>none</emphasis></para>
+		<para>
+		RPC Command Format:
+		</para>
+		<programlisting  format="linespecific">
+	kamcmd pl.get_pid
+		</programlisting>
+	</section>
+	<section>
+		<title>
+		<function moreinfo="none">pl.push_load</function>
+		</title>
+		<para>
+		Force the value of the load parameter.  This command is useful
+		for testing the Feedback algorithm.
+		</para>
+		<para>
+		Name: <emphasis>pl.push_load</emphasis>
+		</para>
+		<para>Parameters:</para>
+		<itemizedlist>
+			<listitem><para>
+			<emphasis>load</emphasis> - the forced value of load
+			(it must be greater then 0.0 and smaller then 1.0).
+			</para></listitem>
+		</itemizedlist>
+		<para>
+		RPC Command Format:
+		</para>
+		<programlisting  format="linespecific">
+	kamcmd pl.push_load 0.85
+		</programlisting>
+	</section>
+	</section>
+	
 </chapter>

+ 88 - 0
modules/pipelimit/pipelimit.c

@@ -50,6 +50,7 @@
 #include "../../lib/kcore/statistics.h"
 #include "../../modules/sl/sl.h"
 #include "../../lib/kmi/mi.h"
+#include "../../rpc_lookup.h"
 
 #include "pl_ht.h"
 #include "pl_db.h"
@@ -156,6 +157,8 @@ static mi_export_t mi_cmds [] = {
 	{0,0,0,0,0}
 };
 
+static rpc_export_t rpc_methods[];
+
 /** module exports */
 struct module_exports exports= {
 	"pipelimit",
@@ -279,6 +282,11 @@ static void update_cpu_load(void)
 /* initialize ratelimit module */
 static int mod_init(void)
 {
+	if(rpc_register_array(rpc_methods)!=0)
+	{
+		LM_ERR("failed to register RPC commands\n");
+		return -1;
+	}
 	if(register_mi_mod(exports.name, mi_cmds)!=0)
 	{
 		LM_ERR("failed to register MI commands\n");
@@ -700,3 +708,83 @@ bad_syntax:
 	return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
 }
 
+/* rpc function documentation */
+const char *rpc_pl_stats_doc[2] = {
+	"Print pipelimit statistics: \
+<id> <load> <counter>", 0
+};
+
+const char *rpc_pl_get_pipes_doc[2] = {
+	"Print pipes info: \
+<id> <algorithm> <limit> <counter>", 0
+};
+
+const char *rpc_pl_set_pipe_doc[2] = {
+	"Sets a pipe params: <pipe_id> <pipe_algorithm> <pipe_limit>", 0
+};
+
+const char *rpc_pl_get_pid_doc[2] = {
+	"Print PID Controller parameters for the FEEDBACK algorithm: \
+<ki> <kp> <kd>", 0
+};
+
+const char *rpc_pl_set_pid_doc[2] = {
+	"Sets the PID Controller parameters for the FEEDBACK algorithm: \
+<ki> <kp> <kd>", 0
+};
+
+const char *rpc_pl_push_load_doc[2] = {
+	"Force the value of the load parameter for FEEDBACK algorithm: \
+<load>", 0
+};
+
+/* rpc function implementations */
+void rpc_pl_stats(rpc_t *rpc, void *c);
+void rpc_pl_get_pipes(rpc_t *rpc, void *c);
+void rpc_pl_set_pipe(rpc_t *rpc, void *c);
+
+void rpc_pl_get_pid(rpc_t *rpc, void *c) {
+	rpl_pipe_lock(0);
+	rpc->printf(c, "ki[%f] kp[%f] kd[%f] ", *pid_ki, *pid_kp, *pid_kd);
+	rpl_pipe_release(0);
+}
+
+void rpc_pl_set_pid(rpc_t *rpc, void *c) {
+	double ki, kp, kd;
+
+	if (rpc->scan(c, "fff", &ki, &kp, &kd) < 3) return;
+
+	rpl_pipe_lock(0);
+	*pid_ki = ki;
+	*pid_kp = kp;
+	*pid_kd = kd;
+	rpl_pipe_release(0);
+}
+
+void rpc_pl_push_load(rpc_t *rpc, void *c) {
+	double value;
+
+	if (rpc->scan(c, "f", &value) < 1) return;
+
+	if (value < 0.0 || value > 1.0) {
+		LM_ERR("value out of range: %0.3f in not in [0.0,1.0]\n", value);
+		rpc->fault(c, 400, "Value out of range");
+		return;
+	}
+	rpl_pipe_lock(0);
+	*load_value = value;
+	rpl_pipe_release(0);
+
+	do_update_load();
+}
+
+static rpc_export_t rpc_methods[] = {
+	{"pl.stats",      rpc_pl_stats,     rpc_pl_stats_doc,     0},
+	{"pl.get_pipes",  rpc_pl_get_pipes, rpc_pl_get_pipes_doc, 0},
+	{"pl.set_pipe",   rpc_pl_set_pipe,  rpc_pl_set_pipe_doc,  0},
+	{"pl.get_pid",    rpc_pl_get_pid,   rpc_pl_get_pid_doc,   0},
+	{"pl.set_pid",    rpc_pl_set_pid,   rpc_pl_set_pid_doc,   0},
+	{"pl.push_load",  rpc_pl_push_load, rpc_pl_push_load_doc, 0},
+	{0, 0, 0, 0}
+};
+

+ 98 - 0
modules/pipelimit/pl_ht.c

@@ -39,6 +39,7 @@
 #include "../../hashes.h"
 #include "../../mem/shm_mem.h"
 #include "../../lib/kmi/mi.h"
+#include "../../rpc_lookup.h"
 
 #include "pl_ht.h"
 
@@ -591,3 +592,100 @@ void rpl_pipe_release(int slot)
 }
 
 
+/* rpc function implementations */
+void rpc_pl_stats(rpc_t *rpc, void *c)
+{
+	int i;
+	pl_pipe_t *it;
+
+	for(i=0; i<_pl_pipes_ht->htsize; i++)
+	{
+		lock_get(&_pl_pipes_ht->slots[i].lock);
+		it = _pl_pipes_ht->slots[i].first;
+		while(it)
+		{
+			if (it->algo != PIPE_ALGO_NOP) {
+				if (rpc->printf(c, "PIPE: id=%.*s load=%d counter=%d",
+					it->name.len, it->name.s,
+					it->load, it->last_counter) < 0)
+				{
+					lock_release(&_pl_pipes_ht->slots[i].lock);
+					return;
+				}
+			}
+			it = it->next;
+		}
+		lock_release(&_pl_pipes_ht->slots[i].lock);
+	}
+}
+
+void rpc_pl_get_pipes(rpc_t *rpc, void *c)
+{
+	int i;
+	str algo;
+	pl_pipe_t *it;
+
+	for(i=0; i<_pl_pipes_ht->htsize; i++)
+	{
+		lock_get(&_pl_pipes_ht->slots[i].lock);
+		it = _pl_pipes_ht->slots[i].first;
+		while(it)
+		{
+			if (it->algo != PIPE_ALGO_NOP) {
+				if (str_map_int(algo_names, it->algo, &algo))
+				{
+					lock_release(&_pl_pipes_ht->slots[i].lock);
+					return;
+				}
+				if (rpc->printf(c, "PIPE: id=%.*s algorithm=%.*s limit=%d counter=%d",
+					it->name.len, it->name.s, algo.len, algo.s,
+					it->limit, it->counter) < 0)
+				{
+					lock_release(&_pl_pipes_ht->slots[i].lock);
+					return;
+				}
+			}
+			it = it->next;
+		}
+		lock_release(&_pl_pipes_ht->slots[i].lock);
+	}
+}
+
+void rpc_pl_set_pipe(rpc_t *rpc, void *c)
+{
+	unsigned int algo_id, limit = 0;
+	pl_pipe_t *it;
+	str pipeid, algo_str;
+
+	if (rpc->scan(c, "SSd", &pipeid, &algo_str, &limit) < 3) return;
+
+	if (str_map_str(algo_names, &algo_str, (int*)&algo_id)) {
+		LM_ERR("unknown algorithm: '%.*s'\n", algo_str.len, algo_str.s);
+		rpc->fault(c, 400, "Unknown algorithm");
+		return;
+	}
+
+	LM_DBG("set_pipe: %.*s:%d:%d\n", pipeid.len, pipeid.s, algo_id, limit);
+
+	it = pl_pipe_get(&pipeid, 1);
+	if (it==NULL) {
+		LM_ERR("no pipe: %.*s\n", pipeid.len, pipeid.s);
+		rpc->fault(c, 400, "Unknown pipe id %.*s", pipeid.len, pipeid.s);
+		return;
+	}
+
+	it->algo = algo_id;
+	it->limit = limit;
+
+	if (check_feedback_setpoints(0)) {
+		pl_pipe_release(&pipeid);
+		LM_ERR("feedback limits don't match\n");
+		rpc->fault(c, 400, "Feedback limits don't match");
+		return;
+	} else {
+		*_pl_pid_setpoint = 0.01 * (double)_pl_cfg_setpoint;
+	}
+
+	pl_pipe_release(&pipeid);
+}
+