Skip to content

Commit

Permalink
Plugin framework enhancements.
Browse files Browse the repository at this point in the history
Up until now the plugins for the fd/sd/dir are loaded semi at
random by the way they are stored in the plugin directory as
they are loaded in the order readdir returns the directory entries.

This is NOT how you want it in certain situations so from now on
you can specify in the fd/sd/dir a new keyword in the generic
daemon config resource named "plugin names" which is a list
which is seperated by a ':' and enumerates the plugins that
should be loaded in what order by a daemon. In this resource
you can define the following 'plugin names = "python:bpipe"'
which means in the fd load the following plugins:

- <plugin_dir>/python-fd.so
- <plugin_dir>/bpipe-fd.so

If you don't specify the plugin names then the old behaviour
will be used to load all plugins which match the pattern
*-<daemon>.so

Now we can order the way plugins are loaded there is also a
new flag to the generate_plugin_event() function which is named
reverse which is a boolean and if its set the plugins will be
called in reverse order that they are stored in the plugin list.

Fixes #196: Plugin framework enhancements.
  • Loading branch information
Marco van Wieringen committed Feb 17, 2015
1 parent 68e6fa8 commit 12471f5
Show file tree
Hide file tree
Showing 23 changed files with 425 additions and 215 deletions.
61 changes: 43 additions & 18 deletions src/dird/dir_plugins.c
Expand Up @@ -101,12 +101,31 @@ static inline bool is_plugin_disabled(JCR *jcr)
}
#endif

static inline bRC trigger_plugin_event(JCR *jcr, bDirEventType eventType, bDirEvent *event,
Plugin *plugin, bpContext *plugin_ctx_list,
int index, void *value)
{
bpContext *ctx;

ctx = &plugin_ctx_list[index];
if (!is_event_enabled(ctx, eventType)) {
Dmsg1(dbglvl, "Event %d disabled for this plugin.\n", eventType);
return bRC_OK;
}

if (is_plugin_disabled(ctx)) {
Dmsg0(dbglvl, "Plugin disabled.\n");
return bRC_OK;
}

return dirplug_func(plugin)->handlePluginEvent(ctx, event, value);
}

