]> git.sur5r.net Git - bacula/bacula/commitdiff
First cut SD plugin + minor plugin changes
authorKern Sibbald <kern@sibbald.com>
Mon, 8 Sep 2008 18:15:02 +0000 (18:15 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 8 Sep 2008 18:15:02 +0000 (18:15 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7564 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/dird/dir_plugins.h
bacula/src/filed/fd_plugins.h
bacula/src/plugins/README
bacula/src/plugins/dir/example-plugin-dir.c
bacula/src/plugins/sd/Makefile
bacula/src/stored/Makefile.in
bacula/src/stored/sd_plugins.c [new file with mode: 0644]
bacula/src/stored/sd_plugins.h [new file with mode: 0644]
bacula/src/version.h
bacula/technotes-2.5

index 68362429adceb8d022c61985e8451e0025011777..d631e98a8e44dbedd1d1ea4d06c5816443233c97 100644 (file)
@@ -155,12 +155,12 @@ typedef enum {
 typedef struct s_pluginInfo {
    uint32_t size;
    uint32_t version;
-   char *plugin_magic;
-   char *plugin_license;
-   char *plugin_author;
-   char *plugin_date;
-   char *plugin_version;
-   char *plugin_description;
+   const char *plugin_magic;
+   const char *plugin_license;
+   const char *plugin_author;
+   const char *plugin_date;
+   const char *plugin_version;
+   const char *plugin_description;
 } pInfo;
 
 typedef struct s_pluginFuncs {  
index 2ca6cf017c26c48b098801b3d65a66f6292248b6..24a77401a8659d579d7df1ead7448afcd48f4785 100644 (file)
@@ -205,12 +205,12 @@ typedef enum {
 typedef struct s_pluginInfo {
    uint32_t size;
    uint32_t version;
-   char *plugin_magic;
-   char *plugin_license;
-   char *plugin_author;
-   char *plugin_date;
-   char *plugin_version;
-   char *plugin_description;
+   const char *plugin_magic;
+   const char *plugin_license;
+   const char *plugin_author;
+   const char *plugin_date;
+   const char *plugin_version;
+   const char *plugin_description;
 } pInfo;
 
 /*
index 559a1f163e2444b5d619a3ce6c4c416baa39e76e..6e9112e94d57b66bafac0f918282b632d0f1e93a 100644 (file)
@@ -15,23 +15,27 @@ What is implemented:
   totally independent of Bacula.
 - The main test program is intended to be integrated into
   Bacula (at least a number of the functions therein).
-
-What is not yet implemented:
 - Search for all plugins in the plugin directory
 - Implement Bacula context for plugin instances
 - Implement plugin context for plugin instances
-- Some better method to pass variables
+- Integrate the code into Bacula
+- Figure out a way to deal with 3 types of plugins (Director,
+  File daemon, Storage daemon).
 - Pass Version information in plugin Initialize
+
+What is not yet implemented:
+- Document the interface
+- Test Win32 plugins
+- Print all plugins loaded when Bacula starts
+- Print all plugins loaded during traceback
+- Implement plugin license/version checking
+- Some better method to pass variables
 - Define more functionality (Bacula entry points, ...)
-- Integrate the code into Bacula
 - Make libbac.a into a shared object and allow plugin
   to call functions in directly so that plugins can use
   the same "safe" system utilities that Bacula uses.
-- Document the interface
 - Document libbac.so (when implemented)
-- Write a couple of plugins that really do something.
-- Figure out a way to deal with 3 types of plugins (Director,
-  File daemon, Storage daemon).
+- Write more plugins that really do something.
 - Error handling must be much improved and brought into Bacula
   programming style. It currently just printf()s a message then
-  exits.
+  exits (partially done).
index 14129e6bebb26b2c85126158d2b5c8fbefd5ee1c..ff1474a770bcea5cb737350cd26de541b6466023 100644 (file)
@@ -42,7 +42,7 @@ extern "C" {
 #define PLUGIN_AUTHOR       "Kern Sibbald"
 #define PLUGIN_DATE         "January 2008"
 #define PLUGIN_VERSION      "1"
-#define PLUGIN_DESCRIPTION  "Test File Daemon Plugin"
+#define PLUGIN_DESCRIPTION  "Test Director Daemon Plugin"
 
 /* Forward referenced functions */
 static bRC newPlugin(bpContext *ctx);
index fc79538f3a252462d1bde9bffc12c81fff8d61a0..cc2775f043c038c2c90eebb6b8284ba6d5f2ffce 100644 (file)
@@ -1,25 +1,31 @@
 #
-# Simple Makefile for building test plugin-sds for Bacula
+# Simple Makefile for building test SD plugins for Bacula
 #
 
 # No optimization for now for easy debugging
 CC = g++ -g -O0 -Wall
 
+SDDIR=../../stored
+SRCDIR=../..
+LIBDIR=../../lib
+
 .SUFFIXES:    .c .o
 .c.o:
-       $(CC) -I../.. -DTEST_PROGRAM -c $<
+       $(CC) -I${SRCDIR} -I${SDDIR} -DTEST_PROGRAM -c $<
 
-all: main plugin-sd.so 
+test: main example-plugin-sd.so
 
-main: main.o plugin-sd.h 
-       $(CC) -L../../lib main.o -o main -lbac -lpthread -lssl -l crypto -ldl
+sd_plugins.o: ${SDDIR}/sd_plugins.h ${SDDIR}/sd_plugins.c
+       $(CC)  -I${SRCDIR} -I${SDDIR} -DTEST_PROGRAM -c ${SDDIR}/sd_plugins.c 
 
-plugin-sd.o: plugin-sd.c plugin-sd.h
-       $(CC) -fPIC -I../.. -c plugin-sd.c
+main: sd_plugins.o
+       $(CC) -L${LIBDIR} sd_plugins.o -o main -lbac -lpthread -lssl -l crypto -ldl
 
-plugin-sd.so: plugin-sd.o 
-       $(CC) -shared plugin-sd.o -o plugin-sd.so
+example-plugin-sd.o: example-plugin-sd.c ${SDDIR}/sd_plugins.h
+       $(CC) -fPIC -I../.. -I${SDDIR} -c example-plugin-sd.c
 
+example-plugin-sd.so: example-plugin-sd.o 
+       $(CC) -shared example-plugin-sd.o -o example-plugin-sd.so
 
 clean:
        rm -f main *.so *.o 1 2 3
index abb3f1741fc1633714ced3ac91ded155f564232e..7193b73e06a1217012adb7e7af8d1c9f1ffc59b6 100644 (file)
@@ -27,7 +27,7 @@ SDOBJS =  stored.o ansi_label.o vtape.o \
          device.o dircmd.o dvd.o ebcdic.o fd_cmds.o job.o \
          label.o lock.o mac.o match_bsr.o mount.o parse_bsr.o \
          pythonsd.o read.o read_record.o record.o \
-         reserve.o scan.o \
+         reserve.o scan.o sd_plugins.o \
          spool.o status.o stored_conf.o wait.o
 
 # btape
diff --git a/bacula/src/stored/sd_plugins.c b/bacula/src/stored/sd_plugins.c
new file mode 100644 (file)
index 0000000..d289c98
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+   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 Kern Sibbald.
+   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 "stored.h"
+#include "sd_plugins.h"
+
+const int dbglvl = 0;
+const char *plugin_type = "-sd.so";
+
+
+/* Forward referenced functions */
+static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value);
+static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value);
+static bRC baculaRegisterEvents(bpContext *ctx, ...);
+static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
+  int type, time_t mtime, const char *msg);
+static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
+  int level, const char *msg);
+
+
+/* Bacula info */
+static bInfo binfo = {
+   sizeof(bFuncs),
+   SD_PLUGIN_INTERFACE_VERSION,
+};
+
+/* Bacula entry points */
+static bFuncs bfuncs = {
+   sizeof(bFuncs),
+   SD_PLUGIN_INTERFACE_VERSION,
+   baculaRegisterEvents,
+   baculaGetValue,
+   baculaSetValue,
+   baculaJobMsg,
+   baculaDebugMsg
+};
+
+/*
+ * Create a plugin event 
+ */
+void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
+{
+   bEvent event;
+   Plugin *plugin;
+   int i = 0;
+
+   if (!plugin_list) {
+      return;
+   }
+
+   bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
+   event.eventType = eventType;
+
+   Dmsg2(dbglvl, "plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
+
+   foreach_alist(plugin, plugin_list) {
+      bRC rc;
+      rc = plug_func(plugin)->handlePluginEvent(&plugin_ctx_list[i++], &event, value);
+      if (rc != bRC_OK) {
+         break;
+      }
+   }
+
+   return;
+}
+
+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_list = (void *)malloc(sizeof(bpContext) * num);
+
+   bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
+   Dmsg2(dbglvl, "Instantiate plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
+   foreach_alist(plugin, plugin_list) {
+      /* Start a new instance of each plugin */
+      plugin_ctx_list[i].bContext = (void *)jcr;
+      plugin_ctx_list[i].pContext = NULL;
+      plug_func(plugin)->newPlugin(&plugin_ctx_list[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_list = (bpContext *)jcr->plugin_ctx_list;
+   Dmsg2(dbglvl, "Free instance plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
+   foreach_alist(plugin, plugin_list) {
+      /* Free the plugin instance */
+      plug_func(plugin)->freePlugin(&plugin_ctx_list[i++]);
+   }
+   free(plugin_ctx_list);
+   jcr->plugin_ctx_list = NULL;
+}
+
+
+/* ==============================================================
+ *
+ * Callbacks from the plugin
+ *
+ * ==============================================================
+ */
+static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value)
+{
+   JCR *jcr = (JCR *)(ctx->bContext);
+// Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var);
+   if (!value) {
+      return bRC_Error;
+   }
+// 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;
+   default:
+      break;
+   }
+   return bRC_OK;
+}
+
+static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value)
+{
+   Dmsg1(dbglvl, "bacula: baculaSetValue var=%d\n", var);
+   return bRC_OK;
+}
+
+static bRC 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 bRC_OK;
+}
+
+static bRC 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 bRC_OK;
+}
+
+static bRC 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 bRC_OK;
+}
+
+#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, (void *)"Start Job 1");
+   generate_plugin_event(jcr1, bEventJobEnd);
+   generate_plugin_event(jcr2, bEventJobStart, (void *)"Start Job 1");
+   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/stored/sd_plugins.h b/bacula/src/stored/sd_plugins.h
new file mode 100644 (file)
index 0000000..5974fc9
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+   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 Kern Sibbald.
+   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 __SD_PLUGINS_H 
+#define __SD_PLUGINS_H
+
+#ifndef _BACULA_H
+#ifdef __cplusplus
+/* Workaround for SGI IRIX 6.5 */
+#define _LANGUAGE_C_PLUS_PLUS 1
+#endif
+#define _REENTRANT    1
+#define _THREAD_SAFE  1
+#define _POSIX_PTHREAD_SEMANTICS 1
+#define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE 1
+#define _LARGE_FILES 1
+#endif
+
+#include <sys/types.h>
+#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 {
+  bVarJob       = 1,
+  bVarLevel     = 2,
+  bVarType      = 3,
+  bVarJobId     = 4,
+  bVarClient    = 5,
+  bVarNumVols   = 6,
+  bVarPool      = 7,
+  bVarStorage   = 8,
+  bVarCatalog   = 9,
+  bVarMediaType = 10,
+  bVarJobName   = 11,
+  bVarJobStatus = 12,
+  bVarPriority  = 13,
+  bVarVolumeName = 14,
+  bVarCatalogRes = 15,
+  bVarJobErrors  = 16,
+  bVarJobFiles   = 17,
+  bVarSDJobFiles = 18,
+  bVarSDErrors   = 19,
+  bVarFDJobStatus = 20,
+  bVarSDJobStatus = 21
+} brVariable;
+
+typedef enum {
+  bwVarJobReport  = 1,
+  bwVarVolumeName = 2,
+  bwVarPriority   = 3,
+  bwVarJobLevel   = 4,
+} bwVariable;
+
+
+typedef enum {
+  bEventJobStart      = 1,
+  bEventJobEnd        = 2,
+} bEventType;
+
+typedef struct s_bEvent {
+   uint32_t eventType;
+} bEvent;
+
+typedef struct s_baculaInfo {
+   uint32_t size;
+   uint32_t version;  
+} bInfo;
+
+/* Bacula interface version and function pointers */
+typedef struct s_baculaFuncs {  
+   uint32_t size;
+   uint32_t version;
+   bRC (*registerBaculaEvents)(bpContext *ctx, ...);
+   bRC (*getBaculaValue)(bpContext *ctx, brVariable var, void *value);
+   bRC (*setBaculaValue)(bpContext *ctx, bwVariable var, void *value);
+   bRC (*JobMessage)(bpContext *ctx, const char *file, int line, 
+       int type, time_t mtime, const char *msg);     
+   bRC (*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, void *value=NULL);
+
+
+
+/****************************************************************************
+ *                                                                          *
+ *                Plugin definitions                                        *
+ *                                                                          *
+ ****************************************************************************/
+
+typedef enum {
+  pVarName = 1,
+  pVarDescription = 2
+} pVariable;
+
+
+#define SD_PLUGIN_MAGIC     "*DirPluginData*" 
+#define SD_PLUGIN_INTERFACE_VERSION  1
+
+typedef struct s_pluginInfo {
+   uint32_t size;
+   uint32_t version;
+   const char *plugin_magic;
+   const char *plugin_license;
+   const char *plugin_author;
+   const char *plugin_date;
+   const char *plugin_version;
+   const char *plugin_description;
+} pInfo;
+
+typedef struct s_pluginFuncs {  
+   uint32_t size;
+   uint32_t version;
+   bRC (*newPlugin)(bpContext *ctx);
+   bRC (*freePlugin)(bpContext *ctx);
+   bRC (*getPluginValue)(bpContext *ctx, pVariable var, void *value);
+   bRC (*setPluginValue)(bpContext *ctx, pVariable var, void *value);
+   bRC (*handlePluginEvent)(bpContext *ctx, bEvent *event, void *value);
+} pFuncs;
+
+#define plug_func(plugin) ((pFuncs *)(plugin->pfuncs))
+#define plug_info(plugin) ((pInfo *)(plugin->pinfo))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SD_PLUGINS_H */
index 0153028c76f4ae9cdf92e3b5a52b6af280148935..10c63b996353e13a4155d63523b43f75c3d7c98f 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "2.5.3"
-#define BDATE   "03 September 2008"
-#define LSMDATE "3Sep08"
+#define BDATE   "08 September 2008"
+#define LSMDATE "8Sep08"
 
 #define PROG_COPYRIGHT "Copyright (C) %d-2008 Free Software Foundation Europe e.V.\n"
 #define BYEAR "2008"       /* year for copyright messages in progs */
index 9be8a02c8dc6783370cc439e5bda2f916adce9ec..68488fae35c7dcbef79979d602d2ed7313e06b54 100644 (file)
@@ -61,6 +61,8 @@ plugin
 remove reader/writer in FOPTS????
 
 General:
+08Sep08
+kes  First cut adding SD plugins.
 03Sep08
 kes  Add Slot if it is non-zero to writing bsr file after a
      backup.