From: Radosław Korzeniewski Date: Sat, 14 Dec 2019 14:01:49 +0000 (+0100) Subject: Add pluglib fd plugin support utilities. X-Git-Tag: Release-9.6.0~118 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d106d4362c3ea9b5edcb6e26a9cce8a93862ffb3;p=thirdparty%2Fbacula.git Add pluglib fd plugin support utilities. --- diff --git a/bacula/src/plugins/fd/pluglib.c b/bacula/src/plugins/fd/pluglib.c new file mode 100644 index 000000000..134100925 --- /dev/null +++ b/bacula/src/plugins/fd/pluglib.c @@ -0,0 +1,280 @@ +/* + Bacula(R) - The Network Backup Solution + + Copyright (C) 2000-2019 Kern Sibbald + + The original author of Bacula is Kern Sibbald, with contributions + from many others, a complete list can be found in the file AUTHORS. + + You may use this file and others of this release according to the + license defined in the LICENSE file, which includes the Affero General + Public License, v3.0 ("AGPLv3") and some additional permissions and + terms pursuant to its AGPLv3 Section 7. + + This notice must be preserved when any source code is + conveyed and/or propagated. + + Bacula(R) is a registered trademark of Kern Sibbald. +*/ +/* + * Common definitions and utility functions for Inteos plugins. + * Functions defines a common framework used in our utilities and plugins. + * + * Author: Radosław Korzeniewski, MMXIX + * radoslaw@korzeniewski.net, radekk@inteos.pl + * Inteos Sp. z o.o. http://www.inteos.pl/ + */ + +#include "pluglib.h" + +/* Events that are passed to plugin +typedef enum { + bEventJobStart = 1, + bEventJobEnd = 2, + bEventStartBackupJob = 3, + bEventEndBackupJob = 4, + bEventStartRestoreJob = 5, + bEventEndRestoreJob = 6, + bEventStartVerifyJob = 7, + bEventEndVerifyJob = 8, + bEventBackupCommand = 9, + bEventRestoreCommand = 10, + bEventEstimateCommand = 11, + bEventLevel = 12, + bEventSince = 13, + bEventCancelCommand = 14, + bEventVssBackupAddComponents = 15, + bEventVssRestoreLoadComponentMetadata = 16, + bEventVssRestoreSetComponentsSelected = 17, + bEventRestoreObject = 18, + bEventEndFileSet = 19, + bEventPluginCommand = 20, + bEventVssBeforeCloseRestore = 21, + bEventVssPrepareSnapshot = 22, + bEventOptionPlugin = 23, + bEventHandleBackupFile = 24, + bEventComponentInfo = 25 +} bEventType; +*/ + +const char *eventtype2str(bEvent *event){ + switch (event->eventType){ + case bEventJobStart: + return "bEventJobStart"; + case bEventJobEnd: + return "bEventJobEnd"; + case bEventStartBackupJob: + return "bEventStartBackupJob"; + case bEventEndBackupJob: + return "bEventEndBackupJob"; + case bEventStartRestoreJob: + return "bEventStartRestoreJob"; + case bEventEndRestoreJob: + return "bEventEndRestoreJob"; + case bEventStartVerifyJob: + return "bEventStartVerifyJob"; + case bEventEndVerifyJob: + return "bEventEndVerifyJob"; + case bEventBackupCommand: + return "bEventBackupCommand"; + case bEventRestoreCommand: + return "bEventRestoreCommand"; + case bEventEstimateCommand: + return "bEventEstimateCommand"; + case bEventLevel: + return "bEventLevel"; + case bEventSince: + return "bEventSince"; + case bEventCancelCommand: + return "bEventCancelCommand"; + case bEventVssBackupAddComponents: + return "bEventVssBackupAddComponents"; + case bEventVssRestoreLoadComponentMetadata: + return "bEventVssRestoreLoadComponentMetadata"; + case bEventVssRestoreSetComponentsSelected: + return "bEventVssRestoreSetComponentsSelected"; + case bEventRestoreObject: + return "bEventRestoreObject"; + case bEventEndFileSet: + return "bEventEndFileSet"; + case bEventPluginCommand: + return "bEventPluginCommand"; + case bEventVssBeforeCloseRestore: + return "bEventVssBeforeCloseRestore"; + case bEventVssPrepareSnapshot: + return "bEventVssPrepareSnapshot"; + case bEventOptionPlugin: + return "bEventOptionPlugin"; + case bEventHandleBackupFile: + return "bEventHandleBackupFile"; + case bEventComponentInfo: + return "bEventComponentInfo"; + default: + return "Unknown"; + } +} + + +/* + * Return the real size of the disk based on the size suffix. + * + * in: + * disksize - the numeric value of the disk size to compute + * suff - the suffix for a disksize value + * out: + * uint64_t - the size of the disk computed with suffix + */ +uint64_t pluglib_size_suffix(int disksize, char suff) +{ + uint64_t size; + + switch (suff){ + case 'G': + size = (uint64_t)disksize * 1024 * 1048576; + break; + case 'M': + size = (uint64_t)disksize * 1048576; + break; + case 'T': + size = (uint64_t)disksize * 1048576 * 1048576; + break; + case 'K': + case 'k': + size = (uint64_t)disksize * 1024; + break; + default: + size = disksize; + } + return size; +} + +/* + * Return the real size of the disk based on the size suffix. + * This version uses a floating point numbers (double) for computation. + * + * in: + * disksize - the numeric value of the disk size to compute + * suff - the suffix for a disksize value + * out: + * uint64_t - the size of the disk computed with suffix + */ +uint64_t pluglib_size_suffix(double disksize, char suff) +{ + uint64_t size; + + switch (suff){ + case 'G': + size = disksize * 1024.0 * 1048576.0; + break; + case 'M': + size = disksize * 1048576.0; + break; + case 'T': + size = disksize * 1048576.0 * 1048576.0; + break; + case 'K': + case 'k': + size = disksize * 1024.0; + break; + default: + size = disksize; + } + return size; +} + +/* + * Checks if plugin command points to our Plugin + * + * in: + * command - the plugin command used for backup/restore + * out: + * True - if it is our plugin command + * False - the other plugin command + */ +bool isourplugincommand(const char *pluginprefix, const char *command) +{ + /* check if it is our Plugin command */ + if (strncmp(pluginprefix, command, strlen(pluginprefix)) == 0){ + /* it is not our plugin prefix */ + return true; + } + return false; +} + +/* + * Creates a path hierarchy on local FS. + * It is used for local restore mode to create a required directory. + * The functionality is similar to 'mkdir -p'. + * + * TODO: make a support for relative path + * TODO: check if we can use findlib/makepath implementation instead + * + * in: + * bpContext - for Bacula debug and jobinfo messages + * path - a full path to create, does not check if the path is relative, + * could fail in this case + * out: + * bRC_OK - path creation was successful + * bRC_Error - on any error + */ +bRC pluglib_mkpath(bpContext* ctx, char* path, bool isfatal) +{ +#ifdef PLUGINPREFIX +#define _OLDPREFIX PLUGINPREFIX +#endif +#define PLUGINPREFIX "pluglibmkpath:" + struct stat statp; + POOL_MEM dir(PM_FNAME); + char *p, *q; + + if (!path){ + return bRC_Error; + } + if (stat(path, &statp) == 0){ + if (S_ISDIR(statp.st_mode)){ + return bRC_OK; + } else { + DMSG(ctx, DERROR, "Path %s is not directory\n", path); + JMSG(ctx, isfatal ? M_FATAL : M_ERROR, "Path %s is not directory\n", path); + return bRC_Error; + } + } + DMSG(ctx, DDEBUG, "mkpath verify dir: %s\n", path); + pm_strcpy(dir, path); + p = dir.addr() + 1; + while (*p && (q = strchr(p, (int)PathSeparator)) != NULL){ + *q = 0; + DMSG(ctx, DDEBUG, "mkpath scanning(1): %s\n", dir.c_str()); + if (stat(dir.c_str(), &statp) == 0){ + *q = PathSeparator; + p = q + 1; + continue; + } + DMSG0(ctx, DDEBUG, "mkpath will create dir(1).\n"); + if (mkdir(dir.c_str(), 0750) < 0){ + /* error */ + berrno be; + DMSG2(ctx, DERROR, "Cannot create directory %s Err=%s\n", dir.c_str(), be.bstrerror()); + JMSG2(ctx, isfatal ? M_FATAL : M_ERROR, "Cannot create directory %s Err=%s\n", dir.c_str(), be.bstrerror()); + return bRC_Error; + } + *q = PathSeparator; + p = q + 1; + } + DMSG0(ctx, DDEBUG, "mkpath will create dir(2).\n"); + if (mkdir(path, 0750) < 0){ + /* error */ + berrno be; + DMSG2(ctx, DERROR, "Cannot create directory %s Err=%s\n", path, be.bstrerror()); + JMSG2(ctx, isfatal ? M_FATAL : M_ERROR, "Cannot create directory %s Err=%s\n", path, be.bstrerror()); + return bRC_Error; + } + DMSG0(ctx, DDEBUG, "mkpath finish.\n"); +#ifdef _OLDPREFIX +#define PLUGINPREFIX _OLDPREFIX +#undef _OLDPREFIX +#else +#undef PLUGINPREFIX +#endif + return bRC_OK; +} diff --git a/bacula/src/plugins/fd/pluglib.h b/bacula/src/plugins/fd/pluglib.h new file mode 100644 index 000000000..33a7d3f77 --- /dev/null +++ b/bacula/src/plugins/fd/pluglib.h @@ -0,0 +1,114 @@ +/* + Bacula(R) - The Network Backup Solution + + Copyright (C) 2000-2019 Kern Sibbald + + The original author of Bacula is Kern Sibbald, with contributions + from many others, a complete list can be found in the file AUTHORS. + + You may use this file and others of this release according to the + license defined in the LICENSE file, which includes the Affero General + Public License, v3.0 ("AGPLv3") and some additional permissions and + terms pursuant to its AGPLv3 Section 7. + + This notice must be preserved when any source code is + conveyed and/or propagated. + + Bacula(R) is a registered trademark of Kern Sibbald. +*/ +/* + * Common definitions and utility functions for Inteos plugins. + * Functions defines a common framework used in our utilities and plugins. + * + * Author: Radosław Korzeniewski, MMXIX + * radoslaw@korzeniewski.net, radekk@inteos.pl + * Inteos Sp. z o.o. http://www.inteos.pl/ + */ + +#ifndef _PLUGLIB_H_ +#define _PLUGLIB_H_ + +#include +#include +#include + +#include "bacula.h" +#include "fd_plugins.h" + +/* Pointers to Bacula functions used in plugins */ +extern bFuncs *bfuncs; +extern bInfo *binfo; + +/* definitions */ +/* size of different string or query buffers */ +#define BUFLEN 4096 +#define BIGBUFLEN 65536 + +/* debug and messages functions */ +#define JMSG0(ctx,type,msg) \ + if (ctx) bfuncs->JobMessage ( ctx, __FILE__, __LINE__, type, 0, PLUGINPREFIX " " msg ); + +#define JMSG1 JMSG +#define JMSG(ctx,type,msg,var) \ + if (ctx) bfuncs->JobMessage ( ctx, __FILE__, __LINE__, type, 0, PLUGINPREFIX " " msg, var ); + +#define JMSG2(ctx,type,msg,var1,var2) \ + if (ctx) bfuncs->JobMessage ( ctx, __FILE__, __LINE__, type, 0, PLUGINPREFIX " " msg, var1, var2 ); + +#define JMSG3(ctx,type,msg,var1,var2,var3) \ + if (ctx) bfuncs->JobMessage ( ctx, __FILE__, __LINE__, type, 0, PLUGINPREFIX " " msg, var1, var2, var3 ); + +#define JMSG4(ctx,type,msg,var1,var2,var3,var4) \ + if (ctx) bfuncs->JobMessage ( ctx, __FILE__, __LINE__, type, 0, PLUGINPREFIX " " msg, var1, var2, var3, var4 ); + +#define DMSG0(ctx,level,msg) \ + if (ctx) bfuncs->DebugMessage ( ctx, __FILE__, __LINE__, level, PLUGINPREFIX " " msg ); + +#define DMSG1 DMSG +#define DMSG(ctx,level,msg,var) \ + if (ctx) bfuncs->DebugMessage ( ctx, __FILE__, __LINE__, level, PLUGINPREFIX " " msg, var ); + +#define DMSG2(ctx,level,msg,var1,var2) \ + if (ctx) bfuncs->DebugMessage ( ctx, __FILE__, __LINE__, level, PLUGINPREFIX " " msg, var1, var2 ); + +#define DMSG3(ctx,level,msg,var1,var2,var3) \ + if (ctx) bfuncs->DebugMessage ( ctx, __FILE__, __LINE__, level, PLUGINPREFIX " " msg, var1, var2, var3 ); + +#define DMSG4(ctx,level,msg,var1,var2,var3,var4) \ + if (ctx) bfuncs->DebugMessage ( ctx, __FILE__, __LINE__, level, PLUGINPREFIX " " msg, var1, var2, var3, var4 ); + +#define DMSG6(ctx,level,msg,var1,var2,var3,var4,var5,var6) \ + if (ctx) bfuncs->DebugMessage ( ctx, __FILE__, __LINE__, level, PLUGINPREFIX " " msg, var1, var2, var3, var4, var5, var6 ); + +/* fixed debug level definitions */ +#define D1 1 /* debug for every error */ +#define DERROR D1 +#define D2 10 /* debug only important stuff */ +#define DINFO D2 +#define D3 200 /* debug for information only */ +#define DDEBUG D3 +#define D4 800 /* debug for detailed information only */ +#define DVDEBUG D4 + +#define getBaculaVar(bvar,val) bfuncs->getBaculaValue(ctx, bvar, val); + +/* used for sanity check in plugin functions */ +#define ASSERT_CTX \ + if (!ctx || !ctx->pContext || !bfuncs) \ + { \ + return bRC_Error; \ + } + +/* defines for handleEvent */ +#define DMSG_EVENT_STR(event,value) DMSG2(ctx, DINFO, "%s value=%s\n", eventtype2str(event), NPRT((char *)value)); +#define DMSG_EVENT_CHAR(event,value) DMSG2(ctx, DINFO, "%s value='%c'\n", eventtype2str(event), (char)value); +#define DMSG_EVENT_LONG(event,value) DMSG2(ctx, DINFO, "%s value=%ld\n", eventtype2str(event), (intptr_t)value); +#define DMSG_EVENT_PTR(event,value) DMSG2(ctx, DINFO, "%s value=%p\n", eventtype2str(event), value); + +const char *eventtype2str(bEvent *event); +uint64_t pluglib_size_suffix(int disksize, char suff); +uint64_t pluglib_size_suffix(double disksize, char suff); +bool isourplugincommand(const char *pluginprefix, const char *command); +bRC pluglib_mkpath(bpContext* ctx, char* path, bool isfatal); + +#endif /* _PLUGLIB_H_ */