[SR-Dev] extending module interface
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>
>>>> 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
>>> - 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 /
>>> 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
>>> - 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
>> As you say, from perspective of portability, exporting by function is
>> What would be the meaning of path parameter in mod_register? The module
> 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.
More information about the sr-dev