X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Ffiled%2Ffd_plugins.c;h=ef24d0520e718993d6150072e25e033d6a57f0fa;hb=f9201647d5ecc4a1b0a2d1de7ca339f50fc5d77b;hp=6e547c6dca60917e61ac04f4b6e770049594b6ed;hpb=e487b7a1633c7815701042616b794f784a899bc5;p=bacula%2Fbacula diff --git a/bacula/src/filed/fd_plugins.c b/bacula/src/filed/fd_plugins.c index 6e547c6dca..ef24d0520e 100644 --- a/bacula/src/filed/fd_plugins.c +++ b/bacula/src/filed/fd_plugins.c @@ -62,6 +62,7 @@ static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line, static void *baculaMalloc(bpContext *ctx, const char *file, int line, size_t size); static void baculaFree(bpContext *ctx, const char *file, int line, void *mem); +static bool is_plugin_compatible(Plugin *plugin); /* * These will be plugged into the global pointer structure for @@ -122,7 +123,7 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value) Plugin *plugin; int i = 0; - if (!plugin_list || !jcr || !jcr->plugin_ctx_list) { + if (!plugin_list || !jcr || !jcr->plugin_ctx_list || job_canceled(jcr)) { return; /* Return if no plugins loaded */ } @@ -156,10 +157,10 @@ void generate_plugin_event(JCR *jcr, bEventType eventType, void *value) bool plugin_check_file(JCR *jcr, char *fname) { Plugin *plugin; - bool ok = false; + int rc = bRC_OK; int i = 0; - if (!plugin_list || !jcr || !jcr->plugin_ctx_list) { + if (!plugin_list || !jcr || !jcr->plugin_ctx_list || job_canceled(jcr)) { return false; /* Return if no plugins loaded */ } @@ -177,15 +178,15 @@ bool plugin_check_file(JCR *jcr, char *fname) if (plug_func(plugin)->checkFile == NULL) { continue; } - ok = plug_func(plugin)->checkFile(jcr->plugin_ctx, fname); - if (ok) { + rc = plug_func(plugin)->checkFile(jcr->plugin_ctx, fname); + if (rc == bRC_Seen) { break; } } jcr->plugin = NULL; jcr->plugin_ctx = NULL; - return ok; + return rc == bRC_Seen; } @@ -213,8 +214,10 @@ int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level) char *cmd = ff_pkt->top_fname; struct save_pkt sp; bEvent event; + POOL_MEM fname(PM_FNAME); + POOL_MEM link(PM_FNAME); - if (!plugin_list || !jcr->plugin_ctx_list) { + if (!plugin_list || !jcr->plugin_ctx_list || job_canceled(jcr)) { return 1; /* Return if no plugins loaded */ } @@ -276,13 +279,22 @@ int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level) } jcr->plugin_sp = &sp; ff_pkt = jcr->ff; - ff_pkt->fname = sp.fname; - ff_pkt->link = sp.link; + /* + * Copy fname and link because save_file() zaps them. This + * avoids zaping the plugin's strings. + */ + pm_strcpy(fname, sp.fname); + pm_strcpy(link, sp.link); + ff_pkt->fname = fname.c_str(); + ff_pkt->link = link.c_str(); ff_pkt->type = sp.type; memcpy(&ff_pkt->statp, &sp.statp, sizeof(ff_pkt->statp)); - Dmsg1(dbglvl, "Save_file: file=%s\n", ff_pkt->fname); + Dmsg1(dbglvl, "Save_file: file=%s\n", fname.c_str()); save_file(jcr, ff_pkt, true); bRC rc = plug_func(plugin)->endBackupFile(jcr->plugin_ctx); + if (rc == bRC_More || rc == bRC_OK) { + accurate_mark_file_as_seen(jcr, fname.c_str()); + } if (rc == bRC_More) { continue; } @@ -312,6 +324,9 @@ bool send_plugin_name(JCR *jcr, BSOCK *sd, bool start) Jmsg0(jcr, M_FATAL, 0, _("Plugin save packet not found.\n")); return false; } + if (job_canceled(jcr)) { + return false; + } if (start) { index++; /* JobFiles not incremented yet */ @@ -435,6 +450,7 @@ bail_out: /* * Tell the plugin to create the file. Return values are + * This is called only during Restore * * CF_ERROR -- error * CF_SKIP -- skip processing this file @@ -450,7 +466,7 @@ int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) int flags; int rc; - if (!plugin || !plugin_ctx || !set_cmd_plugin(bfd, jcr)) { + if (!plugin || !plugin_ctx || !set_cmd_plugin(bfd, jcr) || job_canceled(jcr)) { return CF_ERROR; } rp.pkt_size = sizeof(rp); @@ -509,6 +525,7 @@ int plugin_create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace) * Reset the file attributes after all file I/O is done -- this allows * the previous access time/dates to be set properly, and it also allows * us to properly set directory permissions. + * Not currently Implemented. */ bool plugin_set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) { @@ -520,12 +537,15 @@ bool plugin_set_attributes(JCR *jcr, ATTR *attr, BFILE *ofd) return true; } +/* + * Print to file the plugin info. + */ void dump_fd_plugin(Plugin *plugin, FILE *fp) { if (!plugin) { return ; } - pInfo *info = (pInfo *) plugin->pinfo; + pInfo *info = (pInfo *)plugin->pinfo; fprintf(fp, "\tversion=%d\n", info->version); fprintf(fp, "\tdate=%s\n", NPRTB(info->plugin_date)); fprintf(fp, "\tmagic=%s\n", NPRTB(info->plugin_magic)); @@ -549,7 +569,8 @@ void load_fd_plugins(const char *plugin_dir) } plugin_list = New(alist(10, not_owned_by_alist)); - if (!load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type)) { + if (!load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type, + is_plugin_compatible)) { /* Either none found, or some error */ if (plugin_list->size() == 0) { delete plugin_list; @@ -565,15 +586,58 @@ void load_fd_plugins(const char *plugin_dir) plugin_bread = my_plugin_bread; plugin_bwrite = my_plugin_bwrite; plugin_blseek = my_plugin_blseek; + + /* + * Verify that the plugin is acceptable, and print information + * about it. + */ foreach_alist(plugin, plugin_list) { Jmsg(NULL, M_INFO, 0, _("Loaded plugin: %s\n"), plugin->file); Dmsg1(dbglvl, "Loaded plugin: %s\n", plugin->file); - } dbg_plugin_add_hook(dump_fd_plugin); } +/* + * Check if a plugin is compatible. Called by the load_plugin function + * to allow us to verify the plugin. + */ +static bool is_plugin_compatible(Plugin *plugin) +{ + pInfo *info = (pInfo *)plugin->pinfo; + Dmsg0(50, "is_plugin_compatible called\n"); + if (debug_level >= 50) { + dump_fd_plugin(plugin, stdin); + } + if (strcmp(info->plugin_magic, FD_PLUGIN_MAGIC) != 0) { + Jmsg(NULL, M_ERROR, 0, _("Plugin magic wrong. Plugin=%s wanted=%s got=%s\n"), + plugin->file, FD_PLUGIN_MAGIC, info->plugin_magic); + Dmsg3(50, "Plugin magic wrong. Plugin=%s wanted=%s got=%s\n", + plugin->file, FD_PLUGIN_MAGIC, info->plugin_magic); + + return false; + } + if (info->version != FD_PLUGIN_INTERFACE_VERSION) { + Jmsg(NULL, M_ERROR, 0, _("Plugin version incorrect. Plugin=%s wanted=%d got=%d\n"), + plugin->file, FD_PLUGIN_INTERFACE_VERSION, info->version); + Dmsg3(50, "Plugin version incorrect. Plugin=%s wanted=%d got=%d\n", + plugin->file, FD_PLUGIN_INTERFACE_VERSION, info->version); + return false; + } + if (strcmp(info->plugin_license, "Bacula GPLv2") != 0 && + strcmp(info->plugin_license, "GPLv2") != 0) { + Jmsg(NULL, M_ERROR, 0, _("Plugin license incompatible. Plugin=%s license=%s\n"), + plugin->file, info->plugin_license); + Dmsg2(50, "Plugin license incompatible. Plugin=%s license=%s\n", + plugin->file, info->plugin_license); + return false; + } + + return true; +} + + /* * Create a new instance of each plugin for this Job * Note, plugin_list can exist but jcr->plugin_ctx_list can @@ -588,6 +652,9 @@ void new_plugins(JCR *jcr) Dmsg0(dbglvl, "plugin list is NULL\n"); return; } + if (job_canceled(jcr)) { + return; + } int num = plugin_list->size();