43
43
#define REPORT_TO_USER 2
45
45
using namespace std;
46
using namespace drizzled;
47
using namespace drizzled::plugin;
47
typedef struct drizzled_plugin_manifest builtin_plugin[];
49
typedef Manifest builtin_plugin[];
48
50
extern builtin_plugin DRIZZLED_BUILTIN_LIST;
49
static drizzled_plugin_manifest *drizzled_builtins[]=
51
static Manifest *drizzled_builtins[]=
51
DRIZZLED_BUILTIN_LIST,(struct drizzled_plugin_manifest *)0
53
DRIZZLED_BUILTIN_LIST,(Manifest *)0
54
56
char *opt_plugin_load= NULL;
55
57
const char *opt_plugin_load_default= QUOTE_ARG(DRIZZLED_PLUGIN_LIST);
56
58
char *opt_plugin_dir_ptr;
57
59
char opt_plugin_dir[FN_REFLEN];
58
static const char *plugin_declarations_sym= "_mysql_plugin_declarations_";
60
static const char *plugin_declarations_sym= "_drizzled_plugin_declaration_";
60
62
/* Note that 'int version' must be the first field of every plugin
61
63
sub-structure (plugin->info).
155
157
static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
156
158
const char *list);
157
static int test_plugin_options(MEM_ROOT *, struct st_plugin_int *,
159
static int test_plugin_options(MEM_ROOT *, Handle *,
159
static bool register_builtin(struct st_plugin_int *,
160
struct st_plugin_int **);
161
static bool register_builtin(Handle *,
161
163
static void unlock_variables(Session *session, struct system_variables *vars);
162
164
static void cleanup_variables(Session *session, struct system_variables *vars);
163
165
static void plugin_vars_free_values(sys_var *vars);
236
238
Plugin support code
237
239
****************************************************************************/
239
static struct st_plugin_dl *plugin_dl_find(const LEX_STRING *dl)
241
static Library *plugin_dl_find(const LEX_STRING *dl)
242
struct st_plugin_dl *tmp;
244
246
for (i= 0; i < plugin_dl_array.elements; i++)
246
tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
248
tmp= *dynamic_element(&plugin_dl_array, i, Library **);
247
249
if (! my_strnncoll(files_charset_info,
248
250
(const unsigned char *)dl->str, dl->length,
249
251
(const unsigned char *)tmp->dl.str, tmp->dl.length))
255
static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl)
257
static Library *plugin_dl_insert_or_reuse(Library *plugin_dl)
258
struct st_plugin_dl *tmp;
260
262
for (i= 0; i < plugin_dl_array.elements; i++)
262
tmp= *dynamic_element(&plugin_dl_array, i, struct st_plugin_dl **);
264
tmp= *dynamic_element(&plugin_dl_array, i, Library **);
264
memcpy(tmp, plugin_dl, sizeof(struct st_plugin_dl));
266
memcpy(tmp, plugin_dl, sizeof(Library));
268
270
if (insert_dynamic(&plugin_dl_array, (unsigned char*)&plugin_dl))
270
272
tmp= *dynamic_element(&plugin_dl_array, plugin_dl_array.elements - 1,
271
struct st_plugin_dl **)=
272
(struct st_plugin_dl *) memdup_root(&plugin_mem_root, (unsigned char*)plugin_dl,
273
sizeof(struct st_plugin_dl));
274
(Library *) memdup_root(&plugin_mem_root, (unsigned char*)plugin_dl,
277
static inline void free_plugin_mem(struct st_plugin_dl *p)
279
static inline void free_plugin_mem(Library *p)
280
282
dlclose(p->handle);
365
367
free_plugin_mem(&plugin_dl);
366
368
if (report & REPORT_TO_USER)
367
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(struct st_plugin_dl));
369
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(Library));
368
370
if (report & REPORT_TO_LOG)
369
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_OUTOFMEMORY), sizeof(struct st_plugin_dl));
371
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_OUTOFMEMORY), sizeof(Library));
380
382
for (i= 0; i < plugin_dl_array.elements; i++)
382
struct st_plugin_dl *tmp= *dynamic_element(&plugin_dl_array, i,
383
struct st_plugin_dl **);
384
Library *tmp= *dynamic_element(&plugin_dl_array, i,
384
386
if (! my_strnncoll(files_charset_info,
385
387
(const unsigned char *)dl->str, dl->length,
386
388
(const unsigned char *)tmp->dl.str, tmp->dl.length))
401
static st_plugin_int *plugin_insert_or_reuse(struct st_plugin_int *plugin)
403
static Handle *plugin_insert_or_reuse(Handle *plugin)
403
struct st_plugin_int *tmp;
404
405
if (insert_dynamic(&plugin_array, (unsigned char*)&plugin))
406
tmp= *dynamic_element(&plugin_array, plugin_array.elements - 1,
407
struct st_plugin_int **)=
408
(struct st_plugin_int *) memdup_root(&plugin_mem_root, (unsigned char*)plugin,
409
sizeof(struct st_plugin_int));
407
plugin= *dynamic_element(&plugin_array, plugin_array.elements - 1,
434
432
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UDF_EXISTS), name->str);
437
/* Clear the whole struct to catch future extensions. */
438
memset(&tmp, 0, sizeof(tmp));
439
if (! (tmp.plugin_dl= plugin_dl_add(dl, report)))
435
Library *library= plugin_dl_add(dl, report);
441
440
/* Find plugin by name */
442
for (plugin= tmp.plugin_dl->plugins; plugin->name; plugin++)
441
for (manifest= library->plugins; manifest->name; manifest++)
444
uint32_t name_len= strlen(plugin->name);
445
443
if (! my_strnncoll(system_charset_info,
446
444
(const unsigned char *)name->str, name->length,
447
(const unsigned char *)plugin->name,
445
(const unsigned char *)manifest->name,
446
strlen(manifest->name)))
450
struct st_plugin_int *tmp_plugin_ptr;
448
tmp= new (std::nothrow) Handle(manifest, library);
453
tmp.name.str= (char *)plugin->name;
454
tmp.name.length= name_len;
456
if (!test_plugin_options(tmp_root, &tmp, argc, argv))
452
if (!test_plugin_options(tmp_root, tmp, argc, argv))
458
if ((tmp_plugin_ptr= plugin_insert_or_reuse(&tmp)))
454
if ((tmp= plugin_insert_or_reuse(tmp)))
460
registry.add(tmp_plugin_ptr);
461
init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096);
457
init_alloc_root(&tmp->mem_root, 4096, 4096);
464
mysql_del_sys_var_chain(tmp.system_vars);
460
mysql_del_sys_var_chain(tmp->system_vars);
467
463
/* plugin was disabled */
482
static void plugin_del(struct st_plugin_int *plugin)
478
static void plugin_del(Handle *plugin)
484
480
PluginRegistry ®istry= PluginRegistry::getPluginRegistry();
485
481
if (plugin->isInited)
487
if (plugin->plugin->status_vars)
483
if (plugin->getManifest().status_vars)
489
remove_status_vars(plugin->plugin->status_vars);
485
remove_status_vars(plugin->getManifest().status_vars);
492
if (plugin->plugin->deinit)
493
plugin->plugin->deinit(registry);
488
if (plugin->getManifest().deinit)
489
plugin->getManifest().deinit(registry);
496
492
/* Free allocated strings before deleting the plugin. */
501
497
pthread_rwlock_wrlock(&LOCK_system_variables_hash);
502
498
mysql_del_sys_var_chain(plugin->system_vars);
503
499
pthread_rwlock_unlock(&LOCK_system_variables_hash);
504
free_root(&plugin->mem_root, MYF(0));
507
503
static void reap_plugins(void)
511
struct st_plugin_int *plugin;
507
drizzled::plugin::Handle *plugin;
513
509
count= plugin_array.elements;
515
511
for (idx= 0; idx < count; idx++)
517
plugin= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
513
plugin= *dynamic_element(&plugin_array, idx, drizzled::plugin::Handle **);
518
514
plugin_del(plugin);
522
static bool plugin_initialize(struct st_plugin_int *plugin)
518
static bool plugin_initialize(drizzled::plugin::Handle *plugin)
524
520
assert(plugin->isInited == false);
526
522
PluginRegistry ®istry= PluginRegistry::getPluginRegistry();
527
if (plugin->plugin->init)
523
if (plugin->getManifest().init)
529
if (plugin->plugin->init(registry))
525
if (plugin->getManifest().init(registry))
531
527
errmsg_printf(ERRMSG_LVL_ERROR,
532
528
_("Plugin '%s' init function returned error.\n"),
529
plugin->getName().c_str());
537
533
plugin->isInited= true;
539
if (plugin->plugin->status_vars)
535
if (plugin->getManifest().status_vars)
541
add_status_vars(plugin->plugin->status_vars); // add_status_vars makes a copy
537
add_status_vars(plugin->getManifest().status_vars); // add_status_vars makes a copy
603
599
if (my_init_dynamic_array(&plugin_dl_array,
604
sizeof(struct st_plugin_dl *),16,16) ||
600
sizeof(Library *),16,16) ||
605
601
my_init_dynamic_array(&plugin_array,
606
sizeof(struct st_plugin_int *),16,16))
602
sizeof(Handle *),16,16))
614
610
for (builtins= drizzled_builtins; *builtins; builtins++)
616
for (plugin= *builtins; plugin->name; plugin++)
612
for (manifest= *builtins; manifest->name; manifest++)
618
memset(&tmp, 0, sizeof(tmp));
620
tmp.name.str= (char *)plugin->name;
621
tmp.name.length= strlen(plugin->name);
614
handle= new (std::nothrow) Handle(manifest);
623
618
free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE));
624
if (test_plugin_options(&tmp_root, &tmp, argc, argv))
619
if (test_plugin_options(&tmp_root, handle, argc, argv))
627
if (register_builtin(&tmp, &plugin_ptr))
622
if (register_builtin(handle, &handle))
630
if (plugin_initialize(plugin_ptr))
625
if (plugin_initialize(handle))
650
645
for (idx= 0; idx < plugin_array.elements; idx++)
652
plugin_ptr= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
653
if (plugin_ptr->isInited == false)
647
handle= *dynamic_element(&plugin_array, idx, Handle **);
648
if (handle->isInited == false)
655
if (plugin_initialize(plugin_ptr))
656
plugin_del(plugin_ptr);
650
if (plugin_initialize(handle))
803
796
dl.reserve(count);
804
797
for (idx= 0; idx < count; idx++)
805
798
dl.push_back(*dynamic_element(&plugin_dl_array, idx,
806
struct st_plugin_dl **));
807
800
for (idx= 0; idx < count; idx++)
808
801
free_plugin_mem(dl[idx]);
809
802
delete_dynamic(&plugin_dl_array);
1870
static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
1863
static int construct_options(MEM_ROOT *mem_root, Handle *tmp,
1871
1864
my_option *options, bool can_disable)
1873
const char *plugin_name= tmp->plugin->name;
1866
const char *plugin_name= tmp->getManifest().name;
1874
1867
uint32_t namelen= strlen(plugin_name), optnamelen;
1875
1868
uint32_t buffer_length= namelen * 4 + (can_disable ? 75 : 10);
1876
1869
char *name= (char*) alloc_root(mem_root, buffer_length) + 1;
2085
static my_option *construct_help_options(MEM_ROOT *mem_root,
2086
struct st_plugin_int *p)
2078
static my_option *construct_help_options(MEM_ROOT *mem_root, Handle *p)
2088
2080
st_mysql_sys_var **opt;
2089
2081
my_option *opts;
2090
2082
bool can_disable;
2091
2083
uint32_t count= EXTRA_OPTIONS;
2093
for (opt= p->plugin->system_vars; opt && *opt; opt++, count+= 2) {};
2085
for (opt= p->getManifest().system_vars; opt && *opt; opt++, count+= 2) {};
2095
if (!(opts= (my_option*) alloc_root(mem_root, sizeof(my_option) * count)))
2087
opts= (my_option*)alloc_root(mem_root, (sizeof(my_option) * count));
2098
2091
memset(opts, 0, sizeof(my_option) * count);
2100
if ((my_strcasecmp(&my_charset_utf8_general_ci, p->name.str, "MyISAM") == 0))
2093
if ((my_strcasecmp(&my_charset_utf8_general_ci, p->getName().c_str(), "MyISAM") == 0))
2101
2094
can_disable= false;
2102
else if ((my_strcasecmp(&my_charset_utf8_general_ci, p->name.str, "MEMORY") == 0))
2095
else if ((my_strcasecmp(&my_charset_utf8_general_ci, p->getName().c_str(), "MEMORY") == 0))
2103
2096
can_disable= false;
2105
2098
can_disable= true;
2141
2134
struct st_bookmark *var;
2142
2135
uint32_t len, count= EXTRA_OPTIONS;
2143
assert(tmp->plugin && tmp->name.str);
2145
for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
2137
for (opt= tmp->getManifest().system_vars; opt && *opt; opt++)
2146
2138
count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
2148
if ((my_strcasecmp(&my_charset_utf8_general_ci, tmp->name.str, "MyISAM") == 0))
2140
if ((my_strcasecmp(&my_charset_utf8_general_ci, tmp->getName().c_str(), "MyISAM") == 0))
2149
2141
can_disable= false;
2150
else if ((my_strcasecmp(&my_charset_utf8_general_ci, tmp->name.str, "MEMORY") == 0))
2142
else if ((my_strcasecmp(&my_charset_utf8_general_ci, tmp->getName().c_str(), "MEMORY") == 0))
2151
2143
can_disable= false;
2153
2145
can_disable= true;
2157
2149
if (!(opts= (my_option*) alloc_root(tmp_root, sizeof(my_option) * count)))
2159
errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory for plugin '%s'."), tmp->name.str);
2151
errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory for plugin '%s'."), tmp->getName().c_str());
2162
2154
memset(opts, 0, sizeof(my_option) * count);
2164
2156
if (construct_options(tmp_root, tmp, opts, can_disable))
2166
errmsg_printf(ERRMSG_LVL_ERROR, _("Bad options for plugin '%s'."), tmp->name.str);
2158
errmsg_printf(ERRMSG_LVL_ERROR, _("Bad options for plugin '%s'."), tmp->getName().c_str());
2184
for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
2176
for (opt= tmp->getManifest().system_vars; opt && *opt; opt++)
2186
2178
if (((o= *opt)->flags & PLUGIN_VAR_NOSYSVAR))
2189
if ((var= find_bookmark(tmp->name.str, o->name, o->flags)))
2181
if ((var= find_bookmark(tmp->getName().c_str(), o->name, o->flags)))
2190
2182
v= new (mem_root) sys_var_pluginvar(var->key + 1, o);
2193
len= tmp->name.length + strlen(o->name) + 2;
2185
len= tmp->getName().length() + strlen(o->name) + 2;
2194
2186
varname= (char*) alloc_root(mem_root, len);
2195
sprintf(varname,"%s-%s",tmp->name.str,o->name);
2187
sprintf(varname,"%s-%s",tmp->getName().c_str(),o->name);
2196
2188
my_casedn_str(&my_charset_utf8_general_ci, varname);
2198
2190
for (p= varname; *p; p++)
2235
2227
Help Verbose text with Plugin System Variables
2236
2228
****************************************************************************/
2238
static int option_cmp(my_option *a, my_option *b)
2240
return my_strcasecmp(&my_charset_utf8_general_ci, a->name, b->name);
2244
void my_print_help_inc_plugins(my_option *main_options, uint32_t size)
2246
DYNAMIC_ARRAY all_options;
2247
struct st_plugin_int *p;
2233
bool operator() (const my_option &a, const my_option &b)
2235
return my_strcasecmp(&my_charset_utf8_general_ci, a.name, b.name);
2240
void my_print_help_inc_plugins(my_option *main_options)
2242
vector<my_option> all_options;
2248
2244
MEM_ROOT mem_root;
2245
my_option *opt= NULL;
2251
2247
init_alloc_root(&mem_root, 4096, 4096);
2252
my_init_dynamic_array(&all_options, sizeof(my_option), size, size/4);
2254
2249
if (initialized)
2255
2250
for (uint32_t idx= 0; idx < plugin_array.elements; idx++)
2257
p= *dynamic_element(&plugin_array, idx, struct st_plugin_int **);
2259
if (!p->plugin->system_vars ||
2260
!(opt= construct_help_options(&mem_root, p)))
2252
p= *dynamic_element(&plugin_array, idx, Handle **);
2254
if (p->getManifest().system_vars == NULL)
2257
opt= construct_help_options(&mem_root, p);
2263
2261
/* Only options with a non-NULL comment are displayed in help text */
2264
2262
for (;opt->id; opt++)
2265
2264
if (opt->comment)
2266
insert_dynamic(&all_options, (unsigned char*) opt);
2266
all_options.push_back(*opt);
2269
2272
for (;main_options->id; main_options++)
2270
insert_dynamic(&all_options, (unsigned char*) main_options);
2274
if (main_options->comment)
2276
all_options.push_back(*main_options);
2272
sort_dynamic(&all_options, (qsort_cmp) option_cmp);
2281
* @TODO: Fix the my_option building so that it doens't break sort
2283
* sort(all_options.begin(), all_options.end(), OptionCmp());
2274
2286
/* main_options now points to the empty option terminator */
2275
insert_dynamic(&all_options, (unsigned char*) main_options);
2277
my_print_help((my_option*) all_options.buffer);
2278
my_print_variables((my_option*) all_options.buffer);
2280
delete_dynamic(&all_options);
2287
all_options.push_back(*main_options);
2289
my_print_help(&*(all_options.begin()));
2290
my_print_variables(&*(all_options.begin()));
2281
2292
free_root(&mem_root, MYF(0));