Skip to content

Writing your first plugin🔗

vAccel plugins provide the glue code between vAccel User API operations and their hardware implementations. A vAccel plugin is a shared object, built in any programming language that can generate it.

The required operations that need to be implemented for a shared object to be linked as a vAccel plugin, are the following:

  • An init() function, called upon plugin initialization
static int init(void) {

}
  • A fini() function, called before unloading the plugin
static int fini(void) {

}
  • A definition of the VACCEL_PLUGIN with:
  • .name : The name of the plugin
  • .version : The version of the plugin
  • .vaccel_version : The vAccel library version that the plugin was built against
  • .init : The function to call upon plugin initialization (eg. init())
  • .fini : The function to call before unloading the plugin (eg. on program exit, fini())
VACCEL_PLUGIN(
    .name = "vAccel template plugin",
    .version = "0.9",
    .vaccel_version = VACCEL_VERSION,
    .init = init,
    .fini = fini
)

At initialization, the plugin needs to register the vAccel operations that it implements. To do that, we use an array of struct vaccel_ops, that map each function implementation to the respective API operation. An operation array could look like the following:

static struct vaccel_op ops[] = {
    VACCEL_OP_INIT(ops[0], VACCEL_OP_NOOP, my_noop_function),
    [...]
};

where VACCEL_OP_NOOP is the operation type and my_noop_function is the function implementation:

struct vaccel_op {
    /* operation type */
    vaccel_op_type_t type;

    /* function implementing the operation */
    void *func;

    [...]
};

Implement a simple NOOP plugin🔗

To better understand how to implement an actual plugin we provide a vaccel-plugin-template. This repo is a good start for developing a vAccel plugin in C.

Let's look into src/vaccel.c from the template repo:

#include <inttypes.h>
#include <stdio.h>
#include <vaccel.h> /* header with vAccel API */

/* A function that will be mapped to a vAccel User API operation using
 * register_plugin_functions() */
static int my_noop_function(struct vaccel_session *sess)
{
    fprintf(stderr, "[my noop function] session: %" PRId64 "\n", sess->id);
    return VACCEL_OK;
}

/* An array of the operations to be mapped */
struct vaccel_op ops[] = {
    VACCEL_OP_INIT(ops[0], VACCEL_NO_OP, my_noop_function),
};

/* The init() function, called upon plugin initialization */
static int init(void)
{
    /* This is where the static function above `my_noop_function()`
     * gets mapped to the relevant vAccel User API operation. */
    return vaccel_plugin_register_ops(ops, sizeof(ops) / sizeof(ops[0]));
}

/* The fini() function, called before unloading the plugin */
static int fini(void)
{
    return VACCEL_OK;
}

VACCEL_PLUGIN(.name = "template", .version = "0.9",
              .vaccel_version = VACCEL_VERSION, .init = init, .fini = fini)

The plugin registers my_noop_function() to serve as the implementation of the VACCEL_OP_NOOP API operation.

Install requirements🔗

Before building a vAccel plugin, we need to install the main vAccel library. Instructions on how to build vAccel can be found here.

We also need some packages to build the plugin itself:

sudo apt-get install build-essential ninja-build pkg-config python3-pip
sudo pip install meson

Build the plugin🔗

Now we can build the vAccel plugin template that implements the NOOP user API operation with our own custom function.

First clone the repo:

git clone https://github.com/nubificus/vaccel-plugin-template
cd vaccel-plugin-template

Use meson to prepare the build directory:

meson setup build

an build the plugin with:

meson compile -C build

This should output a shared object (libvaccel-template.so) in ./build/src/.

To be used as a plugin, we need to select it using the environment variable VACCEL_PLUGINS when running our vAccel application (ie. VACCEL_PLUGINS=/path/to/libvaccel-template.so).

See Running the examples for more info.