]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/fd_plugins.c
Tweak debug
[bacula/bacula] / bacula / src / filed / fd_plugins.c
index f75b51d7b937f3aebad638d95260fc62d8d71711..c0aa2eed0246c11c8fb2396579c2e8219dc2c608 100644 (file)
@@ -34,7 +34,7 @@
 #include "bacula.h"
 #include "filed.h"
 
-const int dbglvl = 50;
+const int dbglvl = 150;
 #ifdef HAVE_WIN32
 const char *plugin_type = "-fd.dll";
 #else
@@ -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);
@@ -69,7 +76,7 @@ static boffset_t my_plugin_blseek(BFILE *bfd, boffset_t offset, int whence);
 
 /* Bacula info */
 static bInfo binfo = {
-   sizeof(bFuncs),
+   sizeof(bInfo),
    FD_PLUGIN_INTERFACE_VERSION 
 };
 
@@ -81,9 +88,30 @@ 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 disabled;                        /* set if plugin disabled */
+};
+
+static bool is_plugin_disabled(JCR *jcr)
+{
+   bacula_ctx *b_ctx;
+   if (!jcr->plugin_ctx) {
+      return true;
+   }
+   b_ctx = (bacula_ctx *)jcr->plugin_ctx->bContext;
+   return b_ctx->disabled;
+}
+
 
 /*
  * Create a plugin event 
@@ -106,12 +134,19 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
    /* Pass event to every plugin */
    foreach_alist(plugin, plugin_list) {
       bRC rc;
-      rc = plug_func(plugin)->handlePluginEvent(&plugin_ctx_list[i++], &event, value);
+      jcr->plugin_ctx = &plugin_ctx_list[i++];
+      jcr->plugin = plugin;
+      if (is_plugin_disabled(jcr)) {
+         continue;
+      }
+      rc = plug_func(plugin)->handlePluginEvent(jcr->plugin_ctx, &event, value);
       if (rc != bRC_OK) {
          break;
       }
    }
 
+   jcr->plugin = NULL;
+   jcr->plugin_ctx = NULL;
    return;
 }
 
@@ -159,15 +194,27 @@ int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
       goto bail_out;
    }
 
+   /* Note, we stop the loop on the first plugin that matches the name */
    foreach_alist(plugin, plugin_list) {
       Dmsg3(dbglvl, "plugin=%s cmd=%s len=%d\n", plugin->file, cmd, len);
       if (strncmp(plugin->file, cmd, len) != 0) {
          i++;
          continue;
       }
+      /* 
+       * We put the current plugin pointer, and the plugin context
+       *  into the jcr, because during save_file(), the plugin
+       *  will be called many times and these values are needed.
+       */
+      jcr->plugin_ctx = &plugin_ctx_list[i];
+      jcr->plugin = plugin;
+      if (is_plugin_disabled(jcr)) {
+         goto bail_out;
+      }
+
       Dmsg1(dbglvl, "Command plugin = %s\n", cmd);
       /* Send the backup command to the right plugin*/
-      if (plug_func(plugin)->handlePluginEvent(&plugin_ctx_list[i], &event, cmd) != bRC_OK) {
+      if (plug_func(plugin)->handlePluginEvent(jcr->plugin_ctx, &event, cmd) != bRC_OK) {
          goto bail_out;
       }
       /* Loop getting filenames to backup then saving them */
@@ -180,7 +227,7 @@ int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
          Dmsg3(dbglvl, "startBackup st_size=%p st_blocks=%p sp=%p\n", &sp.statp.st_size, &sp.statp.st_blocks,
                 &sp);
          /* Get the file save parameters */
-         if (plug_func(plugin)->startBackupFile(&plugin_ctx_list[i], &sp) != bRC_OK) {
+         if (plug_func(plugin)->startBackupFile(jcr->plugin_ctx, &sp) != bRC_OK) {
             goto bail_out;
          }
          if (sp.type == 0 || sp.fname == NULL) {
@@ -188,8 +235,6 @@ int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
                cmd);
             goto bail_out;
          }
-         jcr->plugin_ctx = &plugin_ctx_list[i];
-         jcr->plugin = plugin;
          jcr->plugin_sp = &sp;
          ff_pkt = jcr->ff;
          ff_pkt->fname = sp.fname;
@@ -198,17 +243,20 @@ int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level)
          memcpy(&ff_pkt->statp, &sp.statp, sizeof(ff_pkt->statp));
          Dmsg1(dbglvl, "Save_file: file=%s\n", ff_pkt->fname);
          save_file(jcr, ff_pkt, true);
-         bRC rc = plug_func(plugin)->endBackupFile(&plugin_ctx_list[i]);
+         bRC rc = plug_func(plugin)->endBackupFile(jcr->plugin_ctx);
          if (rc == bRC_More) {
             continue;
          }
          goto bail_out;
       }
+      goto bail_out;
    }
    Jmsg1(jcr, M_ERROR, 0, "Command plugin \"%s\" not found.\n", cmd);
 
 bail_out:
    jcr->cmd_plugin = false;
