]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Add malloc and free Bacula entry points for plugins. Increment
authorKern Sibbald <kern@sibbald.com>
Thu, 9 Oct 2008 20:55:50 +0000 (20:55 +0000)
committerKern Sibbald <kern@sibbald.com>
Thu, 9 Oct 2008 20:55:50 +0000 (20:55 +0000)
     FD plugin interface version. Create a bacula plugin context
     structure to keep track of whether or not the plugin is disabled.
kes  Apply FileIndex fix for plugin name stream suggested by James.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7741 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/AUTHORS
bacula/kernstodo
bacula/patches/2.4.2-migration-deadlock.patch [new file with mode: 0644]
bacula/src/filed/fd_plugins.c
bacula/src/filed/fd_plugins.h
bacula/src/filed/status.c
bacula/src/lib/plugins.h
bacula/technotes-2.5

index 34607fe655fd676df91e5795ec8ab89f0fae6dd1..e2b696d26f86fcd7e876d5f336816f4e4bfba5c0 100644 (file)
@@ -12,6 +12,7 @@ Adam Thorton
 Adrew J. Millar
 Adrian Close
 Aitor Matilla
+Alan Brown
 Aleksandar Milivojevic
 Alexander Bergolth
 Alexandre Baron
index 0b290f351db8baa1179d4964a2ee81af64f284dc..967a215fe7634a38c86675718c62e3fa0ead15db 100644 (file)
@@ -71,12 +71,26 @@ Professional Needs:
 
 Priority:
 ================
+- Detect deadlocks in reservations.
+- Plugins:
+  - add malloc/restore
+  - Add list during dump
+  - Add in plugin code flag
+  - Add bRC_EndJob -- stops more calls to plugin this job
+  - Add bRC_Term (unload plugin)
+  - remove time_t from Jmsg and use utime_t?
+  - add more doc
+     - distinguish two types of plugins
+- Extended ACLs
 - Deadlock detection, watchdog sees if counter advances when jobs are
   running.  With debug on, can do a "status" command.
 - User options for plugins.
+- Pool Storage override precidence over command line.
 - Autolabel only if Volume catalog information indicates tape not
   written. This will avoid overwriting a tape that gets an I/O
   error on reading the volume label.
+- I/O error, SD thinks it is not the right Volume, should check slot
+  then disable volume, but Asks for mount.
 - Can be posible modify package to create and use configuration files in 
    the Debian manner? 
 
diff --git a/bacula/patches/2.4.2-migration-deadlock.patch b/bacula/patches/2.4.2-migration-deadlock.patch
new file mode 100644 (file)
index 0000000..ba43d2f
--- /dev/null
@@ -0,0 +1,47 @@
+
+  This patch fixes migration SQL not to migrate a job that has not 
+  terminated, or in otherwords do not migrate a running job.
+  This is a partial fix to bug #1164.
+
+  Any prior patches to src/dird/migration must already be applied.
+  Apply it to 2.4.2 with:
+
+  cd <bacula-source>
+  patch -p0 <2.4.2-migration-deadlock.patch
+  ./configure <your-options>
+  make
+  ...
+  make install
+
+
+Index: src/dird/migrate.c
+===================================================================
+--- src/dird/migrate.c (revision 7729)
++++ src/dird/migrate.c (working copy)
+@@ -554,7 +554,7 @@
+ const char *sql_jobids_from_mediaid =
+    "SELECT DISTINCT Job.JobId,Job.StartTime FROM JobMedia,Job"
+    " WHERE JobMedia.JobId=Job.JobId AND JobMedia.MediaId IN (%s)"
+-   " AND Job.Type='B'"
++   " AND Job.Type='B' AND Job.JobStatus = 'T'"
+    " ORDER by Job.StartTime";
+ /* Get the number of bytes in the pool */
+@@ -563,7 +563,7 @@
+    " (SELECT DISTINCT Job.JobId from Pool,Job,Media,JobMedia WHERE"
+    " Pool.Name='%s' AND Media.PoolId=Pool.PoolId AND"
+    " VolStatus in ('Full','Used','Error','Append') AND Media.Enabled=1 AND"
+-   " Job.Type='B' AND"
++   " Job.Type='B' AND Job.JobStatus = 'T' AND"
+    " JobMedia.JobId=Job.JobId AND Job.PoolId=Media.PoolId)";
+ /* Get the number of bytes in the Jobs */
+@@ -582,7 +582,7 @@
+    "SELECT DISTINCT Job.JobId from Pool,Job,Media,JobMedia WHERE"
+    " Pool.Name='%s' AND Media.PoolId=Pool.PoolId AND"
+    " VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND"
+-   " Job.Type='B' AND"
++   " Job.Type='B' AND Job.JobStatus = 'T' AND"
+    " JobMedia.JobId=Job.JobId AND Job.PoolId=Media.PoolId"
+    " AND Job.RealEndTime<='%s'";
index db73eae976d9776effa4fc351bad7131695f8522..beae72f4748764c689672f6cd97eb3e910eb1c37 100644 (file)
@@ -59,7 +59,14 @@ static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
   int type, time_t mtime, const char *fmt, ...);
 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
   int level, const char *fmt, ...);
