Plugins initialization inside libpkg

Plugins initialization

Discovering the plugins by pkgng and loading them is just the first step.

Once a plugin is loaded libpkg will ask for the plugin to initialize itself.

During the plugin initialization step a plugin generally does two things:

  • Registering it's metadata information - plugin name, version and short description
  • Registering a hook into the library

Registering a hook into the library is not required by all plugins. For example plugins that provide new commands to the pkg frontend are not registering hooks into the library. Such example plugin is the command-mystats plugin.

Other plugins which directly hook into libpkg must register a hook. Such plugins are being executed when a certain condition occurs - like for example executing a plugin before any install/deinstall actions are taken.

These are the two required steps a plugin must perform during initialization. Of course other initialization steps could be taken, if for example the plugin requires it - like for example loading a plugin specific configuration file. See the zfssnap plugin for such an example.

Enough theory, let's look at some code now!

In order to get a plugin initialized libpkg will look for a function with specific name provided by the plugin which does the initialization. That function is called init().

The plugin's init function has the following prototype:

  1. int init(struct pkg_plugin *p);

The plugin's init function should also take care of returning proper return values, where EPKG_OK (0) means successful initialization and EPKG_FATAL ( > 0 ) means failure during initialization. Plugins which failed to initialize will not be loaded.

Below you can see the definition of the stats plugin init() function, which performs the initialization of the stats plugin and returns EPKG_OK or EPKG_FATAL depending on whether the plugin initialized successfully or not.

  1. /*
  2.  * stats plugin initialization
  3.  */
  4. int
  5. init(struct pkg_plugin *p)
  6. {
  7.         /*
  8.          * Hook into the library and provide package stats for the following actions:
  9.          *
  10.          * - pre-install
  11.          * - post-install
  12.          * - pre-deinstall
  13.          * - post-deinstall
  14.          */
  15.         pkg_plugin_set(p, PKG_PLUGIN_NAME, name);
  16.         pkg_plugin_set(p, PKG_PLUGIN_DESC, description);
  17.         pkg_plugin_set(p, PKG_PLUGIN_VERSION, version);
  19.         if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_PRE_INSTALL, &plugin_stats_callback) != EPKG_OK) {
  20.                 fprintf(stderr, "Plugin '%s' failed to hook into the library\n", PLUGIN_NAME);
  21.                 return (EPKG_FATAL);
  22.         }
  24.         if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_POST_INSTALL, &plugin_stats_callback) != EPKG_OK) {
  25.                 fprintf(stderr, "Plugin '%s' failed to hook into the library\n", PLUGIN_NAME);
  26.                 return (EPKG_FATAL);
  27.         }
  28.         if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_PRE_DEINSTALL, &plugin_stats_callback) != EPKG_OK) {
  29.                 fprintf(stderr, "Plugin '%s' failed to hook into the library\n", PLUGIN_NAME);
  30.                 return (EPKG_FATAL);
  31.         }
  33.         if (pkg_plugin_hook_register(p, PKG_PLUGIN_HOOK_POST_DEINSTALL, &plugin_stats_callback) != EPKG_OK) {
  34.                 fprintf(stderr, "Plugin '%s' failed to hook into the library\n", PLUGIN_NAME);
  35.                 return (EPKG_FATAL);
  36.         }
  38.         return (EPKG_OK);
  39. }

Don't worry about the pkg_plugin_hook_register() function if it doesn't ring any bell to you for now as we'll be discussing it a bit later in the next section of the handbook.

In the next chapter we take a closer look at the init() functions and how to register a hook into libpkg.