[SR-Dev] extending module interface

Daniel-Constantin Mierla miconda at gmail.com
Thu Nov 20 12:06:47 CET 2008

On 11/20/08 12:58, Andrei Pelinescu-Onciul wrote:
> On Nov 20, 2008 at 12:53, Daniel-Constantin Mierla <miconda at gmail.com> wrote:
>> On 11/20/08 12:40, Andrei Pelinescu-Onciul wrote:
>>> On Nov 20, 2008 at 11:50, Daniel-Constantin Mierla <miconda at gmail.com> 
>>> wrote:
>>>> Hello,
>>>> working to port PV engine to srouter, but also needed for kamailio's 
>>>> migration of pseudo-variables (PVs) from core to modules, I need to 
>>>> extend the module interface. The srouter has already support to work in 
>>>> dual mode committed by Andrei few days ago, so it should affect only 
>>>> kamailio's module interface if ser side does not need.
>>>> Here is the issue. In kamailio/openser we have so called transformations 
>>>> that are bound to PV. They are now implemented directly in core. To move 
>>>> them in a module, the interface needs to be extended, like we did in the 
>>>> past to export PVs from modules.
>>>> The important aspect is that they must 
>>>> become visible immediately after the module is loaded -- this happens 
>>>> also with PVs (so cannot use mod_init, etc...). This is required because 
>>>> they may occur during script parsing, therefore the core/parser should 
>>>> get knowledge of them in very early stage.
>>>> PVs are exported via a specific structure in module interface. We can do 
>>>> same for transformations. There is another option, which can be used for 
>>>> other purposes in the future - introducing in module interface a 
>>>> callback to be run immediately after a module is loaded. The 
>>>> transformations can be exported inside the callback.
>>> I personally don't like extending the module_export structure. It was
>>> done a lot in the past (both in kamailio/openser and ser), but IMHO
>>> is a mistake, because then you have to update _all_ the module to the
>>> new interface or do some hack like we have in sip-router to support
>>> several module interface versions.
>>> Instead of extending the structure is better to either add a new one
>>> an look (dlsym) for it when loading a module (if it's not present we
>>> just assume the module doesn't implement it), or use a callback.
>>>> Extending this way, in the future, the modules can make other attributes 
>>>> visible to core/other modules immediately after loading without changing 
>>>> the module interface.
>>>> Therefore I would go for second option. Other opinions?
>>> I prefer the callback too. As a matter of fact the first ser versions
>>> used to have a mod_register function for exactly that purpose:
>>> the module loader would resolve the mod_register symbol (dlsym()) and 
>>> then call it. In the first versions mod_register would also add/register 
>>> the module_export structure (which was not automatically loaded).
>>> I was going to propose mod_register revival too, for slightly different
>>> reasons: 
>>> - IMHO the mod_export structure is too big and some parts of it are
>>>   used only by a few modules, so I think it's easier/nicer to keep it 
>>>   smaller and register the not so common stuff from mod_register.
>>> - using this callback mechanism is easy to extend mod_export in the 
>>> future without requiring _any_ change in modules who don't implement / 
>>>   don't
>>>   care for the new functionality.
>>> - on some system it seems not to be possible to resolve a symbol pointing
>>> to a data structure, only symbols pointing to functions are ok (that
>>> and windows are on of the reasons for the static modules compilation
>>> options). So if we ever decide to fully support such systems we might
>>> need to register everything from mod_register even the module_export
>>>  structure (we could make some macro that would do this
>>>  semi-automatically).
>>> - one could dynamically manipulate mod_exports, before it's register
>>> (e.g. change pointer to functions depending on whether or not the
>>> system is smp :-)).
>>> So as first step I would add support for looking for and executing
>>> mod_register when loading the modules, before resolving/registering
>>>  mod_export. The prototype for it would look like:
>>>  int mod_register(char* path, int* dlflags)
>>> (it's better to do the dlflags hack as soon as possible)
>>> ret < 0 => don't load the module, 0 success, >0  reserved for future use.
>>> Does anybody disagree?
>>> Do you have a better name, or better prototype proposal?
>>> No _quick_ answer will be considered agreement (we can easily change it
>>> latter anyway if only a few module use it).
>> mod_register sounds good.
>> I was looking to keep everything in module_exports structure, just for 
>> consistency. But this indeed requires a lot of updates upon small change 
>> there.
>> As you say, from perspective of portability, exporting by function is 
>> better.
>> What would be the meaning of path parameter in mod_register? The module 
>> name?
> The path including the module name (what was passed to dlopen).
> It might be usefull in some corner cases (like module who wants to load
>  another module/plugin).
ok, btw, kamailio modules export also the dlflags needed to open the 
object -- required by perl module -- this should be kept in mind.


Daniel-Constantin Mierla

More information about the sr-dev mailing list