OLSR / OONF

OLSR.org Network Framework - olsrd v2 / DLEP

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dynamic plugin loading seems broken

jpo-github-work opened this issue · comments

I'm unsure about this, because it seems like a very fundamental functionality. It's hard to imagine that this is broken and nobody noticed until now, but here we go. I'm using the simplest configuration that can reproduce the issue:

[global]
	plugin lan_import

[log]
	debug plugins

Calling the program:

[olsr@fedora ~]$ sudo /usr/local/sbin/olsrd2_dynamic -l load-plugin.conf 
19:21:44.448 DEBUG(plugins) src/libcore/oonf_subsystem.c 514: dlopen (/liboonf_lan_import.so.0.15.1,0x1) failed: /liboonf_lan_import.so.0.15.1: cannot open shared object file: No such file or directory
19:21:44.448 DEBUG(plugins) src/libcore/oonf_subsystem.c 514: dlopen (/liboonf_lan_import.so,0x1) failed: /liboonf_lan_import.so: cannot open shared object file: No such file or directory
19:21:44.450 INFO(plugins) src/libcore/oonf_subsystem.c 517: dlopen (liboonf_lan_import.so.0.15.1,0x1) succeeded
19:21:44.450 WARN(plugins) src/libcore/oonf_subsystem.c 312: dynamic library loading failed: "(null)"!

The log statement WARN(plugins) src/libcore/oonf_subsystem.c 312: dynamic library loading failed: "(null)"! comes from function oonf_subsystem_load(const char *libname):

struct oonf_subsystem *
oonf_subsystem_load(const char *libname) {
  struct oonf_subsystem *plugin;
  void *dlhandle;
  int idx;

  /* see if the plugin is there */
  if ((plugin = oonf_subsystem_get(libname)) == NULL) {
    /* attempt to load the plugin */
    dlhandle = _open_plugin(libname, &idx);

    if (dlhandle == NULL) {
      /* Logging output has already been done by _open_plugin() */
      return NULL;
    }

    /* plugin should be in the tree now */
    if ((plugin = oonf_subsystem_get(libname)) == NULL) {
      OONF_WARN(LOG_PLUGINS, "dynamic library loading failed: \"%s\"!\n", dlerror());
      dlclose(dlhandle);
      return NULL;
    }

    plugin->_dlhandle = dlhandle;
    plugin->_dlpath_index = idx;
  }
  return plugin;
}

The code tries to load the plugin, if it hasn't previously been loaded, e.g. if oonf_subsystem_get returns NULL. _open_plugin seems to be just a fancy wrapper around dlopen. I can't see code between _open_plugin in line 303 and the second call to oonf_subsystem_get in line 311 that would register the plugin. So the comment /* plugin should be in the tree now */ doesn't match reality and we get the warning in line 312.

Yes you are right, there is no code between the "dlopen()" and the "should be in the tree"... thats because every plugin has a "constructor" section, which is run by the lunker when the plugin is loaded (either statically or dynamically). It was the only way I found to call code within the plugin easily AND use the same codepath for static loading.

See:
https://github.com/OLSR/OONF/blob/master/include/oonf/libcore/oonf_subsystem.h#L66

@HRogge, that was indeed helpful I think I found the issue:

  • src/olsrv2/lan_import/lan_import.c Line 211: DECLARE_OONF_PLUGIN(_import_subsystem);
  • src/generic/layer2_import/layer2_import.c Line 234: DECLARE_OONF_PLUGIN(_import_subsystem);

Both expand to the same symbol and the wrong one gets called.

There are two plugins defining the same capability (lan import).

So there is no bug, you should still have "lan_import" configuration options when working with the layer2_import plugin.

This happened because I needed that "lan_import" data also in the OONF internal layer2 database... so I wrote a new plugin that imports it there and added a second plugin that automatically moves entries based on the name of the source from the layer-2 database to the OLSRv2 LAN database.

If you have layer2_import and olsrv2_l2import plugins, you should have a working "lan_import" config option... without the lan_import plugin.

Well, something is broken, I'm now just unsure what exactly. As I understand you, the original lan_import plugin has been superceded by the layer2_import plugin, correct? That means:

As it stands right now, building and trying to load the lan_import plugin terminates the program, because the loading fails.

Plugin loading works as designed. The root problem has been identified and should be discussed in issue #47.