lib: bt_plugin_find*(): return status code; add "fail on load error" param
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Tue, 25 Jun 2019 16:50:17 +0000 (12:50 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 26 Jun 2019 16:31:23 +0000 (12:31 -0400)
commit9736d991ea189f29b908e9cf18103c1452c59e05
tree7693fe4f42cc244355de1f4508bc6fb182b9f08e
parent0d1c8791396d4cf4c5cc2160838f25608fa12b4b
lib: bt_plugin_find*(): return status code; add "fail on load error" param

The bt_plugin_find*() functions, before this patch, return a plugin
object or a plugin set object. When such a function returns `NULL`, you
have no way to tell if it's because there was an error or if no plugins
were found.

Also, when a plugin cannot be loaded for various reasons, sometimes it's
considered an error and sometimes not, so there's no way to be strict.

This patch makes:

* The bt_plugin_find*() functions return a status code, and return the
  plugin or plugin set object by output parameter.

  The available, new status codes are:

  `BT_PLUGIN_STATUS_OK`:
        Everything is fine.

  `BT_PLUGIN_STATUS_NOT_FOUND`:
        No plugins were found.

  `BT_PLUGIN_STATUS_ERROR`:
        There was a general error while trying to find plugins.

  `BT_PLUGIN_STATUS_LOADING_ERROR`:
        A plugin could not be loaded successfully while trying to find
        plugins.

  `BT_PLUGIN_STATUS_NOMEM`:
        There was an allocation error while trying to find plugins.

  The bt_plugin_find_all_from_file() and bt_plugin_find_all_from_dir()
  never return an empty plugin set: they return
  `BT_PLUGIN_STATUS_NOT_FOUND` instead.

* The bt_plugin_find*() functions accept a new `fail_on_load_error`
  parameter which controls whether a plugin loading error is ignored
  (can eventually lead to `BT_PLUGIN_STATUS_NOT_FOUND` being returned)
  or triggers a loading error condition
  (`BT_PLUGIN_STATUS_LOADING_ERROR`).

When `fail_on_load_error` is true, the functions log errors with
the WARN level. When it's false, they log errors with the INFO level
before ignoring them.

A file is known to be a Babeltrace plugin if:

* Its extension is `.so` (or `.dll` on Windows), g_module_open()
  succeeds for that file, and the required
  `__bt_get_begin_section_plugin_descriptors` symbol can be found.

* Its name starts with `bt_` and ends with `.py`.

Any file that does not meet the criteria above does not trigger a
loading error: the file is simply skipped.

A plugin loading error (`BT_PLUGIN_STATUS_LOADING_ERROR`) is caused by:

For a shared object (`.so` or `.dll`) plugin, one of:
    * Missing `__bt_get_end_section_plugin_descriptors` symbol.
    * Missing `__bt_get_begin_section_plugin_descriptor_attributes` and
      `__bt_get_end_section_plugin_descriptor_attributes` symbols.
    * Missing `__bt_get_begin_section_component_class_descriptors` and
      `__bt_get_end_section_component_class_descriptors` symbols.
    * Missing
      `__bt_get_begin_section_component_class_descriptor_attributes` and
      `__bt_get_end_section_component_class_descriptor_attributes`
      symbols.
    * Unknown plugin descriptor attribute.
    * Unknown component class descriptor attribute.
    * Unknown component class type in component class descriptors.
    * Incompatible or missing ABI version.
    * Failing plugin's user initialization function.

For a built-in plugin:
    * Failing plugin's user initialization function.

For a Python plugin, one of:
    * Failure to load the Python plugin module.
    * Unexpected/malformed plugin info object (missing attributes, wrong
      types, etc.).

With this patch, you must pass a valid file or directory path to
bt_plugin_find_all_from_file() and bt_plugin_find_all_from_dir(). When
you don't, the functions fail with `BT_PLUGIN_STATUS_ERROR`. This is not
considered a loading error (not `BT_PLUGIN_STATUS_LOADING_ERROR`), as
the user can control whether or not this error occurs­ by making sure
the path exists, and it does not occur while loading a plugin.

As of this patch, the CLI ignores loading errors (like before), that is,
passes `BT_FALSE` as the `fail_on_load_error` parameter. A strict mode
could be added, controlled by a command-line option.

In `native_bt_plugin.i`, wrappers are created to set the output
parameter to `NULL` if the status is not `BT_PLUGIN_STATUS_OK`. This is
similar to what was already done to wrap bt_plugin_get_version().

If you pass `fail_on_load_error=True` to bt2.find_plugins() or
bt2.find_plugin(), then this function can raise `bt2.Error` if there's
a loading error.

Tests are adapted to check the returned status code.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I88049c07163055503e9551940973390ebedcfae4
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1537
Reviewed-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
13 files changed:
include/babeltrace2/plugin/plugin-const.h
src/bindings/python/bt2/bt2/__init__.py.in
src/bindings/python/bt2/bt2/native_bt_plugin.i
src/bindings/python/bt2/bt2/plugin.py
src/cli/babeltrace2.c
src/lib/plugin/plugin-so.c
src/lib/plugin/plugin-so.h
src/lib/plugin/plugin.c
src/lib/plugin/plugin.h
src/python-plugin-provider/python-plugin-provider.c
src/python-plugin-provider/python-plugin-provider.h
tests/bindings/python/bt2/test_plugin.py
tests/lib/test_plugin.c
This page took 0.027343 seconds and 4 git commands to generate.