/*
* Create a plugin event
*/
int generate_plugin_event(JCR *jcr, bDirEventType eventType, void *value)
int generate_plugin_event(JCR *jcr, bDirEventType eventType, void *value, bool reverse)
{
bpContext *ctx;
bDirEvent event;
Plugin *plugin;
int i;
Expand All @@ -115,6 +134,7 @@ int generate_plugin_event(JCR *jcr, bDirEventType eventType, void *value)
if (!dird_plugin_list || !jcr || !jcr->plugin_ctx_list) {
return bRC_OK; /* Return if no plugins loaded */
}

if (jcr->is_job_canceled()) {
return bRC_Cancel;
}
Expand All @@ -124,19 +144,24 @@ int generate_plugin_event(JCR *jcr, bDirEventType eventType, void *value)

Dmsg2(dbglvl, "dir-plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);

foreach_alist_index(i, plugin, dird_plugin_list) {
ctx = &plugin_ctx_list[i];
if (!is_event_enabled(ctx, eventType)) {
Dmsg1(dbglvl, "Event %d disabled for this plugin.\n", eventType);
continue;
}
if (is_plugin_disabled(ctx)) {
Dmsg0(dbglvl, "Plugin disabled.\n");
continue;
/*
* See if we need to trigger the loaded plugins in reverse order.
*/
if (reverse) {
foreach_alist_rindex(i, plugin, dird_plugin_list) {
rc = trigger_plugin_event(jcr, eventType, &event, plugin, plugin_ctx_list, i, value);

if (rc != bRC_OK) {
break;
}
}
rc = dirplug_func(plugin)->handlePluginEvent(ctx, &event, value);
if (rc != bRC_OK) {
break;
} else {
foreach_alist_index(i, plugin, dird_plugin_list) {
rc = trigger_plugin_event(jcr, eventType, &event, plugin, plugin_ctx_list, i, value);

if (rc != bRC_OK) {
break;
}
}
}

Expand Down Expand Up @@ -170,7 +195,7 @@ static void dump_dir_plugins(FILE *fp)
* This entry point is called internally by BAREOS to ensure
* that the plugin IO calls come into this code.
*/
void load_dir_plugins(const char *plugin_dir)
void load_dir_plugins(const char *plugin_dir, const char *plugin_names)
{
Plugin *plugin;
int i;
Expand All @@ -182,8 +207,8 @@ void load_dir_plugins(const char *plugin_dir)
}

dird_plugin_list = New(alist(10, not_owned_by_alist));
if (!load_plugins((void *)&binfo, (void *)&bfuncs, dird_plugin_list, plugin_dir, plugin_type,
is_plugin_compatible)) {
if (!load_plugins((void *)&binfo, (void *)&bfuncs, dird_plugin_list,
plugin_dir, plugin_names, plugin_type, is_plugin_compatible)) {
/* Either none found, or some error */
if (dird_plugin_list->size() == 0) {
delete dird_plugin_list;
Expand Down Expand Up @@ -572,7 +597,7 @@ int main(int argc, char *argv[])
} else {
getcwd(plugin_dir, sizeof(plugin_dir)-1);
}
load_dir_plugins(plugin_dir);
load_dir_plugins(plugin_dir, NULL);

jcr1->JobId = 111;
new_plugins(jcr1);
Expand Down
5 changes: 3 additions & 2 deletions src/dird/dir_plugins.h
Expand Up @@ -142,12 +142,13 @@ typedef struct s_dirbareosFuncs {
* Bareos Core Routines -- not used within a plugin
*/
#ifdef DIRECTOR_DAEMON
void load_dir_plugins(const char *plugin_dir);
void load_dir_plugins(const char *plugin_dir, const char *plugin_names);
void unload_dir_plugins(void);
int list_dir_plugins(POOL_MEM &msg);
void new_plugins(JCR *jcr);
void free_plugins(JCR *jcr);
int generate_plugin_event(JCR *jcr, bDirEventType event, void *value=NULL);
int generate_plugin_event(JCR *jcr, bDirEventType event,
void *value = NULL, bool reverse = false);
#endif

/****************************************************************************
Expand Down
2 changes: 1 addition & 1 deletion src/dird/dird.c
Expand Up @@ -310,7 +310,7 @@ int main (int argc, char *argv[])
4 /* UA */ + 5 /* sched+watchdog+jobsvr+misc */);
lmgr_init_thread(); /* initialize the lockmanager stack */

load_dir_plugins(me->plugin_directory);
load_dir_plugins(me->plugin_directory, me->plugin_names);

/* If we are in testing mode, we don't try to fix the catalog */
cat_op mode=(test_config)?CHECK_CONNECTION:UPDATE_AND_FIX;
Expand Down
1 change: 1 addition & 0 deletions src/dird/dird_conf.c
Expand Up @@ -120,6 +120,7 @@ static RES_ITEM dir_items[] = {
{ "workingdirectory", store_dir, ITEM(res_dir.working_directory), 0, ITEM_DEFAULT, _PATH_BAREOS_WORKINGDIR },
{ "piddirectory", store_dir, ITEM(res_dir.pid_directory), 0, ITEM_DEFAULT, _PATH_BAREOS_PIDDIR },
{ "plugindirectory", store_dir, ITEM(res_dir.plugin_directory), 0, 0, NULL },
{ "pluginnames", store_str, ITEM(res_dir.plugin_names), 0, 0, NULL },
{ "scriptsdirectory", store_dir, ITEM(res_dir.scripts_directory), 0, 0, NULL },
{ "subscriptions", store_pint32, ITEM(res_dir.subscriptions), 0, ITEM_DEFAULT, "0" },
{ "subsysdirectory", store_dir, ITEM(res_dir.subsys_directory), 0, 0, NULL },
Expand Down
5 changes: 3 additions & 2 deletions src/dird/dird_conf.h
Expand Up @@ -102,8 +102,9 @@ class DIRRES {
char *password; /* Password for UA access */
char *query_file; /* SQL query file */
char *working_directory; /* WorkingDirectory */
const char *scripts_directory; /* ScriptsDirectory */
const char *plugin_directory; /* Plugin Directory */
char *scripts_directory; /* ScriptsDirectory */
char *plugin_directory; /* Plugin Directory */
char *plugin_names; /* Plugin names to load */
char *pid_directory; /* PidDirectory */
char *subsys_directory; /* SubsysDirectory */
MSGSRES *messages; /* Daemon message handler */
Expand Down
119 changes: 77 additions & 42 deletions src/filed/fd_plugins.c
Expand Up @@ -185,13 +185,47 @@ bool is_plugin_disabled(JCR *jcr)
return is_plugin_disabled(jcr->plugin_ctx);
}

static inline void trigger_plugin_event(JCR *jcr, bEventType eventType, bEvent *event, Plugin *plugin,
bpContext *plugin_ctx_list, int index, void *value)
{
bpContext *ctx;

/*
* Note, at this point do not change
* jcr->plugin or jcr->plugin_ctx
*/
Dsm_check(999);
ctx = &plugin_ctx_list[index];
if (!is_event_enabled(ctx, eventType)) {
Dmsg1(dbglvl, "Event %d disabled for this plugin.\n", eventType);
return;
}

if (is_plugin_disabled(ctx)) {
return;
}

if (eventType == bEventEndRestoreJob) {
Dmsg0(50, "eventType==bEventEndRestoreJob\n");
if (jcr->plugin && jcr->plugin->restoreFileStarted) {
plug_func(jcr->plugin)->endRestoreFile(jcr->plugin_ctx);
}

if (jcr->plugin) {
jcr->plugin->restoreFileStarted = false;
jcr->plugin->createFileCalled = false;
}
}

plug_func(plugin)->handlePluginEvent(ctx, event, value);
}

/**
* Create a plugin event When receiving bEventCancelCommand, this function is
* called by an other thread.
*/
void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
void generate_plugin_event(JCR *jcr, bEventType eventType, void *value, bool reverse)
{
bpContext *ctx;
bEvent event;
Plugin *plugin;
char *name = NULL;
Expand All @@ -207,7 +241,7 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)

/*
* Some events are sent to only a particular plugin or must be
* called even if the job is canceled
* called even if the job is canceled.
*/
switch(eventType) {
case bEventPluginCommand:
Expand All @@ -218,9 +252,13 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
}
break;
case bEventRestoreObject:
/* After all RestoreObject, we have it one more time with value=NULL */
/*
* After all RestoreObject, we have it one more time with value = NULL
*/
if (value) {
/* Some RestoreObjects may not have a plugin name */
/*
* Some RestoreObjects may not have a plugin name
*/
rop = (restore_object_pkt *)value;
if (*rop->plugin_name) {
name = rop->plugin_name;
Expand All @@ -246,7 +284,9 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
break;
}

/* If call_if_canceled is set, we call the plugin anyway */
/*
* If call_if_canceled is set, we call the plugin anyway
*/
if (!call_if_canceled && jcr->is_job_canceled()) {
return;
}
Expand All @@ -258,39 +298,31 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)

/*
* Pass event to every plugin that has requested this event type
* (except if name is set). If name is set, we pass it only to
* the plugin with that name.
* (except if name is set). If name is set, we pass it only to
* the plugin with that name.
*
* See if we need to trigger the loaded plugins in reverse order.
*/
foreach_alist_index(i, plugin, fd_plugin_list) {
if (!for_this_plugin(plugin, name, len)) {
Dmsg2(dbglvl, "Not for this plugin name=%s NULL=%d\n",
name, (name == NULL) ? 1 : 0);
continue;
}
/*
* Note, at this point do not change
* jcr->plugin or jcr->plugin_ctx
*/
Dsm_check(999);
ctx = &plugin_ctx_list[i];
if (!is_event_enabled(ctx, eventType)) {
Dmsg1(dbglvl, "Event %d disabled for this plugin.\n", eventType);
continue;
}
if (is_plugin_disabled(ctx)) {
continue;
}
if (eventType == bEventEndRestoreJob) {
Dmsg0(50, "eventType==bEventEndRestoreJob\n");
if (jcr->plugin && jcr->plugin->restoreFileStarted) {
plug_func(jcr->plugin)->endRestoreFile(jcr->plugin_ctx);
if (reverse) {
foreach_alist_rindex(i, plugin, fd_plugin_list) {
if (!for_this_plugin(plugin, name, len)) {
Dmsg2(dbglvl, "Not for this plugin name=%s NULL=%d\n",
name, (name == NULL) ? 1 : 0);
continue;
}
if (jcr->plugin) {
jcr->plugin->restoreFileStarted = false;
jcr->plugin->createFileCalled = false;

trigger_plugin_event(jcr, eventType, &event, plugin, plugin_ctx_list, i, value);
}
} else {
foreach_alist_index(i, plugin, fd_plugin_list) {
if (!for_this_plugin(plugin, name, len)) {
Dmsg2(dbglvl, "Not for this plugin name=%s NULL=%d\n",
name, (name == NULL) ? 1 : 0);
continue;
}

trigger_plugin_event(jcr, eventType, &event, plugin, plugin_ctx_list, i, value);
}
plug_func(plugin)->handlePluginEvent(ctx, &event, value);
}

return;
Expand Down Expand Up @@ -1118,7 +1150,7 @@ static void dump_fd_plugins(FILE *fp)
* This entry point is called internally by Bareos to ensure
* that the plugin IO calls come into this code.
*/
void load_fd_plugins(const char *plugin_dir)
void load_fd_plugins(const char *plugin_dir, const char *plugin_names)
{
Plugin *plugin;
int i;
Expand All @@ -1131,8 +1163,10 @@ void load_fd_plugins(const char *plugin_dir)
fd_plugin_list = New(alist(10, not_owned_by_alist));
Dsm_check(999);
if (!load_plugins((void *)&binfo, (void *)&bfuncs, fd_plugin_list,
plugin_dir, plugin_type, is_plugin_compatible)) {
/* Either none found, or some error */
plugin_dir, plugin_names, plugin_type, is_plugin_compatible)) {
/*
* Either none found, or some error
*/
if (fd_plugin_list->size() == 0) {
delete fd_plugin_list;
fd_plugin_list = NULL;
Expand All @@ -1141,7 +1175,9 @@ void load_fd_plugins(const char *plugin_dir)
}
}

/* Plug entry points called from findlib */
/*
* Plug entry points called from findlib
*/
plugin_bopen = my_plugin_bopen;
plugin_bclose = my_plugin_bclose;
plugin_bread = my_plugin_bread;
Expand All @@ -1150,8 +1186,7 @@ void load_fd_plugins(const char *plugin_dir)
Dsm_check(999);

/*
* Verify that the plugin is acceptable, and print information
* about it.
* Verify that the plugin is acceptable, and print information about it.
*/
foreach_alist_index(i, plugin, fd_plugin_list) {
Jmsg(NULL, M_INFO, 0, _("Loaded plugin: %s\n"), plugin->file);
Expand Down Expand Up @@ -2003,7 +2038,7 @@ int main(int argc, char *argv[])
} else {
getcwd(plugin_dir, sizeof(plugin_dir)-1);
}
load_fd_plugins(plugin_dir);
load_fd_plugins(plugin_dir, NULL);

jcr1->JobId = 111;
new_plugins(jcr1);
Expand Down
5 changes: 3 additions & 2 deletions src/filed/fd_plugins.h
Expand Up @@ -230,12 +230,13 @@ typedef struct s_bareosInfo {
#ifdef FILE_DAEMON
struct BFILE; /* forward referenced */
struct FF_PKT;
void load_fd_plugins(const char *plugin_dir);
void load_fd_plugins(const char *plugin_dir, const char *plugin_names);
void unload_fd_plugins(void);
int list_fd_plugins(POOL_MEM &msg);
void new_plugins(JCR *jcr);
void free_plugins(JCR *jcr);
void generate_plugin_event(JCR *jcr, bEventType event, void *value=NULL);
void generate_plugin_event(JCR *jcr, bEventType event,
void *value = NULL, bool reverse = false);
bool send_plugin_name(JCR *jcr, BSOCK *sd, bool start);
bool plugin_name_stream(JCR *jcr, char *name);
int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace);
Expand Down
2 changes: 1 addition & 1 deletion src/filed/filed.c
Expand Up @@ -242,7 +242,7 @@ int main (int argc, char *argv[])
read_state_file(me->working_directory, "bareos-fd",
get_first_port_host_order(me->FDaddrs));

load_fd_plugins(me->plugin_directory);
load_fd_plugins(me->plugin_directory, me->plugin_names);

#ifdef BOMB
me += 1000000;
Expand Down
1 change: 1 addition & 0 deletions src/filed/filed_conf.c
Expand Up @@ -94,6 +94,7 @@ static RES_ITEM cli_items[] = {
{ "piddirectory", store_dir, ITEM(res_client.pid_directory), 0, ITEM_DEFAULT, _PATH_BAREOS_PIDDIR },
{ "subsysdirectory", store_dir, ITEM(res_client.subsys_directory), 0, 0, NULL },
{ "plugindirectory", store_dir, ITEM(res_client.plugin_directory), 0, 0, NULL },
{ "pluginnames", store_str, ITEM(res_client.plugin_names), 0, 0, NULL },
{ "scriptsdirectory", store_dir, ITEM(res_client.scripts_directory), 0, 0, NULL },
{ "maximumconcurrentjobs", store_pint32, ITEM(res_client.MaxConcurrentJobs), 0, ITEM_DEFAULT, "20" },
{ "messages", store_res, ITEM(res_client.messages), R_MSGS, 0, NULL },
Expand Down
1 change: 1 addition & 0 deletions src/filed/filed_conf.h
Expand Up @@ -86,6 +86,7 @@ struct CLIENTRES {
char *pid_directory;
char *subsys_directory;
char *plugin_directory; /* Plugin directory */
char *plugin_names;
char *scripts_directory;
MSGSRES *messages; /* Daemon message handler */
uint32_t MaxConcurrentJobs;
Expand Down

0 comments on commit 12471f5

Please sign in to comment.