~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/plugin/loader.cc

Added code necessary for building plugins dynamically.
Merged in changes from lifeless to allow autoreconf to work.
Touching plugin.ini files now triggers a rebuid - so config/autorun.sh is no
longer required to be run after touching those.
Removed the duplicate plugin names - also removed the issue that getting them
different would silently fail weirdly later.

Show diffs side-by-side

added added

removed removed

Lines of Context:
59
59
class sys_var_pluginvar;
60
60
static vector<sys_var_pluginvar *> plugin_sysvar_vec;
61
61
 
 
62
char *opt_plugin_add= NULL;
62
63
char *opt_plugin_load= NULL;
63
 
const char *opt_plugin_load_default= QUOTE_ARG(PANDORA_PLUGIN_LIST);
 
64
const char *opt_plugin_load_default= PANDORA_PLUGIN_LIST;
64
65
char *opt_plugin_dir_ptr;
65
66
char opt_plugin_dir[FN_REFLEN];
66
67
static const char *plugin_declarations_sym= "_drizzled_plugin_declaration_";
72
73
static bool initialized= false;
73
74
 
74
75
static DYNAMIC_ARRAY plugin_dl_array;
75
 
static DYNAMIC_ARRAY plugin_array;
 
76
static DYNAMIC_ARRAY module_array;
76
77
 
77
78
static bool reap_needed= false;
78
79
 