+static void *baculaMalloc(bpContext *ctx, const char *file, int line,
+              size_t size);
+static void baculaFree(bpContext *ctx, const char *file, int line, void *mem);
 
+/*
+ * These will be plugged into the global pointer structure for
+ *  the findlib.
+ */
 static int     my_plugin_bopen(BFILE *bfd, const char *fname, int flags, mode_t mode);
 static int     my_plugin_bclose(BFILE *bfd);
 static ssize_t my_plugin_bread(BFILE *bfd, void *buf, size_t count);
@@ -81,9 +88,20 @@ static bFuncs bfuncs = {
    baculaGetValue,
    baculaSetValue,
    baculaJobMsg,
-   baculaDebugMsg
+   baculaDebugMsg,
+   baculaMalloc,
+   baculaFree
 };
 
+/* 
+ * Bacula private context
+ */
+struct bacula_ctx {
+   JCR *jcr;                             /* jcr for plugin */
+   bRC  rc;                              /* last return code */
+   bool in_plugin;                       /* in plugin code */
+   bool disabled;                        /* set if plugin disabled */
+};
 
 /*
  * Create a plugin event 
@@ -218,11 +236,15 @@ bail_out:
 bool send_plugin_name(JCR *jcr, BSOCK *sd, bool start)
 {
    int stat;
+   int index = jcr->JobFiles;
    struct save_pkt *sp = (struct save_pkt *)jcr->plugin_sp;
   
+   if (start) {
+      index++;                  /* JobFiles not incremented yet */
+   }
    Dmsg1(dbglvl, "send_plugin_name=%s\n", sp->cmd);
    /* Send stream header */
