]> git.sur5r.net Git - bacula/bacula/commitdiff
Plugin restore works
authorKern Sibbald <kern@sibbald.com>
Wed, 13 Feb 2008 10:33:21 +0000 (10:33 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 13 Feb 2008 10:33:21 +0000 (10:33 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6411 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/filed/fd-plugins.c
bacula/src/filed/fd-plugins.h
bacula/src/filed/restore.c
bacula/src/findlib/bfile.c
bacula/src/lib/attr.h
bacula/src/plugins/fd/bpipe-fd.c

index 2e1d151a409d10537499df66f8ca181e551038c6..961ff3db4a06d1395746f21e083a96cb561c6eb7 100644 (file)
@@ -243,7 +243,7 @@ void plugin_name_stream(JCR *jcr, char *name)
    int i = 0;
    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
 
-   Dmsg1(000, "Read plugin stream string=%s\n", name);
+   Dmsg1(100, "Read plugin stream string=%s\n", name);
    skip_nonspaces(&p);             /* skip over jcr->JobFiles */
    skip_spaces(&p);
    start = *p == '1';
@@ -270,7 +270,7 @@ void plugin_name_stream(JCR *jcr, char *name)
     * After this point, we are dealing with a restore start
     */
 
-   Dmsg1(000, "plugin cmd=%s\n", cmd);
+   Dmsg1(100, "plugin restore cmd=%s\n", cmd);
    if (!(p = strchr(cmd, ':'))) {
       Jmsg1(jcr, M_ERROR, 0, "Malformed plugin command: %s\n", cmd);
       goto bail_out;
@@ -285,12 +285,12 @@ void plugin_name_stream(JCR *jcr, char *name)
     */
    foreach_alist(plugin, plugin_list) {
       bEvent event;
-      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) {
          i++;
          continue;
       }
-      Dmsg1(000, "Restore Command plugin = %s\n", cmd);
+      Dmsg1(100, "Restore Command plugin = %s\n", cmd);
       event.eventType = bEventRestoreCommand;     
       if (plug_func(plugin)->handlePluginEvent(&plugin_ctx_list[i], 
             &event, cmd) != bRC_OK) {
@@ -315,11 +315,35 @@ 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 = (bpContext *)jcr->plugin_ctx;
+   Plugin *plugin = (Plugin *)jcr->plugin;
+   struct restore_pkt rp;
+   struct io_pkt io;
+
    if (!set_cmd_plugin(bfd, jcr)) {
       return CF_ERROR;
    }
+   rp.stream = attr->stream;
+   rp.data_stream = attr->data_stream;
+   rp.type = attr->type;
+   rp.file_index = attr->file_index;
+   rp.LinkFI = attr->LinkFI;
+   rp.uid = attr->uid;
+   rp.statp = attr->statp;                /* structure assignment */
+   rp.attrEx = attr->attrEx;
+   rp.ofname = attr->ofname;
+   rp.olname = attr->olname;
+   if (plug_func(plugin)->createFile(plugin_ctx, &rp) != bRC_OK) {
+      return CF_ERROR;
+   }
+   io.func = IO_OPEN;
+   io.count = 0;
+   io.buf = NULL;
+   io.mode = 0777 & attr->statp.st_mode;
+   io.flags = O_WRONLY;
+   if (plug_func(plugin)->pluginIO(plugin_ctx, &io) != bRC_OK) {
+      return CF_ERROR;
+   }
    return CF_EXTRACT;
 }
 
@@ -410,6 +434,8 @@ static int my_plugin_bopen(JCR *jcr, const char *fname, int flags, mode_t mode)
    io.func = IO_OPEN;
    io.count = 0;
    io.buf = NULL;
+   io.mode = mode;
+   io.flags = flags;
    plug_func(plugin)->pluginIO(plugin_ctx, &io);
    return io.status;
 }
index 08365fc5492430b9d7adbad930644c8e83aea4e8..c88392a540689a2ead72cb71488f132aa13a8e35 100644 (file)
@@ -74,6 +74,16 @@ struct save_pkt {
  * This packet is used for file restore info transfer.
 */
 struct restore_pkt {
+   int32_t stream;                    /* attribute stream id */
+   int32_t data_stream;               /* id of data stream to follow */
+   int32_t type;                      /* file type FT */
+   int32_t file_index;                /* file index */
+   int32_t LinkFI;                    /* file index to data if hard link */
+   uid_t uid;                         /* userid */
+   struct stat statp;                 /* decoded stat packet */
+   const char *attrEx;                /* extended attributes if any */
+   const char *ofname;                /* output filename */
+   const char *olname;                /* output link name */
 };
 
 enum {
@@ -87,6 +97,8 @@ enum {
 struct io_pkt {
    int32_t func;                      /* Function code */
    int32_t count;                     /* read/write count */
+   mode_t mode;                       /* permissions for created files */
+   int32_t flags;                     /* open flags (e.g. O_WRONLY ...) */
    char *buf;                         /* read/write buffer */
    int32_t status;                    /* return status */
    int32_t io_errno;                  /* errno code */  
index 5624b2d33d325751420e277ba8bc90ada16251ad..33c02c1c398627b61196b29aa30435028c12f4bc 100644 (file)
@@ -645,7 +645,7 @@ void do_restore(JCR *jcr)
          break;
 
       case STREAM_PLUGIN_NAME:
-         Dmsg1(000, "stream_plugin_name=%s\n", sd->msg);
+         Dmsg1(000, "restore stream_plugin_name=%s\n", sd->msg);
          plugin_name_stream(jcr, sd->msg);
          break;
 
index be0d49bd91377e416719a422a7107ff3ec4709ca..f5c961a419831f8a17283cc5d4ae22756e1fa835 100644 (file)
 #include "bacula.h"
 #include "find.h"
 
-int     (*plugin_bopen)(JCR *jcr, const char *fname, int flags, mode_t mode) = NULL;
-int     (*plugin_bclose)(JCR *jcr) = NULL;
-ssize_t (*plugin_bread)(JCR *jcr, void *buf, size_t count) = NULL;
-ssize_t (*plugin_bwrite)(JCR *jcr, void *buf, size_t count) = NULL;
+int       (*plugin_bopen)(JCR *jcr, const char *fname, int flags, mode_t mode) = NULL;
+int       (*plugin_bclose)(JCR *jcr) = NULL;
+ssize_t   (*plugin_bread)(JCR *jcr, void *buf, size_t count) = NULL;
+ssize_t   (*plugin_bwrite)(JCR *jcr, void *buf, size_t count) = NULL;
 boffset_t (*plugin_blseek)(JCR *jcr, boffset_t offset, int whence) = NULL;
 
 
@@ -404,6 +404,15 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
    
    unix_name_to_win32(&win32_fname, (char *)fname);
 
+   if (bfd->cmd_plugin && plugin_bopen) {
+      int rtnstat;
+      Dmsg1(000, "call plugin_bopen fname=%s\n", fname);
+      rtnstat = plugin_bopen(bfd->jcr, fname, flags, mode);
+      free_pool_memory(win32_fname_wchar);
+      free_pool_memory(win32_fname);
+      return rtnstat;
+   }
+
    if (!(p_CreateFileA || p_CreateFileW))
       return 0;
 
@@ -538,6 +547,12 @@ int bclose(BFILE *bfd)
    if (bfd->mode == BF_CLOSED) {
       return 0;
    }
+
+   if (bfd->cmd_plugin && plugin_bclose) {
+      stat = plugin_bclose(bfd->jcr);
+      goto all_done;
+   }
+
    if (bfd->use_backup_api && bfd->mode == BF_READ) {
       BYTE buf[10];
       if (!bfd->lpContext && !p_BackupRead(bfd->fh,
@@ -567,6 +582,8 @@ int bclose(BFILE *bfd)
       stat = -1;
       errno = b_errno_win32;
    }
+
+all_done:
    bfd->mode = BF_CLOSED;
    bfd->lpContext = NULL;
    bfd->cmd_plugin = false;
@@ -581,6 +598,10 @@ ssize_t bread(BFILE *bfd, void *buf, size_t count)
 {
    bfd->rw_bytes = 0;
 
+   if (bfd->cmd_plugin && plugin_bread) {
+      return plugin_bread(bfd->jcr, buf, count);
+   }
+
    if (bfd->use_backup_api) {
       if (!p_BackupRead(bfd->fh,
            (BYTE *)buf,
@@ -614,6 +635,10 @@ ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
 {
    bfd->rw_bytes = 0;
 
+   if (bfd->cmd_plugin && plugin_bwrite) {
+      return plugin_bwrite(bfd->jcr, buf, count);
+   }
+
    if (bfd->use_backup_api) {
       if (!p_BackupWrite(bfd->fh,
            (BYTE *)buf,
@@ -653,6 +678,10 @@ boffset_t blseek(BFILE *bfd, boffset_t offset, int whence)
    LONG  offset_high = (LONG)(offset >> 32);
    DWORD dwResult;
 
+   if (bfd->cmd_plugin && plugin_bwrite) {
+      return plugin_blseek(bfd->jcr, offset, whence);
+   }
+
    dwResult = SetFilePointer(bfd->fh, offset_low, &offset_high, whence);
 
    if (dwResult == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
@@ -785,8 +814,10 @@ int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
 
    /* Normal file open */
    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 */
    if (bfd->fid != -1 && flags & O_NOATIME) {
       int oldflags = fcntl(bfd->fid, F_GETFL, 0);
@@ -845,7 +876,9 @@ int bclose(BFILE *bfd)
    Dmsg1(400, "Close file %d\n", bfd->fid);
 
    if (bfd->cmd_plugin && plugin_bclose) {
-      return plugin_bclose(bfd->jcr);
+      stat = plugin_bclose(bfd->jcr);
+      bfd->fid = -1;
+      bfd->cmd_plugin = false;
    }
 
    if (bfd->fid == -1) {
@@ -899,14 +932,14 @@ bool is_bopen(BFILE *bfd)
 
 boffset_t blseek(BFILE *bfd, boffset_t offset, int whence)
 {
-    boffset_t pos;
+   boffset_t pos;
 
    if (bfd->cmd_plugin && plugin_bwrite) {
       return plugin_blseek(bfd->jcr, offset, whence);
    }
-    pos = (boffset_t)lseek(bfd->fid, (off_t)offset, whence);
-    bfd->berrno = errno;
-    return pos;
+   pos = (boffset_t)lseek(bfd->fid, (off_t)offset, whence);
+   bfd->berrno = errno;
+   return pos;
 }
 
 #endif
index 4b3cbe65e005f1324d15824b2ce23e87c63c0ede..7828c170ef43bfbad59a934bd0f246c49f91c857 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2003-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2003-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 e4700503855dfcff00aaad627bf3c6204da75daa..98f93c450e192d18b2070ff6d89d813ada4d95aa 100644 (file)
@@ -260,41 +260,63 @@ static bRC endBackupFile(bpContext *ctx)
 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->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__, M_FATAL, 0, msg);
-         printf("%s", msg);
-         return bRC_Error;
+      printf("bpipe-fd: IO_OPEN\n");
+      if (io->flags & (O_CREAT | O_WRONLY)) {
+         p_ctx->fd = popen(p_ctx->writer, "w");
+         printf("bpipe-fd: IO_OPEN writer=%s\n", p_ctx->writer);
+         if (!p_ctx->fd) {
+            io->io_errno = errno;
+            bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, 
+               "bpipe-fd: writer=%s failed: ERR=%d\n", p_ctx->writer, errno);
+            return bRC_Error;
+         }
+      } else {
+         p_ctx->fd = popen(p_ctx->reader, "r");
+         printf("bpipe-fd: IO_OPEN reader=%s\n", p_ctx->reader);
+         if (!p_ctx->fd) {
+            io->io_errno = errno;
+            bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, 
+               "bpipe-fd: reader=%s failed: ERR=%d\n", p_ctx->reader, errno);
+            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:
       if (!p_ctx->fd) {
-         bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "NULL FD\n");
+         bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "NULL read FD\n");
          return bRC_Error;
       }
       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)) {
-         bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Pipe I/O error\n");
+         bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Pipe read error\n");
          printf("Error reading pipe\n");
          return bRC_Error;
       }
-      printf("status=%d\n", io->status);
+//    printf("status=%d\n", io->status);
       break;
 
    case IO_WRITE:
-      printf("bpipe-fd: IO_WRITE buf=%p len=%d\n", io->buf, io->count);
+      if (!p_ctx->fd) {
+         bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "NULL write FD\n");
+         return bRC_Error;
+      }
+      printf("bpipe-fd: IO_WRITE fd=%p buf=%p len=%d\n", p_ctx->fd, io->buf, io->count);
+      io->status = fwrite(io->buf, 1, io->count, p_ctx->fd);
+      printf("bpipe-fd: IO_WRITE buf=%p len=%d\n", io->buf, io->status);
+      if (io->status == 0 && ferror(p_ctx->fd)) {
+         bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Pipe write error\n");
+         printf("Error writing pipe\n");
+         return bRC_Error;
+      }
+//    printf("status=%d\n", io->status);
       break;
 
    case IO_CLOSE: