- 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 the plugin must be careful to always check
- value pointer prior to dereferencing 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 the above are self-explanatory.
-
-\begin{description}
- \item [bEventJobStart] is called whenever a Job starts. The value
- passed is a pointer to a string that contains: "Jobid=nnn
- Job=job-name". Where nnn will be replaced by the JobId and job-name
- will be replaced by the Job name. The variable is temporary so if you
- need the values, you must copy them.
-
- \item [bEventJobEnd] is called whenever a Job ends. No value is passed.
-
- \item [bEventStartBackupJob] is called when a Backup Job begins. No value
- is passed.
-
- \item [bEventEndBackupJob] is called when a Backup Job ends. No value is
- passed.
-
- \item [bEventStartRestoreJob] is called when a Restore Job starts. No value
- is passed.
-
- \item [bEventEndRestoreJob] is called when a Restore Job ends. No value is
- passed.
-
- \item [bEventStartVerifyJob] is called when a Verify Job starts. No value
- is passed.
-
- \item [bEventEndVerifyJob] is called when a Verify Job ends. No value
- is passed.
-
- \item [bEventBackupCommand] is called prior to the bEventStartBackupJob and
- the plugin is passed the command string (everything after the equal sign
- in "Plugin =" as the value.
-
- Note, if you intend to backup a file, this is an important first point to
- write code that copies the command string passed into your pContext area
- so that you will know that a backup is being performed and you will know
- the full contents of the "Plugin =" command (i.e. what to backup and
- what virtual filename the user wants to call it.
-
- \item [bEventRestoreCommand] is called prior to the bEventStartRestoreJob and
- the plugin is passed the command string (everything after the equal sign
- in "Plugin =" as the value.
-
- See the notes above concerning backup and the command string. This is the
- point at which Bacula passes you the original command string that was
- specified during the backup, so you will want to save it in your pContext
- area for later use when Bacula calls the plugin again.
-
- \item [bEventLevel] is called when the level is set for a new Job. The value
- is a 32 bit integer stored in the void*, which represents the Job Level code.
-
- \item [bEventSince] is called when the since time is set for a new Job. The
- value is a time\_t time at which the last job was run.
-\end{description}
-
-During each of the above calls, the plugin receives either no specific value or
-only one value, which in some cases may not be sufficient. However, knowing the
-context of the event, the plugin can call back to the Bacula entry points it
-was passed during the {\bf loadPlugin} call and get to a number of Bacula variables.
-(at the current time few Bacula variables are implemented, but it easily extended
-at a future time and as needs require).
-
-\subsection{startBackupFile(bpContext *ctx, struct save\_pkt *sp)}
-This entry point is called only if your plugin is a command plugin, and
-it is called when Bacula encounters the "Plugin = " directive in
-the Include section of the FileSet.
-Called when beginning the backup of a file. Here Bacula provides you
-with a pointer to the {\bf save\_pkt} structure and you must fill in
-this packet with the "attribute" data of the file.
-
-\begin{verbatim}
-struct save_pkt {
- int32_t pkt_size; /* size of this packet */
- char *fname; /* Full path and filename */
- char *link; /* Link name if any */
- struct stat statp; /* System stat() packet for file */
- int32_t type; /* FT_xx for this file */
- uint32_t flags; /* Bacula internal flags */
- bool portable; /* set if data format is portable */
- char *cmd; /* command */
- int32_t pkt_end; /* end packet sentinel */
-};
-\end{verbatim}
-
-The second argument is a pointer to the {\bf save\_pkt} structure for the file
-to be backed up. The plugin is responsible for filling in all the fields
-of the {\bf save\_pkt}. If you are backing up
-a real file, then generally, the statp structure can be filled in by doing
-a {\bf stat} system call on the file.
-
-If you are backing up a database or
-something that is more complex, you might want to create a virtual file.
-That is a file that does not actually exist on the filesystem, but represents
-say an object that you are backing up. In that case, you need to ensure
-that the {\bf fname} string that you pass back is unique so that it
-does not conflict with a real file on the system, and you need to
-artifically create values in the statp packet.
-
-Example programs such as {\bf bpipe-fd.c} show how to set these fields.
-You must take care not to store pointers the stack in the pointer fields such
-as fname and link, because when you return from your function, your stack entries
-will be destroyed. The solution in that case is to malloc() and return the pointer
-to it. In order to not have memory leaks, you should store a pointer to all memory
-allocated in your pContext structure so that in subsequent calls or at termination,
-you can release it back to the system.
-
-Once the backup has begun, Bacula will call your plugin at the {\bf pluginIO}
-entry point to "read" the data to be backed up. Please see the {\bf bpipe-fd.c}
-plugin for how to do I/O.
-
-Example of filling in the save\_pkt as used in bpipe-fd.c:
-
-\begin{verbatim}
- struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
- time_t now = time(NULL);
- 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;
- p_ctx->backup = true;
- return bRC_OK;
-\end{verbatim}
-
-Note: the filename to be created has already been created from the
-command string previously sent to the plugin and is in the plugin
-context (p\_ctx->fname) and is a malloc()ed string. This example
-creates a regular file (S\_IFREG), with various fields being created.
-
-In general, the sequence of commands issued from Bacula to the plugin
-to do a backup while processing the "Plugin = " directive are:
-
-\begin{enumerate}
- \item generate a bEventBackupCommand event to the specified plugin
- and pass it the command string.
- \item make a startPluginBackup call to the plugin, which
- fills in the data needed in save\_pkt to save as the file
- attributes and to put on the Volume and in the catalog.
- \item call Bacula's internal save\_file() subroutine to save the specified
- file. The plugin will then be called at pluginIO() to "open"
- the file, and then to read the file data.
- Note, if you are dealing with a virtual file, the "open" operation
- is something the plugin does internally and it doesn't necessarily
- mean opening a file on the filesystem. For example in the case of
- the bpipe-fd.c program, it initiates a pipe to the requested program.
- Finally when the plugin signals to Bacula that all the data was read,
- Bacula will call the plugin with the "close" pluginIO() function.
-\end{enumerate}
-
-
-\subsection{endBackupFile(bpContext *ctx)}
-Called at the end of backing up a file for a command plugin. If the plugin's work
-is done, it should return bRC\_OK. If the plugin wishes to create another
-file and back it up, then it must return bRC\_More (not yet implemented).
-This is probably a good time to release any malloc()ed memory you used to
-pass back filenames.
-
-\subsection{startRestoreFile(bpContext *ctx, const char *cmd)}
-Called when the first record is read from the Volume that was
-previously written by the command plugin.
-
-\subsection{createFile(bpContext *ctx, struct restore\_pkt *rp)}
-Called for a command plugin to create a file during a Restore job before
-restoring the data.
-This entry point is called before any I/O is done on the file. After
-this call, Bacula will call pluginIO() to open the file for write.
-
-The data in the
-restore\_pkt is passed to the plugin and is based on the data that was
-originally given by the plugin during the backup and the current user
-restore settings (e.g. where, RegexWhere, replace). This allows the
-plugin to first create a file (if necessary) so that the data can
-be transmitted to it. The next call to the plugin will be a
-pluginIO command with a request to open the file write-only.
-
-This call must return one of the following values:
-
-\begin{verbatim}
- enum {
- CF_SKIP = 1, /* skip file (not newer or something) */
- CF_ERROR, /* error creating file */
- CF_EXTRACT, /* file created, data to extract */
- CF_CREATED /* file created, no data to extract */
-};
-\end{verbatim}
-
-in the restore\_pkt value {\bf create\_status}. For a normal file,
-unless there is an error, you must return {\bf CF\_EXTRACT}.
-
-\begin{verbatim}
-
-struct restore_pkt {
- int32_t pkt_size; /* size of this packet */
- int32_t stream; /* attribute stream id */
- int32_t data_stream; /* id of data stream to follow */
- int32_t type; /* file type FT */
- int32_t file_index; /* file index */
- int32_t LinkFI; /* file index to data if hard link */
- uid_t uid; /* userid */
- struct stat statp; /* decoded stat packet */
- const char *attrEx; /* extended attributes if any */
- const char *ofname; /* output filename */
- const char *olname; /* output link name */
- const char *where; /* where */
- const char *RegexWhere; /* regex where */
- int replace; /* replace flag */
- int create_status; /* status from createFile() */
- int32_t pkt_end; /* end packet sentinel */
-
-};
-\end{verbatim}
-
-Typical code to create a regular file would be the following:
-
-\begin{verbatim}
- struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
- time_t now = time(NULL);
- sp->fname = p_ctx->fname; /* set the full path/filename I want to create */
- sp->type = FT_REG;
- 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;
- return bRC_OK;
-\end{verbatim}
-
-This will create a virtual file. If you are creating a file that actually
-exists, you will most likely want to fill the statp packet using the
-stat() system call.
-
-Creating a directory is similar, but requires a few extra steps:
-
-\begin{verbatim}
- struct plugin_ctx *p_ctx = (struct plugin_ctx *)ctx->pContext;
- time_t now = time(NULL);
- sp->fname = p_ctx->fname; /* set the full path I want to create */
- sp->link = xxx; where xxx is p_ctx->fname with a trailing forward slash
- sp->type = FT_DIREND
- sp->statp.st_mode = 0700 | S_IFDIR;
- 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;
- return bRC_OK;
-\end{verbatim}
-
-The link field must be set with the full cononical path name, which always
-ends with a forward slash. If you do not terminate it with a forward slash,
-you will surely have problems later.
-
-As with the example that creates a file, if you are backing up a real
-directory, you will want to do an stat() on the directory.
-
-Note, if you want the directory permissions and times to be correctly
-restored, you must create the directory {\bf after} all the file directories
-have been sent to Bacula. That allows the restore process to restore all the
-files in a directory using default directory options, then at the end, restore
-the directory permissions. If you do it the other way around, each time you
-restore a file, the OS will modify the time values for the directory entry.