]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/sd_plugins.c
ebl Add debug hook
[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 static void dump_sd_plugin(Plugin *plugin, FILE *fp)
99 {
100    if (!plugin) {
101       return ;
102    }
103    pInfo *info = (pInfo *) plugin->pinfo;
104    fprintf(fp, "\tversion=%d\n", info->version);
105    fprintf(fp, "\tdate=%s\n", NPRTB(info->plugin_date));
106    fprintf(fp, "\tmagic=%s\n", NPRTB(info->plugin_magic));
107    fprintf(fp, "\tauthor=%s\n", NPRTB(info->plugin_author));
108    fprintf(fp, "\tlicence=%s\n", NPRTB(info->plugin_license));
109    fprintf(fp, "\tversion=%s\n", NPRTB(info->plugin_version));
110    fprintf(fp, "\tdescription=%s\n", NPRTB(info->plugin_description));
111 }
112
113 void load_dir_plugins(const char *plugin_dir)
114 {
115    if (!plugin_dir) {
116       return;
117    }
118
119    plugin_list = New(alist(10, not_owned_by_alist));
120    load_plugins((void *)&binfo, (void *)&bfuncs, plugin_dir, plugin_type);
121    dbg_plugin_add_hook(dump_sd_plugin);
122 }
123
124 /*
125  * Create a new instance of each plugin for this Job
126  */
127 void new_plugins(JCR *jcr)
128 {
129    Plugin *plugin;
130    int i = 0;
131
132    if (!plugin_list) {
133       return;
134    }
135
136    int num = plugin_list->size();
137
138    if (num == 0) {
139       return;
140    }
141
142    jcr->plugin_ctx_list = (bpContext *)malloc(sizeof(bpContext) * num);
143
144    bpContext *plugin_ctx_list = jcr->plugin_ctx_list;
145    Dmsg2(dbglvl, "Instantiate plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
146    foreach_alist(plugin, plugin_list) {
147       /* Start a new instance of each plugin */
148       plugin_ctx_list[i].bContext = (void *)jcr;
149       plugin_ctx_list[i].pContext = NULL;
150       plug_func(plugin)->newPlugin(&plugin_ctx_list[i++]);
151    }
152 }
153
154 /*
155  * Free the plugin instances for this Job
156  */
157 void free_plugins(JCR *jcr)
158 {
159    Plugin *plugin;
160    int i = 0;
161
162    if (!plugin_list) {
163       return;
164    }
165
166    bpContext *plugin_ctx_list = (bpContext *)jcr->plugin_ctx_list;
167    Dmsg2(dbglvl, "Free instance plugin_ctx_list=%p JobId=%d\n", jcr->plugin_ctx_list, jcr->JobId);
168    foreach_alist(plugin, plugin_list) {
169       /* Free the plugin instance */
170       plug_func(plugin)->freePlugin(&plugin_ctx_list[i++]);
171    }
172    free(plugin_ctx_list);
173    jcr->plugin_ctx_list = NULL;
174 }
175
176
177 /* ==============================================================
178  *
179  * Callbacks from the plugin
180  *
181  * ==============================================================
182  */
183 static bRC baculaGetValue(bpContext *ctx, brVariable var, void *value)
184 {
185    JCR *jcr = (JCR *)(ctx->bContext);
186 // Dmsg1(dbglvl, "bacula: baculaGetValue var=%d\n", var);
187    if (!value) {
188       return bRC_Error;
189    }
190 // Dmsg1(dbglvl, "Bacula: jcr=%p\n", jcr); 
191    switch (var) {
192    case bVarJobId:
193       *((int *)value) = jcr->JobId;
194       Dmsg1(dbglvl, "Bacula: return bVarJobId=%d\n", jcr->JobId);
195       break;
196    default:
197       break;
198    }
199    return bRC_OK;
200 }
201
202 static bRC baculaSetValue(bpContext *ctx, bwVariable var, void *value)
203 {
204    Dmsg1(dbglvl, "bacula: baculaSetValue var=%d\n", var);
205    return bRC_OK;
206 }
207
208 static bRC baculaRegisterEvents(bpContext *ctx, ...)
209 {
210    va_list args;
211    uint32_t event;
212
213    va_start(args, ctx);
214    while ((event = va_arg(args, uint32_t))) {
215       Dmsg1(dbglvl, "Plugin wants event=%u\n", event);
216    }
217    va_end(args);
218    return bRC_OK;
219 }
220
221 static bRC baculaJobMsg(bpContext *ctx, const char *file, int line,
222   int type, time_t mtime, const char *msg)
223 {
224    Dmsg5(dbglvl, "Job message: %s:%d type=%d time=%ld msg=%s\n",
225       file, line, type, mtime, msg);
226    return bRC_OK;
227 }
228
229 static bRC baculaDebugMsg(bpContext *ctx, const char *file, int line,
230   int level, const char *msg)
231 {
232    Dmsg4(dbglvl, "Debug message: %s:%d level=%d msg=%s\n",
233       file, line, level, msg);
234    return bRC_OK;
235 }
236
237 #ifdef TEST_PROGRAM
238
239
240 int main(int argc, char *argv[])
241 {
242    char plugin_dir[1000];
243    JCR mjcr1, mjcr2;
244    JCR *jcr1 = &mjcr1;
245    JCR *jcr2 = &mjcr2;
246
247    strcpy(my_name, "test-dir");
248     
249    getcwd(plugin_dir, sizeof(plugin_dir)-1);
250    load_dir_plugins(plugin_dir);
251
252    jcr1->JobId = 111;
253    new_plugins(jcr1);
254
255    jcr2->JobId = 222;
256    new_plugins(jcr2);
257
258    generate_plugin_event(jcr1, bEventJobStart, (void *)"Start Job 1");
259    generate_plugin_event(jcr1, bEventJobEnd);
260    generate_plugin_event(jcr2, bEventJobStart, (void *)"Start Job 1");
261    free_plugins(jcr1);
262    generate_plugin_event(jcr2, bEventJobEnd);
263    free_plugins(jcr2);
264
265    unload_plugins();
266
267    Dmsg0(dbglvl, "bacula: OK ...\n");
268    close_memory_pool();
269    sm_dump(false);
270    return 0;
271 }
272
273 #endif /* TEST_PROGRAM */