Merge branch 'develop' into feature-127-protocol-split

This commit is contained in:
Robert Schmidt
2019-02-21 20:18:35 +01:00
647 changed files with 79545 additions and 70280 deletions
+17
View File
@@ -0,0 +1,17 @@
# OAI shared library loader
Shared libraries usage is modularization mechanism which provides the following advantages:
1. Prevents including in the main executable code which is not used in a given configuration
1. Provides flexibility, several implementation of a given functionality can be chosen at run-time, without any compilation step. For example you can build several devices (USRP, BladeFR, LimeSDR) and choose which one you want to use on the command line or via the configuration.
1. Makes code evolution easier: as soon as the shared library interface is clearly defined, you can work on the functionality implemented in a shared library while regularly updating the other components of the code. You can decide to develop your own version of a functionality, decide to deliver it or not, letting the user decide wwhat version he wants to use.
The main drawback is a performance cost at init time, when loading libraries.
## Documentation
* [runtime usage](loader/rtusage.md)
* [developer usage](loader/devusage.md)
* [module architecture](loader/arch.md)
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)
+7
View File
@@ -0,0 +1,7 @@
# loader source files
The oai shared library loader is implemented in two source files, located in [common/utils](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils)
1. [load_module_shlib.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.c) contains the loader implementation
1. [load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.h) is the loader include file containing both private and public data type definitions. It also contain API prototypes.
[loader home page](../loader.md)
+16
View File
@@ -0,0 +1,16 @@
The loader objectives are
1. provides a common mechanism to prevent an executable to include code that is only used under specific configurations, without rebuilding the code
1. Provide a common mechanism to allow to choose between different implementations of a given set of functions, without rebuilding the code
As a developer you may need to look at these sections:
* [loading a shared library](devusage/loading.md)
* [loader API](devusage/api.md)
* [loader public structures](devusage/struct.md)
Loader usage examples can be found in oai sources:
* device and transport initialization code: [function `load_lib` in *targets/ARCH/COMMON/__common_lib.c__* ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/targets/ARCH/COMMON/common_lib.c#L91)
* turbo encoder and decoder initialization: [function `load_codinglib`in *openair1/PHY/CODING/__coding_load.c__*](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/CODING/coding_load.c#L113)
[loader home page](../loader.md)
+20
View File
@@ -0,0 +1,20 @@
Loader API is defined in the [common/utils/load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/load_module_shlib.h) include file.
```c
int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf)
```
* possibly initializes the loader, if it has not been already initialized
* Formats the full shared library path, using the `modname` argument and the loader `shlibpath` and `shlibversion`configuration parameters.
* loads the shared library, using the dlopen system call
* looks for `< modname >_autoinit` symbol, using the `dlsym` system call and possibly call the corresponding function.
* looks for `< modname >_checkbuildver` symbol, using the `dlsym` system call and possibly calls the corresponding function. If the return value of this call is `-1`, program execution is stopped. It is the responsibility of the shared library developer to implement or not a `< modname >_checkbuildver` function and to decide if a version mismatch is a fatal condition. The `< modname >_checkbuildver` function must match the `checkverfunc_t` function type. The first argument is the main executable version, as set in the `PACKAGE_VERSION` macro defined in the [oai CMakeLists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt#L218), around line 218. The second argument points to the shared library version which should be set by the `< modname >_checkbuildver` function.
* If the farray pointer is null, looks for `< modname >_getfarray` symbol, calls the corresponding function when the symbol is found. `< modname >_getfarray` takes one argument, a pointer to a `loader_shlibfunc_t` array, and returns the number of items in this array, as defined by the `getfarrayfunc_t` type. The `loader_shlibfunc_t` array returned by the shared library must be fully filled (both `fname` and `fptr` fields).
* looks for the `numf` function symbols listed in the `farray[i].fname` arguments and set the corresponding `farray[i].fptr`function pointers
```c
void * get_shlibmodule_fptr(char *modname, char *fname)
```
Returns a pointer to the symbol `fname`, defined in module `modname`, or `NULL` if the symbol is not found.
[loader home page](../../loader.md)
[loader developer home page](../devusage.md)
@@ -0,0 +1,56 @@
Implementing a shared library dynamic load using the oai loader is a two steps task:
1. define the `loader_shlibfunc_t` array, describing the list of externally available functions implemented in the library. This is the interface of the module.
1. Call the `load_module_shlib` function, passing it the previously defined array and the number of items in this array. The first argument to `load_module_shlib` is the name identifying the module, which is also used to format the corresponding library name, as described [here](loader/rtusage#shared-library-names)
After a successful `load__module_shlib` call, the function pointer of each `loader_shlibfunc_t` array item has been set and can be used to call the corresponding function.
Typical loader usage looks like:
```c
/* shared library loader include file */
#include "common/utils/load_module_shlib.h"
.............
/*
define and initialize the array, describing the list of functions
implemented in "mymodule"
*/
loader_shlibfunc_t mymodule_fdesc[2];
mymodule_fdesc[0].fname="mymodule_f1";
mymodule_fdesc[1].fname="mymodule_f2";
/*
load the library, it's name must be libmymod.so. Configuration can be
used to specify a specific path to look for libmymod.so. Configuration
can also specify a version, for example "V1", in this case the loader
will look for libmymodV1.so
*/
ret=load_module_shlib("mymod",mymodule_fdesc, sizeof(mymodule_fdesc)/sizeof(loader_shlibfunc_t));
if (ret < 0) {
fprintf(stderr,"Library couldn't be loaded\n");
} else {
/*
library has been loaded, we probably want to call some functions...
*/
ret=((funcf1_t)mymodule_fdesc[0].fptr)();
..................
/*
later and/or somewhere else in the code you may want to call function "mymodule_f2"
You can use the loader get_shlibmodule_fptr(char *modname, char *fname) function
to retrieve the pointer to that function
*/
funcf2_t *f2;
int ret;
int intarg1;
char *strarg;
........................
f2 = (funcf2_t)get_shlibmodule_fptr("mymodule", "mymodule_f2")
if (f2 != NULL) {
ret = f2(intarg1,strarg);
}
...............
```
When loading a shared library the loader looks for a symbol named `< module name > _autoinit` and, if it finds it, calls it. The `autoinit` function is called without any argument and the returned value, if any, is not tested.
[loader home page](../loader.md)
[loader developer home page](../../loader/devusage.md)
@@ -0,0 +1,10 @@
# `loader_shlibfunc_t`structure
It is defined in include file [ common/util/load_module_shlib.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/load_module_shlib.h#L38). This structure is used to list the symbols that should be searched by the loader when calling the `load_module_shlib` function.
| Fields | Description | I/O |
|:-----------|:------------------------------------------------------------------|----:|
| `fname` | symbol name, is passed to the [`dlsym`](http://man7.org/linux/man-pages/man3/dlsym.3.html) system call performed by the loader to get a pointer to the symbol | I |
| `fptr` | pointer to the symbol name, set by the loader. `fptr` is defined as a `int (*fptr)(void)` function type | O |
[loader home page](../../loader.md)
[loader developer home page](../devusage.md)
+50
View File
@@ -0,0 +1,50 @@
## shared library names
Shared library full names are built by the loader using the format:
> < *path* >/lib< *module name* >< *module version* >.so
1. the < *module name* > is defined at development time, it comes from the `modname` argument of the `load_module_shlib` call.
1. the < *module version* > and < *path* > optional parameters, are defined at run-time, depending on the configuration.
## loader parameters
The loader is using the [configuration module](../../../config/DOC/config.md), and defines global and per library parameters. Global parameters must be specified under the **loader** section and library specific parameters under a **loader.<*module name*>** section. Module specific parameters override the global parameters.
### Global loader parameters
| name | type | default | description |
|:---:|:---:|:---:|:----|
| `shlibpath` | `string of char` | `""` | directory path used to look for shared libraries, may be superseded by the library specific `shlibpath`.|
| `maxshlibs` | `integer` | 10 | Maximum number of shared libraries the loader can manage. |
### library specific loader parameters
| name | type | default | description |
|:---:|:---:|:---:|:----|
| `shlibpath` | `string of char` | `""` | directory path used to look for this shared library.|
| `shlibversion` | `string of char` | `""` | version to be used to load this shared library.|
### loader configuration examples
The following configuration file example just reproduce the default loader parameters:
```c
loader :
{
shlibpath = "./";
maxshlibs = 10;
liboai_device :
{
shlibpath = "./";
shlibversion = "";
}
};
```
If you want to load a device called *liboai_device_USRP.so* without writting a specific configuration, you can start the softmodem using the following command:
> ./lte-softmodem -O libconfig:/usr/local/oai/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.nbiot.band7.tm1.50PRB.usrpb210.conf:dbgl5 --loader.oai_device.shlibversion _USRP
With this latest example, nn the softmodem logs, you can check that the right device library has been loaded:
```bash
[LIBCONFIG] loader.oai_device.shlibpath not found in /usr/local/oai/develop-nb-iot-merge/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.nbiot.band7.tm1.50PRB.usrpb210.conf
[LIBCONFIG] loader.oai_device.shlibversion set to default value ""
[LIBCONFIG] loader.oai_device: 1/2 parameters successfully set, (1 to default value)
[CONFIG] shlibversion set to _USRP from command line
[CONFIG] loader.oai_device 1 options set from command line
```
[loader home page](../loader.md)