From: Kern Sibbald Date: Thu, 18 Sep 2008 16:03:37 +0000 (+0000) Subject: Update plugin API documentation X-Git-Tag: Release-3.0.0~966 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=269a4f5d19da1737e3286f4f8164c37fc4049381;p=bacula%2Fdocs Update plugin API documentation --- diff --git a/docs/manuals/en/concepts/concepts.kilepr b/docs/manuals/en/concepts/concepts.kilepr index 8d234ade..18ced57d 100644 --- a/docs/manuals/en/concepts/concepts.kilepr +++ b/docs/manuals/en/concepts/concepts.kilepr @@ -161,10 +161,10 @@ order=-1 [item:newfeatures.tex] archive=true -column=0 +column=8 encoding= highlight=LaTeX -line=439 +line=32 open=true order=0 diff --git a/docs/manuals/en/concepts/newfeatures.tex b/docs/manuals/en/concepts/newfeatures.tex index dbc907c2..052614db 100644 --- a/docs/manuals/en/concepts/newfeatures.tex +++ b/docs/manuals/en/concepts/newfeatures.tex @@ -27,9 +27,10 @@ or moved and if any files have been deleted. This allows Bacula to make an accur backup of your system to that point in time so that if you do a restore, it will restore your system exactly. One note of caution about using Accurate backup is that it requires more resources (CPU and memory) on both the Director and -the Client machine to create the list of previous files backed up, to send that -list to the File daemon, and do comparisons on the File daemon between every file -and the list. +the Client machines to create the list of previous files backed up, to send that +list to the File daemon, for the File daemon to keep the list (possibly very big) +in memory, and for the File daemon to do comparisons between every file in the +FileSet and the list. \section{Copy Jobs} @@ -593,3 +594,294 @@ A new job directive permits to specify the spool size per job. This is used in advanced job tunning. {\bf SpoolSize={\it bytes}} \end{description} + +\section{Building Bacula Plugins} +There is currently one sample program {\bf example-plugin-fd.c} and +one working plugin {\bf bpipe-fd.c} that can be found in the Bacula +{\bf src/plugins/fd} directory. Both are built with the following: + +\begin{verbatim} + cd + ./configure + make + ... + cd src/plugins/fd + make + make test +\end{verbatim} + +After building Bacula and changing into the src/plugins/fd directory, +the {\bf make} command will build the {\bf bpipe-fd.so} plugin, which +is a very useful and working program. + +The {\bf make test} command will build the {\bf example-plugin-fd.so} +plugin and a binary named main, which is build from the source +code located in {\bf src/filed/fd\_plugins.c}. + +If you execute {\bf ./main}, it will load and run the example-plugin-fd +plugin simulating a small number of the calling sequences that Bacula uses +in calling a real plugin. This allows you to do initial testing of +your plugin prior to trying it with Bacula. + +You can get a good idea of how to write your own plugin by first +studying the example-plugin-fd, and actually running it. Then +it can also be instructive to read the bpipe-fd.c code as it is +a real plugin, which is still rather simple and small. + +When actually writing your own plugin, you may use the example-plugin-fd.c +code as a template for your code. + +\section{Bacula FD Plugin API} +To write a Bacula plugin, you cread a dynamic shared object +program (or dll on Win32) with a particular name and two +entry points, place it in the {\bf Plugins Directory}, and when the FD +starts, it will load all the plugins found in that directory. +Once it loads them, it calls the {\bf loadPlugin} entry point (see below) +then later, it will call particular functions that are defined by the +{\bf loadPlugin} interface. When Bacula is finished with the plugin +(when Bacula is going to exit), it will call the {\bf unloadPlugin} +entry point. + +The two entry points are: + +\begin{verbatim} +bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs) + +and + +bRC unloadPlugin() +\end{verbatim} + +both these entry points to the shared object are defined as C entry points +to avoid name mangling complications with C++. However, the shared object +can actually be written in any language. + +The definitions for {\bf bRC} and the arguments are {\bf +src/filed/fd-plugins.h} and so this header file needs to be included in +your plug. It along with {\bf lib/plugins.h} define basically the whole +plugin interface. Within this header file, it includes the fillowing +files: + +\begin{verbatim} +#include +#include "config.h" +#include "bc_types.h" +#include "lib/plugins.h" +#include +\end{verbatim} + +Aside from the {\bf bc\_types.h} header, the plugin definition uses the +minimum code from Bacula. The bc\_types.h file is required to ensure that +the data type defintions in arguments correspond to the Bacula core code. + +At a future point in time, we hope to make the Bacula libbac.a into a +shared object so that the plugin can use much more of Bacula's +infrastructure, but for this first cut, we have tried to minimize the +dependence on Bacula. + +\subsection{loadPlugin} +As previously mentioned, the {\bf loadPlugin} entry point in the plugin +is called immediately after Bacula loads the plugin. In calling the +plugin, the first two arguments are information from Bacula that +is passed to the plugin, and the last two arguments are information +about the plugin that is returned to Bacula. The call is: + +\begin{verbatim} +bRC loadPlugin(bInfo *lbinfo, bFuncs *lbfuncs, pInfo **pinfo, pFuncs **pfuncs) +\end{verbatim} + +and the arguments are: + +\begin{description} +\item [lbinfo] +This is information about Bacula in general. Currently, the only value +defined in the bInfo structure is version, which is the Bacula plugin +interface version, currently defined as 1. +The exact definition as of this writing is: + +\begin{verbatim} +typedef struct s_baculaInfo { + uint32_t size; + uint32_t version; +} bInfo; +\end{verbatim} + +\item [lbfuncs] +The bFuncs structure defines the callback entry points within Bacula +that the plugin can use register events, get Bacula values, set +Bacula values, and send messages to the Job output. + +The exact definition as of this writing is: + +\begin{verbatim} +ypedef struct s_baculaFuncs { + uint32_t size; + uint32_t version; + bRC (*registerBaculaEvents)(bpContext *ctx, ...); + bRC (*getBaculaValue)(bpContext *ctx, bVariable var, void *value); + bRC (*setBaculaValue)(bpContext *ctx, bVariable var, void *value); + bRC (*JobMessage)(bpContext *ctx, const char *file, int line, + int type, time_t mtime, const char *fmt, ...); + bRC (*DebugMessage)(bpContext *ctx, const char *file, int line, + int level, const char *fmt, ...); +} bFuncs; +\end{verbatim} + +We will discuss these entry points and how to use them a bit later when +describing the plugin code. + +\item [pInfo] +When the loadPlugin entry point is called, the plugin must initialize +an information structure about the plugin and return a pointer to +this structure to Bacula. + +The exact definition as of this writing is: + +\begin{verbatim} +typedef struct s_pluginInfo { + uint32_t size; + uint32_t version; + const char *plugin_magic; + const char *plugin_license; + const char *plugin_author; + const char *plugin_date; + const char *plugin_version; + const char *plugin_description; +} pInfo; +\end{verbatim} + +Where: + \begin{description} + \item [version] is the current plugin interface version, currently + set to 1. + \item [plugin\_magic] is a pointer to the string "*FDPluginData*", a + sort of sanity check. + \item [plugin\_license] is a pointer to a string that describes the + plugin license. + \item [plugin\_author] is a pointer to the name of the author of the program. + \item [plugin\_date] is the pointer string containing the date of the plugin. + \item [plugin\_version] is a pointer to a string containing the version of + the plugin. + \item [plugin\_description] is a pointer to a string describing what the + plugin does. + \end{description} + +The pInfo structure must be defined in static memory because Bacula does not +copy it and may refer to the values at any time while the plugin is +loaded. + +\item [pFuncs] +When the loadPlugin entry point is called, the plugin must initialize +an entry point structure about the plugin and return a pointer to +this structure to Bacula. This structure contains pointer to each +of the entry points that the plugin must provide for Bacula. When +Bacula is actually running the plugin, it will call the defined +entry points at particular times. All entry points must be defined. + +The pFuncs structure must be defined in static memory because Bacula does not +copy it and may refer to the values at any time while the plugin is +loaded. + + +The exact definition as of this writing is: + +\begin{verbatim} +typedef struct s_pluginFuncs { + uint32_t size; + uint32_t version; + bRC (*newPlugin)(bpContext *ctx); + bRC (*freePlugin)(bpContext *ctx); + bRC (*getPluginValue)(bpContext *ctx, pVariable var, void *value); + bRC (*setPluginValue)(bpContext *ctx, pVariable var, void *value); + bRC (*handlePluginEvent)(bpContext *ctx, bEvent *event, void *value); + bRC (*startBackupFile)(bpContext *ctx, struct save_pkt *sp); + bRC (*endBackupFile)(bpContext *ctx); + bRC (*startRestoreFile)(bpContext *ctx, const char *cmd); + bRC (*endRestoreFile)(bpContext *ctx); + bRC (*pluginIO)(bpContext *ctx, struct io_pkt *io); + bRC (*createFile)(bpContext *ctx, struct restore_pkt *rp); + bRC (*setFileAttributes)(bpContext *ctx, struct restore_pkt *rp); +} pFuncs; +\end{verbatim} + +Where: + \begin{description} + \item [size] is the size of the structure. + \item [version] is the plugin interface version. + \item [newPlugin] is the entry point that Bacula will call + when a new instance of the plugin is created. This typically + happens at the beginning of a Job. If 10 Jobs are running + simultaneously, there will be at least 10 instances of the + plugin. + + The bpContext structure will be passed to the plugin, and + during this call, if the plugin needs to have any private + working storage that is associated with the particular + instance of the plugin, it should create it from the heap + (malloc the memory). The plugin then puts a pointer to + its private working storage in the {\bf pContext} variable. + +\begin{verbatim} +typedef struct s_bpContext { + void *pContext; /* Plugin private context */ + void *bContext; /* Bacula private context */ +} bpContext; + +\end{verbatim} + + This context pointer will be passed as the first argument to all + the entry points that Bacula can call within the plugin. Needless + to say, the plugin should not change the bContext variable, which + is Bacula's private context pointer for this instance of this + plugin. + + \item [freePlugin] this entry point is called when the + this instance of the plugin is no longer needed (the Job is + ending), and the plugin should release any memory it may + have allocated for the pContext. + + \item [getPluginValue] Bacula will call this entry point to get + a value from the plugin. This entry point is currently not called. + + \item [setPluginValue] Bacula will call this entry point to set + a value in the plugin. This entry point is currently not called. + + \item [handlePluginEvent] This entry point is called when Bacula + encounters certain events. Bacula passes the pointer to an event + structure (bEvent), which currently has one item, the eventType: + +\begin{verbatim} +typedef struct s_bEvent { + uint32_t eventType; +} bEvent; +\end{verbatim} + + which defines what event has been triggered, and for each event, + Bacula will pass a pointer to a value associated with that event. + If no value is associated with a particular event, Bacula will + pass a NULL pointer, so you must always check for it. + + The current list of events are: + +\begin{verbatim} +typedef enum { + bEventJobStart = 1, + bEventJobEnd = 2, + bEventStartBackupJob = 3, + bEventEndBackupJob = 4, + bEventStartRestoreJob = 5, + bEventEndRestoreJob = 6, + bEventStartVerifyJob = 7, + bEventEndVerifyJob = 8, + bEventBackupCommand = 9, + bEventRestoreCommand = 10, + bEventLevel = 11, + bEventSince = 12, +} bEventType; + +\end{verbatim} + +Most of which are pretty explanatory. + \end{description} + +\end{description}