From: Kern Sibbald Date: Wed, 13 Feb 2008 10:33:21 +0000 (+0000) Subject: Plugin restore works X-Git-Tag: Release-7.0.0~5028 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=1948e0dd4f8296598c64cc79b471624c766ae5c3;p=bacula%2Fbacula Plugin restore works git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6411 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/filed/fd-plugins.c b/bacula/src/filed/fd-plugins.c index 2e1d151a40..961ff3db4a 100644 --- a/bacula/src/filed/fd-plugins.c +++ b/bacula/src/filed/fd-plugins.c @@ -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; } diff --git a/bacula/src/filed/fd-plugins.h b/bacula/src/filed/fd-plugins.h index 08365fc549..c88392a540 100644 --- a/bacula/src/filed/fd-plugins.h +++ b/bacula/src/filed/fd-plugins.h @@ -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 */ diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index 5624b2d33d..33c02c1c39 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -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; diff --git a/bacula/src/findlib/bfile.c b/bacula/src/findlib/bfile.c index be0d49bd91..f5c961a419 100644 --- a/bacula/src/findlib/bfile.c +++ b/bacula/src/findlib/bfile.c @@ -39,10 +39,10 @@ #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 diff --git a/bacula/src/lib/attr.h b/bacula/src/lib/attr.h index 4b3cbe65e0..7828c170ef 100644 --- a/bacula/src/lib/attr.h +++ b/bacula/src/lib/attr.h @@ -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. diff --git a/bacula/src/plugins/fd/bpipe-fd.c b/bacula/src/plugins/fd/bpipe-fd.c index e470050385..98f93c450e 100644 --- a/bacula/src/plugins/fd/bpipe-fd.c +++ b/bacula/src/plugins/fd/bpipe-fd.c @@ -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: