]> git.sur5r.net Git - bacula/bacula/commitdiff
Plugin updates
authorKern Sibbald <kern@sibbald.com>
Fri, 8 Feb 2008 19:07:53 +0000 (19:07 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 8 Feb 2008 19:07:53 +0000 (19:07 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6380 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/filed/backup.c
bacula/src/filed/fd-plugins.c
bacula/src/findlib/bfile.c
bacula/src/findlib/find.c
bacula/src/lib/bpipe.c
bacula/src/lib/bpipe.h
bacula/src/plugins/fd/bpipe-fd.c

index a863ddd505f047d61c634c8cd7a1d495263dcba7..4e91bfdbe8267dd43c07d69db933b73449d01de3 100644 (file)
@@ -468,18 +468,21 @@ int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level)
 #ifdef HAVE_WIN32
       do_read = !is_portable_backup(&ff_pkt->bfd) || ff_pkt->statp.st_size > 0;
 #else
-      do_read = ff_pkt->statp.st_size > 0;
+      do_read = ff_pkt->statp.st_size > 0;  
 #endif
    } else if (ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
               ff_pkt->type == FT_REPARSE ||
          (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
       do_read = true;
-   } else if (ff_pkt->cmd_plugin) {
+   }
+   if (ff_pkt->cmd_plugin) {
       do_read = true;
    }
 
+   Dmsg1(100, "do_read=%d\n", do_read);
    if (do_read) {
       btimer_t *tid;
+
       if (ff_pkt->type == FT_FIFO) {
          tid = start_thread_timer(jcr, pthread_self(), 60);
       } else {
index a2c4970c1e488635db3b996ba5735378823915d6..96a01cd83b118a81ee7636e6412a125355175dd8 100644 (file)
@@ -113,7 +113,7 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
    }
 
    /* Handle plugin command here (backup/restore of file) */
-   Dmsg1(000, "plugin cmd=%s\n", cmd);
+   Dmsg1(100, "plugin cmd=%s\n", cmd);
    if (!(p = strchr(cmd, ':'))) {
       Jmsg1(jcr, M_ERROR, 0, "Malformed plugin command: %s\n", cmd);
       goto bail_out;
@@ -124,9 +124,9 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
    }
 
    foreach_alist(plugin, plugin_list) {
-      Dmsg3(000, "plugin=%s cmd=%s len=%d\n", plugin->file, cmd, len);
+      Dmsg3(100, "plugin=%s cmd=%s len=%d\n", plugin->file, cmd, len);
       if (strncmp(plugin->file, cmd, len) == 0) {
-         Dmsg1(000, "Command plugin = %s\n", cmd);
+         Dmsg1(100, "Command plugin = %s\n", cmd);
          if (plug_func(plugin)->handlePluginEvent(&plugin_ctx_list[i], &event, value) != bRC_OK) {
             goto bail_out;
          }
@@ -134,8 +134,7 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
          sp.type = FT_REG;
          sp.portable = true;
          sp.cmd = cmd;
-         Dmsg0(000, "Plugin startBackup\n");
-         printf("st_size=%p st_blocks=%p sp=%p\n", &sp.statp.st_size, &sp.statp.st_blocks,
+         Dmsg3(000, "startBackup st_size=%p st_blocks=%p sp=%p\n", &sp.statp.st_size, &sp.statp.st_blocks,
                 &sp);
          if (plug_func(plugin)->startPluginBackup(&plugin_ctx_list[i], &sp) != bRC_OK) {
             goto bail_out;
@@ -153,6 +152,7 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
       }
       i++;
    }
+   Jmsg1(jcr, M_ERROR, 0, "Command plugin \"%s\" not found.\n", cmd);
       
 bail_out:
    return;
index 1473db59993bc27b5104ac7697631a8d27ac8a61..586d7502f244e6393f1f645aa0f9477188a886e6 100644 (file)
@@ -784,11 +784,12 @@ bool is_restore_stream_supported(int stream)
 int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
 {
    if (bfd->cmd_plugin && plugin_bopen) {
+      Dmsg1(000, "call plugin_bopen fname=%s\n", fname);
       return plugin_bopen(bfd->jcr, fname, flags, mode);
    }
 
    /* Normal file open */
-   Dmsg1(400, "open file %s\n", fname);
+   Dmsg1(100, "open file %s\n", fname);
    /* We use fnctl to set O_NOATIME if requested to avoid open error */
    bfd->fid = open(fname, flags & ~O_NOATIME, mode);
    /* Set O_NOATIME if possible */
index c7d789340ac6db44680d4bd260004e096356c6a9..3f0ad75377075efa199937d525c41f8b4a7135ca 100644 (file)
@@ -198,7 +198,7 @@ find_files(JCR *jcr, FF_PKT *ff, int callback(FF_PKT *ff_pkt, void *hpkt, bool t
          }
          foreach_dlist(node, &incexe->plugin_list) {
             char *fname = node->c_str();
-            Dmsg1(000, "PluginCommand: %s\n", fname);
+            Dmsg1(100, "PluginCommand: %s\n", fname);
             ff->top_fname = fname;
             ff->cmd_plugin = true;
             generate_plugin_event(jcr, bEventPluginCommand, (void *)fname);
index 03640a5fb17a375fcd93371f46189859c296fdac..58a22eb70fe0c77e33fd5c4caa22ec2b04861b30 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2002-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2002-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.
index 49125e1e683cc904e671c6f7685f06dd3538361c..b50439d04c1988b63d4c14c503aed3ce9c9c2b16 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2002-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2002-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.
index 75fcda85a049342a9797f3eb971397f62ea8983b..c6c841cc763cf05556ca60237672e1ebd16bc2ae 100644 (file)
@@ -26,7 +26,7 @@
    Switzerland, email:ftf@fsfeurope.org.
 */
 /*
- * Sample Plugin program
+ * A simple pipe plugin for Bacula
  *
  *  Kern Sibbald, October 2007
  *
@@ -35,6 +35,7 @@
 
 #undef malloc
 #undef free
+#undef strdup
 
 #ifdef __cplusplus
 extern "C" {
@@ -86,15 +87,20 @@ static pFuncs pluginFuncs = {
 };
 
 struct plugin_ctx {
-   int record;
    boffset_t offset;
+   FILE *fd;
+   bool backup;
+   char *cmd;
+   char *fname;
+   char *reader;
+   char *writer;
 };
 
 bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs)
 {
    bfuncs = lbfuncs;                  /* set Bacula funct pointers */
    binfo  = lbinfo;
-   printf("bpipe-fd: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version);
+// printf("bpipe-fd: Loaded: size=%d version=%d\n", bfuncs->size, bfuncs->version);
 
    *pinfo  = &pluginInfo;             /* return pointer to our info */
    *pfuncs = &pluginFuncs;            /* return pointer to our functions */
@@ -104,15 +110,14 @@ bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs)
 
 bRC unloadPlugin() 
 {
-   printf("bpipe-fd: Unloaded\n");
+// printf("bpipe-fd: Unloaded\n");
    return bRC_OK;
 }
 
 static bRC newPlugin(bpContext *ctx)
 {
    struct plugin_ctx *p_ctx = (struct plugin_ctx *)malloc(sizeof(struct plugin_ctx));
-
-   p_ctx->record = -1;
+   memset(p_ctx, 0, sizeof(struct plugin_ctx));
    ctx->pContext = (void *)p_ctx;        /* set our context pointer */
    return bRC_OK;
 }
@@ -120,6 +125,9 @@ static bRC newPlugin(bpContext *ctx)
 static bRC freePlugin(bpContext *ctx)
 {
    struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
+   if (p_ctx->cmd) {
+      free(p_ctx->cmd);
+   }
    free(p_ctx);
    return bRC_OK;
 }
@@ -136,38 +144,64 @@ static bRC setPluginValue(bpContext *ctx, pVariable var, void *value)
 
 static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value)
 {
+   struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
    char *name;
 
    switch (event->eventType) {
    case bEventJobStart:
-      printf("bpipe-fd: JobStart=%s\n", (char *)value);
+//    printf("bpipe-fd: JobStart=%s\n", (char *)value);
       break;
    case bEventJobEnd:
-      printf("bpipe-fd: JobEnd\n");
+//    printf("bpipe-fd: JobEnd\n");
       break;
    case bEventBackupStart:
-      printf("bpipe-fd: BackupStart\n");
+//    printf("bpipe-fd: BackupStart\n");
       break;
    case bEventBackupEnd:
-      printf("bpipe-fd: BackupEnd\n");
+//    printf("bpipe-fd: BackupEnd\n");
       break;
    case bEventLevel:
-      printf("bpipe-fd: JobLevel=%c %d\n", (int)value, (int)value);
+//    printf("bpipe-fd: JobLevel=%c %d\n", (int)value, (int)value);
       break;
    case bEventSince:
-      printf("bpipe-fd: since=%d\n", (int)value);
+//    printf("bpipe-fd: since=%d\n", (int)value);
       break;
 
    case bEventRestoreStart: 
-      printf("bpipe-fd: RestoreStart\n");
+//    printf("bpipe-fd: RestoreStart\n");
       break;
    case bEventRestoreEnd:
-      printf("bpipe-fd: RestoreEnd\n");
+//    printf("bpipe-fd: RestoreEnd\n");
       break;
 
    /* Plugin command e.g. plugin = <plugin-name>:<name-space>:command */
    case bEventPluginCommand:
-      printf("bpipe-fd: command=%s\n", (char *)value);
+      char *p;
+//    printf("bpipe-fd: pluginEvent cmd=%s\n", (char *)value);
+      p_ctx->cmd = strdup((char *)value);
+      p = strchr(p_ctx->cmd, ':');
+      if (!p) {
+         printf("Plugin terminator not found: %s\n", (char *)value);
+         return bRC_Error;
+      }
+      *p++ = 0;           /* terminate plugin */
+      p_ctx->fname = p;
+      p = strchr(p, ':');
+      if (!p) {
+         printf("File terminator not found: %s\n", (char *)value);
+         return bRC_Error;
+      }
+      *p++ = 0;           /* terminate file */
+      p_ctx->reader = p;
+      p = strchr(p, ':');
+      if (!p) {
+         printf("Reader terminator not found: %s\n", (char *)value);
+         return bRC_Error;
+      }
+      *p++ = 0;           /* terminate reader string */
+      p_ctx->writer = p;
+      printf("bpipe-fd: plugin=%s fname=%s reader=%s writer=%s\n", 
+         p_ctx->cmd, p_ctx->fname, p_ctx->reader, p_ctx->writer);
       break;
 
    default:
@@ -182,20 +216,18 @@ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value)
 
 static bRC startPluginBackup(bpContext *ctx, struct save_pkt *sp)
 {
-   static char *fname = (char *)"/@BPIPE/test.txt";
+   struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
    time_t now = time(NULL);
-   sp->fname = fname;
-   sp->statp.st_mode = 0700;
+   sp->fname = p_ctx->fname;
+   sp->statp.st_mode = 0700 | S_IFREG;
    sp->statp.st_ctime = now;
    sp->statp.st_mtime = now;
    sp->statp.st_atime = now;
    sp->statp.st_size = -1;
    sp->statp.st_blksize = 4096;
    sp->statp.st_blocks = 1;
-   printf("bpipe: st_size=%p st_blocks=%p sp=%p\n", &sp->statp.st_size, &sp->statp.st_blocks,
-                sp);
-
-   printf("bpipe-fd: startPluginBackup\n");
+   p_ctx->backup = true;
+// printf("bpipe-fd: startPluginBackup\n");
    return bRC_OK;
 }
 
@@ -205,31 +237,43 @@ static bRC startPluginBackup(bpContext *ctx, struct save_pkt *sp)
 static bRC pluginIO(bpContext *ctx, struct io_pkt *io)
 {
    struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
+   char msg[200];
     
    io->status = 0;
    io->io_errno = 0;
    switch(io->func) {
    case IO_OPEN:
-      p_ctx->record = 0;
-      printf("bpipe-fd: IO_OPEN\n");
+      p_ctx->fd = popen(p_ctx->reader, "r");
+      if (!p_ctx->fd) {
+         io->io_errno = errno;
+         snprintf(msg, sizeof(msg), "bpipe-fd: reader=%s failed: ERR=%d\n", p_ctx->reader, errno);
+         bfuncs->JobMessage(ctx, __FILE__, __LINE__, 1, 0, msg);
+         printf("%s", msg);
+         return bRC_Error;
+      }
+      printf("bpipe-fd: IO_OPEN reader=%s fd=%p\n", p_ctx->reader, p_ctx->fd);
+      sleep(1);                 /* let pipe connect */
       break;
+
    case IO_READ:
-      printf("bpipe-fd: IO_READ buf=%p len=%d\n", io->buf, io->count);
-      if (p_ctx->record == 0) {
-         strcpy(io->buf, "This is a test string.\n");
-         io->status = strlen(io->buf);
-         p_ctx->offset = io->status;
-         p_ctx->record = 1;
-         return bRC_OK;
+      io->status = fread(io->buf, 1, io->count, p_ctx->fd);
+      printf("bpipe-fd: IO_READ buf=%p len=%d\n", io->buf, io->status);
+      if (io->status == 0 && ferror(p_ctx->fd)) {
+         printf("Error reading pipe\n");
+         return bRC_Error;
       }
-      io->status = 0;
+      printf("status=%d\n", io->status);
       break;
+
    case IO_WRITE:
       printf("bpipe-fd: IO_WRITE buf=%p len=%d\n", io->buf, io->count);
       break;
+
    case IO_CLOSE:
+      io->status = pclose(p_ctx->fd);
       printf("bpipe-fd: IO_CLOSE\n");
       break;
+
    case IO_SEEK:
       io->offset = p_ctx->offset;
       break;