From: Radosław Korzeniewski Date: Thu, 8 Apr 2021 13:02:12 +0000 (+0200) Subject: metaplugin: Add local restore with Core functions. X-Git-Tag: Release-11.3.2~593 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=88f94e9a1ab37d6145b0a4f894e4189acbc09d20;p=thirdparty%2Fbacula.git metaplugin: Add local restore with Core functions. --- diff --git a/bacula/src/plugins/fd/pluginlib/Makefile b/bacula/src/plugins/fd/pluginlib/Makefile index 812107c81..ec741f92a 100644 --- a/bacula/src/plugins/fd/pluginlib/Makefile +++ b/bacula/src/plugins/fd/pluginlib/Makefile @@ -77,6 +77,14 @@ test_metaplugin_backend.lo: $(TESTMETAPLUGINBACKENDSRC) @echo "Compiling backend $< ..." $(NO_ECHO)$(LIBTOOL_COMPILE) $(CXX) $(DEFS) $(DEBUG) $(CPPFLAGS) $(CFLAGS) -I${SRCDIR} -I${FDDIR} -DLOGDIR=\"$(DESTDIR)$(working_dir)\" -c $< +test_metaplugin_backend_fd: $(TESTMETAPLUGINBACKENDOBJ) test_metaplugin_backend_fd.lo + @echo "Building $@ ..." + $(NO_ECHO)$(LIBTOOL_LINK) --silent $(CXX) $(LDFLAGS) test_metaplugin_backend_fd.lo $(TESTMETAPLUGINBACKENDOBJ) -o $@ + +test_metaplugin-fd.la: $(PTCOMMOBJ) $(PLUGINLIBSOBJ) $(METAPLUGINOBJ) test_metaplugin-fd.lo + @echo "Linking $(@:.la=.so) ..." + $(NO_ECHO)$(LIBTOOL_LINK) --silent $(CXX) $(LDFLAGS) -shared $^ -o $@ -rpath $(plugindir) -module -export-dynamic -avoid-version + pluginlib_test: $(PLUGINLIBSTESTOBJ) $(PLUGINLIBSTEST) $(UNITTESTSOBJ) $(LIBBACOBJ) @echo "Building $@ ..." $(NO_ECHO)$(LIBTOOL_LINK) --silent $(CXX) $(LDFLAGS) -L$(LIBDIR) -lbac $(PLUGINLIBSTESTOBJ) -o $@ diff --git a/bacula/src/plugins/fd/pluginlib/metaplugin.cpp b/bacula/src/plugins/fd/pluginlib/metaplugin.cpp index 852c48d2d..93e255e59 100644 --- a/bacula/src/plugins/fd/pluginlib/metaplugin.cpp +++ b/bacula/src/plugins/fd/pluginlib/metaplugin.cpp @@ -17,7 +17,7 @@ Bacula(R) is a registered trademark of Kern Sibbald. */ /** - * @file metaplugin.h + * @file metaplugin.cpp * @author Radosław Korzeniewski (radoslaw@korzeniewski.net) * @brief This is a Bacula metaplugin interface. * @version 2.1.0 @@ -2145,10 +2145,14 @@ bRC METAPLUGIN::endBackupFile(bpContext *ctx) } /* - * The PLUGIN is not using this callback to handle restore. + * The PLUGIN is using this callback to handle Core restore. */ bRC METAPLUGIN::startRestoreFile(bpContext *ctx, const char *cmd) { + if (CORELOCALRESTORE && islocalpath(where)){ + DMSG0(ctx, DDEBUG, "Forwarding restore to Core\n"); + return bRC_Core; + } return bRC_OK; } @@ -2594,7 +2598,7 @@ static bRC startRestoreFile(bpContext *ctx, const char *cmd) { ASSERT_CTX; - DMSG0(ctx, D1, "startRestoreFile.\n"); + DMSG1(ctx, D1, "startRestoreFile: %s\n", NPRT(cmd)); METAPLUGIN *self = pluginclass(ctx); return self->startRestoreFile(ctx, cmd); } diff --git a/bacula/src/plugins/fd/pluginlib/metaplugin.h b/bacula/src/plugins/fd/pluginlib/metaplugin.h index f17fcabf2..6ebeff31a 100644 --- a/bacula/src/plugins/fd/pluginlib/metaplugin.h +++ b/bacula/src/plugins/fd/pluginlib/metaplugin.h @@ -40,6 +40,17 @@ #define PLUGINLIB_METAPLUGIN_H +// custom checkFile() callback +typedef bRC (*checkFile_t)(bpContext *ctx, char *fname); + +// metadata handling map +struct metadataTypeMap +{ + const char *command; + metadata_type type; +}; +extern const metadataTypeMap plugin_metadata_map[]; + // Plugin Info definitions extern const char *PLUGIN_LICENSE; extern const char *PLUGIN_AUTHOR; @@ -48,16 +59,17 @@ extern const char *PLUGIN_VERSION; extern const char *PLUGIN_DESCRIPTION; // Plugin linking time variables -extern const char *PLUGINPREFIX; -extern const char *PLUGINNAME; -extern const char *PLUGINNAMESPACE; -extern const bool CUSTOMNAMESPACE; +extern const char *PLUGINPREFIX; /// is used for prefixing every Job and Debug messages generted by a plugin +extern const char *PLUGINNAME; /// should match the backend $pluginname$ used for Handshake procedure +extern const bool CUSTOMNAMESPACE; /// defines if metaplugin should send `Namespace=...` backend plugin parameter using PLUGINNAMESPACE variable +extern const char *PLUGINNAMESPACE; /// custom backend plugin namespace used as file name prefix extern const char *PLUGINAPI; extern const char *BACKEND_CMD; -// custom checkFile() callback -typedef bRC (*checkFile_t)(bpContext *ctx, char *fname); -extern checkFile_t checkFile; +/// defines if metaplugin should handle local filesystem restore with Bacula Core functions +/// `false` means metaplugin will redirect local restore to backend +/// `true` means Bacula Core functions will handle local restore +extern const bool CORELOCALRESTORE; // The list of restore options saved to the RestoreObject. extern struct ini_items plugin_items_dump[]; @@ -65,13 +77,8 @@ extern struct ini_items plugin_items_dump[]; // the list of valid plugin options extern const char *valid_params[]; -struct metadataTypeMap -{ - const char *command; - metadata_type type; -}; - -extern const metadataTypeMap plugin_metadata_map[]; +// custom checkFile() callback +extern checkFile_t checkFile; /* * This is a main plugin API class. It manages a plugin context. diff --git a/bacula/src/plugins/fd/pluginlib/pluginlib.h b/bacula/src/plugins/fd/pluginlib/pluginlib.h index b13713a9e..871dad3c3 100644 --- a/bacula/src/plugins/fd/pluginlib/pluginlib.h +++ b/bacula/src/plugins/fd/pluginlib/pluginlib.h @@ -183,6 +183,25 @@ inline bool isourpluginfname(const char *pluginprefix, const char *fname) alist * plugutil_str_split_to_alist(const char * str, const char sep = '.'); +/** + * @brief Verifies if path is local except '/' + * + * @param path + * @return true + * @return false + */ +inline bool islocalpath(const char *path) +{ + bool result = path && strlen(path) > 1; + bool spath = path[0] == '/'; +#ifdef HAVE_WIN32 + bool wpath = isalpha(path[0]) && path[1] == ':' ; // simple drive letter +#else + bool wpath = false; +#endif + return result && (spath || wpath); +} + /* plugin parameters manipulation */ bool render_param(POOLMEM **param, const char *pname, const char *fmt, const char *name, const char *value); bool render_param(POOLMEM **param, const char *pname, const char *fmt, const char *name, const int value); diff --git a/bacula/src/plugins/fd/pluginlib/pluginlib_test.cpp b/bacula/src/plugins/fd/pluginlib/pluginlib_test.cpp index 7352fcd08..c4f994b49 100644 --- a/bacula/src/plugins/fd/pluginlib/pluginlib_test.cpp +++ b/bacula/src/plugins/fd/pluginlib/pluginlib_test.cpp @@ -32,6 +32,13 @@ bFuncs *bfuncs; bInfo *binfo; +struct vectstruct +{ + const char *path; + bool result; + const char *descr; +}; + int main() { Unittests pluglib_test("pluglib_test"); @@ -98,5 +105,27 @@ int main() ok(bstrcmp(param.c_str(), fname1) , "check scan parameter for char* str param"); nok(scan_parameter_str(cmd2, "prefix", param), "check scan parameter for char* str not match"); + const vectstruct testvect1[] = { + { "", false, "checking empty" }, + { "/", false, "checking slash" }, + { "other", false, "checking other" }, + { "/tmp", true, "checking local" }, + { "/tmp/restore", true, "checking local" }, +#ifdef HAVE_WIN32 + { "c:", true, "checking local win32" }, + { "d:/", true, "checking local win32" }, + { "E:/", true, "checking local win32" }, + { "F:/test", true, "checking local win32" }, + { "g:/test/restore", true, "checking local win32" }, +#endif + { NULL, false, NULL }, + }; + + for (int i = 0; testvect1[i].path != NULL; i++) + { + bool result = islocalpath(testvect1[i].path); + ok(result == testvect1[i].result, testvect1[i].descr); + } + return report(); }