From: Kern Sibbald Date: Fri, 3 Oct 2008 20:38:16 +0000 (+0000) Subject: kes Fix plugin_bwrite - plugin-blseek mixup pointed out by James. X-Git-Tag: Release-7.0.0~4038 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=af16e70656ee421cb0f5f3eddc7a606dd3d4d0a3;p=bacula%2Fbacula kes Fix plugin_bwrite - plugin-blseek mixup pointed out by James. kes Rewrite plugin restore interface a bit to correspond to how Bacula creates and writes to the restored file. kes Add some DebugMessage() calls to the bpipe-fd.c program. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7696 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/bc_types.h b/bacula/src/bc_types.h index c90392f046..b5cda8557c 100644 --- a/bacula/src/bc_types.h +++ b/bacula/src/bc_types.h @@ -197,4 +197,16 @@ typedef float float32_t; #define sockopt_val_t void * #endif +/* + * Status codes returned by create_file() + * Used in findlib, filed, and plugins + */ +enum { + CF_SKIP = 1, /* skip file (not newer or something) */ + CF_ERROR, /* error creating file */ + CF_EXTRACT, /* file created, data to extract */ + CF_CREATED /* file created, no data to extract */ +}; + + #endif /* __bc_types_INCLUDED */ diff --git a/bacula/src/filed/fd_plugins.c b/bacula/src/filed/fd_plugins.c index 6f60a56d84..cec7f7ec94 100644 --- a/bacula/src/filed/fd_plugins.c +++ b/bacula/src/filed/fd_plugins.c @@ -292,9 +292,10 @@ void plugin_name_stream(JCR *jcr, char *name) * After this point, we are dealing with a restore start */ - Dmsg1(dbglvl, "plugin restore cmd=%s\n", cmd); +// Dmsg1(dbglvl, "plugin restore cmd=%s\n", cmd); if (!(p = strchr(cmd, ':'))) { - Jmsg1(jcr, M_ERROR, 0, "Malformed plugin command: %s\n", cmd); + Jmsg1(jcr, M_ERROR, 0, + _("Malformed plugin command. Name not terminated by colon: %s\n"), cmd); goto bail_out; } len = p - cmd; @@ -340,7 +341,7 @@ int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) bpContext *plugin_ctx = (bpContext *)jcr->plugin_ctx; Plugin *plugin = (Plugin *)jcr->plugin; struct restore_pkt rp; - struct io_pkt io; + mode_t mode; if (!set_cmd_plugin(bfd, jcr)) { return CF_ERROR; @@ -360,17 +361,22 @@ int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) rp.where = jcr->where; rp.RegexWhere = jcr->RegexWhere; rp.replace = jcr->replace; + rp.create_status = CF_ERROR; + Dmsg1(dbglvl, "call plugin createFile=%s\n", rp.ofname); if (plug_func(plugin)->createFile(plugin_ctx, &rp) != bRC_OK) { return CF_ERROR; } - io.pkt_size = sizeof(io); - io.pkt_end = sizeof(io); - 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) { + if (rp.create_status == CF_ERROR || rp.create_status == CF_CREATED) { + return rp.create_status; + } + mode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; + Dmsg0(dbglvl, "call bopen\n"); + if ((bopen(bfd, attr->ofname, mode, S_IRUSR | S_IWUSR)) < 0) { + berrno be; + be.set_errno(bfd->berrno); + Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), + attr->ofname, be.bstrerror()); + Dmsg2(dbglvl,"Could not create %s: ERR=%s\n", attr->ofname, be.bstrerror()); return CF_ERROR; } return CF_EXTRACT; @@ -383,6 +389,7 @@ int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) */ bool plugin_set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) { + Dmsg0(dbglvl, "plugin_set_attributes\n"); return true; } @@ -529,6 +536,7 @@ static int my_plugin_bclose(BFILE *bfd) errno = io.io_errno; bfd->lerror = io.lerror; } + Dmsg1(dbglvl, "plugin_bclose stat=%d\n", io.status); return io.status; } diff --git a/bacula/src/filed/fd_plugins.h b/bacula/src/filed/fd_plugins.h index 0ca7b878b3..307b9f441f 100644 --- a/bacula/src/filed/fd_plugins.h +++ b/bacula/src/filed/fd_plugins.h @@ -100,6 +100,7 @@ struct restore_pkt { const char *where; /* where */ const char *RegexWhere; /* regex where */ int replace; /* replace flag */ + int create_status; /* status from createFile() */ int32_t pkt_end; /* end packet sentinel */ }; diff --git a/bacula/src/findlib/bfile.c b/bacula/src/findlib/bfile.c index cab610346c..17bdcec500 100644 --- a/bacula/src/findlib/bfile.c +++ b/bacula/src/findlib/bfile.c @@ -706,7 +706,7 @@ boffset_t blseek(BFILE *bfd, boffset_t offset, int whence) LONG offset_high = (LONG)(offset >> 32); DWORD dwResult; - if (bfd->cmd_plugin && plugin_bwrite) { + if (bfd->cmd_plugin && plugin_blseek) { return plugin_blseek(bfd, offset, whence); } diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h index 2b31466122..895ecbf46b 100644 --- a/bacula/src/findlib/find.h +++ b/bacula/src/findlib/find.h @@ -69,17 +69,6 @@ struct utimbuf { int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); #endif -/* - * Status codes returned by create_file() - */ -enum { - CF_SKIP = 1, /* skip file (not newer or something) */ - CF_ERROR, /* error creating file */ - CF_EXTRACT, /* file created, data to extract */ - CF_CREATED /* file created, no data to extract */ -}; - - /* * Options saved int "options" of the include/exclude lists. * They are directly jammed ito "flag" of ff packet diff --git a/bacula/src/plugins/fd/bpipe-fd.c b/bacula/src/plugins/fd/bpipe-fd.c index 35e891314c..8f14decd63 100644 --- a/bacula/src/plugins/fd/bpipe-fd.c +++ b/bacula/src/plugins/fd/bpipe-fd.c @@ -37,6 +37,9 @@ #undef free #undef strdup +#define fi __FILE__ +#define li __LINE__ + #ifdef __cplusplus extern "C" { #endif @@ -206,7 +209,7 @@ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value) */ switch (event->eventType) { case bEventJobStart: -// printf("bpipe-fd: JobStart=%s\n", (char *)value); + bfuncs->DebugMessage(ctx, fi, li, 50, "bpipe-fd: JobStart=%s\n", (char *)value); break; case bEventJobEnd: // printf("bpipe-fd: JobEnd\n"); @@ -238,25 +241,25 @@ static bRC handlePluginEvent(bpContext *ctx, bEvent *event, void *value) /* Fall-through wanted */ case bEventBackupCommand: char *p; - printf("bpipe-fd: pluginEvent cmd=%s\n", (char *)value); + bfuncs->DebugMessage(ctx, fi, li, 50, "bpipe-fd: pluginEvent cmd=%s\n", (char *)value); p_ctx->cmd = strdup((char *)value); p = strchr(p_ctx->cmd, ':'); if (!p) { - bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Plugin terminator not found: %s\n", (char *)value); + bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Plugin terminator not found: %s\n", (char *)value); return bRC_Error; } *p++ = 0; /* terminate plugin */ p_ctx->fname = p; p = strchr(p, ':'); if (!p) { - bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "File terminator not found: %s\n", (char *)value); + bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "File terminator not found: %s\n", (char *)value); return bRC_Error; } *p++ = 0; /* terminate file */ p_ctx->reader = p; p = strchr(p, ':'); if (!p) { - bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Reader terminator not found: %s\n", (char *)value); + bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Reader terminator not found: %s\n", (char *)value); return bRC_Error; } *p++ = 0; /* terminate reader string */ @@ -316,15 +319,16 @@ static bRC pluginIO(bpContext *ctx, struct io_pkt *io) io->io_errno = 0; switch(io->func) { case IO_OPEN: -// printf("bpipe-fd: IO_OPEN\n"); + bfuncs->DebugMessage(ctx, fi, li, 50, "bpipe-fd: IO_OPEN\n"); if (io->flags & (O_CREAT | O_WRONLY)) { char *writer_codes = apply_rp_codes(p_ctx); p_ctx->fd = popen(writer_codes, "w"); - printf("bpipe-fd: IO_OPEN writer=%s\n", writer_codes); + bfuncs->DebugMessage(ctx, fi, li, 50, "bpipe-fd: IO_OPEN fd=%d writer=%s\n", + p_ctx->fd, writer_codes); if (!p_ctx->fd) { io->io_errno = errno; - bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, + bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Open pipe writer=%s failed: ERR=%s\n", writer_codes, strerror(errno)); if (writer_codes) { free(writer_codes); @@ -336,10 +340,11 @@ static bRC pluginIO(bpContext *ctx, struct io_pkt *io) } } else { p_ctx->fd = popen(p_ctx->reader, "r"); -// printf("bpipe-fd: IO_OPEN reader=%s\n", p_ctx->reader); + bfuncs->DebugMessage(ctx, fi, li, 50, "bpipe-fd: IO_OPEN fd=%p reader=%s\n", + p_ctx->fd, p_ctx->reader); if (!p_ctx->fd) { io->io_errno = errno; - bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, + bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Open pipe reader=%s failed: ERR=%s\n", p_ctx->reader, strerror(errno)); return bRC_Error; } @@ -349,38 +354,40 @@ static bRC pluginIO(bpContext *ctx, struct io_pkt *io) case IO_READ: if (!p_ctx->fd) { - bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Logic error: NULL read FD\n"); + bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Logic error: 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); +// bfuncs->DebugMessage(ctx, fi, li, 50, "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, + bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, + "Pipe read error: ERR=%s\n", strerror(errno)); + bfuncs->DebugMessage(ctx, fi, li, 50, "Pipe read error: ERR=%s\n", strerror(errno)); -// printf("Error reading pipe\n"); return bRC_Error; } break; case IO_WRITE: if (!p_ctx->fd) { - bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Logic error: NULL write FD\n"); + bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Logic error: 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, + bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Pipe write error\n"); -// printf("Error writing pipe\n"); + bfuncs->DebugMessage(ctx, fi, li, 50, + "Pipe read error: ERR=%s\n", strerror(errno)); return bRC_Error; } break; case IO_CLOSE: if (!p_ctx->fd) { - bfuncs->JobMessage(ctx, __FILE__, __LINE__, M_FATAL, 0, "Logic error: NULL FD\n"); + bfuncs->JobMessage(ctx, fi, li, M_FATAL, 0, "Logic error: NULL FD on bpipe close\n"); return bRC_Error; } io->status = pclose(p_ctx->fd); @@ -405,6 +412,16 @@ static bRC endRestoreFile(bpContext *ctx) return bRC_OK; } +/* + * This is called during restore to create the file (if necessary) + * We must return in rp->create_status: + * + * CF_ERROR -- error + * CF_SKIP -- skip processing this file + * CF_EXTRACT -- extract the file (i.e.call i/o routines) + * CF_CREATED -- created, but no content to extract (typically directories) + * + */ static bRC createFile(bpContext *ctx, struct restore_pkt *rp) { // printf("bpipe-fd: createFile\n"); @@ -413,9 +430,14 @@ static bRC createFile(bpContext *ctx, struct restore_pkt *rp) } strncpy(((struct plugin_ctx *)ctx->pContext)->where, rp->where, 513); ((struct plugin_ctx *)ctx->pContext)->replace = rp->replace; + rp->create_status = CF_EXTRACT; return bRC_OK; } +/* + * We will get here if the File is a directory after everything + * is written in the directory. + */ static bRC setFileAttributes(bpContext *ctx, struct restore_pkt *rp) { // printf("bpipe-fd: setFileAttributes\n"); diff --git a/bacula/src/version.h b/bacula/src/version.h index 65ee06f9c0..48cb5fde0f 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -3,9 +3,9 @@ */ #undef VERSION -#define VERSION "2.5.9" -#define BDATE "30 September 2008" -#define LSMDATE "309Sep08" +#define VERSION "2.5.10" +#define BDATE "03 October 2008" +#define LSMDATE "03Oct08" #define PROG_COPYRIGHT "Copyright (C) %d-2008 Free Software Foundation Europe e.V.\n" #define BYEAR "2008" /* year for copyright messages in progs */ diff --git a/bacula/technotes-2.5 b/bacula/technotes-2.5 index 0ed23d29e9..3aa54b784a 100644 --- a/bacula/technotes-2.5 +++ b/bacula/technotes-2.5 @@ -17,6 +17,11 @@ dbdriver remove reader/writer in FOPTS???? General: +03Oct08 +kes Fix plugin_bwrite - plugin-blseek mixup pointed out by James. +kes Rewrite plugin restore interface a bit to correspond to how Bacula + creates and writes to the restored file. +kes Add some DebugMessage() calls to the bpipe-fd.c program. 30Sep08 kes Apply Marco van Wieringen's set of patches, cleans up Migration/Copy Implement 'Pool Uncopied Jobs', allow Solaris Compiler to build