130
131
class sys_var_pluginvar: public sys_var
131
132
{
132
133
public:
133
 
  plugin::Handle *plugin;
 
134
  plugin::Module *plugin;
134
135
  struct st_mysql_sys_var *plugin_var;
135
136
 
136
137
  sys_var_pluginvar(const std::string name_arg,
158
159
static bool plugin_load_list(plugin::Registry &registry,
159
160
                             MEM_ROOT *tmp_root, int *argc, char **argv,
160
161
                             const char *list);
161
 
static int test_plugin_options(MEM_ROOT *, plugin::Handle *,
 
162
static int test_plugin_options(MEM_ROOT *, plugin::Module *,
162
163
                               int *, char **);
163
164
static bool register_builtin(plugin::Registry &registry,
164
 
                             plugin::Handle *,
165
 
                             plugin::Handle **);
 
165
                             plugin::Module *,
 
166
                             plugin::Module **);
166
167
static void unlock_variables(Session *session, struct system_variables *vars);
167
168
static void cleanup_variables(Session *session, struct system_variables *vars);
168
169
static void plugin_vars_free_values(sys_var *vars);
321
322
  /* Compile dll path */
322
323
  dlpath.append(opt_plugin_dir);
323
324
  dlpath.append("/");
 
325
  dlpath.append("lib");
324
326
  dlpath.append(dl->str);
 
327
  dlpath.append("_plugin.so");
325
328
  /* Open new dll handle */
326
 
  if (!(plugin_dl.handle= dlopen(dlpath.c_str(), RTLD_LAZY|RTLD_GLOBAL)))
 
329
  if (!(plugin_dl.handle= dlopen(dlpath.c_str(), RTLD_NOW|RTLD_GLOBAL)))
327
330
  {
328
331
    const char *errmsg=dlerror();
329
332
    uint32_t dlpathlen= dlpath.length();
405
408
 
406
409
 
407
410
 
408
 
static plugin::Handle *plugin_insert_or_reuse(plugin::Handle *plugin)
 
411
static plugin::Module *plugin_insert_or_reuse(plugin::Module *module)
409
412
{
410
 
  if (insert_dynamic(&plugin_array, (unsigned char*)&plugin))
411
 
    return(0);
412
 
  plugin= *dynamic_element(&plugin_array, plugin_array.elements - 1,
413
 
                        plugin::Handle **);
414
 
  return(plugin);
 
413
  if (insert_dynamic(&module_array, (unsigned char*)&module))
 
414
    return NULL;
 
415
  module= *dynamic_element(&module_array, module_array.elements - 1,
 
416
                           plugin::Module **);
 
417
  return module;
415
418
}
416
419
 
417
420
 
439
442
  if (library == NULL)
440
443
    return true;
441
444
 
442
 
  plugin::Handle *tmp= NULL;
 
445
  plugin::Module *tmp= NULL;
443
446
  /* Find plugin by name */
444
447
  for (manifest= library->plugins; manifest->name; manifest++)
445
448
  {
448
451
                       (const unsigned char *)manifest->name,
449
452
                       strlen(manifest->name)))
450
453
    {
451
 
      tmp= new (std::nothrow) plugin::Handle(manifest, library);
 
454
      tmp= new (std::nothrow) plugin::Module(manifest, library);
452
455
      if (tmp == NULL)
453
456
        return true;
454
457
 
478
481
}
479
482
 
480
483
 
481
 
static void plugin_del(plugin::Registry &registry, plugin::Handle *plugin)
 
484
static void delete_module(plugin::Registry &registry, plugin::Module *module)
482
485
{
483
 
  if (plugin->isInited)
 
486
  plugin::Manifest manifest= module->getManifest();
 
487
 
 
488
  if (module->isInited)
484
489
  {
485
 
    if (plugin->getManifest().status_vars)
 
490
    if (manifest.status_vars)
486
491
    {
487
 
      remove_status_vars(plugin->getManifest().status_vars);
 
492
      remove_status_vars(manifest.status_vars);
488
493
    }
489
494
 
490
 
    if (plugin->getManifest().deinit)
491
 
      plugin->getManifest().deinit(registry);
 
495
    if (manifest.deinit)
 
496
      manifest.deinit(registry);
492
497
  }
493
498
 
494
499
  /* Free allocated strings before deleting the plugin. */
495
 
  plugin_vars_free_values(plugin->system_vars);
496
 
  if (plugin->plugin_dl)
497
 
    plugin_dl_del(&plugin->plugin_dl->dl);
498
 
  plugin->isInited= false;
 
500
  plugin_vars_free_values(module->system_vars);
 
501
  if (module->plugin_dl)
 
502
    plugin_dl_del(&module->plugin_dl->dl);
 
503
  module->isInited= false;
499
504
  pthread_rwlock_wrlock(&LOCK_system_variables_hash);
500
 
  mysql_del_sys_var_chain(plugin->system_vars);
 
505
  mysql_del_sys_var_chain(module->system_vars);
501
506
  pthread_rwlock_unlock(&LOCK_system_variables_hash);
502
 
  delete plugin;
 
507
  delete module;
503
508
}
504
509
 
505
510
static void reap_plugins(plugin::Registry &plugins)
506
511
{
507
512
  size_t count;
508
513
  uint32_t idx;
509
 
  plugin::Handle *plugin;
 
514
  plugin::Module *module;
510
515
 
511
 
  count= plugin_array.elements;
 
516
  count= module_array.elements;
512
517
 
513
518
  for (idx= 0; idx < count; idx++)
514
519
  {
515
 
    plugin= *dynamic_element(&plugin_array, idx, plugin::Handle **);
516
 
    plugin_del(plugins, plugin);
 
520
    module= *dynamic_element(&module_array, idx, plugin::Module **);
 
521
    delete_module(plugins, module);
517
522
  }
518
523
  drizzle_del_plugin_sysvar();
519
524
}
520
525
 
521
526
 
522
 
static void plugin_initialize_vars(plugin::Handle *plugin)
 
527
static void plugin_initialize_vars(plugin::Module *module)
523
528
{
524
 
  if (plugin->getManifest().status_vars)
 
529
  if (module->getManifest().status_vars)
525
530
  {
526
 
    add_status_vars(plugin->getManifest().status_vars); // add_status_vars makes a copy
 
531
    add_status_vars(module->getManifest().status_vars); // add_status_vars makes a copy
527
532
  }
528
533
 
529
534
  /*
530
535
    set the plugin attribute of plugin's sys vars so they are pointing
531
536
    to the active plugin
532
537
  */
533
 
  if (plugin->system_vars)
 
538
  if (module->system_vars)
534
539
  {
535
 
    sys_var_pluginvar *var= plugin->system_vars->cast_pluginvar();
 
540
    sys_var_pluginvar *var= module->system_vars->cast_pluginvar();
536
541
    for (;;)
537
542
    {
538
 
      var->plugin= plugin;
 
543
      var->plugin= module;
539
544
      if (! var->getNext())
540
545
        break;
541
546
      var= var->getNext()->cast_pluginvar();
545
550
 
546
551
 
547
552
static bool plugin_initialize(plugin::Registry &registry,
548
 
                              plugin::Handle *plugin)
 
553
                              plugin::Module *module)
549
554
{
550
 
  assert(plugin->isInited == false);
 
555
  assert(module->isInited == false);
551
556
 
552
 
  registry.setCurrentHandle(plugin);
553
 
  if (plugin->getManifest().init)
 
557
  registry.setCurrentModule(module);
 
558
  if (module->getManifest().init)
554
559
  {
555
 
    if (plugin->getManifest().init(registry))
 
560
    if (module->getManifest().init(registry))
556
561
    {
557
562
      errmsg_printf(ERRMSG_LVL_ERROR,
558
563
                    _("Plugin '%s' init function returned error.\n"),
559
 
                    plugin->getName().c_str());
 
564
                    module->getName().c_str());
560
565
      return true;
561
566
    }
562
567
  }
563
 
  registry.clearCurrentHandle();
564
 
  plugin->isInited= true;
 
568
  registry.clearCurrentModule();
 
569
  module->isInited= true;
565
570
 
566
571
 
567
572
  return false;
591
596
  uint32_t idx;
592
597
  plugin::Manifest **builtins;
593
598
  plugin::Manifest *manifest;
594
 
  plugin::Handle *handle;
 
599
  plugin::Module *module;
595
600
  MEM_ROOT tmp_root;
596
601
 
597
602
  if (initialized)
607
612
 
608
613
  if (my_init_dynamic_array(&plugin_dl_array,
609
614
                            sizeof(plugin::Library *),16,16) ||
610
 
      my_init_dynamic_array(&plugin_array,
611
 
                            sizeof(plugin::Handle *),16,16))
 
615
      my_init_dynamic_array(&module_array,
 
616
                            sizeof(plugin::Module *),16,16))
612
617
    goto err;
613
618
 
614
619
  initialized= 1;
620
625
  {
621
626
    for (manifest= *builtins; manifest->name; manifest++)
622
627
    {
623
 
      handle= new (std::nothrow) plugin::Handle(manifest);
624
 
      if (handle == NULL)
 
628
      module= new (std::nothrow) plugin::Module(manifest);
 
629
      if (module == NULL)
625
630
        return true;
626
631
 
627
632
      free_root(&tmp_root, MYF(MY_MARK_BLOCKS_FREE));
628
 
      if (test_plugin_options(&tmp_root, handle, argc, argv))
 
633
      if (test_plugin_options(&tmp_root, module, argc, argv))
629
634
        continue;
630
635
 
631
 
      if (register_builtin(registry, handle, &handle))
 
636
      if (register_builtin(registry, module, &module))
632
637
        goto err_unlock;
633
638
 
634
 
      plugin_initialize_vars(handle);
 
639
      plugin_initialize_vars(module);
635
640
 
636
641
      if (! (flags & PLUGIN_INIT_SKIP_INITIALIZATION))
637
642
      {
638
 
        if (plugin_initialize(registry, handle))
 
643
        if (plugin_initialize(registry, module))
639
644
          goto err_unlock;
640
645
      }
641
646
    }
646
651
  if (! (flags & PLUGIN_INIT_SKIP_DYNAMIC_LOADING))
647
652
  {
648
653
    if (opt_plugin_load)
 
654
    {
649
655
      plugin_load_list(registry, &tmp_root, argc, argv, opt_plugin_load);
 
656
    }
 
657
    else
 
658
    {
 
659
      string tmp_plugin_list(opt_plugin_load_default);
 
660
      if (opt_plugin_add)
 
661
      {
 
662
        tmp_plugin_list.push_back(',');
 
663
        tmp_plugin_list.append(opt_plugin_add);
 
664
      }
 
665
      plugin_load_list(registry, &tmp_root, argc, argv, tmp_plugin_list.c_str());
 
666
    }
650
667
  }
651
668
 
652
669
  if (flags & PLUGIN_INIT_SKIP_INITIALIZATION)
655
672
  /*
656
673
    Now we initialize all remaining plugins
657
674
  */
658
 
  for (idx= 0; idx < plugin_array.elements; idx++)
 
675
  for (idx= 0; idx < module_array.elements; idx++)
659
676
  {
660
 
    handle= *dynamic_element(&plugin_array, idx, plugin::Handle **);
661
 
    if (handle->isInited == false)
 
677
    module= *dynamic_element(&module_array, idx, plugin::Module **);
 
678
    if (module->isInited == false)
662
679
    {
663
 
      plugin_initialize_vars(handle);
 
680
      plugin_initialize_vars(module);
664
681
 
665
 
      if (plugin_initialize(registry, handle))
666
 
        plugin_del(registry, handle);
 
682
      if (plugin_initialize(registry, module))
 
683
        delete_module(registry, module);
667
684
    }
668
685
  }
669
686
 
681
698
 
682
699
 
683
700
static bool register_builtin(plugin::Registry &registry,
684
 
                             plugin::Handle *tmp,
685
 
                             plugin::Handle **ptr)
 
701
                             plugin::Module *tmp,
 
702
                             plugin::Module **ptr)
686
703
{
687
704
 
688
705
  tmp->isInited= false;
689
706
  tmp->plugin_dl= 0;
690
707
 
691
 
  if (insert_dynamic(&plugin_array, (unsigned char*)&tmp))
 
708
  if (insert_dynamic(&module_array, (unsigned char*)&tmp))
692
709
    return(1);
693
710
 
694
 
  *ptr= *dynamic_element(&plugin_array, plugin_array.elements - 1,
695
 
                         plugin::Handle **);
 
711
  *ptr= *dynamic_element(&module_array, module_array.elements - 1,
 
712
                         plugin::Module **);
696
713
 
697
714
  registry.add(*ptr);
698
715
 
725
742
      list= NULL; /* terminate the loop */
726
743
      /* fall through */
727
744
    case ':':     /* can't use this as delimiter as it may be drive letter */
728
 
    case ';':
 
745
    case ',':
729
746
      str->str[str->length]= '\0';
730
747
      if (str == &name)  // load all plugins in named module
731
748
      {
787
804
void plugin_shutdown(plugin::Registry &registry)
788
805
{
789
806
  uint32_t idx;
790
 
  size_t count= plugin_array.elements;
791
 
  vector<plugin::Handle *> plugins;
 
807
  size_t count= module_array.elements;
792
808
  vector<plugin::Library *> dl;
793
809
 
794
810
  if (initialized)
807
823
 
808
824
  /* Dispose of the memory */
809
825
 
810
 
  delete_dynamic(&plugin_array);
 
826
  delete_dynamic(&module_array);
811
827
 
812
828
  count= plugin_dl_array.elements;
813
829
  dl.reserve(count);
1133
1149
{
1134
1150
  sys_var *var;
1135
1151
  sys_var_pluginvar *pi= NULL;
1136
 
  plugin::Handle *plugin;
 
1152
  plugin::Module *module;
1137
1153
 
1138
1154
  pthread_rwlock_rdlock(&LOCK_system_variables_hash);
1139
1155
  if ((var= intern_find_sys_var(str, length, false)) &&
1140
1156
      (pi= var->cast_pluginvar()))
1141
1157
  {
1142
1158
    pthread_rwlock_unlock(&LOCK_system_variables_hash);
1143
 
    if (!(plugin= pi->plugin))
 
1159
    if (!(module= pi->plugin))
1144
1160
      var= NULL; /* failed to lock it, it must be uninstalling */
1145
 
    else if (plugin->isInited == false)
 
1161
    else if (module->isInited == false)
1146
1162
    {
1147
1163
      var= NULL;
1148
1164
    }
1877
1893
}
1878
1894
 
1879
1895
 
1880
 
static int construct_options(MEM_ROOT *mem_root, plugin::Handle *tmp,
 
1896
static int construct_options(MEM_ROOT *mem_root, plugin::Module *tmp,
1881
1897
                             my_option *options, bool can_disable)
1882
1898
{
1883
1899
  const char *plugin_name= tmp->getManifest().name;
2105
2121
}
2106
2122
 
2107
2123
 
2108
 
static my_option *construct_help_options(MEM_ROOT *mem_root, plugin::Handle *p)
 
2124
static my_option *construct_help_options(MEM_ROOT *mem_root, plugin::Module *p)
2109
2125
{
2110
2126
  st_mysql_sys_var **opt;
2111
2127
  my_option *opts;
2163
2179
  NOTE:
2164
2180
    Requires that a write-lock is held on LOCK_system_variables_hash
2165
2181
*/
2166
 
static int test_plugin_options(MEM_ROOT *tmp_root, plugin::Handle *tmp,
 
2182
static int test_plugin_options(MEM_ROOT *tmp_root, plugin::Module *tmp,
2167
2183
                               int *argc, char **argv)
2168
2184
{
2169
2185
  struct sys_var_chain chain= { NULL, NULL };
2287
2303
void my_print_help_inc_plugins(my_option *main_options)
2288
2304
{
2289
2305
  vector<my_option> all_options;
2290
 
  plugin::Handle *p;
 
2306
  plugin::Module *p;
2291
2307
  MEM_ROOT mem_root;
2292
2308
  my_option *opt= NULL;
2293
2309
 
2294
2310
  init_alloc_root(&mem_root, 4096, 4096);
2295
2311
 
2296
2312
  if (initialized)
2297
 
    for (uint32_t idx= 0; idx < plugin_array.elements; idx++)
 
2313
    for (uint32_t idx= 0; idx < module_array.elements; idx++)
2298
2314
    {
2299
 
      p= *dynamic_element(&plugin_array, idx, plugin::Handle **);
 
2315
      p= *dynamic_element(&module_array, idx, plugin::Module **);
2300
2316
 
2301
2317
      if (p->getManifest().system_vars == NULL)
2302
2318
        continue;