+   jcr->plugin = NULL;
+   jcr->plugin_ctx = NULL;
    return 1;
 }
 
@@ -218,11 +266,20 @@ 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 (!sp) {
+      Jmsg0(jcr, M_FATAL, 0, _("Plugin save packet not found.\n"));
+      return false;
+   }
   
+   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 +288,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");
@@ -261,7 +318,7 @@ bool plugin_name_stream(JCR *jcr, char *name)
    Plugin *plugin;
    int len;
    int i = 0;
-   bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
+   bpContext *plugin_ctx_list = jcr->plugin_ctx_list;
 
    Dmsg1(dbglvl, "Read plugin stream string=%s\n", name);
    skip_nonspaces(&p);             /* skip over jcr->JobFiles */
@@ -281,8 +338,7 @@ bool plugin_name_stream(JCR *jcr, char *name)
        */
       Dmsg2(dbglvl, "End plugin data plugin=%p ctx=%p\n", jcr->plugin, jcr->plugin_ctx);
       if (jcr->plugin) {
-         plugin = (Plugin *)jcr->plugin;
-         plug_func(plugin)->endRestoreFile((bpContext *)jcr->plugin_ctx);
+         plug_func(jcr->plugin)->endRestoreFile(jcr->plugin_ctx);
       }
       jcr->plugin_ctx = NULL;
       jcr->plugin = NULL;
@@ -317,17 +373,23 @@ bool plugin_name_stream(JCR *jcr, char *name)
          i++;
          continue;
       }
+      jcr->plugin_ctx = &plugin_ctx_list[i];
+      jcr->plugin = plugin;
+      if (is_plugin_disabled(jcr)) {
+         goto bail_out;
+      }
       Dmsg1(dbglvl, "Restore Command plugin = %s\n", cmd);
       event.eventType = bEventRestoreCommand;     
-      if (plug_func(plugin)->handlePluginEvent(&plugin_ctx_list[i]
+      if (plug_func(plugin)->handlePluginEvent(jcr->plugin_ctx
             &event, cmd) != bRC_OK) {
          goto bail_out;
       }
-      jcr->plugin_ctx = &plugin_ctx_list[i];
-      jcr->plugin = plugin;
+      /* ***FIXME**** check error code */
       plug_func(plugin)->startRestoreFile((bpContext *)jcr->plugin_ctx, cmd);
       goto bail_out;
    }
+   Jmsg1(jcr, M_WARNING, 0, _("Plugin=%s not found.\n"), cmd);
+
 bail_out:
    return start;
 }
@@ -343,13 +405,13 @@ bail_out:
  */
 int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
 {
-   bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx;
-   Plugin *plugin = (Plugin *)jcr->plugin;
+   bpContext *plugin_ctx = jcr->plugin_ctx;
+   Plugin *plugin = jcr->plugin;
    struct restore_pkt rp;
    int flags;
    int rc;
 
-   if (!set_cmd_plugin(bfd, jcr)) {
+   if (!plugin || !plugin_ctx || !set_cmd_plugin(bfd, jcr)) {
       return CF_ERROR;
    }
    rp.pkt_size = sizeof(rp);
@@ -478,15 +540,20 @@ void new_plugins(JCR *jcr)
       return;
    }
 
-   jcr->plugin_ctx_list = (void *)malloc(sizeof(bpContext) * num);
+   jcr->plugin_ctx_list = (bpContext *)malloc(sizeof(bpContext) * num);
 
    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
    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++]);
+      if (plug_func(plugin)->newPlugin(&plugin_ctx_list[i++]) != bRC_OK) {
+         b_ctx->disabled = true;
+      }
    }
 }
 
@@ -504,9 +571,10 @@ 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 the plugin instance */
-      plug_func(plugin)->freePlugin(&plugin_ctx_list[i++]);
+      plug_func(plugin)->freePlugin(&plugin_ctx_list[i]);
+      free(plugin_ctx_list[i++].bContext);     /* free Bacula private context */
    }
    free(plugin_ctx_list);
    jcr->plugin_ctx_list = NULL;
