From: Kern Sibbald Date: Fri, 8 Feb 2008 19:07:53 +0000 (+0000) Subject: Plugin updates X-Git-Tag: Release-7.0.0~5055 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=c52a4e2a6649118db4c65cb733da6363b9d6699f;p=bacula%2Fbacula Plugin updates git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6380 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index a863ddd505..4e91bfdbe8 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -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 { diff --git a/bacula/src/filed/fd-plugins.c b/bacula/src/filed/fd-plugins.c index a2c4970c1e..96a01cd83b 100644 --- a/bacula/src/filed/fd-plugins.c +++ b/bacula/src/filed/fd-plugins.c @@ -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; diff --git a/bacula/src/findlib/bfile.c b/bacula/src/findlib/bfile.c index 1473db5999..586d7502f2 100644 --- a/bacula/src/findlib/bfile.c +++ b/bacula/src/findlib/bfile.c @@ -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 */ diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index c7d789340a..3f0ad75377 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -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); diff --git a/bacula/src/lib/bpipe.c b/bacula/src/lib/bpipe.c index 03640a5fb1..58a22eb70f 100644 --- a/bacula/src/lib/bpipe.c +++ b/bacula/src/lib/bpipe.c @@ -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. diff --git a/bacula/src/lib/bpipe.h b/bacula/src/lib/bpipe.h index 49125e1e68..b50439d04c 100644 --- a/bacula/src/lib/bpipe.h +++ b/bacula/src/lib/bpipe.h @@ -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. diff --git a/bacula/src/plugins/fd/bpipe-fd.c b/bacula/src/plugins/fd/bpipe-fd.c index 75fcda85a0..c6c841cc76 100644 --- a/bacula/src/plugins/fd/bpipe-fd.c +++ b/bacula/src/plugins/fd/bpipe-fd.c @@ -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 = ::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;