From 85b9ac1d1f3494ba97b3a9257deb48ded0ab3284 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 28 Jan 2008 14:41:46 +0000 Subject: [PATCH] Alpha integration of Dir plugin git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6333 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/dird/Makefile.in | 4 +- bacula/src/dird/dir-plugins.c | 258 ++++++++++++++++++ .../dir/plugin-dir.h => dird/dir-plugins.h} | 56 ++-- bacula/src/dird/dird.c | 5 +- bacula/src/dird/dird.h | 3 +- bacula/src/filed/fd-plugins.c | 3 +- bacula/src/filed/fd-plugins.h | 8 +- bacula/src/lib/Makefile.in | 6 +- bacula/src/lib/{plugin.c => plugins.c} | 2 +- bacula/src/lib/{plugin.h => plugins.h} | 6 +- bacula/src/plugins/dir/Makefile | 16 +- bacula/src/plugins/dir/dir-plugins.c | 258 ++++++++++++++++++ bacula/src/plugins/dir/dir-plugins.h | 149 ++++++++++ .../{plugin-dir.c => example-plugin-dir.c} | 37 ++- bacula/src/plugins/dir/main.c | 119 -------- bacula/src/plugins/fd/fd-plugins.h | 8 +- 16 files changed, 767 insertions(+), 171 deletions(-) create mode 100644 bacula/src/dird/dir-plugins.c rename bacula/src/{plugins/dir/plugin-dir.h => dird/dir-plugins.h} (74%) rename bacula/src/lib/{plugin.c => plugins.c} (99%) rename bacula/src/lib/{plugin.h => plugins.h} (97%) create mode 100644 bacula/src/plugins/dir/dir-plugins.c create mode 100644 bacula/src/plugins/dir/dir-plugins.h rename bacula/src/plugins/dir/{plugin-dir.c => example-plugin-dir.c} (76%) delete mode 100644 bacula/src/plugins/dir/main.c diff --git a/bacula/src/dird/Makefile.in b/bacula/src/dird/Makefile.in index 3e44d46227..e3e68e76fc 100644 --- a/bacula/src/dird/Makefile.in +++ b/bacula/src/dird/Makefile.in @@ -29,7 +29,7 @@ dummy: # SVRSRCS = dird.c admin.c authenticate.c \ autoprune.c backup.c bsr.c \ - catreq.c dird_conf.c expand.c \ + catreq.c dir-plugins.c dird_conf.c expand.c \ fd_cmds.c getmsg.c inc_conf.c job.c \ jobq.c migrate.c \ mountreq.c msgchan.c next_vol.c newvol.c \ @@ -44,7 +44,7 @@ SVRSRCS = dird.c admin.c authenticate.c \ ua_status.c ua_tree.c ua_update.c verify.c SVROBJS = dird.o admin.o authenticate.o \ autoprune.o backup.o bsr.o \ - catreq.o dird_conf.o expand.o \ + catreq.o dir-plugins.o dird_conf.o expand.o \ fd_cmds.o getmsg.o inc_conf.o job.o \ jobq.o migrate.o \ mountreq.o msgchan.o next_vol.o newvol.o \ diff --git a/bacula/src/dird/dir-plugins.c b/bacula/src/dird/dir-plugins.c new file mode 100644 index 0000000000..69518b9f42 --- /dev/null +++ b/bacula/src/dird/dir-plugins.c @@ -0,0 +1,258 @@ +/* + Bacula® - The Network Backup Solution + + Copyright (C) 2007-2008 Free Software Foundation Europe e.V. + + The main author of Bacula is Kern Sibbald, with contributions from + many others, a complete list can be found in the file AUTHORS. + This program is Free Software; you can redistribute it and/or + modify it under the terms of version two of the GNU General Public + License as published by the Free Software Foundation, which is + listed in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + + Bacula® is a registered trademark of John Walker. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +*/ +/* + * Main program to test loading and running Bacula plugins. + * Destined to become Bacula pluginloader, ... + * + * Kern Sibbald, October 2007 + */ +#include "bacula.h" +#include "jcr.h" +#include "dir-plugins.h" + +const int dbglvl = 0; +const char *plugin_type = "-dir.so"; + + +/* Forward referenced functions */ +static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value); +static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value); +static bpError baculaRegisterEvents(bpContext *ctx, ...); +static bpError baculaJobMsg(bpContext *ctx, const char *file, int line, + int type, time_t mtime, const char *msg); +static bpError baculaDebugMsg(bpContext *ctx, const char *file, int line, + int level, const char *msg); + + +/* Bacula info */ +static bInfo binfo = { + sizeof(bFuncs), + PLUGIN_INTERFACE, +}; + +/* Bacula entry points */ +static bFuncs bfuncs = { + sizeof(bFuncs), + PLUGIN_INTERFACE, + baculaRegisterEvents, + baculaGetValue, + baculaSetValue, + baculaJobMsg, + baculaDebugMsg +}; + +/* + * Create a plugin event + */ +void generate_plugin_event(JCR *jcr, bEventType eventType) +{ + bEvent event; + Plugin *plugin; + int i = 0; + + if (!plugin_list) { + return; + } + + bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx; + Dmsg2(dbglvl, "plugin_ctx=%p JobId=%d\n", jcr->plugin_ctx, jcr->JobId); + event.eventType = eventType; + foreach_alist(plugin, plugin_list) { + plug_func(plugin)->handlePluginEvent(&plugin_ctx[i++], &event); + } +} + +void load_dir_plugins(const char *plugin_dir) +{ + if (!plugin_dir) { + return; + } + + plugin_list = New(alist(10, not_owned_by_alist)); + load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type); +} + +/* + * Create a new instance of each plugin for this Job + */ +void new_plugins(JCR *jcr) +{ + Plugin *plugin; + int i = 0; + + if (!plugin_list) { + return; + } + + int num = plugin_list->size(); + + if (num == 0) { + return; + } + + jcr->plugin_ctx = (void *)malloc(sizeof(bpContext) * num); + + bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx; + Dmsg2(dbglvl, "Instantiate plugin_ctx=%p JobId=%d\n", jcr->plugin_ctx, jcr->JobId); + foreach_alist(plugin, plugin_list) { + /* Start a new instance of each plugin */ + plugin_ctx[i].bContext = (void *)jcr; + plugin_ctx[i].pContext = NULL; + plug_func(plugin)->newPlugin(&plugin_ctx[i++]); + } +} + +/* + * Free the plugin instances for this Job + */ +void free_plugins(JCR *jcr) +{ + Plugin *plugin; + int i = 0; + + if (!plugin_list) { + return; + } + + bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx; + Dmsg2(dbglvl, "Free instance plugin_ctx=%p JobId=%d\n", jcr->plugin_ctx, jcr->JobId); + foreach_alist(plugin, plugin_list) { + /* Free the plugin instance */ + plug_func(plugin)->freePlugin(&plugin_ctx[i++]); + } + free(plugin_ctx); + jcr->plugin_ctx = NULL; +} + + +/* ============================================================== + * + * Callbacks from the plugin + * + * ============================================================== + */ +static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value) +{ + JCR *jcr = (JCR *)(ctx->bContext); +// Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var); + if (!value) { + return 1; + } +// Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr); + switch (var) { + case bVarJobId: + *((int *)value) = jcr->JobId; + Dmsg1(dbglvl, "Bacula: return bVarJobId=%d\n", jcr->JobId); + break; + case bVarFDName: + *((char **)value) = my_name; + Dmsg1(dbglvl, "Bacula: return my_name=%s\n", my_name); + break; + case bVarLevel: + case bVarType: + case bVarClient: + case bVarJobName: + case bVarJobStatus: + case bVarSinceTime: + break; + } + return 0; +} + +static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value) +{ + Dmsg1(dbglvl, "bacula: baculaSetValue var=%d\n", var); + return 0; +} + +static bpError baculaRegisterEvents(bpContext *ctx, ...) +{ + va_list args; + uint32_t event; + + va_start(args, ctx); + while ((event = va_arg(args, uint32_t))) { + Dmsg1(dbglvl, "Plugin wants event=%u\n", event); + } + va_end(args); + return 0; +} + +static bpError baculaJobMsg(bpContext *ctx, const char *file, int line, + int type, time_t mtime, const char *msg) +{ + Dmsg5(dbglvl, "Job message: %s:%d type=%d time=%ld msg=%s\n", + file, line, type, mtime, msg); + return 0; +} + +static bpError baculaDebugMsg(bpContext *ctx, const char *file, int line, + int level, const char *msg) +{ + Dmsg4(dbglvl, "Debug message: %s:%d level=%d msg=%s\n", + file, line, level, msg); + return 0; +} + +#ifdef TEST_PROGRAM + + +int main(int argc, char *argv[]) +{ + char plugin_dir[1000]; + JCR mjcr1, mjcr2; + JCR *jcr1 = &mjcr1; + JCR *jcr2 = &mjcr2; + + strcpy(my_name, "test-dir"); + + getcwd(plugin_dir, sizeof(plugin_dir)-1); + load_dir_plugins(plugin_dir); + + jcr1->JobId = 111; + new_plugins(jcr1); + + jcr2->JobId = 222; + new_plugins(jcr2); + + generate_plugin_event(jcr1, bEventJobStart); + generate_plugin_event(jcr1, bEventJobEnd); + generate_plugin_event(jcr2, bEventJobStart); + free_plugins(jcr1); + generate_plugin_event(jcr2, bEventJobEnd); + free_plugins(jcr2); + + unload_plugins(); + + Dmsg0(dbglvl, "bacula: OK ...\n"); + close_memory_pool(); + sm_dump(false); + return 0; +} + +#endif /* TEST_PROGRAM */ diff --git a/bacula/src/plugins/dir/plugin-dir.h b/bacula/src/dird/dir-plugins.h similarity index 74% rename from bacula/src/plugins/dir/plugin-dir.h rename to bacula/src/dird/dir-plugins.h index cc78a42cb6..e25b3265c4 100644 --- a/bacula/src/plugins/dir/plugin-dir.h +++ b/bacula/src/dird/dir-plugins.h @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2007-2007 Free Software Foundation Europe e.V. + Copyright (C) 2007-2008 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -32,8 +32,8 @@ * */ -#ifndef __PLUGIN_FD_H -#define __PLUGIN_FD_H +#ifndef __FD_PLUGINS_H +#define __FD_PLUGINS_H #include #ifndef __CONFIG_H @@ -41,13 +41,15 @@ #include "config.h" #endif #include "bc_types.h" -#include "lib/plugin.h" +#include "lib/plugins.h" #ifdef __cplusplus extern "C" { #endif + + /**************************************************************************** * * * Bacula definitions * @@ -56,34 +58,50 @@ extern "C" { /* Bacula Variable Ids */ typedef enum { - bVarJobId = 1 + bVarJobId = 1, + bVarFDName = 2, + bVarLevel = 3, + bVarType = 4, + bVarClient = 5, + bVarJobName = 6, + bVarJobStatus = 7, + bVarSinceTime = 8 } bVariable; typedef enum { bEventJobStart = 1, - bEventJobInit = 2, - bEventJobRun = 3, - bEventJobEnd = 4, - bEventNewVolume = 5, - bEventVolumePurged = 6, - bEventReload = 7 + bEventJobEnd = 2, } bEventType; typedef struct s_bEvent { uint32_t eventType; } bEvent; +typedef struct s_baculaInfo { + uint32_t size; + uint32_t interface; +} bInfo; /* Bacula interface version and function pointers */ typedef struct s_baculaFuncs { uint32_t size; uint32_t interface; + bpError (*registerBaculaEvents)(bpContext *ctx, ...); bpError (*getBaculaValue)(bpContext *ctx, bVariable var, void *value); bpError (*setBaculaValue)(bpContext *ctx, bVariable var, void *value); - bpError (*allocBaculaMem)(bpContext *ctx, uint32_t size, char *addr); - bpError (*freeBaculaMem)(bpContext *ctx, char *addr); + bpError (*JobMessage)(bpContext *ctx, const char *file, int line, + int type, time_t mtime, const char *msg); + bpError (*DebugMessage)(bpContext *ctx, const char *file, int line, + int level, const char *msg); } bFuncs; +/* Bacula Subroutines */ +void load_dir_plugins(const char *plugin_dir); +void new_plugins(JCR *jcr); +void free_plugins(JCR *jcr); +void generate_plugin_event(JCR *jcr, bEventType event); + + /**************************************************************************** * * @@ -100,7 +118,7 @@ typedef enum { #define PLUGIN_MAGIC "*PluginData*" #define PLUGIN_INTERFACE 1 -typedef struct s_pluginFuncs { +typedef struct s_pluginInfo { uint32_t size; uint32_t interface; char *plugin_magic; @@ -109,6 +127,11 @@ typedef struct s_pluginFuncs { char *plugin_date; char *plugin_version; char *plugin_description; +} pInfo; + +typedef struct s_pluginFuncs { + uint32_t size; + uint32_t interface; bpError (*newPlugin)(bpContext *ctx); bpError (*freePlugin)(bpContext *ctx); bpError (*getPluginValue)(bpContext *ctx, pVariable var, void *value); @@ -116,10 +139,11 @@ typedef struct s_pluginFuncs { bpError (*handlePluginEvent)(bpContext *ctx, bEvent *event); } pFuncs; -#define pref(plugin) ((pFuncs *)(plugin->pfuncs)) +#define plug_func(plugin) ((pFuncs *)(plugin->pfuncs)) +#define plug_info(plugin) ((pInfo *)(plugin->pinfo)) #ifdef __cplusplus } #endif -#endif /* __PLUGIN_FD_H */ +#endif /* __FD_PLUGINS_H */ diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index 7a065582de..db0c015d7c 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2007 Free Software Foundation Europe e.V. + Copyright (C) 2000-2008 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -247,6 +247,8 @@ int main (int argc, char *argv[]) read_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs)); } + load_dir_plugins(director->plugin_directory); + drop(uid, gid); /* reduce privileges if requested */ if (!check_catalog()) { @@ -333,6 +335,7 @@ void terminate_dird(int sig) already_here = true; stop_watchdog(); generate_daemon_event(NULL, "Exit"); + unload_plugins(); write_state_file(director->working_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs)); delete_pid_file(director->pid_directory, "bacula-dir", get_first_port_host_order(director->DIRaddrs)); term_scheduler(); diff --git a/bacula/src/dird/dird.h b/bacula/src/dird/dird.h index 8caea1ebb5..f4c603fb74 100644 --- a/bacula/src/dird/dird.h +++ b/bacula/src/dird/dird.h @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2007 Free Software Foundation Europe e.V. + Copyright (C) 2000-2008 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -36,6 +36,7 @@ #include "lib/runscript.h" #include "lib/breg.h" #include "dird_conf.h" +#include "dir-plugins.h" #define DIRECTOR_DAEMON 1 diff --git a/bacula/src/filed/fd-plugins.c b/bacula/src/filed/fd-plugins.c index ef6ecc3f4b..1547f14a52 100644 --- a/bacula/src/filed/fd-plugins.c +++ b/bacula/src/filed/fd-plugins.c @@ -221,7 +221,6 @@ static bpError baculaDebugMsg(bpContext *ctx, const char *file, int line, #ifdef TEST_PROGRAM -char my_name = "test-fd"; int main(int argc, char *argv[]) { @@ -229,6 +228,8 @@ int main(int argc, char *argv[]) JCR mjcr1, mjcr2; JCR *jcr1 = &mjcr1; JCR *jcr2 = &mjcr2; + + strcpy(my_name, "test-fd"); getcwd(plugin_dir, sizeof(plugin_dir)-1); load_fd_plugins(plugin_dir); diff --git a/bacula/src/filed/fd-plugins.h b/bacula/src/filed/fd-plugins.h index af575c9841..702abb4d61 100644 --- a/bacula/src/filed/fd-plugins.h +++ b/bacula/src/filed/fd-plugins.h @@ -32,8 +32,8 @@ * */ -#ifndef __PLUGIN_FD_H -#define __PLUGIN_FD_H +#ifndef __FD_PLUGINS_H +#define __FD_PLUGINS_H #include #ifndef __CONFIG_H @@ -41,7 +41,7 @@ #include "config.h" #endif #include "bc_types.h" -#include "lib/plugin.h" +#include "lib/plugins.h" #ifdef __cplusplus extern "C" { @@ -146,4 +146,4 @@ typedef struct s_pluginFuncs { } #endif -#endif /* __PLUGIN_FD_H */ +#endif /* __FD_PLUGINS_H */ diff --git a/bacula/src/lib/Makefile.in b/bacula/src/lib/Makefile.in index 5b7e5f08b1..dc819f8276 100644 --- a/bacula/src/lib/Makefile.in +++ b/bacula/src/lib/Makefile.in @@ -25,7 +25,7 @@ LIBSRCS = attr.c base64.c berrno.c bsys.c bget_msg.c \ cram-md5.c crc32.c crypto.c daemon.c edit.c fnmatch.c \ guid_to_name.c hmac.c jcr.c lex.c alist.c dlist.c \ md5.c message.c mem_pool.c openssl.c parse_conf.c \ - plugin.c queue.c bregex.c \ + plugins.c queue.c bregex.c \ res.c rwlock.c scan.c serial.c sha1.c \ signal.c smartall.c rblist.c tls.c tree.c \ util.c var.c watchdog.c workq.c btimers.c \ @@ -38,7 +38,7 @@ LIBOBJS = attr.o base64.o berrno.o bsys.o bget_msg.o \ cram-md5.o crc32.o crypto.o daemon.o edit.o fnmatch.o \ guid_to_name.o hmac.o jcr.o lex.o alist.o dlist.o \ md5.o message.o mem_pool.o openssl.o parse_conf.o \ - plugin.o queue.o bregex.o \ + plugins.o queue.o bregex.o \ res.o rwlock.o scan.o serial.o sha1.o \ signal.o smartall.o rblist.o tls.o tree.o \ util.o var.o watchdog.o workq.o btimers.o \ @@ -109,7 +109,7 @@ bsnprintf: bsnprintf.o rm -f bsnprintf.o $(CXX) $(DEFS) $(DEBUG) -c $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) bsnprintf.c -plugin.o: plugin.c plugin.h +plugins.o: plugins.c plugins.h @echo "Compiling $<" $(NO_ECHO)$(CXX) -fPIC $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $< diff --git a/bacula/src/lib/plugin.c b/bacula/src/lib/plugins.c similarity index 99% rename from bacula/src/lib/plugin.c rename to bacula/src/lib/plugins.c index 110e7fcf63..c67228e6fd 100644 --- a/bacula/src/lib/plugin.c +++ b/bacula/src/lib/plugins.c @@ -31,7 +31,7 @@ * Kern Sibbald, October 2007 */ #include "bacula.h" -#include "plugin.h" +#include "plugins.h" /* All loaded plugins */ alist *plugin_list; diff --git a/bacula/src/lib/plugin.h b/bacula/src/lib/plugins.h similarity index 97% rename from bacula/src/lib/plugin.h rename to bacula/src/lib/plugins.h index 07f0741fd7..5af9e05c4a 100644 --- a/bacula/src/lib/plugin.h +++ b/bacula/src/lib/plugins.h @@ -30,8 +30,8 @@ * * Kern Sibbald, October 2007 */ -#ifndef __PLUGIN_H -#define __PLUGIN_H +#ifndef __PLUGINS_H +#define __PLUGINS_H #include "bacula.h" #ifndef HAVE_WIN32 @@ -87,4 +87,4 @@ extern bool load_plugins(void *binfo, void *bfuncs, const char *plugin_dir, cons extern void unload_plugins(); -#endif /* __PLUGIN_H */ +#endif /* __PLUGINS_H */ diff --git a/bacula/src/plugins/dir/Makefile b/bacula/src/plugins/dir/Makefile index f5c430e655..97e4dbb052 100644 --- a/bacula/src/plugins/dir/Makefile +++ b/bacula/src/plugins/dir/Makefile @@ -1,5 +1,5 @@ # -# Simple Makefile for building test plugins for Bacula +# Simple Makefile for building test Director plugins for Bacula # # No optimization for now for easy debugging @@ -9,16 +9,16 @@ CC = g++ -g -O0 -Wall .c.o: $(CC) -I../.. -DTEST_PROGRAM -c $< -all: main plugin-dir.so +all: dir-plugins example-plugin-dir.so -main: main.o plugin-dir.h - $(CC) -L../../lib main.o -o main -lbac -lpthread -lssl -l crypto -ldl +dir-plugins: dir-plugins.o dir-plugins.h + $(CC) -L../../lib dir-plugins.o -o main -lbac -lpthread -lssl -l crypto -ldl -plugin-dir.o: plugin-dir.c plugin-dir.h - $(CC) -fPIC -I../.. -c plugin-dir.c +example-plugin-dir.o: example-plugin-dir.c dir-plugins.h + $(CC) -fPIC -I../.. -c example-plugin-dir.c -plugin-dir.so: plugin-dir.o - $(CC) -shared plugin-dir.o -o plugin-dir.so +example-plugin-dir.so: example-plugin-dir.o + $(CC) -shared example-plugin-dir.o -o example-plugin-dir.so clean: diff --git a/bacula/src/plugins/dir/dir-plugins.c b/bacula/src/plugins/dir/dir-plugins.c new file mode 100644 index 0000000000..69518b9f42 --- /dev/null +++ b/bacula/src/plugins/dir/dir-plugins.c @@ -0,0 +1,258 @@ +/* + Bacula® - The Network Backup Solution + + Copyright (C) 2007-2008 Free Software Foundation Europe e.V. + + The main author of Bacula is Kern Sibbald, with contributions from + many others, a complete list can be found in the file AUTHORS. + This program is Free Software; you can redistribute it and/or + modify it under the terms of version two of the GNU General Public + License as published by the Free Software Foundation, which is + listed in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + + Bacula® is a registered trademark of John Walker. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +*/ +/* + * Main program to test loading and running Bacula plugins. + * Destined to become Bacula pluginloader, ... + * + * Kern Sibbald, October 2007 + */ +#include "bacula.h" +#include "jcr.h" +#include "dir-plugins.h" + +const int dbglvl = 0; +const char *plugin_type = "-dir.so"; + + +/* Forward referenced functions */ +static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value); +static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value); +static bpError baculaRegisterEvents(bpContext *ctx, ...); +static bpError baculaJobMsg(bpContext *ctx, const char *file, int line, + int type, time_t mtime, const char *msg); +static bpError baculaDebugMsg(bpContext *ctx, const char *file, int line, + int level, const char *msg); + + +/* Bacula info */ +static bInfo binfo = { + sizeof(bFuncs), + PLUGIN_INTERFACE, +}; + +/* Bacula entry points */ +static bFuncs bfuncs = { + sizeof(bFuncs), + PLUGIN_INTERFACE, + baculaRegisterEvents, + baculaGetValue, + baculaSetValue, + baculaJobMsg, + baculaDebugMsg +}; + +/* + * Create a plugin event + */ +void generate_plugin_event(JCR *jcr, bEventType eventType) +{ + bEvent event; + Plugin *plugin; + int i = 0; + + if (!plugin_list) { + return; + } + + bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx; + Dmsg2(dbglvl, "plugin_ctx=%p JobId=%d\n", jcr->plugin_ctx, jcr->JobId); + event.eventType = eventType; + foreach_alist(plugin, plugin_list) { + plug_func(plugin)->handlePluginEvent(&plugin_ctx[i++], &event); + } +} + +void load_dir_plugins(const char *plugin_dir) +{ + if (!plugin_dir) { + return; + } + + plugin_list = New(alist(10, not_owned_by_alist)); + load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type); +} + +/* + * Create a new instance of each plugin for this Job + */ +void new_plugins(JCR *jcr) +{ + Plugin *plugin; + int i = 0; + + if (!plugin_list) { + return; + } + + int num = plugin_list->size(); + + if (num == 0) { + return; + } + + jcr->plugin_ctx = (void *)malloc(sizeof(bpContext) * num); + + bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx; + Dmsg2(dbglvl, "Instantiate plugin_ctx=%p JobId=%d\n", jcr->plugin_ctx, jcr->JobId); + foreach_alist(plugin, plugin_list) { + /* Start a new instance of each plugin */ + plugin_ctx[i].bContext = (void *)jcr; + plugin_ctx[i].pContext = NULL; + plug_func(plugin)->newPlugin(&plugin_ctx[i++]); + } +} + +/* + * Free the plugin instances for this Job + */ +void free_plugins(JCR *jcr) +{ + Plugin *plugin; + int i = 0; + + if (!plugin_list) { + return; + } + + bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx; + Dmsg2(dbglvl, "Free instance plugin_ctx=%p JobId=%d\n", jcr->plugin_ctx, jcr->JobId); + foreach_alist(plugin, plugin_list) { + /* Free the plugin instance */ + plug_func(plugin)->freePlugin(&plugin_ctx[i++]); + } + free(plugin_ctx); + jcr->plugin_ctx = NULL; +} + + +/* ============================================================== + * + * Callbacks from the plugin + * + * ============================================================== + */ +static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value) +{ + JCR *jcr = (JCR *)(ctx->bContext); +// Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var); + if (!value) { + return 1; + } +// Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr); + switch (var) { + case bVarJobId: + *((int *)value) = jcr->JobId; + Dmsg1(dbglvl, "Bacula: return bVarJobId=%d\n", jcr->JobId); + break; + case bVarFDName: + *((char **)value) = my_name; + Dmsg1(dbglvl, "Bacula: return my_name=%s\n", my_name); + break; + case bVarLevel: + case bVarType: + case bVarClient: + case bVarJobName: + case bVarJobStatus: + case bVarSinceTime: + break; + } + return 0; +} + +static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value) +{ + Dmsg1(dbglvl, "bacula: baculaSetValue var=%d\n", var); + return 0; +} + +static bpError baculaRegisterEvents(bpContext *ctx, ...) +{ + va_list args; + uint32_t event; + + va_start(args, ctx); + while ((event = va_arg(args, uint32_t))) { + Dmsg1(dbglvl, "Plugin wants event=%u\n", event); + } + va_end(args); + return 0; +} + +static bpError baculaJobMsg(bpContext *ctx, const char *file, int line, + int type, time_t mtime, const char *msg) +{ + Dmsg5(dbglvl, "Job message: %s:%d type=%d time=%ld msg=%s\n", + file, line, type, mtime, msg); + return 0; +} + +static bpError baculaDebugMsg(bpContext *ctx, const char *file, int line, + int level, const char *msg) +{ + Dmsg4(dbglvl, "Debug message: %s:%d level=%d msg=%s\n", + file, line, level, msg); + return 0; +} + +#ifdef TEST_PROGRAM + + +int main(int argc, char *argv[]) +{ + char plugin_dir[1000]; + JCR mjcr1, mjcr2; + JCR *jcr1 = &mjcr1; + JCR *jcr2 = &mjcr2; + + strcpy(my_name, "test-dir"); + + getcwd(plugin_dir, sizeof(plugin_dir)-1); + load_dir_plugins(plugin_dir); + + jcr1->JobId = 111; + new_plugins(jcr1); + + jcr2->JobId = 222; + new_plugins(jcr2); + + generate_plugin_event(jcr1, bEventJobStart); + generate_plugin_event(jcr1, bEventJobEnd); + generate_plugin_event(jcr2, bEventJobStart); + free_plugins(jcr1); + generate_plugin_event(jcr2, bEventJobEnd); + free_plugins(jcr2); + + unload_plugins(); + + Dmsg0(dbglvl, "bacula: OK ...\n"); + close_memory_pool(); + sm_dump(false); + return 0; +} + +#endif /* TEST_PROGRAM */ diff --git a/bacula/src/plugins/dir/dir-plugins.h b/bacula/src/plugins/dir/dir-plugins.h new file mode 100644 index 0000000000..e25b3265c4 --- /dev/null +++ b/bacula/src/plugins/dir/dir-plugins.h @@ -0,0 +1,149 @@ +/* + Bacula® - The Network Backup Solution + + Copyright (C) 2007-2008 Free Software Foundation Europe e.V. + + The main author of Bacula is Kern Sibbald, with contributions from + many others, a complete list can be found in the file AUTHORS. + This program is Free Software; you can redistribute it and/or + modify it under the terms of version two of the GNU General Public + License as published by the Free Software Foundation, which is + listed in the file LICENSE. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + + Bacula® is a registered trademark of John Walker. + The licensor of Bacula is the Free Software Foundation Europe + (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, + Switzerland, email:ftf@fsfeurope.org. +*/ +/* + * Interface definition for Bacula Plugins + * + * Kern Sibbald, October 2007 + * + */ + +#ifndef __FD_PLUGINS_H +#define __FD_PLUGINS_H + +#include +#ifndef __CONFIG_H +#define __CONFIG_H +#include "config.h" +#endif +#include "bc_types.h" +#include "lib/plugins.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/**************************************************************************** + * * + * Bacula definitions * + * * + ****************************************************************************/ + +/* Bacula Variable Ids */ +typedef enum { + bVarJobId = 1, + bVarFDName = 2, + bVarLevel = 3, + bVarType = 4, + bVarClient = 5, + bVarJobName = 6, + bVarJobStatus = 7, + bVarSinceTime = 8 +} bVariable; + +typedef enum { + bEventJobStart = 1, + bEventJobEnd = 2, +} bEventType; + +typedef struct s_bEvent { + uint32_t eventType; +} bEvent; + +typedef struct s_baculaInfo { + uint32_t size; + uint32_t interface; +} bInfo; + +/* Bacula interface version and function pointers */ +typedef struct s_baculaFuncs { + uint32_t size; + uint32_t interface; + bpError (*registerBaculaEvents)(bpContext *ctx, ...); + bpError (*getBaculaValue)(bpContext *ctx, bVariable var, void *value); + bpError (*setBaculaValue)(bpContext *ctx, bVariable var, void *value); + bpError (*JobMessage)(bpContext *ctx, const char *file, int line, + int type, time_t mtime, const char *msg); + bpError (*DebugMessage)(bpContext *ctx, const char *file, int line, + int level, const char *msg); +} bFuncs; + +/* Bacula Subroutines */ +void load_dir_plugins(const char *plugin_dir); +void new_plugins(JCR *jcr); +void free_plugins(JCR *jcr); +void generate_plugin_event(JCR *jcr, bEventType event); + + + +/**************************************************************************** + * * + * Plugin definitions * + * * + ****************************************************************************/ + +typedef enum { + pVarName = 1, + pVarDescription = 2 +} pVariable; + + +#define PLUGIN_MAGIC "*PluginData*" +#define PLUGIN_INTERFACE 1 + +typedef struct s_pluginInfo { + uint32_t size; + uint32_t interface; + char *plugin_magic; + char *plugin_license; + char *plugin_author; + char *plugin_date; + char *plugin_version; + char *plugin_description; +} pInfo; + +typedef struct s_pluginFuncs { + uint32_t size; + uint32_t interface; + bpError (*newPlugin)(bpContext *ctx); + bpError (*freePlugin)(bpContext *ctx); + bpError (*getPluginValue)(bpContext *ctx, pVariable var, void *value); + bpError (*setPluginValue)(bpContext *ctx, pVariable var, void *value); + bpError (*handlePluginEvent)(bpContext *ctx, bEvent *event); +} pFuncs; + +#define plug_func(plugin) ((pFuncs *)(plugin->pfuncs)) +#define plug_info(plugin) ((pInfo *)(plugin->pinfo)) + +#ifdef __cplusplus +} +#endif + +#endif /* __FD_PLUGINS_H */ diff --git a/bacula/src/plugins/dir/plugin-dir.c b/bacula/src/plugins/dir/example-plugin-dir.c similarity index 76% rename from bacula/src/plugins/dir/plugin-dir.c rename to bacula/src/plugins/dir/example-plugin-dir.c index 8d5e8e93b0..f58679ff60 100644 --- a/bacula/src/plugins/dir/plugin-dir.c +++ b/bacula/src/plugins/dir/example-plugin-dir.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2007-2007 Free Software Foundation Europe e.V. + Copyright (C) 2007-2008 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -32,7 +32,7 @@ * */ #include -#include "plugin-dir.h" +#include "dir-plugins.h" #ifdef __cplusplus extern "C" { @@ -40,9 +40,9 @@ extern "C" { #define PLUGIN_LICENSE "GPL" #define PLUGIN_AUTHOR "Kern Sibbald" -#define PLUGIN_DATE "November 2007" +#define PLUGIN_DATE "January 2008" #define PLUGIN_VERSION "1" -#define PLUGIN_DESCRIPTION "Test Director Plugin" +#define PLUGIN_DESCRIPTION "Test File Daemon Plugin" /* Forward referenced functions */ static bpError newPlugin(bpContext *ctx); @@ -54,9 +54,10 @@ static bpError handlePluginEvent(bpContext *ctx, bEvent *event); /* Pointers to Bacula functions */ static bFuncs *bfuncs = NULL; +static bInfo *binfo = NULL; -static pFuncs pluginFuncs = { - sizeof(pluginFuncs), +static pInfo pluginInfo = { + sizeof(pluginInfo), PLUGIN_INTERFACE, PLUGIN_MAGIC, PLUGIN_LICENSE, @@ -64,6 +65,11 @@ static pFuncs pluginFuncs = { PLUGIN_DATE, PLUGIN_VERSION, PLUGIN_DESCRIPTION, +}; + +static pFuncs pluginFuncs = { + sizeof(pluginFuncs), + PLUGIN_INTERFACE, /* Entry points into plugin */ newPlugin, /* new plugin instance */ @@ -73,11 +79,13 @@ static pFuncs pluginFuncs = { handlePluginEvent }; -bpError loadPlugin(bFuncs *lbfuncs, pFuncs **pfuncs) +bpError loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs) { bfuncs = lbfuncs; /* set Bacula funct pointers */ + binfo = lbinfo; printf("plugin: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->interface); + *pinfo = &pluginInfo; /* return pointer to our info */ *pfuncs = &pluginFuncs; /* return pointer to our functions */ return 0; @@ -94,6 +102,7 @@ static bpError newPlugin(bpContext *ctx) int JobId = 0; bfuncs->getBaculaValue(ctx, bVarJobId, (void *)&JobId); printf("plugin: newPlugin JobId=%d\n", JobId); + bfuncs->registerBaculaEvents(ctx, 1, 2, 0); return 0; } @@ -119,7 +128,19 @@ static bpError setPluginValue(bpContext *ctx, pVariable var, void *value) static bpError handlePluginEvent(bpContext *ctx, bEvent *event) { - printf("plugin: HandleEvent Event=%d\n", event->eventType); + char *name; + switch (event->eventType) { + case bEventJobStart: + printf("plugin: HandleEvent JobStart\n"); + break; + case bEventJobEnd: + printf("plugin: HandleEvent JobEnd\n"); + break; + } + bfuncs->getBaculaValue(ctx, bVarFDName, (void *)&name); + printf("FD Name=%s\n", name); + bfuncs->JobMessage(ctx, __FILE__, __LINE__, 1, 0, "JobMesssage message"); + bfuncs->DebugMessage(ctx, __FILE__, __LINE__, 1, "DebugMesssage message"); return 0; } diff --git a/bacula/src/plugins/dir/main.c b/bacula/src/plugins/dir/main.c deleted file mode 100644 index 387df26128..0000000000 --- a/bacula/src/plugins/dir/main.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - Bacula® - The Network Backup Solution - - Copyright (C) 2007-2007 Free Software Foundation Europe e.V. - - The main author of Bacula is Kern Sibbald, with contributions from - many others, a complete list can be found in the file AUTHORS. - This program is Free Software; you can redistribute it and/or - modify it under the terms of version two of the GNU General Public - License as published by the Free Software Foundation, which is - listed in the file LICENSE. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. - - Bacula® is a registered trademark of John Walker. - The licensor of Bacula is the Free Software Foundation Europe - (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, - Switzerland, email:ftf@fsfeurope.org. -*/ -/* - * Main program to test loading and running Bacula plugins. - * Destined to become Bacula pluginloader, ... - * - * Kern Sibbald, October 2007 - */ -#include "bacula.h" -#include -#include "lib/plugin.h" -#include "plugin-dir.h" - -const char *plugin_type = "-dir.so"; - - -/* Forward referenced functions */ -static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value); -static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value); - - -/* Bacula entry points */ -static bFuncs bfuncs = { - sizeof(bFuncs), - PLUGIN_INTERFACE, - baculaGetValue, - baculaSetValue, - NULL, - NULL -}; - - - - -int main(int argc, char *argv[]) -{ - char plugin_dir[1000]; - bpContext ctx; - bEvent event; - Plugin *plugin; - - plugin_list = New(alist(10, not_owned_by_alist)); - - ctx.bContext = NULL; - ctx.pContext = NULL; - getcwd(plugin_dir, sizeof(plugin_dir)-1); - - load_plugins((void *)&bfuncs, plugin_dir, plugin_type); - - foreach_alist(plugin, plugin_list) { - printf("bacula: plugin_size=%d plugin_version=%d\n", - pref(plugin)->size, pref(plugin)->interface); - printf("License: %s\nAuthor: %s\nDate: %s\nVersion: %s\nDescription: %s\n", - pref(plugin)->plugin_license, pref(plugin)->plugin_author, - pref(plugin)->plugin_date, pref(plugin)->plugin_version, - pref(plugin)->plugin_description); - - /* Start a new instance of the plugin */ - pref(plugin)->newPlugin(&ctx); - event.eventType = bEventNewVolume; - pref(plugin)->handlePluginEvent(&ctx, &event); - /* Free the plugin instance */ - pref(plugin)->freePlugin(&ctx); - - /* Start a new instance of the plugin */ - pref(plugin)->newPlugin(&ctx); - event.eventType = bEventNewVolume; - pref(plugin)->handlePluginEvent(&ctx, &event); - /* Free the plugin instance */ - pref(plugin)->freePlugin(&ctx); - } - - unload_plugins(); - - printf("bacula: OK ...\n"); - close_memory_pool(); - sm_dump(false); - return 0; -} - -static bpError baculaGetValue(bpContext *ctx, bVariable var, void *value) -{ - printf("bacula: baculaGetValue var=%d\n", var); - if (value) { - *((int *)value) = 100; - } - return 0; -} - -static bpError baculaSetValue(bpContext *ctx, bVariable var, void *value) -{ - printf("bacula: baculaSetValue var=%d\n", var); - return 0; -} diff --git a/bacula/src/plugins/fd/fd-plugins.h b/bacula/src/plugins/fd/fd-plugins.h index af575c9841..702abb4d61 100644 --- a/bacula/src/plugins/fd/fd-plugins.h +++ b/bacula/src/plugins/fd/fd-plugins.h @@ -32,8 +32,8 @@ * */ -#ifndef __PLUGIN_FD_H -#define __PLUGIN_FD_H +#ifndef __FD_PLUGINS_H +#define __FD_PLUGINS_H #include #ifndef __CONFIG_H @@ -41,7 +41,7 @@ #include "config.h" #endif #include "bc_types.h" -#include "lib/plugin.h" +#include "lib/plugins.h" #ifdef __cplusplus extern "C" { @@ -146,4 +146,4 @@ typedef struct s_pluginFuncs { } #endif -#endif /* __PLUGIN_FD_H */ +#endif /* __FD_PLUGINS_H */ -- 2.39.2