]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/sd_plugins.c
First cut SD plugin + minor plugin changes
[bacula/bacula] / bacula / src / stored / sd_plugins.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation, which is 
11    listed in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * Main program to test loading and running Bacula plugins.
30  *   Destined to become Bacula pluginloader, ...
31  *
32  * Kern Sibbald, October 2007
33  */
34 #include "bacula.h"
35 #include "stored.h"
36 #include "sd_plugins.h"
37
38 const int dbglvl = 0;
39 const char *plugin_type = "-sd.so";
40
41
42 /* Forward referenced functions */
43 static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value);
44 static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value);
45 static bRC baculaRegisterEvents(bpContext *ctx, ...);
46 static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
47   int type, time_t mtime, const char *msg);
48 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
49   int level, const char *msg);
50
51
52 /* Bacula info */
53 static bInfo binfo = {
54    sizeof(bFuncs),
55    SD_PLUGIN_INTERFACE_VERSION,
56 };
57
58 /* Bacula entry points */
59 static bFuncs bfuncs = {
60    sizeof(bFuncs),
61    SD_PLUGIN_INTERFACE_VERSION,
62    baculaRegisterEvents,
63    baculaGetValue,
64    baculaSetValue,
65    baculaJobMsg,
66    baculaDebugMsg
67 };
68
69 /*
70  * Create a plugin event 
71  */
72 void generate_plugin_event(JCR *jcr, bEventType eventType, void *value)
73 {
74    bEvent event;
75    Plugin *plugin;
76    int i = 0;
77
78    if (!plugin_list) {
79       return;
80    }
81
82    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
83    event.eventType = eventType;
84
85    Dmsg2(dbglvl, "plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
86
87    foreach_alist(plugin, plugin_list) {
88       bRC rc;
89       rc = plug_func(plugin)->handlePluginEvent(&plugin_ctx_list[i++], &event, value);
90       if (rc != bRC_OK) {
91          break;
92       }
93    }
94
95    return;
96 }
97
98 void load_dir_plugins(const char *plugin_dir)
99 {
100    if (!plugin_dir) {
101       return;
102    }
103
104    plugin_list = New(alist(10, not_owned_by_alist));
105    load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type);
106 }
107
108 /*
109  * Create a new instance of each plugin for this Job
110  */
111 void new_plugins(JCR *jcr)
112 {
113    Plugin *plugin;
114    int i = 0;
115
116    if (!plugin_list) {
117       return;
118    }
119
120    int num = plugin_list->size();
121
122    if (num == 0) {
123       return;
124    }
125
126    jcr->plugin_ctx_list = (void *)malloc(sizeof(bpContext) * num);
127
128    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
129    Dmsg2(dbglvl, "Instantiate plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
130    foreach_alist(plugin, plugin_list) {
131       /* Start a new instance of each plugin */
132       plugin_ctx_list[i].bContext = (void *)jcr;
133       plugin_ctx_list[i].pContext = NULL;
134       plug_func(plugin)->newPlugin(&plugin_ctx_list[i++]);
135    }
136 }
137
138 /*
139  * Free the plugin instances for this Job
140  */
141 void free_plugins(JCR *jcr)
142 {
143    Plugin *plugin;
144    int i = 0;
145
146    if (!plugin_list) {
147       return;
148    }
149
150    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
151    Dmsg2(dbglvl, "Free instance plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
152    foreach_alist(plugin, plugin_list) {
153       /* Free the plugin instance */
154       plug_func(plugin)->freePlugin(&plugin_ctx_list[i++]);
155    }
156    free(plugin_ctx_list);
157    jcr->plugin_ctx_list = NULL;
158 }
159
160
161 /* ==============================================================
162  *
163  * Callbacks from the plugin
164  *
165  * ==============================================================
166  */
167 static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value)
168 {
169    JCR *jcr = (JCR *)(ctx->bContext);
170 // Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var);
171    if (!value) {
172       return bRC_Error;
173    }
174 // Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr); 
175    switch (var) {
176    case bVarJobId:
177       *((int *)value) = jcr->JobId;
178       Dmsg1(dbglvl, "Bacula: return bVarJobId=%d\n", jcr->JobId);
179       break;
180    default:
181       break;
182    }
183    return bRC_OK;
184 }
185
186 static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value)
187 {
188    Dmsg1(dbglvl, "bacula: baculaSetValue var=%d\n", var);
189    return bRC_OK;
190 }
191
192 static bRC baculaRegisterEvents(bpContext *ctx, ...)
193 {
194    va_list args;
195    uint32_t event;
196
197    va_start(args, ctx);
198    while ((event = va_arg(args, uint32_t))) {
199       Dmsg1(dbglvl, "Plugin wants event=%u\n", event);
200    }
201    va_end(args);
202    return bRC_OK;
203 }
204
205 static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
206   int type, time_t mtime, const char *msg)
207 {
208    Dmsg5(dbglvl, "Job message: %s:%d type=%d time=%ld msg=%s\n",
209       file, line, type, mtime, msg);
210    return bRC_OK;
211 }
212
213 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
214   int level, const char *msg)
215 {
216    Dmsg4(dbglvl, "Debug message: %s:%d level=%d msg=%s\n",
217       file, line, level, msg);
218    return bRC_OK;
219 }
220
221 #ifdef TEST_PROGRAM
222
223
224 int main(int argc, char *argv[])
225 {
226    char plugin_dir[1000];
227    JCR mjcr1, mjcr2;
228    JCR *jcr1 = &mjcr1;
229    JCR *jcr2 = &mjcr2;
230
231    strcpy(my_name, "test-dir");
232     
233    getcwd(plugin_dir, sizeof(plugin_dir)-1);
234    load_dir_plugins(plugin_dir);
235
236    jcr1->JobId = 111;
237    new_plugins(jcr1);
238
239    jcr2->JobId = 222;
240    new_plugins(jcr2);
241
242    generate_plugin_event(jcr1, bEventJobStart, (void *)"Start Job 1");
243    generate_plugin_event(jcr1, bEventJobEnd);
244    generate_plugin_event(jcr2, bEventJobStart, (void *)"Start Job 1");
245    free_plugins(jcr1);
246    generate_plugin_event(jcr2, bEventJobEnd);
247    free_plugins(jcr2);
248
249    unload_plugins();
250
251    Dmsg0(dbglvl, "bacula: OK ...\n");
252    close_memory_pool();
253    sm_dump(false);
254    return 0;
255 }
256
257 #endif /* TEST_PROGRAM */