@@ -516,8 +584,8 @@ static int my_plugin_bopen(BFILE *bfd, const char *fname, int flags, mode_t mode
 {
    JCR *jcr = bfd->jcr;
    Plugin *plugin = (Plugin *)jcr->plugin;
-   bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx;
    struct io_pkt io;
+
    Dmsg1(dbglvl, "plugin_bopen flags=%x\n", flags);
    io.pkt_size = sizeof(io);
    io.pkt_end = sizeof(io);
@@ -529,7 +597,7 @@ static int my_plugin_bopen(BFILE *bfd, const char *fname, int flags, mode_t mode
    io.mode = mode;
    io.win32 = false;
    io.lerror = 0;
-   plug_func(plugin)->pluginIO(plugin_ctx, &io);
+   plug_func(plugin)->pluginIO(jcr->plugin_ctx, &io);
    bfd->berrno = io.io_errno;
    if (io.win32) {
       errno = b_errno_win32;
@@ -545,7 +613,6 @@ static int my_plugin_bclose(BFILE *bfd)
 {
    JCR *jcr = bfd->jcr;
    Plugin *plugin = (Plugin *)jcr->plugin;
-   bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx;
    struct io_pkt io;
    Dmsg0(dbglvl, "===== plugin_bclose\n");
    io.pkt_size = sizeof(io);
@@ -555,7 +622,7 @@ static int my_plugin_bclose(BFILE *bfd)
    io.buf = NULL;
    io.win32 = false;
    io.lerror = 0;
-   plug_func(plugin)->pluginIO(plugin_ctx, &io);
+   plug_func(plugin)->pluginIO(jcr->plugin_ctx, &io);
    bfd->berrno = io.io_errno;
    if (io.win32) {
       errno = b_errno_win32;
@@ -571,7 +638,6 @@ static ssize_t my_plugin_bread(BFILE *bfd, void *buf, size_t count)
 {
    JCR *jcr = bfd->jcr;
    Plugin *plugin = (Plugin *)jcr->plugin;
-   bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx;
    struct io_pkt io;
    Dmsg0(dbglvl, "plugin_bread\n");
    io.pkt_size = sizeof(io);
@@ -581,7 +647,7 @@ static ssize_t my_plugin_bread(BFILE *bfd, void *buf, size_t count)
    io.buf = (char *)buf;
    io.win32 = false;
    io.lerror = 0;
-   plug_func(plugin)->pluginIO(plugin_ctx, &io);
+   plug_func(plugin)->pluginIO(jcr->plugin_ctx, &io);
    bfd->berrno = io.io_errno;
    if (io.win32) {
       errno = b_errno_win32;
@@ -596,7 +662,6 @@ static ssize_t my_plugin_bwrite(BFILE *bfd, void *buf, size_t count)
 {
    JCR *jcr = bfd->jcr;
    Plugin *plugin = (Plugin *)jcr->plugin;
-   bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx;
    struct io_pkt io;
    Dmsg0(dbglvl, "plugin_bwrite\n");
    io.pkt_size = sizeof(io);
@@ -606,7 +671,7 @@ static ssize_t my_plugin_bwrite(BFILE *bfd, void *buf, size_t count)
    io.buf = (char *)buf;
    io.win32 = false;
    io.lerror = 0;
-   plug_func(plugin)->pluginIO(plugin_ctx, &io);
+   plug_func(plugin)->pluginIO(jcr->plugin_ctx, &io);
    bfd->berrno = io.io_errno;
    if (io.win32) {
       errno = b_errno_win32;
@@ -621,7 +686,6 @@ static boffset_t my_plugin_blseek(BFILE *bfd, boffset_t offset, int whence)
 {
    JCR *jcr = bfd->jcr;
    Plugin *plugin = (Plugin *)jcr->plugin;
-   bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx;
    struct io_pkt io;
    Dmsg0(dbglvl, "plugin_bseek\n");
    io.pkt_size = sizeof(io);
@@ -631,7 +695,7 @@ static boffset_t my_plugin_blseek(BFILE *bfd, boffset_t offset, int whence)
    io.whence = whence;
    io.win32 = false;
    io.lerror = 0;
-   plug_func(plugin)->pluginIO(plugin_ctx, &io);
+   plug_func(plugin)->pluginIO(jcr->plugin_ctx, &io);
    bfd->berrno = io.io_errno;
    if (io.win32) {
       errno = b_errno_win32;
@@ -650,9 +714,14 @@ 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;
+   jcr = ((bacula_ctx *)ctx->bContext)->jcr;
 // Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var);
-   if (!value) {
+   if (!value || !ctx) {
+      return bRC_Error;
+   }
+   jcr = ((bacula_ctx *)ctx->bContext)->jcr;
+   if (!jcr) {
       return bRC_Error;
    }
 // Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr); 
@@ -678,6 +747,9 @@ static bRC baculaGetValue(bpContext *ctx, bVariable var, void *value)
 
 static bRC baculaSetValue(bpContext *ctx, bVariable var, void *value)
 {
+   if (!value || !ctx) {
+      return bRC_Error;
+   }
    Dmsg1(dbglvl, "bacula: baculaSetValue var=%d\n", var);
    return bRC_OK;
 }
@@ -687,6 +759,10 @@ static bRC baculaRegisterEvents(bpContext *ctx, ...)
    va_list args;
    uint32_t event;
 
+   if (!ctx) {
+      return bRC_Error;
+   }
+
    va_start(args, ctx);
    while ((event = va_arg(args, uint32_t))) {
       Dmsg1(dbglvl, "Plugin wants event=%u\n", event);
@@ -700,7 +776,13 @@ static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
 {
    va_list arg_ptr;
    char buf[2000];
-   JCR *jcr = (JCR *)(ctx->bContext);
+   JCR *jcr;
+
+   if (ctx) {
+      jcr = ((bacula_ctx *)ctx->bContext)->jcr;
+   } else {
+      jcr = NULL;
+   }
 
    va_start(arg_ptr, fmt);
    bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
@@ -722,6 +804,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;