-   if (!sd->fsend("%ld %d 0", jcr->JobFiles+1, STREAM_PLUGIN_NAME)) {
+   if (!sd->fsend("%ld %d 0", index, STREAM_PLUGIN_NAME)) {
      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
            sd->bstrerror());
      return false;
@@ -231,7 +253,7 @@ bool send_plugin_name(JCR *jcr, BSOCK *sd, bool start)
 
    if (start) {
       /* Send data -- not much */
-      stat = sd->fsend("%ld 1 %d %s%c", jcr->JobFiles+1, sp->portable, sp->cmd, 0);
+      stat = sd->fsend("%ld 1 %d %s%c", index, sp->portable, sp->cmd, 0);
    } else {
       /* Send end of data */
       stat = sd->fsend("0 0");
@@ -484,7 +506,10 @@ void new_plugins(JCR *jcr)
    Dmsg2(dbglvl, "Instantiate plugin_ctx=%p JobId=%d\n", plugin_ctx_list, jcr->JobId);
    foreach_alist(plugin, plugin_list) {
       /* Start a new instance of each plugin */
-      plugin_ctx_list[i].bContext = (void *)jcr;
+      bacula_ctx *b_ctx = (bacula_ctx *)malloc(sizeof(bacula_ctx));
+      memset(b_ctx, 0, sizeof(bacula_ctx));
+      b_ctx->jcr = jcr;
+      plugin_ctx_list[i].bContext = (void *)b_ctx;   /* Bacula private context */
       plugin_ctx_list[i].pContext = NULL;
       plug_func(plugin)->newPlugin(&plugin_ctx_list[i++]);
    }
@@ -504,7 +529,8 @@ void free_plugins(JCR *jcr)
 
    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
    Dmsg2(dbglvl, "Free instance plugin_ctx=%p JobId=%d\n", plugin_ctx_list, jcr->JobId);
-   foreach_alist(plugin, plugin_list) {
+   foreach_alist(plugin, plugin_list) {   
+      free(plugin_ctx_list[i].bContext);     /* free Bacula private context */
       /* Free the plugin instance */
       plug_func(plugin)->freePlugin(&plugin_ctx_list[i++]);
    }
@@ -650,7 +676,7 @@ static boffset_t my_plugin_blseek(BFILE *bfd, boffset_t offset, int whence)
  */
 static bRC baculaGetValue(bpContext *ctx, bVariable var, void *value)
 {
-   JCR *jcr = (JCR *)(ctx->bContext);
+   JCR *jcr = ((bacula_ctx *)ctx->bContext)->jcr;
 // Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var);
    if (!value) {
       return bRC_Error;
@@ -700,7 +726,7 @@ static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
 {
    va_list arg_ptr;
    char buf[2000];
-   JCR *jcr = (JCR *)(ctx->bContext);
+   JCR *jcr = ((bacula_ctx *)ctx->bContext)->jcr;
 
    va_start(arg_ptr, fmt);
    bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
@@ -722,6 +748,27 @@ static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
    return bRC_OK;
 }
 
+static void *baculaMalloc(bpContext *ctx, const char *file, int line,
+              size_t size)
+{
+#ifdef SMARTALLOC
+   return sm_malloc(file, line, size);
+#else
+   return malloc(size);
+#endif
+}
+
+static void baculaFree(bpContext *ctx, const char *file, int line, void *mem)
+{
+#ifdef SMARTALLOC
+   sm_free(file, line, mem);
+#else
+   free(mem);
+#endif
+}
+
+
+
 #ifdef TEST_PROGRAM
 
 int     (*plugin_bopen)(JCR *jcr, const char *fname, int flags, mode_t mode) = NULL;
index 35a5378e866a6c4f813f34d4e16266e3c2e2953c..302ebb2346204e63bfa0573232287b020fc525a0 100644 (file)
@@ -147,6 +147,7 @@ typedef enum {
   bVarSinceTime = 8
 } bVariable;
 
+/* Events that are passed to plugin */
 typedef enum {
   bEventJobStart        = 1,
   bEventJobEnd          = 2,
@@ -205,6 +206,9 @@ typedef struct s_baculaFuncs {
        int type, time_t mtime, const char *fmt, ...);     
    bRC (*DebugMessage)(bpContext *ctx, const char *file, int line,
        int level, const char *fmt, ...);
+   void *(*malloc)(bpContext *ctx, const char *file, int line, 
+       size_t size);
+   void (*free)(bpContext *ctx, const char *file, int line, void *mem);
 } bFuncs;
 
 
@@ -223,7 +227,7 @@ typedef enum {
 
 
 #define FD_PLUGIN_MAGIC     "*FDPluginData*" 
-#define FD_PLUGIN_INTERFACE_VERSION  1
+#define FD_PLUGIN_INTERFACE_VERSION  2
 
 typedef struct s_pluginInfo {
    uint32_t size;
index 4461a66f57a190e92e23a5957cda872836095305..7b646476e677342a33f563bedc1d410d00bb46fd 100644 (file)
@@ -143,6 +143,21 @@ static void  list_status_header(STATUS_PKT *sp)
    len = Mmsg(msg, _(" Sizeof: boffset_t=%d size_t=%d debug=%d trace=%d\n"),
          sizeof(boffset_t), sizeof(size_t), debug_level, get_trace());
    sendit(msg.c_str(), len, sp);
+   if (debug_level > 0 && plugin_list->size() > 0) {
+      Plugin *plugin;
+      int len;
+      pm_strcpy(msg, "Plugin=");
+      foreach_alist(plugin, plugin_list) {
+         len = pm_strcat(msg, plugin->file);
+         if (len > 80) {
+            pm_strcat(msg, "\n   ");
+         } else {
+            pm_strcat(msg, " ");
+         }
+      }
+      len = pm_strcat(msg, "\n");
+      sendit(msg.c_str(), len, sp);
+   }
 }
 
 static void  list_running_jobs(STATUS_PKT *sp)
index be08be96595b666ff1b5721965196852831bcced..787b2ca226833d84414e49e367ac5beab85d5d58 100644 (file)
@@ -55,12 +55,13 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
 
 extern DLL_IMP_EXP alist *plugin_list;
 
-/* Universal return codes from all functions */
+/* Universal return codes from all plugin functions */
 typedef enum {
-  bRC_OK    = 0,                         /* OK */
-  bRC_Stop  = 1,                         /* Stop calling other plugins */
-  bRC_Error = 2,                         /* Some kind of error */
-  bRC_More  = 3,                         /* More files to backup */
+  bRC_OK     = 0,                        /* OK */
+  bRC_Stop   = 1,                        /* Stop calling other plugins */
+  bRC_Error  = 2,                        /* Some kind of error */
+  bRC_More   = 3,                        /* More files to backup */
+  bRC_Term   = 4                         /* Unload me */
 } bRC;
 
 /* Context packet as first argument of all functions */
index 5a1d7701cd2129b9db4415c9630bf484675dd51b..33e2ca5aa7221f89150a29eac34c71501a680619 100644 (file)
@@ -17,6 +17,12 @@ dbdriver
 remove reader/writer in FOPTS????
 
 General:
+09Oct08
+kes  Add malloc and free Bacula entry points for plugins. Increment
+     FD plugin interface version. Create a bacula plugin context 
+     structure to keep track of whether or not the plugin is disabled.
+kes  Apply FileIndex fix for plugin name stream suggested by James.
+kes  List plugins in FD status report when debug > 0.
 08Oct08
 ebl  Add a new VerId variable that is printed in version command.
 kes  Fix migration SQL not to migrate a job that has not terminated.