Hello,
from a thread in sip-router user mailing list:
http://lists.sip-router.org/pipermail/sr-users/2012-March/072657.html
This thread talks about reloading lua scripts in runtime context.
/ I'm starting to play with lua scripting in Kamailio. It's really cool,
/>>/ some complex stuff in the script becomes really easy this way. The
/>>/ script is becoming quite big, therefore I'd like to use lua_run
/>>/ instead of lua_dofile. My doubt is pretty basic: if i load a script
/>>/ in memory at startup via the "load" parameter and the script is
/>>/ modifed afterwards, is there any way to reload the module so the
/>>/ script is reread?
/>the two contexts created by app_lua were designed one for loading at
startup and the other for reloading every time. Reloading on demand at
runtime is not possible. I thought of checking the timestamp of the
script, but can be a bit risky if saving on intermediary state during
updates. The scripts are loaded in each process, sending a mi/rpc
command will require to do some inter-process signaling. Both doable,
not in my short term plans, though, if someone is contributing, will be
appreciated.
I have attached a test patch to start playing with this task.
A new function app_lua.runfile is created, and called via sercmd tool to
load some lua script in runtime context.
Some signaling is needed so every kamailio child process would reload
the script too.
Could you give some clues about performing this interprocess signaling
suitably for kamailio?
Best regards,
Vicente.
diff --git modules/app_lua/app_lua_api.c modules/app_lua/app_lua_api.c
index 9d5e662..bdd87c3 100644
--- modules/app_lua/app_lua_api.c
+++ modules/app_lua/app_lua_api.c
@@ -481,3 +481,26 @@ void app_lua_dump_stack(lua_State *L)
}
}
}
+
+
+/**
+ *
+ */
+int app_lua_runfile(struct sip_msg *msg, char *script)
+{
+ int ret;
+ char *txt;
+
+ LM_DBG("executing Lua file in run context: [[%s]]\n", script);
+ LM_DBG("lua top index is: %d\n", lua_gettop(_sr_L_env.LL));
+ _sr_L_env.msg = msg;
+ ret = luaL_dofile(_sr_L_env.LL, script);
+ if(ret!=0)
+ {
+ txt = (char*)lua_tostring(_sr_L_env.LL, -1);
+ LM_ERR("error from Lua: %s\n", (txt)?txt:"unknown");
+ lua_pop(_sr_L_env.LL, 1);
+ }
+ _sr_L_env.msg = 0;
+ return (ret==0)?0:-1;
+}
diff --git modules/app_lua/app_lua_api.h modules/app_lua/app_lua_api.h
index 3d1bff7..8781931 100644
--- modules/app_lua/app_lua_api.h
+++ modules/app_lua/app_lua_api.h
@@ -65,5 +65,7 @@ int app_lua_return_error(lua_State *L);
void app_lua_dump_stack(lua_State *L);
+int app_lua_runfile(struct sip_msg *msg, char *script);
+
#endif
diff --git modules/app_lua/app_lua_mod.c modules/app_lua/app_lua_mod.c
index 19a0c52..4f7c640 100644
--- modules/app_lua/app_lua_mod.c
+++ modules/app_lua/app_lua_mod.c
@@ -24,11 +24,14 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
+#include <string.h>
#include "../../sr_module.h"
#include "../../dprint.h"
#include "../../ut.h"
#include "../../mod_fix.h"
+#include "../../rpc.h"
+#include "../../rpc_lookup.h"
#include "app_lua_api.h"
@@ -41,6 +44,8 @@ static int mod_init(void);
static void mod_destroy(void);
static int child_init(int rank);
+static int app_lua_init_rpc(void);
+
static int w_app_lua_dostring(struct sip_msg *msg, char *script, char *extra);
static int w_app_lua_dofile(struct sip_msg *msg, char *script, char *extra);
static int w_app_lua_runstring(struct sip_msg *msg, char *script, char *extra);
@@ -108,6 +113,13 @@ static int mod_init(void)
{
if(lua_sr_init_mod()<0)
return -1;
+
+ if(app_lua_init_rpc()!=0)
+ {
+ LM_ERR("failed to register RPC commands\n");
+ return -1;
+ }
+
return 0;
}
@@ -329,3 +341,62 @@ static int fixup_lua_run(void** param, int param_no)
return fixup_spve_null(param, 1);
}
+
+/**
+ * RPC related functions.
+ */
+
+static const char* app_lua_rpc_runfile_doc[2] = {
+ "Load a file in lua run context.",
+ 0
+};
+
+
+/*
+ * RPC command to load a file in lua run context.
+ */
+static void app_lua_rpc_runfile(rpc_t* rpc, void* ctx)
+{
+ char *script_path;
+
+ if(!lua_sr_initialized())
+ {
+ LM_ERR("Lua env not intitialized\n");
+ rpc->fault(ctx, 500, "Lua Env Not Initialized Error");
+ return;
+ }
+
+ if (rpc->scan(ctx, "s", &script_path) < 1)
+ {
+ rpc->fault(ctx, 500, "Invalid parameters");
+ return;
+ }
+
+ LM_DBG("trying to load script %.*s in run context.\n",
+ (int)strlen(script_path), script_path);
+
+ /* int app_lua_runfile(struct sip_msg *msg, char *script) */
+ if(app_lua_runfile(NULL, script_path)!=0) {
+ LM_DBG("could load %.*s script in lua run context\n",
+ (int)strlen(script_path), script_path);
+ rpc->fault(ctx, 500, "Unable to load script");
+ return;
+ }
+}
+
+
+rpc_export_t app_lua_rpc_list[] = {
+ {"app_lua.runfile", app_lua_rpc_runfile,
+ app_lua_rpc_runfile_doc, 0},
+ {0, 0, 0, 0}
+};
+
+static int app_lua_init_rpc(void)
+{
+ if (rpc_register_array(app_lua_rpc_list)!=0)
+ {
+ LM_ERR("failed to register RPC commands\n");
+ return -1;
+ }
+ return 0;
+}
_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev